From bca5c95e909012eec6566d1fff86d9c48e76e96d Mon Sep 17 00:00:00 2001 From: "jidhin.angadithazha" Date: Thu, 19 Mar 2026 11:49:16 +0100 Subject: [PATCH] Flex OBC Initial Package creation --- Makefile | 710 + Makefile.static | 352 + Makefile.wrapper | 192 + Source/appl/ARMBrsHwIntTb_CortexR.c | 674 + Source/appl/ARMBrsHw_CortexR.c | 296 + Source/appl/ARMStartup_CortexR.c | 754 + Source/appl/BrsHw.c | 845 + Source/appl/BrsMain.c | 954 + Source/appl/BrsMainStartup.c | 584 + Source/appl/BrsMain_Appl.c | 892 + Source/appl/BrsMain_Callout_Stubs.c | 255 + Source/appl/BrsMain_FblOsStub.c | 148 + Source/appl/bm_ap.c | 1032 ++ Source/appl/fbl_secboot_ap.c | 232 + Source/bsw/Common/Can_GeneralTypes.h | 80 + Source/bsw/Common/ComStack_Types.h | 284 + Source/bsw/Common/Compiler.h | 191 + Source/bsw/Common/Compiler_Cfg.h | 1014 + Source/bsw/Common/EthSwt_GeneralTypes.h | 393 + Source/bsw/Common/EthTrcv_GeneralTypes.h | 176 + Source/bsw/Common/Eth_GeneralTypes.h | 91 + Source/bsw/Common/Eth_GeneralTypesDefs.h | 315 + Source/bsw/Common/Fr_GeneralTypes.h | 322 + Source/bsw/Common/Lin_GeneralTypes.h | 254 + Source/bsw/Common/MemMap.h | 2993 +++ Source/bsw/Common/Platform_Types.h | 216 + Source/bsw/Common/Std_Types.h | 198 + Source/bsw/Common/v_def.h | 1175 ++ Source/bsw/CryIf/CryIf.c | 2014 ++ Source/bsw/CryIf/CryIf.h | 649 + Source/bsw/CryIf/CryIf_Cbk.h | 63 + Source/bsw/CryIf/CryIf_Private.h | 202 + Source/bsw/CryIf/Make/CryIf_cfg.mak | 81 + Source/bsw/CryIf/Make/CryIf_check.mak | 79 + Source/bsw/CryIf/Make/CryIf_defs.mak | 82 + Source/bsw/CryIf/Make/CryIf_rules.mak | 101 + .../BSWMD/Crypto_30_LibCv_MemMap.arxml | 117 + .../BSWMD/Crypto_30_LibCv_bswmd.arxml | 15429 ++++++++++++++++ Source/bsw/Crypto_30_LibCv/ChangeHistory.txt | 77 + .../TechnicalReference_Crypto_30_LibCv.pdf | Bin 0 -> 387770 bytes .../GeneratorMsr/Crypto_30_LibCv.jar | Bin 0 -> 2581796 bytes .../Implementation/Crypto_30_LibCv.c | 5051 +++++ .../Implementation/Crypto_30_LibCv.h | 600 + .../Implementation/Crypto_30_LibCv_Aead.c | 1695 ++ .../Crypto_30_LibCv_AeadDecrypt.h | 132 + .../Crypto_30_LibCv_AeadEncrypt.h | 132 + .../Crypto_30_LibCv_AutosarDefines.h | 390 + .../Implementation/Crypto_30_LibCv_Cipher.c | 3018 +++ .../Implementation/Crypto_30_LibCv_Curve.c | 1474 ++ .../Implementation/Crypto_30_LibCv_Curve.h | 151 + .../Implementation/Crypto_30_LibCv_Custom.h | 626 + .../Implementation/Crypto_30_LibCv_Decrypt.h | 243 + .../Implementation/Crypto_30_LibCv_Encrypt.h | 190 + .../Implementation/Crypto_30_LibCv_Hash.c | 235 + .../Implementation/Crypto_30_LibCv_Hash.h | 151 + .../Crypto_30_LibCv_InternalApi.h | 402 + .../Crypto_30_LibCv_KeyDerive.c | 5359 ++++++ .../Crypto_30_LibCv_KeyDerive.h | 502 + .../Crypto_30_LibCv_KeyExchange.c | 4477 +++++ .../Crypto_30_LibCv_KeyExchange.h | 663 + .../Crypto_30_LibCv_KeyGenerate.c | 1156 ++ .../Crypto_30_LibCv_KeyGenerate.h | 297 + .../Crypto_30_LibCv_KeyManagement.c | 8444 +++++++++ .../Crypto_30_LibCv_KeyManagement.h | 667 + .../Crypto_30_LibCv_KeySetInvalid.h | 73 + .../Crypto_30_LibCv_KeySetValid.h | 74 + .../Crypto_30_LibCv_KeyUnwrap.h | 79 + .../Implementation/Crypto_30_LibCv_KeyWrap.c | 556 + .../Implementation/Crypto_30_LibCv_KeyWrap.h | 78 + .../Implementation/Crypto_30_LibCv_Mac.c | 3202 ++++ .../Crypto_30_LibCv_MacGenerate.h | 261 + .../Crypto_30_LibCv_MacVerify.h | 261 + .../Implementation/Crypto_30_LibCv_Random.c | 3303 ++++ .../Crypto_30_LibCv_RandomGenerate.h | 135 + .../Crypto_30_LibCv_RandomSeed.h | 153 + .../Implementation/Crypto_30_LibCv_Services.h | 1723 ++ .../Crypto_30_LibCv_Signature.c | 6445 +++++++ .../Crypto_30_LibCv_SignatureGenerate.h | 334 + .../Crypto_30_LibCv_SignatureVerify.h | 389 + .../Make/Crypto_30_LibCv_cfg.mak | 81 + .../Make/Crypto_30_LibCv_check.mak | 79 + .../Make/Crypto_30_LibCv_defs.mak | 81 + .../Make/Crypto_30_LibCv_rules.mak | 105 + Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm.c | 1806 ++ Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm.h | 628 + .../Crypto_30_vHsm/Crypto_30_vHsm_Custom.h | 425 + .../bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc.c | 989 + .../bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc.h | 377 + .../Crypto_30_vHsm/Crypto_30_vHsm_Ipc_Types.h | 66 + .../bsw/Crypto_30_vHsm/Crypto_30_vHsm_Jobs.c | 2204 +++ .../bsw/Crypto_30_vHsm/Crypto_30_vHsm_Jobs.h | 257 + .../Crypto_30_vHsm_KeyManagement.c | 1547 ++ .../Crypto_30_vHsm_KeyManagement.h | 465 + .../Crypto_30_vHsm/Crypto_30_vHsm_Private.h | 105 + .../bsw/Crypto_30_vHsm/Crypto_30_vHsm_Types.h | 136 + .../Make/Crypto_30_vHsm_cfg.mak | 81 + .../Make/Crypto_30_vHsm_check.mak | 79 + .../Make/Crypto_30_vHsm_defs.mak | 81 + .../Make/Crypto_30_vHsm_rules.mak | 102 + Source/bsw/Csm/Crypto_GeneralTypes.h | 837 + Source/bsw/Csm/Csm.c | 5728 ++++++ Source/bsw/Csm/Csm.h | 1586 ++ Source/bsw/Csm/Csm_Cbk.h | 65 + Source/bsw/Csm/Csm_Rte.c | 1861 ++ Source/bsw/Csm/Csm_Rte.h | 2903 +++ Source/bsw/Csm/Csm_Types.h | 45 + Source/bsw/Csm/Make/Csm_cfg.mak | 81 + Source/bsw/Csm/Make/Csm_check.mak | 79 + Source/bsw/Csm/Make/Csm_defs.mak | 81 + Source/bsw/Csm/Make/Csm_rules.mak | 102 + Source/bsw/Det/Det.c | 1055 ++ Source/bsw/Det/Det.h | 386 + Source/bsw/Det/Make/Det_cfg.mak | 75 + Source/bsw/Det/Make/Det_check.mak | 79 + Source/bsw/Det/Make/Det_defs.mak | 80 + Source/bsw/Det/Make/Det_rules.mak | 103 + Source/bsw/Fbl/applvect.h | 106 + Source/bsw/Fbl/fbl_applvect.c | 101 + Source/bsw/Fbl/fbl_assert.h | 129 + Source/bsw/Fbl/fbl_assert_oem.h | 78 + Source/bsw/Fbl/fbl_def.h | 423 + Source/bsw/Fbl/fbl_diag.c | 6492 +++++++ Source/bsw/Fbl/fbl_diag.def | 251 + Source/bsw/Fbl/fbl_diag.h | 1046 ++ Source/bsw/Fbl/fbl_diag.imp | 355 + Source/bsw/Fbl/fbl_flio.c | 362 + Source/bsw/Fbl/fbl_flio.h | 90 + Source/bsw/Fbl/fbl_fsm.c | 419 + Source/bsw/Fbl/fbl_fsm.h | 182 + Source/bsw/Fbl/fbl_fsm_inc.h | 49 + Source/bsw/Fbl/fbl_hw.c | 236 + Source/bsw/Fbl/fbl_hw.h | 191 + Source/bsw/Fbl/fbl_lbt_access.c | 1428 ++ Source/bsw/Fbl/fbl_lbt_access.h | 190 + Source/bsw/Fbl/fbl_main.c | 603 + Source/bsw/Fbl/fbl_main.h | 180 + Source/bsw/Fbl/fbl_main_types.h | 104 + Source/bsw/Fbl/fbl_mem.c | 6012 ++++++ Source/bsw/Fbl/fbl_mem.h | 1151 ++ Source/bsw/Fbl/fbl_mem_oem.h | 453 + Source/bsw/Fbl/fbl_nvpattern_oem.c | 131 + Source/bsw/Fbl/fbl_nvpattern_oem.h | 196 + Source/bsw/Fbl/fbl_ramio.c | 418 + Source/bsw/Fbl/fbl_ramio.h | 92 + Source/bsw/Fbl/fbl_ramio_inc.h | 49 + Source/bsw/Fbl/fbl_sfr.h | 112 + Source/bsw/Fbl/fbl_valstruct.c | 1171 ++ Source/bsw/Fbl/fbl_valstruct.h | 171 + Source/bsw/Fbl/fbl_valstruct_oem.h | 178 + Source/bsw/Fbl/fbl_wd.c | 264 + Source/bsw/Fbl/fbl_wd.h | 118 + Source/bsw/Fbl/flashdrv.h | 92 + Source/bsw/Fbl/v_ver.h | 176 + Source/bsw/FblAsrStubs/BswM.h | 40 + Source/bsw/FblAsrStubs/ComM.h | 40 + Source/bsw/FblAsrStubs/ComM_BusSM.h | 50 + Source/bsw/FblAsrStubs/ComM_Types.h | 47 + Source/bsw/FblAsrStubs/Dem.c | 80 + Source/bsw/FblAsrStubs/Dem.h | 82 + Source/bsw/FblAsrStubs/FblAsrStubs.h | 50 + Source/bsw/FblAsrStubs/MemIf.h | 46 + Source/bsw/FblAsrStubs/MemIf_Types.h | 112 + Source/bsw/FblAsrStubs/NvM_Cbk.h | 34 + Source/bsw/FblAsrStubs/Rte.h | 40 + Source/bsw/FblAsrStubs/Rte_ComM.h | 40 + Source/bsw/FblAsrStubs/Rte_ComM_Type.h | 62 + Source/bsw/FblAsrStubs/Rte_Csm_Type.h | 40 + Source/bsw/FblAsrStubs/Rte_EcuM_Type.h | 40 + Source/bsw/FblAsrStubs/Rte_Type.h | 50 + Source/bsw/FblAsrStubs/v_cfg.h | 99 + Source/bsw/FblBm/bm_main.c | 2459 +++ Source/bsw/FblBm/bm_main.h | 200 + Source/bsw/FblBm/bm_shared.c | 93 + Source/bsw/FblBm/bm_shared.h | 272 + Source/bsw/FblBm/bm_types.h | 166 + Source/bsw/FblBm/bm_types_header.h | 143 + Source/bsw/FblBmHdr/bm_hdr.c | 234 + Source/bsw/FblBmHdr/bm_hdr.h | 75 + Source/bsw/FblBmHdr/bm_hdr_types.h | 67 + .../FblNvPattern/Make/FblNvPattern_cfg.mak | 12 + .../FblNvPattern/Make/FblNvPattern_check.mak | 12 + .../FblNvPattern/Make/FblNvPattern_defs.mak | 12 + .../FblNvPattern/Make/FblNvPattern_rules.mak | 24 + Source/bsw/FblNvPattern/fbl_nvpattern.c | 1306 ++ Source/bsw/FblNvPattern/fbl_nvpattern.h | 167 + Source/bsw/FblSecBoot/fbl_secboot.c | 606 + Source/bsw/FblSecBoot/fbl_secboot.h | 121 + Source/bsw/VStdLib/Make/VStdLib_cfg.mak | 79 + Source/bsw/VStdLib/Make/VStdLib_check.mak | 79 + Source/bsw/VStdLib/Make/VStdLib_defs.mak | 85 + Source/bsw/VStdLib/Make/VStdLib_rules.mak | 100 + Source/bsw/VStdLib/_VStdLib_Cfg.h | 1006 + Source/bsw/VStdLib/vstdlib.c | 7811 ++++++++ Source/bsw/VStdLib/vstdlib.h | 4362 +++++ Source/bsw/WrapNv/Make/WrapNv_cfg.mak | 12 + Source/bsw/WrapNv/Make/WrapNv_check.mak | 12 + Source/bsw/WrapNv/Make/WrapNv_defs.mak | 12 + Source/bsw/WrapNv/Make/WrapNv_rules.mak | 25 + Source/bsw/WrapNv/WrapNv.c | 1880 ++ Source/bsw/WrapNv/WrapNv.h | 241 + Source/bsw/WrapNv/_WrapNv_inc.h | 56 + Source/include/ARMBrsHw_CortexR.h | 327 + Source/include/BrsHw.h | 392 + Source/include/BrsHw_Ports.h | 149 + Source/include/BrsMain.h | 807 + Source/include/BrsMain_Appl.h | 359 + Source/include/BrsMain_Cfg.h | 78 + Source/include/BrsMain_Types.h | 108 + Source/include/Brs_MemMap.h | 350 + Source/include/bm_ap.h | 203 + Source/include/bm_ap_cfg.h | 307 + Source/include/fbl_secboot_ap.h | 81 + b.bat | 2 + .../Config/AUTOSAR/MemMap_SwAddrMethods.arxml | 2151 +++ .../Config/AUTOSAR/PlatformTypes_AR4.arxml | 843 + .../ECUC/FLex_OBC_BM.ecuc.Initial.arxml | 13 + .../Config/ECUC/FLex_OBC_BM.ecuc.arxml | 66 + .../ECUC/FLex_OBC_BM_CryIf_CryIf_ecuc.arxml | 183 + .../FLex_OBC_BM_Crypto_Crypto_001_ecuc.arxml | 242 + .../ECUC/FLex_OBC_BM_Crypto_Crypto_ecuc.arxml | 14788 +++++++++++++++ .../ECUC/FLex_OBC_BM_Csm_Csm_ecuc.arxml | 661 + .../ECUC/FLex_OBC_BM_Det_Det_ecuc.arxml | 89 + .../ECUC/FLex_OBC_BM_EcuC_EcuC_ecuc.arxml | 691 + ..._OBC_BM_FblAsrStubs_FblAsrStubs_ecuc.arxml | 36 + .../FLex_OBC_BM_FblBmHdr_FblBmHdr_ecuc.arxml | 121 + .../ECUC/FLex_OBC_BM_FblBm_FblBm_ecuc.arxml | 71 + .../ECUC/FLex_OBC_BM_FblHal_FblHal_ecuc.arxml | 72 + .../ECUC/FLex_OBC_BM_FblSb_FblSb_ecuc.arxml | 84 + .../ECUC/FLex_OBC_BM_Fbl_Fbl_ecuc.arxml | 428 + .../ECUC/FLex_OBC_BM_MemMap_MemMap_ecuc.arxml | 5441 ++++++ .../ECUC/FLex_OBC_BM_vBRS_vBRS_ecuc.arxml | 216 + .../FLex_OBC_BM_vBaseEnv_vBaseEnv_ecuc.arxml | 255 + .../FLex_OBC_BM_vLinkGen_vLinkGen_ecuc.arxml | 6505 +++++++ .../ECUC/FLex_OBC_BM_vSet_vSet_ecuc.arxml | 837 + .../Crypto_30_LibCv_ib_bswmd.arxml | 76 + .../Crypto_30_vHsm_ib_bswmd.arxml | 90 + .../InternalBehavior/Csm_ib_bswmd.arxml | 55 + .../InternalBehavior/Det_ib_bswmd.arxml | 55 + ...Lex_OBC_BM.JidhinAngadithazha.silent.dcusr | 34 + config/Davinci/FLex_OBC_BM.dpa | 309 + .../Log/automationScriptRunHistory.log | 0 j.bat | 2 + m.bat | 80 + 243 files changed, 196614 insertions(+) create mode 100644 Makefile create mode 100644 Makefile.static create mode 100644 Makefile.wrapper create mode 100644 Source/appl/ARMBrsHwIntTb_CortexR.c create mode 100644 Source/appl/ARMBrsHw_CortexR.c create mode 100644 Source/appl/ARMStartup_CortexR.c create mode 100644 Source/appl/BrsHw.c create mode 100644 Source/appl/BrsMain.c create mode 100644 Source/appl/BrsMainStartup.c create mode 100644 Source/appl/BrsMain_Appl.c create mode 100644 Source/appl/BrsMain_Callout_Stubs.c create mode 100644 Source/appl/BrsMain_FblOsStub.c create mode 100644 Source/appl/bm_ap.c create mode 100644 Source/appl/fbl_secboot_ap.c create mode 100644 Source/bsw/Common/Can_GeneralTypes.h create mode 100644 Source/bsw/Common/ComStack_Types.h create mode 100644 Source/bsw/Common/Compiler.h create mode 100644 Source/bsw/Common/Compiler_Cfg.h create mode 100644 Source/bsw/Common/EthSwt_GeneralTypes.h create mode 100644 Source/bsw/Common/EthTrcv_GeneralTypes.h create mode 100644 Source/bsw/Common/Eth_GeneralTypes.h create mode 100644 Source/bsw/Common/Eth_GeneralTypesDefs.h create mode 100644 Source/bsw/Common/Fr_GeneralTypes.h create mode 100644 Source/bsw/Common/Lin_GeneralTypes.h create mode 100644 Source/bsw/Common/MemMap.h create mode 100644 Source/bsw/Common/Platform_Types.h create mode 100644 Source/bsw/Common/Std_Types.h create mode 100644 Source/bsw/Common/v_def.h create mode 100644 Source/bsw/CryIf/CryIf.c create mode 100644 Source/bsw/CryIf/CryIf.h create mode 100644 Source/bsw/CryIf/CryIf_Cbk.h create mode 100644 Source/bsw/CryIf/CryIf_Private.h create mode 100644 Source/bsw/CryIf/Make/CryIf_cfg.mak create mode 100644 Source/bsw/CryIf/Make/CryIf_check.mak create mode 100644 Source/bsw/CryIf/Make/CryIf_defs.mak create mode 100644 Source/bsw/CryIf/Make/CryIf_rules.mak create mode 100644 Source/bsw/Crypto_30_LibCv/BSWMD/Crypto_30_LibCv_MemMap.arxml create mode 100644 Source/bsw/Crypto_30_LibCv/BSWMD/Crypto_30_LibCv_bswmd.arxml create mode 100644 Source/bsw/Crypto_30_LibCv/ChangeHistory.txt create mode 100644 Source/bsw/Crypto_30_LibCv/Documentation/TechnicalReference_Crypto_30_LibCv.pdf create mode 100644 Source/bsw/Crypto_30_LibCv/GeneratorMsr/Crypto_30_LibCv.jar create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Aead.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AeadDecrypt.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AeadEncrypt.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AutosarDefines.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Cipher.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Curve.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Curve.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Custom.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Decrypt.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Encrypt.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Hash.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Hash.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_InternalApi.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyDerive.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyDerive.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyExchange.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyExchange.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyGenerate.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyGenerate.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyManagement.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyManagement.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeySetInvalid.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeySetValid.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyUnwrap.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyWrap.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyWrap.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Mac.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_MacGenerate.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_MacVerify.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Random.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_RandomGenerate.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_RandomSeed.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Services.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Signature.c create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_SignatureGenerate.h create mode 100644 Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_SignatureVerify.h create mode 100644 Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_cfg.mak create mode 100644 Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_check.mak create mode 100644 Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_defs.mak create mode 100644 Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_rules.mak create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm.c create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm.h create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Custom.h create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc.c create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc.h create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc_Types.h create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Jobs.c create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Jobs.h create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_KeyManagement.c create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_KeyManagement.h create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Private.h create mode 100644 Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Types.h create mode 100644 Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_cfg.mak create mode 100644 Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_check.mak create mode 100644 Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_defs.mak create mode 100644 Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_rules.mak create mode 100644 Source/bsw/Csm/Crypto_GeneralTypes.h create mode 100644 Source/bsw/Csm/Csm.c create mode 100644 Source/bsw/Csm/Csm.h create mode 100644 Source/bsw/Csm/Csm_Cbk.h create mode 100644 Source/bsw/Csm/Csm_Rte.c create mode 100644 Source/bsw/Csm/Csm_Rte.h create mode 100644 Source/bsw/Csm/Csm_Types.h create mode 100644 Source/bsw/Csm/Make/Csm_cfg.mak create mode 100644 Source/bsw/Csm/Make/Csm_check.mak create mode 100644 Source/bsw/Csm/Make/Csm_defs.mak create mode 100644 Source/bsw/Csm/Make/Csm_rules.mak create mode 100644 Source/bsw/Det/Det.c create mode 100644 Source/bsw/Det/Det.h create mode 100644 Source/bsw/Det/Make/Det_cfg.mak create mode 100644 Source/bsw/Det/Make/Det_check.mak create mode 100644 Source/bsw/Det/Make/Det_defs.mak create mode 100644 Source/bsw/Det/Make/Det_rules.mak create mode 100644 Source/bsw/Fbl/applvect.h create mode 100644 Source/bsw/Fbl/fbl_applvect.c create mode 100644 Source/bsw/Fbl/fbl_assert.h create mode 100644 Source/bsw/Fbl/fbl_assert_oem.h create mode 100644 Source/bsw/Fbl/fbl_def.h create mode 100644 Source/bsw/Fbl/fbl_diag.c create mode 100644 Source/bsw/Fbl/fbl_diag.def create mode 100644 Source/bsw/Fbl/fbl_diag.h create mode 100644 Source/bsw/Fbl/fbl_diag.imp create mode 100644 Source/bsw/Fbl/fbl_flio.c create mode 100644 Source/bsw/Fbl/fbl_flio.h create mode 100644 Source/bsw/Fbl/fbl_fsm.c create mode 100644 Source/bsw/Fbl/fbl_fsm.h create mode 100644 Source/bsw/Fbl/fbl_fsm_inc.h create mode 100644 Source/bsw/Fbl/fbl_hw.c create mode 100644 Source/bsw/Fbl/fbl_hw.h create mode 100644 Source/bsw/Fbl/fbl_lbt_access.c create mode 100644 Source/bsw/Fbl/fbl_lbt_access.h create mode 100644 Source/bsw/Fbl/fbl_main.c create mode 100644 Source/bsw/Fbl/fbl_main.h create mode 100644 Source/bsw/Fbl/fbl_main_types.h create mode 100644 Source/bsw/Fbl/fbl_mem.c create mode 100644 Source/bsw/Fbl/fbl_mem.h create mode 100644 Source/bsw/Fbl/fbl_mem_oem.h create mode 100644 Source/bsw/Fbl/fbl_nvpattern_oem.c create mode 100644 Source/bsw/Fbl/fbl_nvpattern_oem.h create mode 100644 Source/bsw/Fbl/fbl_ramio.c create mode 100644 Source/bsw/Fbl/fbl_ramio.h create mode 100644 Source/bsw/Fbl/fbl_ramio_inc.h create mode 100644 Source/bsw/Fbl/fbl_sfr.h create mode 100644 Source/bsw/Fbl/fbl_valstruct.c create mode 100644 Source/bsw/Fbl/fbl_valstruct.h create mode 100644 Source/bsw/Fbl/fbl_valstruct_oem.h create mode 100644 Source/bsw/Fbl/fbl_wd.c create mode 100644 Source/bsw/Fbl/fbl_wd.h create mode 100644 Source/bsw/Fbl/flashdrv.h create mode 100644 Source/bsw/Fbl/v_ver.h create mode 100644 Source/bsw/FblAsrStubs/BswM.h create mode 100644 Source/bsw/FblAsrStubs/ComM.h create mode 100644 Source/bsw/FblAsrStubs/ComM_BusSM.h create mode 100644 Source/bsw/FblAsrStubs/ComM_Types.h create mode 100644 Source/bsw/FblAsrStubs/Dem.c create mode 100644 Source/bsw/FblAsrStubs/Dem.h create mode 100644 Source/bsw/FblAsrStubs/FblAsrStubs.h create mode 100644 Source/bsw/FblAsrStubs/MemIf.h create mode 100644 Source/bsw/FblAsrStubs/MemIf_Types.h create mode 100644 Source/bsw/FblAsrStubs/NvM_Cbk.h create mode 100644 Source/bsw/FblAsrStubs/Rte.h create mode 100644 Source/bsw/FblAsrStubs/Rte_ComM.h create mode 100644 Source/bsw/FblAsrStubs/Rte_ComM_Type.h create mode 100644 Source/bsw/FblAsrStubs/Rte_Csm_Type.h create mode 100644 Source/bsw/FblAsrStubs/Rte_EcuM_Type.h create mode 100644 Source/bsw/FblAsrStubs/Rte_Type.h create mode 100644 Source/bsw/FblAsrStubs/v_cfg.h create mode 100644 Source/bsw/FblBm/bm_main.c create mode 100644 Source/bsw/FblBm/bm_main.h create mode 100644 Source/bsw/FblBm/bm_shared.c create mode 100644 Source/bsw/FblBm/bm_shared.h create mode 100644 Source/bsw/FblBm/bm_types.h create mode 100644 Source/bsw/FblBm/bm_types_header.h create mode 100644 Source/bsw/FblBmHdr/bm_hdr.c create mode 100644 Source/bsw/FblBmHdr/bm_hdr.h create mode 100644 Source/bsw/FblBmHdr/bm_hdr_types.h create mode 100644 Source/bsw/FblNvPattern/Make/FblNvPattern_cfg.mak create mode 100644 Source/bsw/FblNvPattern/Make/FblNvPattern_check.mak create mode 100644 Source/bsw/FblNvPattern/Make/FblNvPattern_defs.mak create mode 100644 Source/bsw/FblNvPattern/Make/FblNvPattern_rules.mak create mode 100644 Source/bsw/FblNvPattern/fbl_nvpattern.c create mode 100644 Source/bsw/FblNvPattern/fbl_nvpattern.h create mode 100644 Source/bsw/FblSecBoot/fbl_secboot.c create mode 100644 Source/bsw/FblSecBoot/fbl_secboot.h create mode 100644 Source/bsw/VStdLib/Make/VStdLib_cfg.mak create mode 100644 Source/bsw/VStdLib/Make/VStdLib_check.mak create mode 100644 Source/bsw/VStdLib/Make/VStdLib_defs.mak create mode 100644 Source/bsw/VStdLib/Make/VStdLib_rules.mak create mode 100644 Source/bsw/VStdLib/_VStdLib_Cfg.h create mode 100644 Source/bsw/VStdLib/vstdlib.c create mode 100644 Source/bsw/VStdLib/vstdlib.h create mode 100644 Source/bsw/WrapNv/Make/WrapNv_cfg.mak create mode 100644 Source/bsw/WrapNv/Make/WrapNv_check.mak create mode 100644 Source/bsw/WrapNv/Make/WrapNv_defs.mak create mode 100644 Source/bsw/WrapNv/Make/WrapNv_rules.mak create mode 100644 Source/bsw/WrapNv/WrapNv.c create mode 100644 Source/bsw/WrapNv/WrapNv.h create mode 100644 Source/bsw/WrapNv/_WrapNv_inc.h create mode 100644 Source/include/ARMBrsHw_CortexR.h create mode 100644 Source/include/BrsHw.h create mode 100644 Source/include/BrsHw_Ports.h create mode 100644 Source/include/BrsMain.h create mode 100644 Source/include/BrsMain_Appl.h create mode 100644 Source/include/BrsMain_Cfg.h create mode 100644 Source/include/BrsMain_Types.h create mode 100644 Source/include/Brs_MemMap.h create mode 100644 Source/include/bm_ap.h create mode 100644 Source/include/bm_ap_cfg.h create mode 100644 Source/include/fbl_secboot_ap.h create mode 100644 b.bat create mode 100644 config/Davinci/Config/AUTOSAR/MemMap_SwAddrMethods.arxml create mode 100644 config/Davinci/Config/AUTOSAR/PlatformTypes_AR4.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM.ecuc.Initial.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM.ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_CryIf_CryIf_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_Crypto_Crypto_001_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_Crypto_Crypto_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_Csm_Csm_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_Det_Det_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_EcuC_EcuC_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_FblAsrStubs_FblAsrStubs_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_FblBmHdr_FblBmHdr_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_FblBm_FblBm_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_FblHal_FblHal_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_FblSb_FblSb_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_Fbl_Fbl_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_MemMap_MemMap_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_vBRS_vBRS_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_vBaseEnv_vBaseEnv_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_vLinkGen_vLinkGen_ecuc.arxml create mode 100644 config/Davinci/Config/ECUC/FLex_OBC_BM_vSet_vSet_ecuc.arxml create mode 100644 config/Davinci/Config/InternalBehavior/Crypto_30_LibCv_ib_bswmd.arxml create mode 100644 config/Davinci/Config/InternalBehavior/Crypto_30_vHsm_ib_bswmd.arxml create mode 100644 config/Davinci/Config/InternalBehavior/Csm_ib_bswmd.arxml create mode 100644 config/Davinci/Config/InternalBehavior/Det_ib_bswmd.arxml create mode 100644 config/Davinci/FLex_OBC_BM.JidhinAngadithazha.silent.dcusr create mode 100644 config/Davinci/FLex_OBC_BM.dpa create mode 100644 config/Davinci/Log/automationScriptRunHistory.log create mode 100644 j.bat create mode 100644 m.bat diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4966c2b --- /dev/null +++ b/Makefile @@ -0,0 +1,710 @@ +######################################################################################################################## +# File Name : Makefile +# Description: Local main project Makefile +# Project : Vector Basic Runtime System +# Module : BrsHw for platform ArmCommon +# and Compiler LlvmTexasInstruments, +# using Vector PES MakeSupport 4.1 +# Template : This Makefile is reviewed according to Brs_Template@MakeSupport[1.02.01] +# +#----------------------------------------------------------------------------------------------------------------------- +# COPYRIGHT +#----------------------------------------------------------------------------------------------------------------------- +# Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +# +#----------------------------------------------------------------------------------------------------------------------- +# REVISION HISTORY +#----------------------------------------------------------------------------------------------------------------------- +# Version Date Author Change Id Description +# ---------------------------------------------------------------------------------------------------------------------- +# 01.00.00 2021-09-29 vishci Initial creation +# 01.00.01 2021-12-17 visbwa Update to Brs_Template 1.01.01, changed default compiler path to fit with chocolatey, +# removed unused code fragments, switched assembler binary to proper tiarmclang and +# adapted the default assembler options, fixed version options +# 01.00.02 2022-01-24 visbwa Added -march attribute value for Cortex-M3/M4 +# 01.00.03 2022-03-24 vismaa Removed Xlinker --scan_libraries +# 01.00.04 2022-05-16 visrgm Added CPU Switch for Cortex-M4F +# 01.01.00 2022-07-25 visbwa Changed linker option -e from brsStartupEntry to intvect_CoreExceptions, as this +# proper entry is always available since Brs_Template 1.03 and references brsStartupEntry +# 01.01.01 2022-07-26 visjhr Added EXCEPTION_TABLE_LDFLAGS +# 01.01.02 2022-07-27 visjhr Fixed EXCEPTION_TABLE_LDFLAGS +# 01.01.03 2022-08-09 visjhr Added ADDITIONAL_INCLUDES += LlvmTi +# 01.01.04 2022-08-10 visjhr Removed all ADDITIONAL_INCLUDES +# 01.01.05 2022-09-05 visdri Add ADDITIONAL_CFLAGS_FROM_VBRS to CFLAGS_VECTOR_OPTIONS +# 01.01.06 2022-09-23 visjhr Added usage of BRS_FIRST_EXECUTION_INSTANCE for selection of entry/startup label +# 01.01.07 2023-01-11 visqli Moved PROJECT_NAME to Makefile.static and included Makefile.static forwards, +# enabled generation of PROJECT_NAME and LINKER_COMMAND_FILE +# 01.01.08 2023-03-13 vishci Added -mcpu and -march value for Cortex-M0/M0plus +# 01.01.09 2023-03-14 visjhr Use BRS_CPU_CORE_x_USED variables to prevent optimization of exception tables +# (HALBE-8500 Generate additional core specific variables in Makefile.config.generated) +# 01.01.10 2023-03-15 vishci Added core specific mfloat-abi option +# 01.01.11 2023-03-20 visbwa Added --memwidth=8 to HexFlags, after user feedback +# 01.01.12 2023-07-06 visdri Compile ARMBrsHwIntTb_CortexR.c / ARMStartup_CortexR.c in ARM state even when +# Thumb state is configured for the project +# 01.01.13 2023-07-14 visbwa Added keep for FBL exception table in RAM (intvect_CoreExceptions_Ram) +# 01.01.14 2023-11-16 visbwa LDFLAG -u=intvect_CoreExceptions_Ram only for FBL UseCase +# 01.01.15 2024-03-05 virrlu Changed ARFLAGS to -r after user feedback +# 01.01.16 2024-03-28 vishci BASEENV-11520 Added forced ARM state to compiling ARMBrsHwIntTb_CortexR.c / ARMStartup_CortexR.c to +# all CORTEX_R based cores, Brs_Template 1.01.05 (Change Id) +# 01.01.17 2024-06-24 kal BASEENV-12084 Added comment clarifying default C language standard (GNU11) +# 01.02.00 2024-08-01 vishci BASEENV-12178 Unify naming of intvect_CoreExceptions_Ram_Vectortable for FBL usecase and added keep flag +# 01.02.01 2024-08-27 vishci Bugfix for intvect_CoreExceptions_Ram_Vectortable flag in Cortex M Cores +# 01.03.00 2025-06-12 visbwa BASEENV-13804 Replaced include of Makefile.config.generated and Makefile.project.part.defines in Makefile.static +# by new Makefile.wrapper; added usage of new parameter TEMPDATA_DIR for LINKER_COMMAND_FILE; +# review to Brs_Template 1.02.00; fixed LNK_SUFFIX +# 01.03.01 2025-07-31 visbwa TAR-93253 Added LDFLAGS_RESPONSE_FILE value in Makefile.static +# 01.03.02 2025-07-31 visbwa TAR-93253 Introduced RESPONSE_FILE_MULTILINE in Makefile.static and set to '1'; +# feature was introduced with zBrs_MakeSupport@Implementation[4.01.65] +# 01.04.00 2025-09-02 kal BASEENV-14399 Added support for Cortex-R52 (TI Arm Clang Compiler Tools >= 4.03.00 LTS) +# 01.04.01 2025-10-16 visbwa Set 4.0.3.LTS as default compiler for Cortex-R52 +######################################################################################################################## + +######################################################################################################################## +# EXAMPLE CODE ONLY +#----------------------------------------------------------------------------------------------------------------------- +# This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. +# The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither +# intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or +# implementations must be tested with diligent care and must comply with all quality requirements which are necessary +# according to the state of the art before their use. +######################################################################################################################## + +#------------------------------------------------------------------------------ +# Static settings placed inside separate file +#------------------------------------------------------------------------------ +include Makefile.static + +#------------------------------------------------------------------------------ +# Name of linker file +# +# If BRS_LINKER_COMMAND_FILE_POSTFIX (derived from referenced vLinGen variant +# vBRS/vBRSGeneral/vBRSVariantUsageOfvLinkGen) was generated into +# Makefile.config.generated (by vBRS Cfg5 generator), use that file. +#------------------------------------------------------------------------------ +ifeq ($(BRS_LINKER_COMMAND_FILE_POSTFIX),) +LINKER_COMMAND_FILE = $(TEMPDATA_DIR)/vLinkGen_Template.$(LNK_SUFFIX) +else +LINKER_COMMAND_FILE = $(TEMPDATA_DIR)/vLinkGen_Template_$(BRS_LINKER_COMMAND_FILE_POSTFIX).$(LNK_SUFFIX) +endif + +#------------------------------------------------------------------------------ +# Define Compiler path, e.g. +# COMPILER_BASE_WIN = D:\uti\%vendor%\%platform%\%version% (\ can be used) +# COMPILER_BASE := $(subst \,/,$(COMPILER_BASE_WIN)) (\ is converted to /) +# COMPILER_BIN = $(COMPILER_BASE)/bin +# COMPILER_INC = $(COMPILER_BASE)/inc +# COMPILER_LIB = $(COMPILER_BASE)/lib +# +# If BRS_COMPILER_PATH (vBRS/vBRSHwConfig/vBRSCompilerPath) was generated into +# Makefile.config.generated (by vBRS Cfg5 generator), use that path. +#------------------------------------------------------------------------------ +ifeq ($(BRS_COMPILER_PATH),) + ifeq ($(CPU_CORE),CORTEX_R52) + #TI Arm Clang Compiler Tools 4.0.3 LTS now offers basic support for R52 + COMPILER_BASE_WIN = D:\uti\TI\LLVMARM\ccs\tools\compiler\ti-cgt-armllvm_4.0.3.LTS + else + COMPILER_BASE_WIN = D:\uti\TI\LLVMARM\ccs\tools\compiler\ti-cgt-armllvm_1.3.0.LTS + endif +else +COMPILER_BASE_WIN = $(BRS_COMPILER_PATH) +endif +COMPILER_BASE := $(subst \,/,$(COMPILER_BASE_WIN)) +COMPILER_BIN = $(COMPILER_BASE)/bin +COMPILER_INC = $(COMPILER_BASE)/include +COMPILER_LIB = $(COMPILER_BASE)/lib + +#------------------------------------------------------------------------------ +# Build Options Selection: VECTOR / CUSTOMER +#------------------------------------------------------------------------------ +ASFLAGS_SELECTOR = VECTOR +CFLAGS_SELECTOR = VECTOR +LDFLAGS_SELECTOR = VECTOR + +#------------------------------------------------------------------------------ +# Define Emulator path +# E.g.: EMU_PATH = C:/UTI/HITOPWIN/P6811 +# +# This parameter is not mandatory. It is used for some platforms, to provide +# e.g. debug connect scripts (e.g. multi within RH850). +#------------------------------------------------------------------------------ +EMU_PATH = + +#------------------------------------------------------------------------------ +# Set $(NANT_USED) to '1', to enable the usage of NAnt support within +# Global Makefile. If this is enabled, the MakeSupport will include the +# NAnt support from an internal link and the NAnt build targets can be used. +#------------------------------------------------------------------------------ +#NANT_USED = 1 + +#------------------------------------------------------------------------------ +# Set MKVERBOSE to a various value, to enable enhanced debug output from +# MakeSupport. To disable this afterwards, set MKVERBOSE to nothing +# (comment out this line and type "set MKVERBOSE=" in command window) +#------------------------------------------------------------------------------ +#MKVERBOSE = 1 + +#------------------------------------------------------------------------------ +# Set $(BRSVINFO_USED) to 1 to enable the generation of BrsVInfo.h within the +# GenData folder by the MakeSupport. +# The BrsVInfo.h will contain e.g. kBrsCompilerVersion, to use this +# information within the embedded code. +#------------------------------------------------------------------------------ +#BRSVINFO_USED = 1 + +#------------------------------------------------------------------------------ +# Set $(USE_RESPONSE_FILE_FOR_LINKAGE) to '1' to pass object files in a response file +# to the linker instead of using the command line. +# +# Use it if you hit the limit of maximum length command line length under Windows. +# +# See e.g. the following link regarding some information on response files: +# https://gcc.gnu.org/wiki/Response_Files +# +# If you enable 'USE_RESPONSE_FILE_FOR_LINKAGE', you also need to define +# 'LDFLAGS_RESPONSE_FILE' in Makefile.static. +#------------------------------------------------------------------------------ +#USE_RESPONSE_FILE_FOR_LINKAGE=1 + +#------------------------------------------------------------------------------ +# Functions used within Assembler/Compiler/Linker options. +# +# Common functionality is encapsulated in the following functions: +# - obj2err +# - obj2lst +# +# Example: +# --list-file=$(call obj2lst,$@) +# --error-file=$(call obj2err,$@) +# +# Please have a look at Makefile_functions.mk for further detailed information. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Extra dependency defines +# The DEPEND tool which is normally a preprocessor +# is called with $(EXTRA_DEPENDFLAGS) and $(CPPFLAGS). +# +# The cross compiler adds its own defines which DEPEND +# doesn't know. +# +# Add cross options set by compiler and other options +# for the preprocessor here. +# e.g.: EXTRA_DEPENDFLAGS += -D__CTC__ +# +# For normal build defines use $(CPPFLAGS_VECTOR_MAKESUPPORT). +#------------------------------------------------------------------------------ +EXTRA_DEPENDFLAGS += + +#-------------------------------------- +# CPU-core-specific CFLAGS option list +#-------------------------------------- +CPU_SWITCH_CORTEX_M0 = Cortex-M0 +CPU_SWITCH_CORTEX_M0PLUS = Cortex-M0plus +CPU_SWITCH_CORTEX_M3 = Cortex-M3 +CPU_SWITCH_CORTEX_M4 = Cortex-M4 +CPU_SWITCH_CORTEX_M4F = Cortex-M4 +CPU_SWITCH_CORTEX_R5F = Cortex-R5 +CPU_SWITCH_CORTEX_R52 = Cortex-R52 + +ifeq ($(CPU_SWITCH_$(CPU_CORE)),) + $(error COMPILERFLAGERROR: The compiler option (-mcpu=) is not defined!) +endif + +#-------------------------------------------------- +# CPU-core-architecture specific CFLAGS option list +#-------------------------------------------------- +ARCHITECTURE_SWITCH_CORTEX_M0 = armv6-m +ARCHITECTURE_SWITCH_CORTEX_M0PLUS = armv6-m +ARCHITECTURE_SWITCH_CORTEX_M3 = armv7-m +ARCHITECTURE_SWITCH_CORTEX_M4 = armv7-m +ARCHITECTURE_SWITCH_CORTEX_M4F = armv7-m +ARCHITECTURE_SWITCH_CORTEX_R5F = armv7-r + +ifeq ($(ARCHITECTURE_SWITCH_$(CPU_CORE)),) + # -march=armv8-r not (yet) supported in tiarmclang 4.0.3 LTS + ifneq ($(CPU_CORE),CORTEX_R52) + $(error COMPILERFLAGERROR: The compiler option (-march=) is not defined!) + endif +endif + + +#------------------------------------------------------------------------------ +# CPU-core-specific FPU option list +#------------------------------------------------------------------------------ +ifeq ($(FPU_USED),1) + CFLAGS_FPU_CORTEX_R5F = vfpv3-d16 -mfloat-abi=hard + CFLAGS_FPU_CORTEX_M4F = fpv4-sp-d16 -mfloat-abi=hard + # CFLAGS_FPU_CORTEX_R52: neon-fp-armv8 FPU is enabled by default +else + CFLAGS_FPU_$(CPU_CORE) = none -mfloat-abi=soft +endif + +ifeq ($(CFLAGS_FPU_$(CPU_CORE)),) + $(error COMPILERFLAGERROR: The compiler option (-mfpu=) is not defined!) +endif + +#------------------------------------------------------------------------------ +# $(AS_ENV) is the environment necessary to run the assembler +# $(AS) defines the path to the assembler +# $(ASFLAGS_VECTOR_MAKESUPPORT) defines all assembler switches, mandatory for +# the Vector build environment (MakeSupport/BrsHw) +# $(ASFLAGS_VECTOR_OPTIONS) defines the Vector default assembler switches +# $(ASFLAGS_CUSTOMER_OPTIONS) defines the customer requested assembler switches +# Depending of ASFLAGS_SELECTOR, ASFLAGS_VECTOR_OPTIONS or ASFLAGS_CUSTOMER_OPTIONS +# are used together with $(ASFLAGS_VECTOR_MAKESUPPORT) for build. +#------------------------------------------------------------------------------ +AS_ENV = +AS = $(COMPILER_BIN)/tiarmclang + +#------------------------------------------------------------------------------ +# Please add only absolutely mandatory options below +#------------------------------------------------------------------------------ +ASFLAGS_VECTOR_MAKESUPPORT = -c \ + -o $@ + +#------------------------------------------------------------------------------ +# $(ASFLAGS_VECTOR_PREPROCESS) defines the options in preprocessing +# just before assembler starts. This flag is used only if +# AS_VECTOR_PREPROCESS (located in Makefile.static) is enabled. +# +# $(CPPFLAGS_CORE) can be added here. +#------------------------------------------------------------------------------ +ASFLAGS_VECTOR_PREPROCESS = $(CPPFLAGS_CORE) + +#------------------------------------------------------------------------------ +# Please add any other option below (Vector default options) +# +# Use $(ASFLAGS_VECTOR_OPTIONS) if assembler supports preprocessing by default. +# In case of assembler does not support preprocessing and preprocessing is +# enabled by $(ASFLAGS_VECTOR_PREPROCESS) in a prestep +# $(CPPFLAGS_CORE) must be set in $(ASFLAGS_VECTOR_PREPROCESS) +#------------------------------------------------------------------------------ +ASFLAGS_VECTOR_OPTIONS = $(CFLAGS_VECTOR_OPTIONS) + +#------------------------------------------------------------------------------ +# Please enter all customer options below +#------------------------------------------------------------------------------ +ASFLAGS_CUSTOMER_OPTIONS = + +#------------------------------------------------------------------------------ +# $(ASVERSION) defines the assembler switch for version report. +# E.g.: ASVERSION = -V +#------------------------------------------------------------------------------ +ASVERSION = --version + +#------------------------------------------------------------------------------ +# $(AS_LC) defines the number of lines used for assembler version information. +# $(AS_OFF) defines the offset of lines used for assembler version information +# in BrsVinfo.h and Deliverydescription (default is 5). +#------------------------------------------------------------------------------ +AS_OFF = +AS_LC = 1 + +#------------------------------------------------------------------------------ +#------------------------- MUST be filled out --------------------------------- +# $(CC_ENV) is the environment necessary to run the compiler +# $(CC) defines the path to the C-Compiler +# $(CFLAGS_VECTOR_MAKESUPPORT) defines all compiler switches, mandatory for +# the Vector build environment (Makesupport/BrsHw) +# $(CFLAGS_VECTOR_OPTIONS) defines the Vector default compiler switches +# $(CFLAGS_CUSTOMER_OPTIONS) defines the customer requested compiler switches +# Depending $(CFLAGS_SELECTOR), $(CFLAGS_VECTOR_OPTIONS) or +# $(CFLAGS_CUSTOMER_OPTIONS) is used together with $(CFLAGS_VECTOR_MAKESUPPORT) +# for build. +# +# Avoid $(OBJ_SUFFIX) to filter use $(basename $@) because +# ECO has a preprocess using CFLAGS_xx and the target is of type source. +#------------------------------------------------------------------------------ +CC_ENV = +CC = $(COMPILER_BIN)/tiarmclang + +#------------------------------------------------------------------------------ +# Please add only absolutely mandatory options below +# +# BRS values: +# -DBRS_COMP_$(COMPILER_MANUFACTURER) +# -DBRS_PLATFORM_$(PLATFORM) +# +# Avoid $(OBJ_SUFFIX) to filter. Use $(basename $@) because +# ECO has a preprocess using CFLAGS_xx and the target is of type source. +#------------------------------------------------------------------------------ +CPPFLAGS_VECTOR_MAKESUPPORT = -DBRS_PLATFORM_$(PLATFORM) \ + -DBRS_COMP_$(COMPILER_MANUFACTURER) + +CFLAGS_VECTOR_MAKESUPPORT = -c \ + -o $@ + +CFLAGS_ARM = -marm +CFLAGS_THUMB = -mthumb + +ifeq ($(CFLAGS_$(INSTRUCTION_SET)),) + $(error COMPILERFLAGERROR: The compiler option for the instruction set is not defined!) +endif + +#------------------------------------------------------------------------------ +# Add depend options here. +# It is separated because of the option to overwrite +# $(COMPILER_SUPPORTS_DEPEND) or have different compile without +# path length problem in command line. +# +# Pay attention below if $(MAKESUPPORT_POST_COMPILE_CMD) is +# used in context of depend file creation. +# +# Example: +# CFLAGS_VECTOR_MAKESUPPORT += -MMD -MF $(@:.o=.dt) +# MAKESUPPORT_POST_COMPILE_CMD += $(SED) -Ef $(MAKESUPPORT_DIR_U)/util/fix_dos_dep_file.sed < $(@:.o=.dt) > $(@:.o=.d); +# MAKESUPPORT_POST_COMPILE_CMD += $(RM) $(@:.o=.dt); +#------------------------------------------------------------------------------ +ifeq ($(COMPILER_SUPPORTS_DEPEND),1) + CFLAGS_VECTOR_MAKESUPPORT += -MD + MAKESUPPORT_POST_COMPILE_CMD += + + #----------------------------------------------------------------------------- + # If $(CC) shall create dependency file as well, fill the following variables. + # Otherwise, 'clang' does the task without using a floating license. + #----------------------------------------------------------------------------- + #DEPEND = $(CC_ENV) $(CC) + #DEPENDFLAGS = +endif + +#------------------------------------------------------------------------------ +# $(REUSE_CPP_DEPEND) is set because compiler has a path length problem +#------------------------------------------------------------------------------ +#REUSE_CPP_DEPEND = 1 +ifeq ($(COMPILER_SUPPORTS_DEPEND)+$(REUSE_CPP_DEPEND),1+1) + $(error Can not set both: COMPILER_SUPPORTS_DEPEND and REUSE_CPP_DEPEND) +endif + +#------------------------------------------------------------------------------ +# Post compile command to cleanup anything during compilation process +# +# Calling convention: +# $(call MAKESUPPORT_POST_COMPILE_CMD,$@,$<) +#------------------------------------------------------------------------------ +MAKESUPPORT_POST_COMPILE_CMD += + +#------------------------------------------------------------------------------ +# Please add any other option below (Vector default options) +# Avoid $(OBJ_SUFFIX) to filter use $(basename $@) because +# ECO has a preprocess using CFLAGS_xx and the target is of type source. +#------------------------------------------------------------------------------ +# If no -std option is specified when compiling a C source file, gnu11 is assumed by default. +CFLAGS_VECTOR_OPTIONS = -Wall \ + -mcpu=$(CPU_SWITCH_$(CPU_CORE)) \ + -mfpu=$(CFLAGS_FPU_$(CPU_CORE)) \ + -mlittle-endian \ + -O1 \ + -g \ + $(CFLAGS_$(INSTRUCTION_SET)) \ + $(ADDITIONAL_CFLAGS_FROM_VBRS) \ + $(CPU_MARCH_FLAGS) + +# Only set -march if CPU_CORE is not R52 +ifeq ($(CPU_CORE),CORTEX_R52) +CPU_MARCH_FLAGS = +else +CPU_MARCH_FLAGS = -march=$(ARCHITECTURE_SWITCH_$(CPU_CORE)) +endif + +#------------------------------------------------------------------------------ +# Please enter all customer options below +# Avoid $(OBJ_SUFFIX) to filter use $(basename $@) because +# ECO has a preprocess using CFLAGS_xx and the target is of type source. +#------------------------------------------------------------------------------ +CFLAGS_CUSTOMER_OPTIONS = + +#------------------------------------------------------------------------------ +# $(CVERSION) defines the compiler switch for version report +# E.g.: CVERSION = -V +#------------------------------------------------------------------------------ +CVERSION = --version + +#------------------------------------------------------------------------------ +# $(CC_LC) defines the number of lines used for compiler version information +# $(CC_OFF) defines the offset of lines used for compiler version information +# in BrsVinfo.h and Deliverydescription (default is 5) +#------------------------------------------------------------------------------ +CC_OFF = +CC_LC = 1 + +#------------------------------------------------------------------------------ +# Filter out section +# Add flags which must be filtered out for specific files +# +# Examples: +# FILTER_Os=-g # no debug option for file Os.c +# FILTER_COMPONENT_Det=-g # no debug option for component Det +#------------------------------------------------------------------------------ +#FILTER_ = +#FILTER_COMPONENT_ = + +# Note: +# The exception table and the init of exc table using the backup exc table are +# implmented in ARM mode => (ARMBrsHwIntTb_CortexR.c, ARMStartup_CortexR.c) +# must be compiled in ARM mode even when Thumb mode instruction set is configured. +ifeq ($(CPU_CORE), $(filter $(CPU_CORE), CORTEX_R4 CORTEX_R4F CORTEX_R5 CORTEX_R5F CORTEX_R52 CORTEX_R7)) + ifeq ($(INSTRUCTION_SET),THUMB) + FILTER_ARMBrsHwIntTb_CortexR = $(CFLAGS_THUMB) + CFLAGS_ARMBrsHwIntTb_CortexR = $(CFLAGS_ARM) + FILTER_ARMStartup_CortexR = $(CFLAGS_THUMB) + CFLAGS_ARMStartup_CortexR = $(CFLAGS_ARM) + endif +endif + +#------------------------------------------------------------------------------ +# Additional file specific compiler options +#------------------------------------------------------------------------------ +#CFLAGS_ = +#CFLAGS_COMPONENT_ = + +#------------------------------------------------------------------------------ +#------------------------- MUST be filled out --------------------------------- +# $(LD_ENV) is the environment necessary to run the linker +# $(LD) defines the path to the linker +# $(LDFLAGS_VECTOR_MAKESUPPORT) defines all linker switches, mandatory for the +# Vector build environment (MakeSupport/BrsHw) +# $(LDFLAGS_VECTOR_OPTIONS) defines the Vector default linker switches +# $(LDFLAGS_CUSTOMER_OPTIONS) defines the customer requested linker switches +# Depending on $(LDFLAGS_SELECTOR), $(LDFLAGS_VECTOR_OPTIONS) or +# $(LDFLAGS_CUSTOMER_OPTIONS)is used together with $(LDFLAGS_VECTOR_MAKESUPPORT) +# for build. +#------------------------------------------------------------------------------ +LD_ENV = +LD = $(COMPILER_BIN)/tiarmclang + +ifeq ($(BRS_FIRST_EXECUTION_INSTANCE),1) + ifeq ($(CPU_CORE),$(filter $(CPU_CORE),CORTEX_M0 CORTEX_M0PLUS CORTEX_M3 CORTEX_M33 CORTEX_M4 CORTEX_M4F CORTEX_M7)) + LDFLAGS_ENTRY = brsStartupEntry + else + LDFLAGS_ENTRY = intvect_CoreExceptions + endif +else + LDFLAGS_ENTRY = Brs_ApplicationEntry +endif + +#------------------------------------------------------------------------------ +# Please add only absolutely mandatory options below +# +# Please use $(PROJECT_NAME).$(BINARY_SUFFIX) or $(TARGET) instead of $@ and +# $(PROJECT_NAME) instead of $* because flags +# are used in delivery description. +# +# Linker script file name : $(LINKER_COMMAND_FILE) +#------------------------------------------------------------------------------ +LDFLAGS_VECTOR_MAKESUPPORT = -Xlinker -c \ + -Xlinker -e=$(LDFLAGS_ENTRY) \ + -Xlinker -m$(PROJECT_NAME).map \ + -o $(TARGET) + +#------------------------------------------------------------------------------ +# Set $(PREPROCESS_LINKER_COMMAND_FILE) to 1 to preprocess +# linker command file. $(USER_LINKER_COMMAND_FILE) can be set manually +# but is $(PROJECT_NAME).$(LNK_SUFFIX) by default. +#------------------------------------------------------------------------------ +#PREPROCESS_LINKER_COMMAND_FILE = 1 + +#------------------------------------------------------------------------------ +# Post link command to cleanup anything during linking process +# +# Calling convention: +# $(call MAKESUPPORT_POST_LINK_CMD,$@,$<) +#------------------------------------------------------------------------------ +MAKESUPPORT_POST_LINK_CMD += + +#------------------------------------------------------------------------------ +# Please add any other option below (Vector default options) +# +# Please use $(PROJECT_NAME).$(BINARY_SUFFIX) or $(TARGET) instead of +# $@ and $(PROJECT_NAME) instead of $* because flags +# are used in delivery description. +# +# Linker script file name : $(LINKER_COMMAND_FILE) +#------------------------------------------------------------------------------ +# --diag_suppress=10063-D is to suppress linker warning for +# "entry-point symbol other than "_c_int00" specified: "intvect_CoreExceptions"" +# +# --diag_suppress=10068-D is to suppress linker warning for +# "no matching section" +# +# --diag_suppress=10247-D is to suppress linker warning for +# "creating output section ".cinit" without a SECTIONS specification" +#------------------------------------------------------------------------------ +ifeq ($(CPU_CORE),CORTEX_R5F) + EXCEPTION_TABLE_LDFLAGS = -Xlinker -u=intvect_CoreExceptions_vectortable \ + -Xlinker -u=intvect_CoreExceptions_vectortable_backup + + ifeq ($(BRS_CPU_CORE_1_USED),1) + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core1Exceptions_vectortable + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core1Exceptions_vectortable_backup + endif + ifeq ($(BRS_CPU_CORE_2_USED),1) + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core2Exceptions_vectortable + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core2Exceptions_vectortable_backup + endif + ifeq ($(BRS_CPU_CORE_3_USED),1) + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core3Exceptions_vectortable + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core3Exceptions_vectortable_backup + endif + ifeq ($(BRS_CPU_CORE_4_USED),1) + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core4Exceptions_vectortable + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core4Exceptions_vectortable_backup + endif + ifeq ($(BRS_CPU_CORE_5_USED),1) + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core5Exceptions_vectortable + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core5Exceptions_vectortable_backup + endif + ifeq ($(BRS_CPU_CORE_6_USED),1) + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core6Exceptions_vectortable + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core6Exceptions_vectortable_backup + endif + ifeq ($(BRS_CPU_CORE_7_USED),1) + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core7Exceptions_vectortable + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_Core7Exceptions_vectortable_backup + endif + ifeq ($(BRS_FBL_EXCEPTIONTABLE_IN_RAM),1) + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_CoreExceptions_Ram + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_CoreExceptions_Ram_Vectortable + endif +endif + +ifeq ($(BRS_ENABLE_FBL_SUPPORT),1) + ifeq ($(CPU_CORE),$(filter $(CPU_CORE),CORTEX_R4 CORTEX_R4F CORTEX_R5 CORTEX_R5F CORTEX_R52 CORTEX_R7)) + ifeq ($(BRS_FBL_EXCEPTIONTABLE_IN_RAM),1) + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_CoreExceptions_Ram + EXCEPTION_TABLE_LDFLAGS += -Xlinker -u=intvect_CoreExceptions_Ram_Vectortable + endif + endif +endif + +LDFLAGS_VECTOR_OPTIONS = -Xlinker -q \ + -Xlinker --warn_sections \ + -Xlinker --unused_section_elimination=on \ + -Xlinker --compress_dwarf=on \ + -Xlinker --copy_compression=rle \ + -Xlinker --reread_libs \ + -Xlinker --display_error_number \ + -Xlinker --priority \ + $(ADDITIONAL_LDFLAGS_FROM_VBRS) \ + -Xlinker $(LINKER_COMMAND_FILE) \ + -Xlinker --diag_suppress=10063-D \ + -Xlinker --diag_suppress=10068-D \ + -Xlinker --diag_suppress=10247-D \ + $(EXCEPTION_TABLE_LDFLAGS) + +#------------------------------------------------------------------------------ +# Please enter all customer options below +# +# Please use $(PROJECT_NAME).$(BINARY_SUFFIX) instead of $@ and +# $(PROJECT_NAME) instead of $*, because flags +# are used in delivery description. +#------------------------------------------------------------------------------ +LDFLAGS_CUSTOMER_OPTIONS = + +#------------------------------------------------------------------------------ +# Please add additional system libraries below +# +# For some compilers, it is necessary to add additional system libraries. +# E.g. the ARM GCC Gnu compiler may need libc for memcpy or libgcc for modulo +# +# To add additional libraries use: +# -lgcc (libgcc: e.g. support for modulo operation) +# -lc (libc: e.g. support for memcpy function) +#------------------------------------------------------------------------------ +SYSLIBS += + +#------------------------------------------------------------------------------ +# $(LDVERSION) defines the linker switch for version report +# E.g.: LDVERSION = -v +#------------------------------------------------------------------------------ +LDVERSION = --version + +#------------------------------------------------------------------------------ +# $(LD_LC) defines the number of lines used for linker version information +# $(LD_OFF) defines the offset of lines used for linker version information +# in BrsVinfo.h and Delivery Description (default is 5) +#------------------------------------------------------------------------------ +LD_OFF = +LD_LC = 1 + +#------------------------------------------------------------------------------ +#------------------------- MUST be filled out if used ------------------------- +# $(HEX_ENV) is the environment necessary to run the hexfile generator +# $(HEX) defines the path to the hex converter, e.g. $(COMPILER_BIN)/gsrec +# $(HEXFLAGS) contains options for HEX tool, e.g. -nos5 -skip .tdata $< -o $@ +#------------------------------------------------------------------------------ +HEX_ENV = $(CC_ENV) +HEX = $(COMPILER_BIN)/tiarmhex + +HEXFLAGS = --intel $(PROJECT_NAME).$(BINARY_SUFFIX) --memwidth=8 --outfile=$(PROJECT_NAME).hex + +#------------------------------------------------------------------------------ +#------------------------- MUST be filled out if used ------------------------- +# $(AR_ENV) is the environment necessary to run the librarian +# $(AR) defines the path to the C-librarian +# $(ARFLAGS) defines all librarian switches +# +# Don't add $@. It is added in rule because AR rule is dynamically generated. +#------------------------------------------------------------------------------ +AR_ENV = +AR = $(COMPILER_BIN)/tiarmar + +ARFLAGS = -r + +#------------------------------------------------------------------------------ +# $(ARVERSION) defines the archiver switch for version report +# E.g.: ARVERSION = -v +#------------------------------------------------------------------------------ +ARVERSION = --version + +#------------------------------------------------------------------------------ +# $(AR_LC) defines the number of lines used for librarian version information +# $(AR_OFF) defines the offset of lines used for archiver version information +# in BrsVinfo.h +#------------------------------------------------------------------------------ +AR_OFF = +AR_LC = 1 + +#------------------------------------------------------------------------------ +# Additional includes essentially for compilation +#------------------------------------------------------------------------------ +ADDITIONAL_INCLUDES += + +#------------------------------------------------------------------------------ +# Additional objects essentially for linking +# E.g.: ADDITIONAL_OBJECTS = $(OBJ_PATH)/myobject.$(OBJ_SUFFIX) +#------------------------------------------------------------------------------ +ADDITIONAL_OBJECTS += + +#------------------------------------------------------------------------------ +# Additional libraries essentially for linking +# E.g.: ADDITIONAL_LIBRARIES = $(LIB_PATH)/mylib.$(LIB_SUFFIX) +#------------------------------------------------------------------------------ +ADDITIONAL_LIBRARIES += + +#------------------------------------------------------------------------------ +# List of assembler source files +# E.g.: ASM_SOURCES = source/startup.$(ASM_SUFFIX) +#------------------------------------------------------------------------------ +ASM_SOURCES += + +#------------------------------------------------------------------------------ +# Add Startup code to application source list +# E.g.: APP_SOURCE_LST += source/startup.c +#------------------------------------------------------------------------------ +APP_SOURCE_LST += + +#------------------------------------------------------------------------------ +# Check if all necessary variables are set +# (Checks that are not possible to be performed within Makefile.static) +#------------------------------------------------------------------------------ + +############################################################################### +######### DO NOT remove these lines from the end of the Makefile!!! ########### +############################################################################### + +#------------------------------------------------------------------------------ +# Include the main makefile where all the targets are defined +#------------------------------------------------------------------------------ +include $(MAKESUPPORT_DIR)/Global.Makefile.target.$(VERSION).mk + +# End of Makefile diff --git a/Makefile.static b/Makefile.static new file mode 100644 index 0000000..d7b3015 --- /dev/null +++ b/Makefile.static @@ -0,0 +1,352 @@ +######################################################################################################################## +# File Name : Makefile.static +# Description: This makefile contains the platform/compiler specific static settings (will be included by Makefile) +# Project : Vector Basic Runtime System +# Module : BrsHw for platform ArmCommon +# and Compiler LlvmTexasInstruments, +# using Vector PES MakeSupport 4.1 +# +#----------------------------------------------------------------------------------------------------------------------- +# COPYRIGHT +#----------------------------------------------------------------------------------------------------------------------- +# Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +# +#----------------------------------------------------------------------------------------------------------------------- +# REVISION HISTORY +#----------------------------------------------------------------------------------------------------------------------- +# Refer to Makefile. +######################################################################################################################## + +######################################################################################################################## +# EXAMPLE CODE ONLY +#----------------------------------------------------------------------------------------------------------------------- +# This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. +# The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither +# intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or +# implementations must be tested with diligent care and must comply with all quality requirements which are necessary +# according to the state of the art before their use. +######################################################################################################################## + +#------------------------------------------------------------------------------ +# Include the wrapper to support DaVinci Cfg5 and Cfg6 folder structures +# (this file is platform/compiler independent and part of vBaseEnv@MakeSupport) +#------------------------------------------------------------------------------ +include Makefile.wrapper + +#------------------------------------------------------------------------------ +# Name of this project. +# +# If BRS_PROJECT_NAME (vBRS/vBRSHwConfig/vBRSProjectName) was generated into +# Makefile.config.generated (by vBRS Cfg5 generator), use that name. +#------------------------------------------------------------------------------ +ifeq ($(BRS_PROJECT_NAME),) +PROJECT_NAME = TestSuit +else +PROJECT_NAME = $(BRS_PROJECT_NAME) +endif + +#------------------------------------------------------------------------------ +# Version of MakeSupport used (current version is 4.1) +#------------------------------------------------------------------------------ +VERSION = 4 +SUB_VERSION = 1 + +############################################################################### +# Platform/compiler/derivative/emulator are relevant for the include of +# linker and symbol preprocessor command file identified by name. +# Vector standard names have to be used +############################################################################### +#------------------------------------------------------------------------------ +# Compiler Manufacturer used in this project +# E.g.: ARM5, ARM6, LLVMDIAB, GHS, GNU, GCCHIGHTEC, IAR, RENESAS, TASKING, TI +#------------------------------------------------------------------------------ +COMPILER_MANUFACTURER = LLVMTEXASINSTRUMENTS + +#------------------------------------------------------------------------------ +# Platform used for this project +# E.g.: ARM, AURIX, POWERPC, RH850 +#------------------------------------------------------------------------------ +PLATFORM = ARM + +#------------------------------------------------------------------------------ +# Emulator used for this project +# E.g.: GHSPROBE, ISYSTEMS, LAUTERBACH, MULTI +# ALL is special for "all derivatives are supported in this file" +#------------------------------------------------------------------------------ +EMULATOR = ALL + +#------------------------------------------------------------------------------ +#------------------------- MUST be filled out --------------------------------- +# Suffix of generated object files. Generated objects are then *.$(OBJ_SUFFIX) +#------------------------------------------------------------------------------ +OBJ_SUFFIX = o + +#------------------------------------------------------------------------------ +# Suffix of assembler files. +# The suffixes s, asm, 850 and arm are already considered by MakeSupport +# and do not need to be added. +#------------------------------------------------------------------------------ +ASM_SUFFIX = + +#------------------------------------------------------------------------------ +#------------------------- MUST be filled out --------------------------------- +# Suffix of generated list files. Generated list files are then *.$(LST_SUFFIX) +#------------------------------------------------------------------------------ +LST_SUFFIX = lst + +#------------------------------------------------------------------------------ +#------------------------- MUST be filled out --------------------------------- +# Suffix linker command file. +#------------------------------------------------------------------------------ +LNK_SUFFIX = ld + +#------------------------------------------------------------------------------ +#------------------------- MUST be filled out --------------------------------- +# Suffix binary output file. +#------------------------------------------------------------------------------ +BINARY_SUFFIX = out + +#------------------------------------------------------------------------------ +#------------------------- MUST be filled out --------------------------------- +# Suffix of generated library files. Generated objects are then *.$(LIB_SUFFIX) +#------------------------------------------------------------------------------ +LIB_SUFFIX = lib + +#------------------------------------------------------------------------------ +# Suffixes of generated error files which are placed in $(ERR_PATH) +# (necessary for Visual Studio / Codewright project file generation) +# Default (nothing entered) is err +# E.g. ERR_SUFFIX_LIST = err +#------------------------------------------------------------------------------ +ERR_SUFFIX_LIST = err +ERR_SUFFIX = err + +#------------------------------------------------------------------------------ +# Suffixes of generated asm/list files which are placed in $(LST_PATH) +# (necessary for Visual Studio / Codewright project file generation) +# Default (nothing entered) is lst +# E.g. LST_SUFFIX_LIST = lst asm +#------------------------------------------------------------------------------ +LST_SUFFIX_LIST = + +#------------------------------------------------------------------------------ +# Path of MakeSupport folder relative to main Makefile +#------------------------------------------------------------------------------ +MAKESUPPORT_DIR_MAK=make_support_var.mk +ifeq ($(MAKESUPPORT_DIR),) + -include $(MAKESUPPORT_DIR_MAK) +endif + +ifeq ($(MAKESUPPORT_DIR),) + # Find first on Delivery structure and then in enhanced directory structure + # Stop after first occurance + $(info Looking for MakeSupport in current structure. This could take a while for first invocation.) + MAKESUPPORT_DIR:=$(shell find ../.. ../../.. -name MakeSupport -print -quit) + ifeq ($(MAKESUPPORT_DIR),) + $(error No MakeSupport directory found. Please set 'MAKESUPPORT_DIR' environment variable manually.) + endif + $(info Found MAKESUPPORT_DIR='$(MAKESUPPORT_DIR)'. Save it to '$(MAKESUPPORT_DIR_MAK)' for next invocation.) + $(file >$(MAKESUPPORT_DIR_MAK),MAKESUPPORT_DIR=$(MAKESUPPORT_DIR)) +endif + +distclean:: + @echo "DISTCLEAN $(MAKESUPPORT_DIR_MAK)" + $(Q)$(RM) $(MAKESUPPORT_DIR_MAK) + +#------------------------------------------------------------------------------ +# $(ERR_OUTPUT) defines the way how to generate error files +# It should be one of: +# PIPE - Error will be printed to sterr/stdout and redirected to +# $(ERR_PATH) +# FLAGS - Compiler supports error file generation with or without path +# definition. Therefore, e.g. $(CFLAGS_VECTOR_MAKESUPPORT) +# and $(LDFLAGS_VECTOR_MAKESUPPORT) have to be adjusted. +# It depends on compiler flags whether output is written to +# console as well. +# CONSOLE - No compiler flags handling in MakeSupport (default). +#------------------------------------------------------------------------------ +ERR_OUTPUT = CONSOLE + +#------------------------------------------------------------------------------ +# Add compiler specific redirection flags here +# +# Uncomment V=1 if compiler has redirection options like @E, @O +# +# Example: +# --error-file=$(call obj2err,$@) +#------------------------------------------------------------------------------ +#ifneq ($(V),1) + ifeq ($(ERR_OUTPUT),FLAGS) + ASFLAGS_VECTOR_MAKESUPPORT += + endif +#endif + +#------------------------------------------------------------------------------ +# $(AS_VECTOR_PREPROCESS) enables the preprocessing +# just before assembler starts. +# +# In case of assembler does not support preprocessing by default, preprocessing +# can be enabled by setting $(ASFLAGS_VECTOR_PREPROCESS) to 1 +#------------------------------------------------------------------------------ +#AS_VECTOR_PREPROCESS = 1 + +#------------------------------------------------------------------------------ +# Enable if cross-compiler supports depend. Additional options +# have to be set. +# Attention: +# Some cross-compilers' depend file can have the problem +# of incompatible depend file for cygwin. They could contain +# "" around filepath or ':' when used absolute file spec. +#------------------------------------------------------------------------------ +COMPILER_SUPPORTS_DEPEND = 1 + +#------------------------------------------------------------------------------ +# Used only when USE_RESPONSE_FILE_FOR_LINKAGE is set to 1. +# +# LDFLAGS_RESPONSE_FILE defines the command-line flag used to specify a +# response file. +# For example, with GCC, response files can be passed using "gcc @linker_options". +# In that case, set this variable to "@". +#------------------------------------------------------------------------------ +LDFLAGS_RESPONSE_FILE=-Xlinker + +#------------------------------------------------------------------------------ +# Used only if USE_RESPONSE_FILE_FOR_LINKAGE is set to 1. +# +# If RESPONSE_FILE_MULTILINE is enabled, the response file will be reformatted +# from a single-line to a multi-line format. This is required by certain +# compilers, such as the TI ARM LLVM compiler. +#------------------------------------------------------------------------------ +RESPONSE_FILE_MULTILINE=1 + +#------------------------------------------------------------------------------ +# Add compiler specific redirection flags here +# +# Uncomment V=1 if compiler has redirection options like @E, @O +# +# Example: +# --error-file=$(call obj2err,$@) +#------------------------------------------------------------------------------ +#ifneq ($(V),1) + ifeq ($(ERR_OUTPUT),FLAGS) + CFLAGS_VECTOR_MAKESUPPORT += + endif +#endif + +#------------------------------------------------------------------------------ +# Add linker specific redirection flags here +# +# Uncomment V=1 if compiler has redirection options like @E, @O +# +# Example: +# --error-file=$(call obj2err,$@) +#------------------------------------------------------------------------------ +#ifneq ($(V),1) + ifeq ($(ERR_OUTPUT),FLAGS) + LDFLAGS_VECTOR_MAKESUPPORT += + endif +#endif + +#------------------------------------------------------------------------------ +# $(AR_COMMAND_WITHOUT_SPACE) enables the usage of an archiver command without +# space between the output flag and the target library name. +# +# E.g. this is necessary for the Renesas archiver: -output=$(TARGET_LIBRARY) +#------------------------------------------------------------------------------ +#AR_COMMAND_WITHOUT_SPACE = 1 + +#------------------------------------------------------------------------------ +# hex target might be added like the following template. +# Variable TARGET can not be used here, because TARGET is set in +# Global.Makefile.target.$(VERSION).mk. VERSION is set in Makefile.static. +# Add hex target to default: +#------------------------------------------------------------------------------ +.PHONY: hex +hex: $(PROJECT_NAME).hex + +$(PROJECT_NAME).hex: $(PROJECT_NAME).$(BINARY_SUFFIX) + @$(ECHO) "HEX $@" + $(Q)$(HEX_ENV) $(HEX) $(HEXFLAGS) + +clean:: + @$(ECHO) "CLEAN hex" + $(Q)$(RM) $(PROJECT_NAME).hex + +#------------------------------------------------------------------------------ +# ASSEMBLE_RULE/COMPILE_RULE/LINK_RULE are obsolete now +# +# In previous deliveries *_RULES were overwritten to add or delete +# options to compile/link. +# +# MakeSupport 4 has the general enhancement to add or delete options for a +# specific file. Please add the following variables to your Makefile to control, +# filter out or add specific: +# +# FILTER_=-any -option -to -filter -out +# CFLAGS_=-any -option -to -add +# +# For another option to add a post compile command, please have a look +# at MAKESUPPORT_POST_COMPILE_CMD in Global.Makefile.target.$(VERSION).mk. +# +# If all of these MakeSupport 4 enhancements do not work, please add +# static pattern rule which is a make feature. +# +# Makefile documentation: +# https://www.gnu.org/software/make/manual/html_node/Static-Usage.html#Static-Usage +# +# Example: +# copy & paste from MakeSupport 4 and add your specific file in front with the second ':' : +# my_c_file.c: $(OBJ_PATH)/%.$(OBJ_SUFFIX): $(PRJROOT_U)/%.c +# ... here are your specific rules... +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# make builds the whole project by default +# To make another target, you have to add it to the prerequisites of default. +# E.g.: default: all $(PROJECT_NAME).opt +# Here hex target might be added. +#------------------------------------------------------------------------------ +.PHONY: default +default: all hex + +#------------------------------------------------------------------------------ +# If platform specific rules exist, they can be described here to be shown +# in the usage output of the help target +#help:: +# $(ECHO) "m mytarget ................ -- build mytarget" +# $(ECHO) " nextline" +#------------------------------------------------------------------------------ +#help:: + +#------------------------------------------------------------------------------ +# Check if all necessary variables are set +#------------------------------------------------------------------------------ +ifeq ($(MAKESUPPORT_DIR),) + $(error Variable MAKESUPPORT_DIR is not defined.) +endif + +ifeq ($(PLATFORM),) + $(error Variable PLATFORM is not defined.) +endif + +ifeq ($(COMPILER_MANUFACTURER),) + $(error Variable COMPILER_MANUFACTURER is not defined.) +endif + +ifeq ($(EMULATOR),) + $(error Variable EMULATOR is not defined.) +endif + +ifeq ($(VERSION),) + $(error Variable VERSION is not defined.) +endif + +#------------------------------------------------------------------------------ +# List of variables which are required and must be set within +# Makefile.config.generated. Check is performed by global makefile +#------------------------------------------------------------------------------ +REQUIRED_MK_CONF_VARS = DERIVATIVE \ + CPU_CORE \ + INSTRUCTION_SET + +# End of Makefile.static diff --git a/Makefile.wrapper b/Makefile.wrapper new file mode 100644 index 0000000..80c0a00 --- /dev/null +++ b/Makefile.wrapper @@ -0,0 +1,192 @@ +######################################################################################################################## +# File Name : Makefile.wrapper +# Description: This makefile is a wrapper to support DaVinci Cfg5 and Cfg6 folder structures +# Project : Vector Basic Runtime System +# Module : vBaseEnv +# using Vector PES MakeSupport 4.1 +# +#----------------------------------------------------------------------------------------------------------------------- +# COPYRIGHT +#----------------------------------------------------------------------------------------------------------------------- +# Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +# +#----------------------------------------------------------------------------------------------------------------------- +# REVISION HISTORY +#----------------------------------------------------------------------------------------------------------------------- +# Version Date Author Change Id Description +# ---------------------------------------------------------------------------------------------------------------------- +# 00.05.00 2025-06-13 visbwa BASEENV-13947 Initial creation for DaVinci Configurator 6 support of PES MakeSupport +# 2025-06-18 visbwa Added support for "custom gendata environment", e.g. used by TscFwHlp +# 00.05.01 2025-06-25 visbwa Fixed CFG5_TEMPDATA_DIR (key sensitive!) +# 01.00.00 2025-07-23 visbwa Final release; changed most warning to info +# 01.01.00 2025-10-14 visbwa Workaround to support CANbedded Make include structure +######################################################################################################################## + +######################################################################################################################## +# EXAMPLE CODE ONLY +#----------------------------------------------------------------------------------------------------------------------- +# This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. +# The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither +# intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or +# implementations must be tested with diligent care and must comply with all quality requirements which are necessary +# according to the state of the art before their use. +######################################################################################################################## + +#------------------------------------------------------------------------------ +# Path to the Cfg6 GenData and Template folders. They are configurable in General.json. +# The paths are relative to the location of the Makefile. +# The default is set to fit with the Cfg6 default folder structure. It needs to be adapted, if this is changed. +# These values are not used within a Cfg5 environment. +#------------------------------------------------------------------------------ +CFG6_GENDATA_DIR = ../Output/Source/GenData +CFG6_TEMPDATA_DIR = ../Output/Source/Templates + +#------------------------------------------------------------------------------ +# Path to the Cfg5 Template folder. It is configurable in Cfg5 Project Settings. +# The path is relative to the location of the Makefile. +# The default is set to fit with the Cfg5 default folder structure. It needs to be adapted, if this is changed. +# This value is not used within a Cfg6 environment. +# The GenData folder for Cfg5 environments is set within Makefile.project.part.defines. +#------------------------------------------------------------------------------ +CFG5_TEMPDATA_DIR = Source + +#------------------------------------------------------------------------------ +# Try to include the project specific settings from DaVinci Cfg5 folder structure +# +# root +# |- Appl (Makefile, Makefile.config.generated) +# |- GenData +# |- Source (LinkerScriptFile) +#------------------------------------------------------------------------------ +-include Makefile.config.generated + +ifeq ($(BRS_GENERATED_HW_CONFIG_VERSION),) + $(info BUILDENVIRONMENT: No Cfg5 environment detected) +else + $(info BUILDENVIRONMENT: Cfg5 environment detected) + CFG5_ENVIRONMENT_DETECTED = 1 +endif + +#------------------------------------------------------------------------------ +# Try to include the project specific settings from DaVinci Cfg6 folder structure +# +# root +# |- Appl (Makefile) +# |- Output +# |- Source +# |- GenData +# |- Make (Makefile.config.generated) +# |- Templates (LinkerScriptFile) +#------------------------------------------------------------------------------ +-include $(CFG6_GENDATA_DIR)/Make/Makefile.config.generated + +ifeq ($(BRS_GENERATED_CFG6_HW_CONFIG_VERSION),) + $(info BUILDENVIRONMENT: No Cfg6 environment detected) +else + $(info BUILDENVIRONMENT: Cfg6 environment detected) + CFG6_ENVIRONMENT_DETECTED = 1 +endif + +#------------------------------------------------------------------------------ +# Workaround for CANbedded TLM to include Os_Core.mak in Os_rules.mak correctly +# because BSW_MAKE_DIR is not yet set in this case. +# (with CANbedded, OS Makefiles are included in MPPD directly and need BSW_MAKE_DIR!) +#------------------------------------------------------------------------------ +ifeq ($(BSW_MAKE_DIR),) + # check for the CANbedded TLM use case using the internal/external structure + # and set the BSW_MAKE_DIR varaible according to the detected folder structure + ifneq ("$(wildcard ../../../internal/external/Components/Os/Make)","") + $(info BUILDENVIRONMENT: CANbedded TLM detected! Workaround for OS Makefile usage in MPPD necessary...) + $(info BUILDENVIRONMENT: BSW_MAKE_DIR set to Make (component based folder structure)) + BSW_MAKE_DIR = Make + else ifneq ("$(wildcard ../../../internal/external/BSW/Os/mak)","") + $(info BUILDENVIRONMENT: CANbedded TLM detected! Workaround for OS Makefile usage in MPPD necessary...) + $(info BUILDENVIRONMENT: BSW_MAKE_DIR set to mak (legacy folder structure)) + BSW_MAKE_DIR = mak + endif +endif + +#------------------------------------------------------------------------------ +# Include of SWCP created MPPD file +#------------------------------------------------------------------------------ +include Makefile.project.part.defines + +#------------------------------------------------------------------------------ +# If neither Cfg5 nor Cfg6 environment was detected, check as fallback case +# if the GENDATA_DIR variable was set in MPPD file and the configured path exists. +# If it exists, use GENDATA_DIR in the following. +#------------------------------------------------------------------------------ +ifeq ($(CFG6_ENVIRONMENT_DETECTED),) + ifeq ($(CFG5_ENVIRONMENT_DETECTED),) + ifneq ($(GENDATA_DIR),) + ifeq ("$(wildcard $(GENDATA_DIR))","") + $(warning BUILDENVIRONMENT: No gendata environment detected. The path, set in GENDATA_DIR, does not exist: $(GENDATA_DIR)) + else + $(info BUILDENVIRONMENT: Custom gendata environment detected via MPPD. GENDATA_DIR: $(GENDATA_DIR)) + CUSTOM_GENDATA_ENVIRONMENT_DETECTED = 1 + endif + else + $(warning BUILDENVIRONMENT: No GENDATA_DIR variable is set. Not able to detect a custom gendata environment) + endif + endif +endif + +#------------------------------------------------------------------------------ +# Plausibility checks +#------------------------------------------------------------------------------ +ifeq ($(CFG6_ENVIRONMENT_DETECTED),) + ifeq ($(CFG5_ENVIRONMENT_DETECTED),) + ifeq ($(CUSTOM_GENDATA_ENVIRONMENT_DETECTED),) + $(error BUILDENVIRONMENT: Neither Cfg5, Cfg6 nor custom environment detected! Check your environment) + endif + endif +else + ifeq ($(CFG5_ENVIRONMENT_DETECTED),1) + $(error BUILDENVIRONMENT: Both environments detected in parallel, Cfg5 and Cfg6! Check your environment) + endif +endif + +#------------------------------------------------------------------------------ +# Static setting of path variables +#------------------------------------------------------------------------------ +ifeq ($(CFG5_ENVIRONMENT_DETECTED),1) + TEMPDATA_DIR = $(CFG5_TEMPDATA_DIR) + $(info BUILDENVIRONMENT: For Cfg5 environment, GENDATA_DIR is set in Makefile.project.part.defines: $(GENDATA_DIR)) + $(info BUILDENVIRONMENT: TEMPDATA_DIR set to Cfg5 supposed value: $(CFG5_TEMPDATA_DIR)) + $(info BUILDENVIRONMENT: To change this path, edit the following file: Makefile.wrapper) +endif + +ifeq ($(CFG6_ENVIRONMENT_DETECTED),1) + GENDATA_DIR = $(CFG6_GENDATA_DIR) + TEMPDATA_DIR = $(CFG6_TEMPDATA_DIR) + ADDITIONAL_INCLUDES += $(TEMPDATA_DIR) + $(info BUILDENVIRONMENT: GENDATA_DIR set to Cfg6 supposed value: $(CFG6_GENDATA_DIR)) + $(info BUILDENVIRONMENT: TEMPDATA_DIR set to Cfg6 supposed value: $(CFG6_TEMPDATA_DIR) and added to ADDITIONAL_INCLUDES) + $(info BUILDENVIRONMENT: To change these paths, edit the following file: Makefile.wrapper) +endif + +ifeq ($(CUSTOM_GENDATA_ENVIRONMENT_DETECTED), 1) + # GENDATA_DIR is taken from Makefile.project.part.defines + # Try to set TEMPDATA_DIR correctly based on subfolder existence in gendata folder + ifneq ("$(wildcard $(GENDATA_DIR)/../Source)","") + TEMPDATA_DIR = $(GENDATA_DIR)/../Source + $(info BUILDENVIRONMENT: TEMPDATA_DIR set to value: $(TEMPDATA_DIR)) + $(info BUILDENVIRONMENT: Custom Cfg5 environment expected. Try to include Makefile.config.generated...) + include $(GENDATA_DIR)/../Makefile.config.generated + else ifneq ("$(wildcard $(GENDATA_DIR)/../Templates)","") + TEMPDATA_DIR = $(GENDATA_DIR)/../Templates + ADDITIONAL_INCLUDES += $(TEMPDATA_DIR) + $(info BUILDENVIRONMENT: TEMPDATA_DIR set to value: $(TEMPDATA_DIR) and added to ADDITIONAL_INCLUDES) + $(info BUILDENVIRONMENT: Custom Cfg6 environment expected. Try to include Makefile.config.generated...) + include $(GENDATA_DIR)/Make/Makefile.config.generated + else + TEMPDATA_DIR = $(GENDATA_DIR) + $(info BUILDENVIRONMENT: TEMPDATA_DIR set to GENDATA_DIR value: $(TEMPDATA_DIR)) + $(info BUILDENVIRONMENT: Complete custom environment expected. Try to include Makefile.config.generated...) + include $(GENDATA_DIR)/Makefile.config.generated + endif + + $(info BUILDENVIRONMENT: To change these paths, edit GENDATA_DIR in Makefile.project.part.defines) +endif + +$(info ********************************************************************************) diff --git a/Source/appl/ARMBrsHwIntTb_CortexR.c b/Source/appl/ARMBrsHwIntTb_CortexR.c new file mode 100644 index 0000000..08a53fb --- /dev/null +++ b/Source/appl/ARMBrsHwIntTb_CortexR.c @@ -0,0 +1,674 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: ARMBrsHwIntTb_CortexR.c + * Project: Vector Basic Runtime System + * Module: BrsHw for all platforms with ARM core Cortex-R + * Template: This file is reviewed according to Brs_Template@Implementation[1.03.12] + * + * \brief Description: This is a global, hardware-independent file for the ARM-BRS. + * It consists of the core exception table for Startup and a 2nd one to be copied into RAM + * for FBL projects. + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to ARMBrsHw_CortexR.h. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * EXAMPLE CODE ONLY + * ------------------------------------------------------------------------------------------------------------------- + * This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. + * The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither + * intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or + * implementations must be tested with diligent care and must comply with all quality requirements which are necessary + * according to the state of the art before their use. + *********************************************************************************************************************/ + +#define ARMBRSHWINTTB_CORTEXR_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "ARMBrsHw_CortexR.h" + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + +#else + #error "Unknown compiler specified!" +#endif + +/********************************************************************************************************************** + * PROTOTYPES OF LOCAL FUNCTIONS + *********************************************************************************************************************/ +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +BRS_ISR_KEYWORD void BrsHw_CoreExceptionHandler(void); +#endif + +#if defined (BRS_ENABLE_OS_MULTICORESUPPORT) +BRS_ISR_KEYWORD void BrsHw_MultiCoreExceptionHandler(void); +BRS_LOCAL_FUNCTION_PROTOTYPE(intvect_Core1Exceptions) +# if (BRS_CPU_CORE_AMOUNT > 2) +BRS_LOCAL_FUNCTION_PROTOTYPE(intvect_Core2Exceptions) +# endif +# if (BRS_CPU_CORE_AMOUNT > 3) +BRS_LOCAL_FUNCTION_PROTOTYPE(intvect_Core3Exceptions) +# endif +# if (BRS_CPU_CORE_AMOUNT > 4) +BRS_LOCAL_FUNCTION_PROTOTYPE(intvect_Core4Exceptions) +# endif +# if (BRS_CPU_CORE_AMOUNT > 5) +BRS_LOCAL_FUNCTION_PROTOTYPE(intvect_Core5Exceptions) +# endif +# if (BRS_CPU_CORE_AMOUNT > 6) +BRS_LOCAL_FUNCTION_PROTOTYPE(intvect_Core6Exceptions) +# endif +# if (BRS_CPU_CORE_AMOUNT > 7) +BRS_LOCAL_FUNCTION_PROTOTYPE(intvect_Core7Exceptions) +# endif +# if (BRS_CPU_CORE_AMOUNT > 8) + #error "More than 8 cores actually not supported by ARMBrsHwIntTb_CortexR.c!" +# endif +#endif /*BRS_ENABLE_OS_MULTICORESUPPORT*/ + +#if defined (BRS_ENABLE_FBL_SUPPORT) && defined (BRS_FBL_EXCEPTIONTABLE_IN_RAM) +BRS_ISR_KEYWORD void BrsHw_CoreExceptionHandler_Ram(void); +#endif + +extern void brsStartupEntry(void); + +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +/* This code is only needed for the first instance/executable in the system */ + +/******************************************************************************************** + * * + * Startup Core Exception Handler * + * * + ********************************************************************************************/ +#define BRS_START_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +BRS_ISR_KEYWORD void BrsHw_CoreExceptionHandler(void) +{ +#if defined (BRSHW_BRSHW_COREEXCEPTIONHANDLER_CALLOUT) + BrsTestsuite_BrsHw_CoreExceptionHandler(); +#endif + + volatile uint8 Brs_Continue; + Brs_Continue = 0; + + while (Brs_Continue == 0) + { + /* Set BrsMain_Continue to 1 to continue here. + * If the debugger is not able to show the stack properly, this mechanism can be used to find the + * source of the exception. */ + } +} +#define BRS_STOP_SEC_STARTUP_CODE +#include "Brs_MemMap.h" + +/******************************************************************************************** + * * + * Startup Core Exception Table * + * * + ********************************************************************************************/ + + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +# pragma clang section text = ".brsExcVect" +__attribute__((naked)) void intvect_CoreExceptions(void) +{ + /* Exception Table */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 0: Reset */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 1: Undefined Instruction */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 2: SVCall */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 3: Abort Prefetch */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 4: Abort Data */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 5: Reserved */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 6: IRQ */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 7: FIQ */ +} +# pragma clang section text = "" + + /* Exception Vectors */ + __attribute__((section(".brsExcVectConst"))) void (* const intvect_CoreExceptions_vectortable[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_CoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_CoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_CoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_CoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_CoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_CoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_CoreExceptionHandler /* Exception 7: FIQ */ + }; + + /* Backup Exception Vectors */ + __attribute__((section(".brsExcVectConst"))) void (* const intvect_CoreExceptions_vectortable_backup[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_CoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_CoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_CoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_CoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_CoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_CoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_CoreExceptionHandler /* Exception 7: FIQ */ + }; +# endif /*BRS_COMP_LLVMDIAB||BRS_COMP_LLVMTEXASINSTRUMENTS*/ + + + +#endif /*BRS_FIRST_EXECUTION_INSTANCE*/ + +#if defined (BRS_ENABLE_OS_MULTICORESUPPORT) +const ARMBrsHw_PhysicalCoreId_CoreExceptions_MappingType BrsHw_intvect_CoreExceptions_list[BRS_CPU_CORE_AMOUNT-1] = { + {1, intvect_Core1Exceptions} +# if (BRS_CPU_CORE_AMOUNT > 2) + ,{2, intvect_Core2Exceptions} +# endif +# if (BRS_CPU_CORE_AMOUNT > 3) + ,{3, intvect_Core3Exceptions} +# endif +# if (BRS_CPU_CORE_AMOUNT > 4) + ,{4, intvect_Core4Exceptions} +# endif +# if (BRS_CPU_CORE_AMOUNT > 5) + ,{5, intvect_Core5Exceptions} +# endif +# if (BRS_CPU_CORE_AMOUNT > 6) + ,{6, intvect_Core6Exceptions} +# endif +# if (BRS_CPU_CORE_AMOUNT > 7) + ,{7, intvect_Core7Exceptions} +# endif +}; + +/******************************************************************************************** + * * + * MultiCore Exception Handler * + * * + ********************************************************************************************/ +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +#define BRS_START_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +#endif +BRS_ISR_KEYWORD void BrsHw_MultiCoreExceptionHandler(void) +{ +#if defined (BRSHW_BRSHW_MULTICOREEXCEPTIONHANDLER_CALLOUT) + BrsTestsuite_BrsHw_MultiCoreExceptionHandler(); +#endif + + volatile uint8 Brs_Continue; + Brs_Continue = 0; + + while (Brs_Continue == 0) + { + /* Set Brs_Continue to 1 to continue here. + * If the debugger is not able to show the stack properly, this mechanism can be used to find the + * source of the exception. */ + } +} +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +#define BRS_STOP_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +#endif + +/******************************************************************************************** + * * + * Core 1 Exception Table * + * * + ********************************************************************************************/ + + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +# pragma clang section text = ".brsExcVect1" +__attribute__((naked)) void intvect_Core1Exceptions(void) +{ + /* Exception Table */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 0: Reset */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 1: Undefined Instruction */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 2: SVCall */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 3: Abort Prefetch */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 4: Abort Data */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 5: Reserved */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 6: IRQ */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 7: FIQ */ +} +# pragma clang section text = "" + + /* Exception Vectors */ + __attribute__((section(".brsExcVect1Const"))) void (* const intvect_Core1Exceptions_vectortable[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; + + /* Backup Exception Vectors */ + __attribute__((section(".brsExcVect1Const"))) void (* const intvect_Core1Exceptions_vectortable_backup[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; +# endif /*BRS_COMP_LLVMDIAB||BRS_COMP_LLVMTEXASINSTRUMENTS*/ + + + + +# if (BRS_CPU_CORE_AMOUNT > 2) +/******************************************************************************************** + * * + * Core 2 Exception Table * + * * + ********************************************************************************************/ + + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +# pragma clang section text = ".brsExcVect2" +__attribute__((naked)) void intvect_Core2Exceptions(void) +{ + /* Exception Table */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 0: Reset */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 1: Undefined Instruction */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 2: SVCall */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 3: Abort Prefetch */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 4: Abort Data */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 5: Reserved */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 6: IRQ */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 7: FIQ */ +} +# pragma clang section text = "" + + /* Exception Vectors */ + __attribute__((section(".brsExcVect2Const"))) void (* const intvect_Core2Exceptions_vectortable[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; + + /* Backup Exception Vectors */ + __attribute__((section(".brsExcVect2Const"))) void (* const intvect_Core2Exceptions_vectortable_backup[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; +# endif /*BRS_COMP_LLVMDIAB||BRS_COMP_LLVMTEXASINSTRUMENTS*/ + + + +# endif /*BRS_CPU_CORE_AMOUNT > 2*/ + +# if (BRS_CPU_CORE_AMOUNT > 3) +/******************************************************************************************** + * * + * Core 3 Exception Table * + * * + ********************************************************************************************/ + + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +# pragma clang section text = ".brsExcVect3" +__attribute__((naked)) void intvect_Core3Exceptions(void) +{ + /* Exception Table */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 0: Reset */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 1: Undefined Instruction */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 2: SVCall */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 3: Abort Prefetch */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 4: Abort Data */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 5: Reserved */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 6: IRQ */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 7: FIQ */ +} +# pragma clang section text = "" + + /* Exception Vectors */ + __attribute__((section(".brsExcVect3Const"))) void (* const intvect_Core3Exceptions_vectortable[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; + + /* Backup Exception Vectors */ + __attribute__((section(".brsExcVect3Const"))) void (* const intvect_Core3Exceptions_vectortable_backup[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; +# endif /*BRS_COMP_LLVMDIAB||BRS_COMP_LLVMTEXASINSTRUMENTS*/ + + + +# endif /*BRS_CPU_CORE_AMOUNT > 3*/ + +# if (BRS_CPU_CORE_AMOUNT > 4) +/******************************************************************************************** + * * + * Core 4 Exception Table * + * * + ********************************************************************************************/ + + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +# pragma clang section text = ".brsExcVect4" +__attribute__((naked)) void intvect_Core4Exceptions(void) +{ + /* Exception Table */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 0: Reset */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 1: Undefined Instruction */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 2: SVCall */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 3: Abort Prefetch */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 4: Abort Data */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 5: Reserved */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 6: IRQ */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 7: FIQ */ +} +# pragma clang section text = "" + + /* Exception Vectors */ + __attribute__((section(".brsExcVect4Const"))) void (* const intvect_Core4Exceptions_vectortable[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; + + /* Backup Exception Vectors */ + __attribute__((section(".brsExcVect4Const"))) void (* const intvect_Core4Exceptions_vectortable_backup[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; +# endif /*BRS_COMP_LLVMDIAB||BRS_COMP_LLVMTEXASINSTRUMENTS*/ + + + +# endif /*BRS_CPU_CORE_AMOUNT > 4*/ + +# if (BRS_CPU_CORE_AMOUNT > 5) +/******************************************************************************************** + * * + * Core 5 Exception Table * + * * + ********************************************************************************************/ + + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +# pragma clang section text = ".brsExcVect5" +__attribute__((naked)) void intvect_Core5Exceptions(void) +{ + /* Exception Table */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 0: Reset */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 1: Undefined Instruction */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 2: SVCall */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 3: Abort Prefetch */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 4: Abort Data */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 5: Reserved */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 6: IRQ */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 7: FIQ */ +} +# pragma clang section text = "" + + /* Exception Vectors */ + __attribute__((section(".brsExcVect5Const"))) void (* const intvect_Core5Exceptions_vectortable[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; + + /* Backup Exception Vectors */ + __attribute__((section(".brsExcVect5Const"))) void (* const intvect_Core5Exceptions_vectortable_backup[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; +# endif /*BRS_COMP_LLVMDIAB||BRS_COMP_LLVMTEXASINSTRUMENTS*/ + + + +# endif /*BRS_CPU_CORE_AMOUNT > 5*/ + +# if (BRS_CPU_CORE_AMOUNT > 6) +/******************************************************************************************** + * * + * Core 6 Exception Table * + * * + ********************************************************************************************/ + + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +# pragma clang section text = ".brsExcVect6" +__attribute__((naked)) void intvect_Core6Exceptions(void) +{ + /* Exception Table */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 0: Reset */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 1: Undefined Instruction */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 2: SVCall */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 3: Abort Prefetch */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 4: Abort Data */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 5: Reserved */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 6: IRQ */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 7: FIQ */ +} +# pragma clang section text = "" + + /* Exception Vectors */ + __attribute__((section(".brsExcVect6Const"))) void (* const intvect_Core6Exceptions_vectortable[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; + + /* Backup Exception Vectors */ + __attribute__((section(".brsExcVect6Const"))) void (* const intvect_Core6Exceptions_vectortable_backup[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; +# endif /*BRS_COMP_LLVMDIAB||BRS_COMP_LLVMTEXASINSTRUMENTS*/ + + + +# endif /*BRS_CPU_CORE_AMOUNT > 6*/ + +# if (BRS_CPU_CORE_AMOUNT > 7) +/******************************************************************************************** + * * + * Core 7 Exception Table * + * * + ********************************************************************************************/ + + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +# pragma clang section text = ".brsExcVect7" +__attribute__((naked)) void intvect_Core7Exceptions(void) +{ + /* Exception Table */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 0: Reset */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 1: Undefined Instruction */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 2: SVCall */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 3: Abort Prefetch */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 4: Abort Data */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 5: Reserved */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 6: IRQ */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 7: FIQ */ +} +# pragma clang section text = "" + + /* Exception Vectors */ + __attribute__((section(".brsExcVect7Const"))) void (* const intvect_Core7Exceptions_vectortable[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; + + /* Backup Exception Vectors */ + __attribute__((section(".brsExcVect7Const"))) void (* const intvect_Core7Exceptions_vectortable_backup[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_MultiCoreExceptionHandler, /* Exception 1: Undefined Instruction */ + BrsHw_MultiCoreExceptionHandler, /* Exception 2: SVCall */ + BrsHw_MultiCoreExceptionHandler, /* Exception 3: Abort Prefetch */ + BrsHw_MultiCoreExceptionHandler, /* Exception 4: Abort Data */ + BrsHw_MultiCoreExceptionHandler, /* Exception 5: Reserved */ + BrsHw_MultiCoreExceptionHandler, /* Exception 6: IRQ */ + BrsHw_MultiCoreExceptionHandler /* Exception 7: FIQ */ + }; +# endif /*BRS_COMP_LLVMDIAB||BRS_COMP_LLVMTEXASINSTRUMENTS*/ + + + +# endif /*BRS_CPU_CORE_AMOUNT > 7*/ +#endif /*BRS_ENABLE_OS_MULTICORESUPPORT*/ + +#if defined (BRS_ENABLE_FBL_SUPPORT) && defined (BRS_FBL_EXCEPTIONTABLE_IN_RAM) +/******************************************************************************************** + * * + * Core Exception Handler in RAM * + * * + ********************************************************************************************/ +#define BRS_START_SEC_RAM_CODE +#include "Brs_MemMap.h" +BRS_ISR_KEYWORD void BrsHw_CoreExceptionHandler_Ram(void) +{ +#if defined (BRSHW_BRSHW_COREEXCEPTIONHANDLER_RAM_CALLOUT) + BrsTestsuite_BrsHw_CoreExceptionHandler_Ram(); +#endif + + volatile uint8 Brs_Continue; + Brs_Continue = 0; + + while (Brs_Continue == 0) + { + /* Set Brs_Continue to 1 to continue here. + * If the debugger is not able to show the stack properly, this mechanism can be used to find the + * source of the exception. */ + } +} +#define BRS_STOP_SEC_RAM_CODE +#include "Brs_MemMap.h" + +/******************************************************************************************** + * * + * Core Exception Table in RAM * + * * + ********************************************************************************************/ +# if !defined (BRS_FIRST_EXECUTION_INSTANCE) + #error "If this executable is not first execution instance, reset vector must be manually set in RAM exception table to entry address!" +/* Replace brsStartupEntry in the RAM exception table with, e.g., 0x80, as this linker symbol will not exist in this case. Then, comment out the error message above. */ +# endif + + + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +# pragma clang section text = ".brsExcVectRam" +__attribute__((naked)) void intvect_CoreExceptions_Ram(void) +{ + /* Exception Table */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 0: Reset */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 1: Undefined Instruction */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 2: SVCall */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 3: Abort Prefetch */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 4: Abort Data */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 5: Reserved */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 6: IRQ */ + __asm(" ldr pc,[pc,#0x18] "); /* Exception 7: FIQ */ +} +# pragma clang section text = "" + + /* Exception Vectors */ + __attribute__((section(".brsExcVectRamConst"))) void (* const intvect_CoreExceptions_Ram_Vectortable[])(void) = { + brsStartupEntry, /* Exception 0: Reset */ + BrsHw_CoreExceptionHandler_Ram, /* Exception 1: Undefined Instruction */ + BrsHw_CoreExceptionHandler_Ram, /* Exception 2: SVCall */ + BrsHw_CoreExceptionHandler_Ram, /* Exception 3: Abort Prefetch */ + BrsHw_CoreExceptionHandler_Ram, /* Exception 4: Abort Data */ + BrsHw_CoreExceptionHandler_Ram, /* Exception 5: Reserved */ + BrsHw_CoreExceptionHandler_Ram, /* Exception 6: IRQ */ + BrsHw_CoreExceptionHandler_Ram /* Exception 7: FIQ */ + }; +# endif /*BRS_COMP_LLVMDIAB||BRS_COMP_LLVMTEXASINSTRUMENTS*/ + + + +#endif /*BRS_ENABLE_FBL_SUPPORT&&BRS_FBL_EXCEPTIONTABLE_IN_RAM*/ diff --git a/Source/appl/ARMBrsHw_CortexR.c b/Source/appl/ARMBrsHw_CortexR.c new file mode 100644 index 0000000..c774fa1 --- /dev/null +++ b/Source/appl/ARMBrsHw_CortexR.c @@ -0,0 +1,296 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: ARMBrsHw_CortexR.c + * Project: Vector Basic Runtime System + * Module: BrsHw for all platforms with ARM core Cortex-R + * Template: This file is reviewed according to Brs_Template@Implementation[1.03.12] + * + * \brief Description: This is a global, platform-independent file for the ARM-BRS. + * This file includes all non-platform dependent functions. + * All the (platform depending) rest needs to be defined in BrsHw.c + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to ARMBrsHw_CortexR.h. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * EXAMPLE CODE ONLY + * ------------------------------------------------------------------------------------------------------------------- + * This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. + * The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither + * intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or + * implementations must be tested with diligent care and must comply with all quality requirements which are necessary + * according to the state of the art before their use. + *********************************************************************************************************************/ + +#define ARMBRSHW_CORTEXR_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "BrsHw.h" + +#if !defined (BRS_DISABLE_OS_USAGE) + /* BootManager, FlashBootLoader, HSM-Updater and HypervisorMaster execution instances do not use an OS. Define is set in BrsMain.h */ + #include "Os.h" +#endif + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ +#if (ARMBRSHW_CORTEXR_VERSION != 0x0205u) + #error "Header and source file are inconsistent!" +#endif +#if (ARMBRSHW_CORTEXR_BUGFIX_VERSION != 0x05u) + #error "Different versions of bugfix in Header and Source used!" +#endif + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + +#else + #error "Unknown compiler specified!" +#endif + +#if !defined (BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0) && !defined (BRS_FIRST_EXECUTION_INSTANCE) +# if !defined (BRSHW_COREEXCEPTIONS_ADDRESS_OF_INIT_CORE) + /* As intvect_CoreExceptions is not available within non-First-Execution-Instance binaries, it is necessary to + hardly configure the address of intvect_CoreExceptions for your platform additionally. + This is needed for the exception vector change within BrsHw_ExceptionTable_Init(). */ + #error "BRSHW_COREEXCEPTIONS_ADDRESS_OF_INIT_CORE needs to be defined in BrsHw.h of your platform!" +# endif +#endif + +#if (BRSMAIN_VERSION < 0x0221u) + /* At least BrsMain 2.21.00 is needed for Hypervisor support and definition of BRS_DISABLE_OS_USAGE */ + #error "BrsMain of at least version 2.21.00 is needed for this BrsHw package!" +#endif + +/********************************************************************************************************************** + * DEFINITION + MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL VARIABLES AND LOCAL HW REGISTERS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * CONTROLLER CONFIGURATION REGISTERS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * PROTOTYPES OF GLOBAL FUNCTIONS + *********************************************************************************************************************/ +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +extern void intvect_CoreExceptions(void); +#endif + +#if defined (BRS_ENABLE_OS_MULTICORESUPPORT) +extern ARMBrsHw_PhysicalCoreId_CoreExceptions_MappingType BrsHw_intvect_CoreExceptions_list[BRS_CPU_CORE_AMOUNT-1]; +#endif + +/********************************************************************************************************************** + * PROTOTYPES OF LOCAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * FUNCTION DEFINITIONS + *********************************************************************************************************************/ + +/*****************************************************************************/ +/* @brief Disable the global system interrupt. + * @pre Must be the first function call in main@BrsMain + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from main@BrsMain at power on initialization + *****************************************************************************/ +void BrsHwDisableInterruptAtPowerOn(void) +{ + /* Disable IRQ, FIQ */ + __asm(" MRS R0, CPSR "); /* Read CPSR Register */ + __asm(" ORR R0, R0, #0x040 "); /* Set Asynchronous FIQ Mask bit */ + __asm(" ORR R0, R0, #0x080 "); /* Set Asynchronous IRQ Mask bit */ + __asm(" MSR CPSR_c, R0 "); /* Write CPSR Register (only bits [7:0]) */ + +#if defined (BRSHW_DISABLE_INTERRUPT_AT_POWERON_HOOK_AVAILABLE) + /* used to configure additional, platform specific registers (e.g. VIC) + BRSHW_DISABLE_INTERRUPT_AT_POWERON_HOOK_AVAILABLE to be defined in BrsHw.h */ + BrsHwDisableInterruptAtPowerOn_Hook(); +#endif +} + +/*****************************************************************************/ +/* @brief Copy exception vectors to active exception table + * @pre - + * @param[in] ExcVecLabel - address of the core exception table + * IntVecLabel - address of the interrupt vector table + * Use BRS_DEFINE_ADDRESS_UNUSED for unused values + * @param[out] - + * @return - + * @context Function is called from main@BrsMain at power on initialization + *****************************************************************************/ +void BrsHw_ExceptionTable_Init(Brs_AddressOfConstType ExcVecLabel, Brs_AddressOfConstType IntVecLabel) +{ + /* VBAR is Undefined/not available on ARMv7-R implementations -> + Exception vector change is done via overwriting the exception vectors, + which are placed at an offset of 0x20 bytes just behind the exception table start. + See ARMv7_Cortex-R_BRS_Exception_Handling.pdf for details of the mechanism! + */ + int i; + uint32 addressOfActiveExceptionTable; + +#if !defined (BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0) + uint32 runningCoreId; +#endif + +#if defined (BRS_ENABLE_OS_MULTICORESUPPORT) + uint32 coreFound; +#endif + +#if defined (BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0) + addressOfActiveExceptionTable = 0x0; + +#else + runningCoreId = BrsHw_GetCore(); + if (runningCoreId == BRSHW_INIT_CORE_ID) + { +# if defined (BRS_FIRST_EXECUTION_INSTANCE) + addressOfActiveExceptionTable = ((uint32)&intvect_CoreExceptions); +# else + addressOfActiveExceptionTable = BRSHW_COREEXCEPTIONS_ADDRESS_OF_INIT_CORE; +# endif + } + else + { +# if defined (BRS_ENABLE_OS_MULTICORESUPPORT) + coreFound = 0; + for (i=0; i < (BRS_CPU_CORE_AMOUNT-1); i++) + { + if (BrsHw_intvect_CoreExceptions_list[i].PhysicalCoreId == runningCoreId) + { + addressOfActiveExceptionTable = (uint32)(BrsHw_intvect_CoreExceptions_list[i].CoreExceptions); + coreFound = 1; + break; + } + } + if (coreFound == 0) + { + BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSHW, (uint16)(__LINE__)); + } +# else + BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSHW, (uint16)(__LINE__)); +# endif /*BRS_ENABLE_OS_MULTICORESUPPORT*/ + } +#endif /*else BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0*/ + + if(ExcVecLabel!=BRS_DEFINE_ADDRESS_UNUSED) + { + for (i=0; i<8; i++) + { + *((uint32*)(addressOfActiveExceptionTable+0x20+i*4)) = *(uint32*)(((uint32)ExcVecLabel)+0x20+i*4); + } + } + +#if defined (BRSHW_ECXEPTIONTABLE_INIT_POSTHOOK_AVAILABLE) + BrsHw_ExceptionTable_Init_PostHook(ExcVecLabel, IntVecLabel); +#endif +} + +/*****************************************************************************/ +/* @brief This API is used for the BRS time measurement support to get a + * default time value for all measurements with this platform to + * be able to compare time measurements on different dates based + * on this time result. + * @pre Should be called with interrupts global disabled + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from e.g. component testsuits for calibration + *****************************************************************************/ +void BrsHwTime100NOP(void) +{ + BRSHWNOP10(); + BRSHWNOP10(); + BRSHWNOP10(); + BRSHWNOP10(); + BRSHWNOP10(); + BRSHWNOP10(); + BRSHWNOP10(); + BRSHWNOP10(); + BRSHWNOP10(); + BRSHWNOP10(); +} + +#if !defined (BRSHW_PLATFORM_SPECIFIC_GETCORE_AVAILABLE) +/*****************************************************************************/ +/* @brief This API is used to read the core ID of the actual running core + * @pre - + * @param[in] - + * @param[out] - + * @return Core ID of the actual running core + * @context Function is e.g. called from main@BrsMain, to only call HW-init + * code once, on the boot core. + * In MultiCore setups, additional BRSHW_INIT_CORE_ID must be + * declared inside BrsHw.h, to configure the proper core ID value + * of that boot core. + *****************************************************************************/ +uint32 BrsHw_GetCore(void) +{ +#if (BRS_CPU_CORE_AMOUNT>1) + uint32 id = 0; + /* Read out the physical processor number (Multiprocessor affinity register (MPIDR)) + * 0 for Core0, Cluster0 + * 1 for Core1, Cluster0 + * 2 for Core0, Cluster1 + * 3 for Core1, Cluster1 + * 4 for Core0, Cluster2 + * 5 for Core1, Cluster2 + */ + brsHwGetMpidr(id); + + return (((id & 0x0000FF00ul) >> 7) | (id & 3ul)); + +#else + /* Stub for SingleCore environments, always returns 0 */ + return 0u; +#endif /*BRS_CPU_CORE_AMOUNT*/ +} +#endif /*!BRSHW_PLATFORM_SPECIFIC_GETCORE_AVAILABLE*/ diff --git a/Source/appl/ARMStartup_CortexR.c b/Source/appl/ARMStartup_CortexR.c new file mode 100644 index 0000000..9e711a8 --- /dev/null +++ b/Source/appl/ARMStartup_CortexR.c @@ -0,0 +1,754 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: ARMStartup_CortexR.c + * Project: Vector Basic Runtime System + * Module: BrsHw for all platforms with ARM core Cortex-R + * Template: This file is reviewed according to Brs_Template@Implementation[1.03.12] + * + * \brief Description: This file contains the assembler part of the BRS StartUpCode. + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to ARMBrsHw_CortexR.h. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * EXAMPLE CODE ONLY + * ------------------------------------------------------------------------------------------------------------------- + * This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. + * The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither + * intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or + * implementations must be tested with diligent care and must comply with all quality requirements which are necessary + * according to the state of the art before their use. + *********************************************************************************************************************/ + +#define ARMSTARTUP_CORTEXR_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "BrsHw.h" + +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +/* This code is only needed for the first instance/executable in the system */ + +#include "vBrs_Lcfg.h" +#include "vLinkGen_Lcfg.h" + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + +#else + #error "Unknown compiler specified!" +#endif + +#if (VLINKGEN_CFG_MAJOR_VERSION != 2u) + #error "This StartUpCode is dependent to the vLinkGen version! vLinkGen major version does not fit!" +#else +# if (VLINKGEN_CFG_MINOR_VERSION < 5u) + #error "This StartUpCode is dependent to the vLinkGen version! Your vLinkGen minor version is too old!" +# endif +#endif + +/********************************************************************************************************************** + * DEFINITION + MACROS + *********************************************************************************************************************/ +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +extern void intvect_CoreExceptions(void); +#endif + +#if defined (BRS_ENABLE_OS_MULTICORESUPPORT) +extern ARMBrsHw_PhysicalCoreId_CoreExceptions_MappingType BrsHw_intvect_CoreExceptions_list[BRS_CPU_CORE_AMOUNT-1]; +#endif + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ +#if defined (BRS_ENABLE_OS_MULTICORESUPPORT) +/* used 32bit values for less assembler differences in accessing code */ +const uint32 BrsHw_InitCoreID = (uint32) BRSHW_INIT_CORE_ID; +const uint32 BrsHw_CpuCoreAmountMinus1 = (uint32) (BRS_CPU_CORE_AMOUNT-1); +#endif + +/********************************************************************************************************************** + * PROTOTYPES OF LOCAL FUNCTIONS + *********************************************************************************************************************/ +BRS_LOCAL_PROTOTYPE(_start) +BRS_LOCAL_PROTOTYPE(brsStartupEntry) +BRS_LOCAL_PROTOTYPE(brsStartupInvalidateCache) +BRS_LOCAL_PROTOTYPE(brsStartupZeroInitLoop) +BRS_LOCAL_PROTOTYPE(brsStartupStackSearch) +BRS_LOCAL_PROTOTYPE(coreRegisterInit) +BRS_LOCAL_PROTOTYPE(coreRegisterInit2) +BRS_LOCAL_PROTOTYPE(coreRegisterInit3) +BRS_LOCAL_PROTOTYPE(stackPointerInit) +BRS_LOCAL_PROTOTYPE(brsPreAsmStartupHook) + + +/* =========================================================================== */ +/* */ +/* Description: Entry point for all cores */ +/* */ +/* =========================================================================== */ + +BRS_SECTION_CODE(brsStartup) + +/* Alternativ entry point from OS default config */ + BRS_GLOBAL(_start) +BRS_MULTILINE_ASM_BEGIN() +BRS_LABEL(_start) +BRS_MULTILINE_ASM_END() +BRS_GLOBAL_END() + + BRS_GLOBAL(brsStartupEntry) +BRS_MULTILINE_ASM_BEGIN() +BRS_LABEL(brsStartupEntry) +#if defined (BRSHW_PRE_ASM_STARTUP_HOOK_AVAILABLE) +#endif + + BRS_BRANCH(brsPreAsmStartupHook) +BRS_MULTILINE_ASM_END() +BRS_GLOBAL_END() + +/* =========================================================================== */ +/* */ +/* Description: Optional hook for platform specific tasks */ +/* */ +/* =========================================================================== */ +#if !defined (BRSHW_PRE_ASM_STARTUP_HOOK_AVAILABLE) + BRS_GLOBAL(brsPreAsmStartupHook) +BRS_MULTILINE_ASM_BEGIN() +BRS_LABEL(brsPreAsmStartupHook) +/* Nothing to do here */ + + BRS_BRANCH(coreRegisterInit) +BRS_MULTILINE_ASM_END() +BRS_GLOBAL_END() +#endif /*!BRSHW_PRE_ASM_STARTUP_HOOK_AVAILABLE*/ + +/* =========================================================================== */ +/* */ +/* Description: Initialize core ID independent core registers */ +/* */ +/* =========================================================================== */ + BRS_GLOBAL(coreRegisterInit) +BRS_MULTILINE_ASM_BEGIN() +BRS_LABEL(coreRegisterInit) + +/* Note: ARMStartup_CortexR.c must be compiled in ARM mode, since + * the exception table is implemented in ARM mode only + */ + __as1(LDR r0, =BrsStartupInstSetInit) + +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ORR r0 ,r0, 0) +#else + __as2(ORR r0 ,r0, #0) +#endif + ___asm(BX r0) + + +BRS_LABEL(BrsStartupInstSetInit) + +#if defined (BRS_FPU_USED) + /* Allow full access to coprocessors 10,11 */ + /* r0 gets the content of the Coprocessor Access Control Register */ +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as5(MRC p15, 0, r0, c1, c0, 2) +# else + __as5(MRC p15, #0x00, r0, c1, c0, #0x02) +# endif + + __as2(ORR r0, r0, #0x00F00000) + /* Write Coprocessor Access Control Register to set access rights for coprocessor cp10, cp11 to full access + Note: Coprocessors cp10 and cp11 support floating-point and vector operations, and the control and configuration of + the Floating-point and Advanced SIMD architecture extensions. */ +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as5(MCR p15, 0, r0, c1, c0, 2) +# else + __as5(MCR p15, #0x00, r0, c1, c0, #0x02) +# endif + +/* Enable Advanced SIMD and Floating-point Extensions */ + __as1(VMRS r0, FPEXC) + __as1(MOV r1, #0x40000000) + __as2(ORR r0, r0, r1) + __as1(VMSR FPEXC, r0) +#endif /*BRS_FPU_USED*/ + +/* Switch to System Mode */ + __as1(MRS r0, CPSR) +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ORR r0, r0, 0x1f) + __as1(MSR CPSR, r0) +#else + __as2(ORR r0, r0, #0x1f) + __as1(MSR cpsr_cxsf, r0) +#endif + + BRS_BRANCH(coreRegisterInit2) +BRS_MULTILINE_ASM_END() +BRS_GLOBAL_END() + +/* =========================================================================== */ +/* */ +/* Description: Initialize all core ID dependent core registers */ +/* Setup exception table */ +/* */ +/* =========================================================================== */ + BRS_GLOBAL(coreRegisterInit2) +BRS_MULTILINE_ASM_BEGIN() +BRS_LABEL(coreRegisterInit2) + +#if defined (BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0) +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as1(MOV R2, 0) +# else + __as1(MOV R2, #0) +# endif + +#else /*(BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0)*/ +# if defined (BRS_ENABLE_OS_MULTICORESUPPORT) + __as1(LDR R1, =BrsHw_InitCoreID) + __as1(LDR R3, [R1]) + /* ==> R3 = BrsHw_InitCoreID */ + + BRS_READ_COREID(R0) + /* ==> R0 = BRS_READ_COREID */ + + /* If actual running core is init core, directly jump to implemantation for init core. + (ExceptionTable of init core is not part of BrsHw_intvect_CoreExceptions_list[]) */ + BRS_BRANCH_EQUAL(R0, R3, set_exception_table_location_on_init_core) + + __as1(LDR R1, =BrsHw_CpuCoreAmountMinus1) + __as1(LDR R5, [R1]) + /* ==> R5 = BrsHw_CpuCoreAmountMinus1 */ + + __as1(LDR R4, =BrsHw_intvect_CoreExceptions_list) + /* ==> R4 = BrsHw_intvect_CoreExceptions_list */ + +/* Use R6 as count register in the loop. Initialize with zero. */ +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as1(MOV R6, 0) +# else + __as1(MOV R6, #0) +# endif + +BRS_LABEL(get_exception_table_location_for_this_core_loop) + + __as1(LDR R7, [R4]) + /* ==> R7 = BrsHw_intvect_CoreExceptions_list[R6].PhysicalCoreId */ + + BRS_READ_COREID(R0) + /* ==> R0 = BRS_READ_COREID */ + + /* Check, if BrsHw_intvect_CoreExceptions_list entry of actual running core is reached */ + BRS_BRANCH_EQUAL(R0, R7, get_exception_table_location_for_this_core) + +/* Increase count register by one. */ +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ADD R6, R6, 1) +# else + __as2(ADD R6, R6, #1) +# endif + +/* Set R4 to point to next entry of BrsHw_intvect_CoreExceptions_list. */ +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ADD R4, R4, 8) +# else + __as2(ADD R4, R4, #8) +# endif + +/* Check if end of BrsHw_intvect_CoreExceptions_list has been reached. */ + BRS_BRANCH_NOT_EQUAL(R6, R5, get_exception_table_location_for_this_core_loop) +/* If no Exception Table address for running core has been found -> BrsMainExceptionStartup. */ + BRS_BRANCH(get_exception_table_location_error) + +BRS_LABEL(get_exception_table_location_for_this_core) + +/* Set R4 to point to next attribute of the current (R6) + struct ARMBrsHw_PhysicalCoreId_CoreExceptions_MappingType: CoreExceptions + */ +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ADD R4, R4, 4) +# else + __as2(ADD R4, R4, #4) +# endif + + __as1(LDR R2, [R4]) + /* ==> R2 = BrsHw_intvect_CoreExceptions_list[R6].CoreExceptions */ + + BRS_BRANCH(get_exception_table_location_end) + +BRS_LABEL(set_exception_table_location_on_init_core) +# endif /*BRS_ENABLE_OS_MULTICORESUPPORT*/ + +# if defined (BRS_FIRST_EXECUTION_INSTANCE) + __as1(LDR R2, =intvect_CoreExceptions) + +# else +/* init core should be configured, but no 1st execution instance! -> BrsMainExceptionStartup. */ + BRS_BRANCH(get_exception_table_location_error) +# endif /*BRS_FIRST_EXECUTION_INSTANCE*/ + +BRS_LABEL(get_exception_table_location_end) +#endif /*else BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0*/ + +/* Copy backup exception vectors over exception vectors at address "intvect_CoreExceptions" + See ARMv7_Cortex-R_BRS_Exception_Handling.pdf for details of the mechanism! + R2 = destination address / R3 = source address / R6 = index / R4,R5 = data buffer +*/ + __as1(MOV R3, R2) + __as1(MOV R7, R2) /* save Exception Table address in R7 */ + +/* Use R6 as count register in the loop. Initialize with zero. */ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as1(MOV R6, 0) + __as2(ADD R2, R2, 32) + __as2(ADD R3, R3, 64) +#else + __as1(MOV R6, #0) + __as2(ADD R2, R2, #32) + __as2(ADD R3, R3, #64) +#endif + +BRS_LABEL(copy_exception_vectors_backup_to_active_start) + + __as3(LDRD R4, R5, [R3], #+8) + __as3(STRD R4, R5, [R2], #+8) + +/* Increase count register by one. */ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ADD R6, R6, 1) +#else + __as2(ADD R6, R6, #1) +#endif + +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + BRS_BRANCH_EQUAL(R6, 4, copy_exception_vectors_backup_to_active_end) +#else + BRS_BRANCH_EQUAL(R6, #4, copy_exception_vectors_backup_to_active_end) +#endif + + BRS_BRANCH(copy_exception_vectors_backup_to_active_start) + +BRS_LABEL(copy_exception_vectors_backup_to_active_end) + +/* Set Exception Table code for all 8 Exceptions to the default "LDR PC, [PC,0x18]" + using R7 = Exception Table address. + Use R6 as count register in the loop. Initialize with zero. +*/ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as1(MOV R6, 0) + __as1(MOVW R2, 0xF018) + __as1(MOVT R2, 0xE59F) +#else + __as1(MOV R6, #0) + __as1(MOVW R2, #0xF018) + __as1(MOVT R2, #0xE59F) +#endif + +BRS_LABEL(restore_exception_table_start) + + __as2(STR R2, [R7], #+4) + +/* Increase count register by one. */ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ADD R6, R6, 1) +#else + __as2(ADD R6, R6, #1) +#endif + +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + BRS_BRANCH_EQUAL(R6, 8, restore_exception_table_end) +#else + BRS_BRANCH_EQUAL(R6, #8, restore_exception_table_end) +#endif + + BRS_BRANCH(restore_exception_table_start) + +BRS_LABEL(restore_exception_table_end) + +/* The exception table is implemented for ARM instrcutions -> The exception must be entered in ARM state + * -> Set SCTLR.TE bit for ARM state + */ + __as5(MRC p15, #0, r0, c1, c0, #0) /* read SCTLR register */ + __as2(BIC r0, r0, #(1 << 30)) /* clear the TE bit to enter Exc in ARM mode */ + __as5(MCR p15, #0, r0, c1, c0, #0) /* write SCTLR register */ + + /* Assure V-Bit is cleard and low exception vectors at 0x00000000 were set + * -> Set SCTLR.V bit for low exception base + */ + __as5(MRC p15, #0x00, r0, c1, c0, #0x0) /* Read SCTLR (System Control Register)*/ + __as2(BIC r0, r0, #(1 << 13)) /* clear the V-bit */ + __as5(MCR p15, #0x00, r0, c1, c0, #0x0) /* Write SCTLR (System Control Register) */ + + BRS_BRANCH(brsStartupInvalidateCache) + +BRS_LABEL(get_exception_table_location_error) + +BRS_MULTILINE_ASM_END() + +/* Branch to BrsMainExceptionStartup if no Exception Table address can be found. */ + BRS_EXTERN_BRANCH(BrsMainExceptionStartup) +BRS_GLOBAL_END() + +/* =========================================================================== */ +/* */ +/* Description: Invalidate cache memory */ +/* */ +/* =========================================================================== */ + BRS_GLOBAL(brsStartupInvalidateCache) +BRS_MULTILINE_ASM_BEGIN() +BRS_LABEL(brsStartupInvalidateCache) + +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as5(MRC p15, 1, r0, c0, c0, 0) /* read cache size id */ + __as1(MOVW r3, 0x01ff) + __as1(MOVT r3, 0x0000) + __as3(AND r0, r3, r0, lsr #13) + __as1(MOV r1, 0) +BRS_LABEL(way_loop) + __as1(MOV r3, 0) +BRS_LABEL(set_loop) + __as2(MOV r2, r1, lsl #30) + __as3(ORR r2, r2, r3, lsl #5) +BRS_LABEL(format) + __as5(MCR p15, 0, r2, c7, c6, 2) /* invalidate */ + ___asm(DSB) + ___asm(ISB) + __as2(ADD r3, r3, 1) + BRS_BRANCH_GREATER_THAN(r0, r3, set_loop) + __as2(ADD r1, r1, 1) + BRS_BRANCH_NOT_EQUAL(r1, 4, way_loop) + +#else + __as5(MRC p15, #1, r0, c0, c0, #0) /* read cache size id */ + __as1(MOVW r3, #0x01ff) + __as1(MOVT r3, #0x0000) + __as3(AND r0, r3, r0, lsr #13) + __as1(MOV r1, #0) +BRS_LABEL(way_loop) + __as1(MOV r3, #0) +BRS_LABEL(set_loop) + __as2(MOV r2, r1, lsl #30) + __as3(ORR r2, r2, r3, lsl #5) +BRS_LABEL(format) + __as5(MCR p15, #0, r2, c7, c6, #2) /* invalidate */ + ___asm(DSB) + ___asm(ISB) + __as2(ADD r3, r3, #1) + BRS_BRANCH_GREATER_THAN(r0, r3, set_loop) + __as2(ADD r1, r1, #1) + BRS_BRANCH_NOT_EQUAL(r1, #4, way_loop) +#endif /*BRS_COMP_x*/ + + BRS_BRANCH(brsStartupZeroInitLoop) + +BRS_MULTILINE_ASM_END() +BRS_GLOBAL_END() + +/* =========================================================================== */ +/* */ +/* Description: Initialize memory blocks and groups with zero */ +/* */ +/* =========================================================================== */ + BRS_GLOBAL(brsStartupZeroInitLoop) +BRS_MULTILINE_ASM_BEGIN() +BRS_LABEL(brsStartupZeroInitLoop) + +/* Initialize memory sections blocks with zeros */ +#if defined (VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_BLOCKS) +# if (VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_BLOCKS>1uL) + __as1(LDR R1, =vLinkGen_ZeroInit_Early_Blocks) + + BRS_READ_COREID(R0) + +BRS_LABEL(startup_block_zero_init_start) + __as1(MOV R2, R1) + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ADD R1, R1, 16) +# else + __as2(ADD R1, R1, #16) +# endif + + __as1(LDR R3, [R2]) /* vLinkGen_ZeroInit_Early_Blocks->start */ + __as2(LDR R4, [R2, #4]) /* vLinkGen_ZeroInit_Early_Blocks->end */ + __as2(LDR R5, [R2, #8]) /* vLinkGen_ZeroInit_Early_Blocks->core */ + __as2(LDR R6, [R2, #12]) /* vLinkGen_ZeroInit_Early_Blocks->alignment */ + +/* Verify if the end of struct vLinkGen_ZeroInit_Early_Blocks is reached, by checking if start == 0, end == 0 and core == 0 */ +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as1(MOV R7, 0) +# else + __as1(MOV R7, #0) +# endif + + __as2(ORR R7, R7, R3) /* Or with vLinkGen_ZeroInit_Early_Blocks->start */ + __as2(ORR R7, R7, R4) /* Or with vLinkGen_ZeroInit_Early_Blocks->end */ + __as2(ORR R7, R7, R5) /* Or with vLinkGen_ZeroInit_Early_Blocks->core */ + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + BRS_BRANCH_EQUAL(R7, 0, startup_block_zero_init_end) /* If start address, end address and core are equal to zero -> Finished */ +# else + BRS_BRANCH_EQUAL(R7, #0, startup_block_zero_init_end) /* If start address, end address and core are equal to zero -> Finished */ +# endif + + BRS_BRANCH_NOT_EQUAL(R0, R5, startup_block_zero_init_start) /* If InitCore is not running -> go to the next array entry */ + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as1(MOV R7, 0) /* set R7 to '0', as value to write in memory later */ + __as1(MOV R8, 0) /* set R8 to '0', as value to write in memory later */ +# else + __as1(MOV R7, #0) /* set R7 to '0', as value to write in memory later */ + __as1(MOV R8, #0) /* set R8 to '0', as value to write in memory later */ +# endif + + BRS_BRANCH_EQUAL(R6, #8, startup_block_zero_init_8byte_loop_start) /* if block is 8-Byte aligned, use specific init loop */ + +BRS_LABEL(startup_block_zero_init_loop_start) + BRS_BRANCH_GREATER_THAN_OR_EQUAL(R3, R4, startup_block_zero_init_start) /* if start address is same with or higher than end address-> Finished. */ + + __as1(STR R7, [R3]) /* write value of R7 ('0') to address of R3 (4-byte access); must be an aligned memory access! */ + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ADD R3, R3, 4) /* increase address value of R3 by '4' */ +# else + __as2(ADD R3, R3, #4) /* increase address value of R3 by '4' */ +# endif + +/* End address of this block was not yet reached. Run through the loop again */ + BRS_BRANCH(startup_block_zero_init_loop_start) + +/* ================================================================ */ +/* 8-Byte aligned initialization, to support 8-Byte aligned ECC RAM */ +/* ================================================================ */ +BRS_LABEL(startup_block_zero_init_8byte_loop_start) + BRS_BRANCH_GREATER_THAN_OR_EQUAL(R3, R4, startup_block_zero_init_start) /* if start address is same with or higher than end address-> Finished. */ + +/* Address stored in R3 must be 8 Byte aligned at this point! */ + __as2(STMIA R3!, {R7, R8}) /* 8 Byte alignment store for ECC, R3 would be automatically updated after the write */ + +/* End address of this block was not yet reached. Run through the loop again */ + BRS_BRANCH(startup_block_zero_init_8byte_loop_start) + +/* Zero-Init loop of blocks end label */ +BRS_LABEL(startup_block_zero_init_end) +# endif /*VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_BLOCKS>1uL*/ + +#else + #error "Mandatory define VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_BLOCKS missing within vLinkGen configuration!" +#endif /*VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_BLOCKS*/ + +/* Initialize memory sections groups with zeros */ +#if defined (VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS) +# if (VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS>1uL) + __as1(LDR R1, =vLinkGen_ZeroInit_Early_Groups) + +BRS_LABEL(startup_group_zero_init_start) + __as1(MOV R2, R1) + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ADD R1, R1, 16) +# else + __as2(ADD R1, R1, #16) +# endif + + __as1(LDR R3, [R2]) /* vLinkGen_ZeroInit_Early_Groups->start */ + __as2(LDR R4, [R2, #4]) /* vLinkGen_ZeroInit_Early_Groups->end */ + __as2(LDR R5, [R2, #8]) /* vLinkGen_ZeroInit_Early_Groups->core */ + __as2(LDR R6, [R2, #12]) /* vLinkGen_ZeroInit_Early_Groups->alignment */ + +/* Verify if the end of struct vLinkGen_ZeroInit_Early_Groups is reached, by checking if start == 0, end == 0 and core == 0 */ +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as1(MOV R7, 0) +# else + __as1(MOV R7, #0) +# endif + + __as2(ORR R7, R7, R3) /* Or with vLinkGen_ZeroInit_Early_Groups->start */ + __as2(ORR R7, R7, R4) /* Or with vLinkGen_ZeroInit_Early_Groups->end */ + __as2(ORR R7, R7, R5) /* Or with vLinkGen_ZeroInit_Early_Groups->core */ + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + BRS_BRANCH_EQUAL(R7, 0, startup_group_zero_init_end) /* If start address, end address and core are equal to zero -> Finished */ +# else + BRS_BRANCH_EQUAL(R7, #0, startup_group_zero_init_end) /* If start address, end address and core are equal to zero -> Finished */ +# endif + + BRS_BRANCH_NOT_EQUAL(R0, R5, startup_group_zero_init_start) /* If InitCore is not running -> go to the next array entry */ + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as1(MOV R7, 0) /* set R7 to '0', as value to write in memory later */ + __as1(MOV R8, 0) /* set R8 to '0', as value to write in memory later */ +# else + __as1(MOV R7, #0) /* set R7 to '0', as value to write in memory later */ + __as1(MOV R8, #0) /* set R8 to '0', as value to write in memory later */ +# endif + + BRS_BRANCH_EQUAL(R6, #8, startup_group_zero_init_8byte_loop_start) /* if group is 8-Byte aligned, use specific init loop */ + +BRS_LABEL(startup_group_zero_init_loop_start) + BRS_BRANCH_GREATER_THAN_OR_EQUAL(R3, R4, startup_group_zero_init_start) /* if start address is same with or higher than end address-> Finished. */ + + __as1(STR R7, [R3]) /* write value of R7 ('0') to address of R3 (4-byte access); must be an aligned memory access! */ + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ADD R3, R3, 4) /* increase address value of R3 by '4' */ +# else + __as2(ADD R3, R3, #4) /* increase address value of R3 by '4' */ +# endif + +/* End address of this group was not yet reached. Run through the loop again */ + BRS_BRANCH(startup_group_zero_init_loop_start) + +/* ================================================================ */ +/* 8-Byte aligned initialization, to support 8-Byte aligned ECC RAM */ +/* ================================================================ */ +BRS_LABEL(startup_group_zero_init_8byte_loop_start) + BRS_BRANCH_GREATER_THAN_OR_EQUAL(R3, R4, startup_group_zero_init_start) /* if start address is same with or higher than end address-> Finished. */ + +/* Address stored in R3 must be 8 Byte aligned at this point! */ + __as2(STMIA R3!, {R7, R8}) /* 8 Byte alignment store for ECC, R3 would be automatically updated after the write */ + +/* End address of this group was not yet reached. Run through the loop again */ + BRS_BRANCH(startup_group_zero_init_8byte_loop_start) + +/* Zero-Init loop of groups end label */ +BRS_LABEL(startup_group_zero_init_end) +# endif /*VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS>1uL*/ + +#else + #error "Mandatory define VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS missing within vLinkGen configuration!" +#endif /*VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS*/ + +/* Jump to routine to search for valid startup stack pointer of actual running core */ + BRS_BRANCH(brsStartupStackSearch) +BRS_MULTILINE_ASM_END() +BRS_GLOBAL_END() + +/* =========================================================================== */ +/* */ +/* Description: Search for valid startup stack pointer of actual running core */ +/* (vBRS is genearing the core specific configuration into the */ +/* struct BrsMain_CoreConfig in vBrs_Lcfg.c) */ +/* */ +/* =========================================================================== */ + BRS_GLOBAL(brsStartupStackSearch) +BRS_MULTILINE_ASM_BEGIN() +BRS_LABEL(brsStartupStackSearch) + + __as1(LDR R1, =BrsMain_CoreConfig_Size) + +BRS_LABEL(core_config_size_init) + __as1(LDR R5, [R1]) /* R5 = BrsMain_CoreConfig_Size */ + + __as1(LDR R1, =BrsMain_CoreConfig) + + BRS_READ_COREID(R0) + +BRS_LABEL(core_config_init_start) + +/* Use R2 as count register in the loop. Initialize with zero. */ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as1(MOV R2, 0) +#else + __as1(MOV R2, #0) +#endif + +BRS_LABEL(brs_coreconfig_loop) + + __as2(LDR R4, [R1,#4]) /* BrsMain_CoreConfig->PhysicalCoreId */ +/* Check if core id (R0) matches to physical core id of BrsMain_CoreConfig entry (R4). */ + BRS_BRANCH_EQUAL(R0, R4, stackPointerInit) + +/* Increase count register by one. */ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ADD R2, R2, 1) +#else + __as2(ADD R2, R2, #1) +#endif + +/* Set R1 to point to next entry of BrsMain_CoreConfig. */ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + __as2(ADD R1, R1, 28) +#else + __as2(ADD R1, R1, #28) +#endif + +/* Check if end of BrsMain_CoreConfig has been reached. */ + BRS_BRANCH_NOT_EQUAL(R2, R5, brs_coreconfig_loop) + +BRS_MULTILINE_ASM_END() + +/* Branch to BrsMainExceptionStartup if there are no more entries in the array. */ + BRS_EXTERN_BRANCH(BrsMainExceptionStartup) +BRS_GLOBAL_END() + +/* =========================================================================== */ +/* */ +/* Description: Initialize all core registers of actual running core with */ +/* specific init values */ +/* */ +/* =========================================================================== */ + BRS_GLOBAL(stackPointerInit) +BRS_MULTILINE_ASM_BEGIN() +BRS_LABEL(stackPointerInit) + __as2(LDR R4, [R1,#8]) /* BrsMain_CoreConfig->StartupStackEndLabel */ + __as1(MOV SP, R4) + + BRS_BRANCH(coreRegisterInit3) + +BRS_MULTILINE_ASM_END() +BRS_GLOBAL_END() + +/* =========================================================================== */ +/* */ +/* Description: Initialize additional core registers */ +/* */ +/* =========================================================================== */ + BRS_GLOBAL(coreRegisterInit3) +BRS_MULTILINE_ASM_BEGIN() +BRS_LABEL(coreRegisterInit3) +BRS_MULTILINE_ASM_END() + +/* =========================================================================== */ +/* */ +/* Description: Jump to Brs_PreMainStartup() (BrsMainStartup.c) */ +/* */ +/* =========================================================================== */ + BRS_EXTERN_BRANCH(Brs_PreMainStartup) + +/* =========================================================================== */ +/* */ +/* Description: Jump to BrsMainExceptionStartup() in case of an unexpected */ +/* return from PreMain/main */ +/* */ +/* =========================================================================== */ + BRS_EXTERN_BRANCH(BrsMainExceptionStartup) + +BRS_GLOBAL_END() + + +#endif /*BRS_FIRST_EXECUTION_INSTANCE*/ diff --git a/Source/appl/BrsHw.c b/Source/appl/BrsHw.c new file mode 100644 index 0000000..e7d6377 --- /dev/null +++ b/Source/appl/BrsHw.c @@ -0,0 +1,845 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsHw.c + * Project: Vector Basic Runtime System + * Module: BrsHw for platform TexasInstruments Sitara AM263x + * Template: This file is reviewed according to Brs_Template@Implementation[1.03.14] + * + * \brief Description: This is the hardware specific code file for Vector Basic Runtime System (BRS). + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to BrsHw.h. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * EXAMPLE CODE ONLY + * ------------------------------------------------------------------------------------------------------------------- + * This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. + * The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither + * intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or + * implementations must be tested with diligent care and must comply with all quality requirements which are necessary + * according to the state of the art before their use. + *********************************************************************************************************************/ + +#define _BRSHW_C_ +#define BRSHW_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "BrsHw.h" + +#if !defined (BRS_DISABLE_OS_USAGE) + /* + * BootManager, FlashBootLoader, HSM-Updater and HypervisorMaster execution instances do not use an OS. + * Define is set in BrsMain.h + */ + #include "Os.h" +#endif +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + void Dpl_init(void); + void Dpl_deinit(void); +#endif + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ +#if (BRSHW_MAJOR_VERSION != 1u) || (BRSHW_MINOR_VERSION != 0u) + #error "Header and source file are inconsistent!" +#endif +#if (BRSHW_PATCH_VERSION != 3u) + #error "Different versions of patch in Header and Source used!" +#endif + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + +#else + #error "Unknown compiler specified!" +#endif + +#if !defined (BRSMAIN_VERSION_COMBINED) +/* BRSMAIN_VERSION_COMBINED was introduced in BrsMain 2.24.00 - no check needed */ +# if (BRSMAIN_VERSION < 0x0221u) + /* At least BrsMain 2.21.00 is needed for Hypervisor support and definition of BRS_DISABLE_OS_USAGE */ + #error "BrsMain of at least version 2.21.00 is needed for this BrsHw package!" +# endif +#endif + +/********************************************************************************************************************** + * DEFINITION + MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL VARIABLES AND LOCAL HW REGISTERS + *********************************************************************************************************************/ +/* part of ArmCommon */ + +/********************************************************************************************************************** + * CONTROLLER CONFIGURATION REGISTERS + *********************************************************************************************************************/ +/* R5FSS Vector Interrupt Manager (VIM) */ +#define BRSHW_VIM_BASEADDR 0x50F00000UL +/* IRQ vector address register. */ +#define BRSHW_INTC_VIM_IRQVEC BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x18UL)) +/* FIQ vector address register. */ +#define BRSHW_INTC_VIM_FIQVEC BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x1CUL)) +/* Raw status/set register. */ +#define BRSHW_INTC_VIM_RAW_J(n) BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x0400UL + (n) * 0x20UL)) +/* Interrupt enable set register. */ +#define BRSHW_INTC_VIM_INTR_EN_SET_J(n) BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x0408UL + (n) * 0x20UL)) +/* Interrupt enable clear register. */ +#define BRSHW_INTC_VIM_INTR_EN_CLR_J(n) BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x040CUL + (n) * 0x20UL)) +/* IRQ interrupt enable status/clear register. */ +#define BRSHW_INTC_VIM_IRQSTS_J(n) BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x0410UL + (n) * 0x20UL)) +/* FIQ interrupt enable status/clear register. */ +#define BRSHW_INTC_VIM_FIQSTS_J(n) BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x0414UL + (n) * 0x20UL)) +/* Interrupt map register. */ +#define BRSHW_INTC_VIM_INTMAP_J(n) BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x0418UL + (n) * 0x20UL)) +/* Interrupt priority register. */ +#define BRSHW_INTC_VIM_PRI_INT_J(n) BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x1000UL + (n) * 0x04UL)) + +/* Master subsystem reset, clock management registers */ +#define BRSHW_MSS_CTRL_BASEADDR 0x50D00000UL +#define BRSHW_MSS_CTRL_MSS_RTI0_HALTEN BRSHW_IOS(uint32, (BRSHW_MSS_CTRL_BASEADDR + 0x454UL)) +//#define BRSHW_MSS_CTRL_MSS_DBG_ACK_CTL1 BRSHW_IOS(uint32, (BRSHW_MSS_CTRL_BASEADDR + 0x168UL))/*TODO*/ +#define BRSHW_MSS_CTRL_MSS_R5_ROM_ECLIPSE BRSHW_IOS(uint32, (BRSHW_MSS_CTRL_BASEADDR + 0x804UL))/*TODO*/ +#define BRSHW_MSS_CTRL_LOCK0_KICK0 BRSHW_IOS(uint32, (BRSHW_MSS_CTRL_BASEADDR + 0x1008UL))/*TODO*/ +#define BRSHW_MSS_CTRL_LOCK0_KICK1 BRSHW_IOS(uint32, (BRSHW_MSS_CTRL_BASEADDR + 0x100CUL))/*TODO*/ + +#define BRSHW_MSS_RTIA_BASEADDR 0x52181000UL +#define BRSHW_MSS_RTIA_RTIGCTRL BRSHW_IOS(uint32, (BRSHW_MSS_RTIA_BASEADDR + 0x0UL)) + +#if defined (BRS_ENABLE_PORT) + #define BRSHW_CPSW_CONTROL BRSHW_IOS(uint32, 0x0212016CUL) + + #define CPSW_CONTROL_PORT1_MODE_SEL_GMII_MII (0x00000000uL) + #define CPSW_CONTROL_PORT1_MODE_SEL_RMII (0x00000001uL) + #define CPSW_CONTROL_PORT1_MODE_SEL_RGMII (0x00000002uL) + #define CPSW_CONTROL_CLK_SEL_PAD (0x00000100uL) +#endif /*BRS_ENABLE_PORT*/ + +/* Top-level reset, clock management registers */ +#define BRSHW_CSL_MSS_TOPRCM_BASE 0x53208000UL +#define BRSHW_CSL_MSS_TOPRCM_SYS_RST_CAUSE BRSHW_IOS(uint32, (BRSHW_CSL_MSS_TOPRCM_BASE + 0x10U)) +#define BRSHW_CSL_MSS_TOPRCM_SYS_RST_CAUSE_CLR BRSHW_IOS(uint32, (BRSHW_CSL_MSS_TOPRCM_BASE + 0x14U)) +#define BRSHW_CSL_MSS_TOPRCM_WARM_RESET_CONFIG BRSHW_IOS(uint32, (BRSHW_CSL_MSS_TOPRCM_BASE + 0x100U))/*TODO*/ + +/********************************************************************************************************************** + * LOCAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * PROTOTYPES OF GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * PROTOTYPES OF LOCAL FUNCTIONS + *********************************************************************************************************************/ +void PowerClock_init(void); + +/********************************************************************************************************************** + * GLOBAL CONST DEFINITIONS + *********************************************************************************************************************/ +#define BOOT_DATA __attribute__((retain,section(".startupData"))) + +/* ----------- HwiP ----------- */ +const HwiP_Config gHwiConfig BOOT_DATA = { + .intcBaseAddr = 0x50F00000u, +}; + +/* ----------- ClockP ----------- */ +#define RTI0_CLOCK_SRC_MUX_ADDR (0x53208118u) +#define RTI0_CLOCK_SRC_WUCPUCLK (0x0u) +#define RTI0_BASE_ADDR (0x52181000u) + +const ClockP_Config gClockConfig BOOT_DATA = { + .timerBaseAddr = RTI0_BASE_ADDR, + .timerHwiIntNum = 91, + .timerInputClkHz = 25000000, + .timerInputPreScaler = 1, + .usecPerTick = 1000, +}; + +/********************************************************************************************************************** + * FUNCTION DEFINITIONS + *********************************************************************************************************************/ +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +#define BRS_START_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +/*****************************************************************************/ +/* @brief This function can be used to initialize controller specific + * stuff that should be handled by the first execution instance, + * even before the memory initialization took place (e.g. + * everything that is necessary to access the memory or to handle + * exceptions). This function is called at the beginning of + * BrsMainStartup(), immediately after the stackpointer was + * initialized in StartupCode + * (if BRSHW_EARLYINIT_AVAILABLE is set in BrsHw.h). + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from Brs_PreMainStartup() at power on + * initialization + *****************************************************************************/ +void BrsHwEarlyInitPowerOn(void) +{ + /* Micro Processor Unit initialization from TI SDK */ + __mpu_init(); +} +#define BRS_STOP_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +#endif /* BRS_FIRST_EXECUTION_INSTANCE */ + +/*****************************************************************************/ +/* @brief This function can be used to initialize controller specific + * stuff that is not related to one of the other InitPowerOn + * functions (e.g. code that is always mandatory, also if MCAL + * and/or OS is used). This function is called from BrsMain + * immediately after BrsHwDisableInterruptAtPowerOn() during + * initialization (if BRSHW_PREINIT_AVAILABLE is set in BrsHw.h) or + * from the BrsMain_MemoryInit_StageHardReset_Hook() during + * initialization (if BRS_ENABLE_PREFER_PLL_WATCHDOG_INIT is set). + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from BrsMainInit() at power on initialization + *****************************************************************************/ +void BrsHwPreInitPowerOn(void) +{ + /* This code is needed to stop the RTIA counter/timer, whenever a break signal from the debugger occurs. + * The following fields need to be set to suspend the RTI on halting of the processor. + * This enables setting of breakpoints, while the OS timer is running. + */ + BRSHW_MSS_CTRL_LOCK0_KICK0 = 0x01234567; + BRSHW_MSS_CTRL_LOCK0_KICK1 = 0x0FEDCBA8; + BRSHW_MSS_CTRL_MSS_RTI0_HALTEN |= (0x7<<4); /*MSS_DBG_ACK_CTL1_RTI*/ + + //BRSHW_MSS_RTIA_RTIGCTRL &= ~(0x1<<15); /* Clear COS bit of RTIA timer, to stop the counter in halting debug mode */ +} + +#if defined (BRS_ENABLE_WATCHDOG) +/*****************************************************************************/ +/* @brief This function must be used to initialize the Watchdog. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from BrsMainInit() at power on initialization + *****************************************************************************/ +void BrsHwWatchdogInitPowerOn(void) +{ + /* Nothing to be done here, Watchdogs disabled after boot from SBL */ +} +#endif /* BRS_ENABLE_WATCHDOG */ + +#if defined (BRS_ENABLE_PLLCLOCKS) +/*****************************************************************************/ +/* @brief This function must be used to initialize the PLL. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from BrsMainInit() at power on initialization + *****************************************************************************/ +void BrsHwPllInitPowerOn(void) +{ + /* TI SBL image powers up the timers and clock sources. + According to TI, the following frequencies are configured: + XTALCLK: 40MHz + Cortex-R5 CORE clock: 400MHz + SYSCLK: 200MHz + RTI1: 25MHz + I2C2: 200MHz + MCAN0,MCAN2: 80MHz + CPSW, CPTS: 200MHz + LIN1: 196MHz + */ + /* Initialize the configured modules and clocks*/ + PowerClock_init(); + +#if defined (BRS_ENABLE_ETHERNET_SUPPORT) + #error "There is no PLL/clocks handling for DrvEth supported by vBaseEnv on this platform! It is expected to always use the 3rd-party MCAL DrvEth, togehther with DrvMcu." +#endif +} +#endif /*BRS_ENABLE_PLLCLOCKS*/ + +#if defined (BRS_ENABLE_PORT) +/* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */ + +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_START_SEC_RAM_CODE + #include "Brs_MemMap.h" +# endif +/*****************************************************************************/ +/* @brief This function sets the output level of a port pin. + * @pre Port pin configurations available within BrsHw_Ports.h, + * no DrvPort used for port pin initialization and + * transferred port pin has to be initialized as output pin with + * GPIO functionality. + * @param[in] p - brsHw_Port_PortType, to be set, + * Level - level, port pin has to be set to + * (BRSHW_PORT_LOGIC_LOW or BRSHW_PORT_LOGIC_HIGH). + * @param[out] - + * @return - + * @context Function is called from BrsHwPortInitPowerOn() and + * provided to external modules (e.g. BrsMainTogglePin()). + *****************************************************************************/ +#define GPIO_LED_PIN (1) + +void BrsHwPort_SetLevel(brsHw_Port_PortType p, uint8 Level) +{ + if(BRSHW_PORT_LOGIC_LOW == Level) + { + GPIO_pinWriteLow((uint32_t) AddrTranslateP_getLocalAddr(CSL_GPIO0_U_BASE), GPIO_LED_PIN); + } + else + { + GPIO_pinWriteHigh((uint32_t) AddrTranslateP_getLocalAddr(CSL_GPIO0_U_BASE), GPIO_LED_PIN); + } +} + +/*****************************************************************************/ +/* @brief This function reads the input level of a port pin. + * @pre Port pin configurations available within BrsHw_Ports.h, + * no DrvPort used for port pin initialization and + * transferred port pin has to be initialized as input pin with + * GPIO functionality. + * @param[in] p - brsHw_Port_PortType, to be read. + * @param[out] - + * @return Level, read from port pin + * (BRSHW_PORT_LOGIC_LOW or BRSHW_PORT_LOGIC_HIGH). + * @context Function is provided to external modules. + *****************************************************************************/ +uint8 BrsHwPort_GetLevel(brsHw_Port_PortType p) +{ + uint8 pinVal; + pinVal = (uint8) GPIO_pinRead(CSL_GPIO0_U_BASE, p.portNumber); + if(pinVal==0x1U) + { + return BRSHW_PORT_LOGIC_HIGH; + } + else + { + return BRSHW_PORT_LOGIC_LOW; + } +} +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_STOP_SEC_RAM_CODE + #include "Brs_MemMap.h" +# endif + +#define SOC_MODULES_END (0xFFFFFFFFu) + +typedef struct { + + uint32_t moduleId; + uint32_t clkId; + uint32_t clkRate; + +} SOC_ModuleClockFrequency; + +uint32_t gSocModules[] = { +# if defined (BRS_ENABLE_CAN_SUPPORT) + #if defined (BRS_ENABLE_CAN_CHANNEL_0) + SOC_RcmPeripheralId_MCAN0, + #endif + #if defined (BRS_ENABLE_CAN_CHANNEL_2) + SOC_RcmPeripheralId_MCAN2, + #endif +# endif +# if defined (BRS_ENABLE_I2C_SUPPORT) + SOC_RcmPeripheralId_I2C, +# endif +# if defined (BRS_ENABLE_LIN_SUPPORT) + #if defined (BRS_ENABLE_LIN_CHANNEL_1) + SOC_RcmPeripheralId_LIN1_UART1, + #endif +# endif + SOC_MODULES_END, +}; + +SOC_ModuleClockFrequency gSocModulesClockFrequency[] = { +# if defined (BRS_ENABLE_CAN_SUPPORT) + #if defined (BRS_ENABLE_CAN_CHANNEL_0) + { SOC_RcmPeripheralId_MCAN0, SOC_RcmPeripheralClockSource_DPLL_CORE_HSDIV0_CLKOUT0, 80000000 }, + #endif + #if defined (BRS_ENABLE_CAN_CHANNEL_2) + { SOC_RcmPeripheralId_MCAN2, SOC_RcmPeripheralClockSource_DPLL_CORE_HSDIV0_CLKOUT0, 80000000 }, + #endif +# endif +# if defined (BRS_ENABLE_I2C_SUPPORT) + { SOC_RcmPeripheralId_I2C, SOC_RcmPeripheralClockSource_DPLL_PER_HSDIV0_CLKOUT1, 96000000 }, +# endif +# if defined (BRS_ENABLE_LIN_SUPPORT) + #if defined (BRS_ENABLE_LIN_CHANNEL_1) + { SOC_RcmPeripheralId_LIN1_UART1, SOC_RcmPeripheralClockSource_DPLL_PER_HSDIV0_CLKOUT1, 192000000 }, + #endif +# endif + { SOC_MODULES_END, SOC_MODULES_END, SOC_MODULES_END }, +}; + +void Module_clockSetFrequency(void) +{ + int32_t status; + uint32_t i = 0; + + while(gSocModulesClockFrequency[i].moduleId!=SOC_MODULES_END) + { + status = SOC_moduleSetClockFrequency( + gSocModulesClockFrequency[i].moduleId, + gSocModulesClockFrequency[i].clkId, + gSocModulesClockFrequency[i].clkRate + ); + DebugP_assertNoLog(status == SystemP_SUCCESS); + i++; + } +} + +void Module_clockEnable(void) +{ + int32_t status; + uint32_t i = 0; + + while(gSocModules[i]!=SOC_MODULES_END) + { + status = SOC_moduleClockEnable(gSocModules[i], 1); + DebugP_assertNoLog(status == SystemP_SUCCESS); + i++; + } +} + +void PowerClock_init(void) +{ + Module_clockEnable(); + Module_clockSetFrequency(); +} + +# if defined (BRS_ENABLE_ETHERNET_SUPPORT) + #define SOC_CONTROLSS_CTRL (0x502F0000U) + #define MSS_IOCFGKICK0 (0x00001008U) + #define MSS_IOCFGKICK1 (0x0000100CU) + + #define SOC_MSS_CTRL_BASE (0x50D00000U) + #define MSS_CPSW_CONTROL_REG (0x810U) + + #define MSS_CPSW_CONTROL_REG_P1_MODE_SEL_SHIFT (0x0U) + #define MSS_CPSW_CONTROL_REG_P1_MODE_SEL_MASK (0x00000003U) + + #define MSS_CPSW_CONTROL_REG_P2_MODE_SEL_SHIFT (0x10U) + #define MSS_CPSW_CONTROL_REG_P2_MODE_SEL_MASK (0x00000030U) + + #define KICK0_UNLOCK_VAL_MCU (0x01234567U) + #define KICK1_UNLOCK_VAL_MCU (0x0FEDCBA8U) + + #define ETH_GMII_SEL_GMII_MODE (0x0U) + #define ETH_GMII_SEL_RMII_MODE (0x1U) + #define ETH_GMII_SEL_RGMII_MODE (0x2U) + + typedef enum + { + ETH_MAC_CONN_TYPE_MII_10 = 0x00U, + /**< MAC connection type for 10Mbps MII mode */ + ETH_MAC_CONN_TYPE_MII_100 = 0x01U, + /**< MAC connection type for 100Mbps MII mode */ + ETH_MAC_CONN_TYPE_RMII_10 = 0x02U, + /**< MAC connection type for 10Mbps RMII mode */ + ETH_MAC_CONN_TYPE_RMII_100 = 0x03U, + /**< MAC connection type for 100Mbps RMII mode */ + ETH_MAC_CONN_TYPE_RGMII_FORCE_100_HALF = 0x04U, + /**< MAC connection type for forced half-duplex 100Mbps RGMII mode */ + ETH_MAC_CONN_TYPE_RGMII_FORCE_100_FULL = 0x05U, + /**< MAC connection type for forced full-duplex 100Mbps RGMII mode */ + ETH_MAC_CONN_TYPE_RGMII_FORCE_1000 = 0x06U, + /**< MAC connection type for forced 1000Mbps RGMII mode */ + ETH_MAC_CONN_TYPE_RGMII_DETECT_INBAND = 0x07U, + /**< MAC connection type for RGMII inband detection mode (speed determined + * based on received RGMII Rx clock) */ + } Eth_MacConnectionType; + + void Eth_EnableTransceiver(Eth_MacConnectionType type) + { + uint32 val; + + switch (type) + { + case ETH_MAC_CONN_TYPE_MII_10: + case ETH_MAC_CONN_TYPE_MII_100: + /* MII modes */ + /* Eth mode select */ + val = ETH_GMII_SEL_GMII_MODE; + break; + case ETH_MAC_CONN_TYPE_RMII_10: + case ETH_MAC_CONN_TYPE_RMII_100: + /* RMII modes */ + val = ETH_GMII_SEL_RMII_MODE; + break; + case ETH_MAC_CONN_TYPE_RGMII_FORCE_100_HALF: + case ETH_MAC_CONN_TYPE_RGMII_FORCE_100_FULL: + case ETH_MAC_CONN_TYPE_RGMII_FORCE_1000: + case ETH_MAC_CONN_TYPE_RGMII_DETECT_INBAND: + /* RGMII modes */ + val = ETH_GMII_SEL_RGMII_MODE; + break; + default: + /* Wrong configuration */ + break; + } + + /* Set MAC port interface in MMR */ + HW_WR_REG32((SOC_CONTROLSS_CTRL +MSS_IOCFGKICK0),KICK0_UNLOCK_VAL_MCU); + HW_WR_REG32((SOC_CONTROLSS_CTRL +MSS_IOCFGKICK1),KICK1_UNLOCK_VAL_MCU); + HW_WR_FIELD32(SOC_MSS_CTRL_BASE + MSS_CPSW_CONTROL_REG, + MSS_CPSW_CONTROL_REG_P1_MODE_SEL,(val)); + HW_WR_FIELD32(SOC_MSS_CTRL_BASE + MSS_CPSW_CONTROL_REG, + MSS_CPSW_CONTROL_REG_P2_MODE_SEL,(val)); +} +# endif /* BRS_ENABLE_ETHERNET_SUPPORT */ + +/*****************************************************************************/ +/* @brief This function must be used to initialize the used ports. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from BrsMainInit() at power on initialization + *****************************************************************************/ +void BrsHwPortInitPowerOn(void) +{ + /* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */ + + /* GPIO initialization */ + /* Initialize USER_LED1 and USER_LED0 JWADD */ + +Pinmux_PerCfg_t gGpioPinCfg[] = +{ +# if defined (BRS_ENABLE_SUPPORT_LEDS) + /* GPIO1 -> QSPI_CSn1 (R3) */ + { + PIN_QSPI_CSN1, + ( PIN_MODE(7) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW | PIN_QUAL_SYNC | PIN_GPIO_R5SS0_0 ) + }, +# endif +# if defined (BRS_ENABLE_CAN_SUPPORT) + /* MCAN0 pin config */ + /* MCAN0_RX -> MCAN0_RX (M1) */ + { + PIN_MCAN0_RX, + ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW ) + }, + /* MCAN0_TX -> MCAN0_TX (L1) */ + { + PIN_MCAN0_TX, + ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW ) + }, + /* MCAN2 pin config */ + /* MCAN2_RX -> MCAN2_RX (A12) */ + { + PIN_MCAN2_RX, + ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW ) + }, + /* MCAN2_TX -> MCAN2_TX (B12) */ + { + PIN_MCAN2_TX, + ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW ) + }, +# endif +# if defined (BRS_ENABLE_I2C_SUPPORT) + /* I2C2 pin config */ + /* I2C2_SCL -> UART0_RTSn (C7) */ + { + PIN_UART0_RTSN, + ( PIN_MODE(1) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW ) + }, + /* I2C2_SDA -> UART0_CTSn (B7) */ + { + PIN_UART0_CTSN, + ( PIN_MODE(1) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW ) + }, +# endif +# if defined (BRS_ENABLE_LIN_SUPPORT) + { + PIN_LIN1_RXD, + ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW ) + }, + /* LIN1_TXD -> LIN_TXD (B9) */ + { + PIN_LIN1_TXD, + ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW ) + }, + +# endif + {PINMUX_END, PINMUX_END} +}; + + Pinmux_config(gGpioPinCfg, PINMUX_DOMAIN_ID_MAIN); + + uint32_t gpioBaseAddr, pinNum; + + #define GPIO_LED_PIN (1) + + gpioBaseAddr = (uint32_t) AddrTranslateP_getLocalAddr(CSL_GPIO0_U_BASE); + pinNum = GPIO_LED_PIN; + + GPIO_setDirMode(gpioBaseAddr, pinNum, GPIO_DIRECTION_OUTPUT); + +# if defined (BRS_ENABLE_SUPPORT_LEDS) + /* Set LED on EVB demo board to show the system is alive */ + BrsMainTogglePin(BRSMAIN_TOGGLEPIN_LED); +# endif + +# if defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN) + /* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */ + #error "Implementation for initialization of specific pin must be added here. See LED pin as reference." +# endif + +# if defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN) + /* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */ + #error "Implementation for initialization of specific pin must be added here. See LED pin as reference." +# endif + +/******************************************************************************* + * CAN driver + *******************************************************************************/ +# if defined (BRS_ENABLE_CAN_SUPPORT) +//Can_PlatformInit(); +# endif /*BRS_ENABLE_CAN_SUPPORT*/ + +/******************************************************************************* + * LIN driver + *******************************************************************************/ +# if defined (BRS_ENABLE_LIN_SUPPORT) +/* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */ +# endif /*BRS_ENABLE_LIN_SUPPORT*/ + +/******************************************************************************* + * ETHERNET driver + *******************************************************************************/ +# if defined (BRS_ENABLE_ETHERNET_SUPPORT) +/* Currently selecting connection RMII 10 by default */ + Eth_EnableTransceiver(ETH_MAC_CONN_TYPE_RMII_10); + #error "There is no portpin handling for DrvEth supported by vBaseEnv on this platform! It is expected to always use the 3rd-party MCAL DrvEth, togehther with DrvPort." +# endif /*BRS_ENABLE_ETHERNET_SUPPORT*/ +} +#endif /*BRS_ENABLE_PORT*/ + +/* BrsHwDisableInterruptAtPowerOn() is part of ArmCommon */ + +/* BrsHw_ExceptionTable_Init() is part of ArmCommon */ + +/*****************************************************************************/ +/* @brief Restart ECU (issue a software reset or jump to startup code) + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from e.g. ECU state handling + *****************************************************************************/ +void BrsHwSoftwareResetECU(void) +{ + BrsMain_SoftwareResetECU_Hook(); + +#if !defined (BRS_ENABLE_FBL_SUPPORT) /* FBL is always running in polling mode with interrupts disabled */ + /*DisableAllInterrupts(); call removed by TI */ +#endif + + SOC_controlModuleUnlockMMR(SOC_DOMAIN_ID_MAIN, MSS_RCM_PARTITION0); + /* Clear reset Reason*/ + HW_WR_REG32(0x53208014, 0x7); + /* R5SS0_RST_WFICHECK */ + HW_WR_REG32(0x53208024, 0x7000707); + /* R5SS1_RST_WFICHECK */ + HW_WR_REG32(0x53208044, 0x7000707); + /* R5SS1_CORE0_LRST_CTRL */ + HW_WR_REG32(0x5320851C, 0x7); + /* R5SS0_CORE0_LRST_CTRL */ + HW_WR_REG32(0x53208518, 0x7); + + while (1) + { + /* Wait until reset/watchdog reset occurs */ + } +} + +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +/* This code is only needed for the first instance/executable in the system */ +#define BRS_START_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +/*****************************************************************************/ +/* @brief Get reset reason + * @pre - + * @param[in] - + * @param[out] - + * @return Reset reason + * @context Function is called from BrsMainStartup to determine if reset + * was triggered through software call (BrsHwSoftwareResetECU()). + * The result is stored by BrsMainStartup in the global variable + * brsMain_ResetReason. It should only be called once, during + * startup. The old API name BrsHwGetResetReason() is remapped + * to BrsMainGetResetReason. + *****************************************************************************/ +brsMain_ResetReasonType BrsHwGetResetReasonStartup(void) +{ + volatile uint32 rst_cause; + uint32 sw_reset = 0x00000020U; + rst_cause = BRSHW_CSL_MSS_TOPRCM_SYS_RST_CAUSE; /*HW_RD_REG32(0x53208010UL);*/ + rst_cause = rst_cause & 0x000000FF; + if(rst_cause == sw_reset) + /* 000 0000 0001 - POR; + 000 0000 0010 - WARM RESET + 000 0000 0100 - STC + 000 0000 1000 - Reset for CORE0 and MSS_CORE00_VIM using MSS_RCM::MSS_CR5SSA0_RST_CTRL + 000 0001 0000 - Reset for CORE1 and MSS_CORE10_VIM using MSS_RCM::MSS_CR5SSB0_RST_CTRL + 000 0010 0000 - Reset for CORE0 only using MSS_RCM::MSS_CORE00_RST_CTRL + 000 0100 0000 - Reset for CORE1 only using using MSS_RCM::MSS_CORE10_RST_CTRL + 000 1000 0000 - Reset for CORE0 and MSS_CORE00_VIM caused because of reset request by debugger in CORE00 + 001 0000 0000 - Reset for CORE10 and MSS_CORE10_VIM caused because of reset request by debugger in CORE10 + 010 0000 0000 - Reset for CR5SS0 by the RESET FSM using MSS_CTRL::R5SS0_CONTROL_RESET_FSM_TRIGGER + 100 0000 0000 - MSS_RCM.MSS_CR5SS_POR_RST_CTRL0 */ + { + return BRSMAIN_RESET_SW; + } + else + { + return BRSMAIN_RESET_OTHER; + } +} +#define BRS_STOP_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +#endif /* BRS_FIRST_EXECUTION_INSTANCE */ + +/* BrsHwTime100NOP() is part of ArmCommon */ + +#if defined (BRS_ENABLE_SAFECTXSUPPORT) +/*****************************************************************************/ +/* @brief This API is used to enable hardware access in untrusted mode + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function must be called after all depending peripheral modules + * are supplied by proper clocks AND before the OS is started. + *****************************************************************************/ +void BrsHw_EnableHwAccess(void) +{ + /* nothing to be done for this platform yet (or never tested) */ + #error "Hardware access in UserMode not yet supported for your specific derivative!" +} +#endif /* BRS_ENABLE_SAFECTXSUPPORT */ + +/* BrsHw_GetCore() is part of ArmCommon */ + +/*****************************************************************************/ +/* @brief This API is used to enable an interrupt source in the core + * interrupt controller. + * @pre - + * @param[in] Source to be enabled. + * @param[in] Priority level to be set. + * @param[out] - + * @return - + * @context Function is called from HlpTest and other test environments. + *****************************************************************************/ +void BrsHw_EnableInterrupt(uint32 Source, uint8 Priority) +{ + /* Clear pending interrupt. */ + if(((BRSHW_INTC_VIM_INTMAP_J(Source / 32U)) >> (Source % 32U)) & (uint32)0x01) + { + BRSHW_INTC_VIM_FIQSTS_J(Source / 32U)= (uint32)(1UL << (Source % 32U)); + BRSHW_INTC_VIM_FIQVEC = 0x01UL; + } + else + { + BRSHW_INTC_VIM_IRQSTS_J(Source / 32U)= (uint32)(1UL << (Source % 32U)); + BRSHW_INTC_VIM_IRQVEC = 0x01UL; + } + /* Set interrupt priority. */ + BRSHW_INTC_VIM_PRI_INT_J(Source) = Priority; + /* Enable interrupt handling. */ + BRSHW_INTC_VIM_INTR_EN_SET_J(Source / 32U) |= (uint32)(1UL << (Source % 32U)); +} + +/*****************************************************************************/ +/* @brief This API is used to disable an interrupt source in the core + * interrupt controller. + * @pre - + * @param[in] Source to be disabled. + * @param[out] - + * @return - + * @context Function is called from HlpTest and other test environments. + *****************************************************************************/ +void BrsHw_DisableInterrupt(uint32 Source) +{ + BRSHW_INTC_VIM_INTR_EN_CLR_J(Source / 32U) |= (uint32)(1UL << (Source % 32U)); +} + +/*****************************************************************************/ +/* @brief This API is used to trigger the given software interrupt source. + * @pre - + * @param[in] Source to be triggered. + * Some derivatives only support few software triggerable sources, + * check for their validity. + * @param[out] - + * @return - + * @context Function is called from HlpTest and other test environments. + *****************************************************************************/ +void BrsHw_TriggerSoftwareInterrupt(uint32 Source) +{ + BRSHW_INTC_VIM_RAW_J(Source / 32U) |= (uint32)(1UL << (Source % 32U)); +} + + #define BOOT_CODE __attribute__((section(".startupCode"))) + + void Dpl_deinit(void) + { + } + + void putchar_(char character) + { + (void)character; + } diff --git a/Source/appl/BrsMain.c b/Source/appl/BrsMain.c new file mode 100644 index 0000000..aa11085 --- /dev/null +++ b/Source/appl/BrsMain.c @@ -0,0 +1,954 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsMain.c + * Project: Vector Basic Runtime System + * Module: BrsMain + * + * \brief Description: Main file of BRS contains + * - Main function (called from StartUpCode and calls stack entry EcuM_Init()) + * - Call of BrsHw HW initialization routines + * - 1ms handler, with support of cycle functions with several cycle times + * - Default_Init_Task, Main and Background Task which can be used by the operating system + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to BrsMain.h. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * EXAMPLE CODE ONLY + * ------------------------------------------------------------------------------------------------------------------- + * This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. + * The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither + * intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or + * implementations must be tested with diligent care and must comply with all quality requirements which are necessary + * according to the state of the art before their use. + *********************************************************************************************************************/ + +#define _BRSMAIN_C_ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "BrsMain.h" + +#if !defined (VVIRTUALTARGET) + #include "vBrs_Lcfg.h" +#else + #include "CANoeApi.h" + #include + #include "Os.h" +#endif + +#if defined (BRS_ENABLE_TESTSUITE_SUPPORT) + #include "BrsTestsuite.h" +#endif + +#include "BrsMain_Appl.h" + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ +#if (BRSMAIN_MAJOR_VERSION != 2u) || (BRSMAIN_MINOR_VERSION != 27u) + #error "Header and source file are inconsistent!" +#endif +#if (BRSMAIN_PATCH_VERSION != 0u) + #error "Different versions of patch in Header and Source used!" +#endif + +/* BRS_GENERATED_HW_CONFIG_VERSION is generated into vBrsCfg.h by Cfg5/Cfg6 vBrs generator */ +#if (BRS_GENERATED_HW_CONFIG_VERSION < 406U) + #error "Version of vBrs Generator too old! Please update it." +#endif + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ +#if !defined (VVIRTUALTARGET) +/* BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED was introduced in Brs_Template 1.04.00 - no check needed */ +# if !defined (BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED) +# if (BRSHW_SOURCECODE_TEMPLATE_VERSION < 0x0103u) + #error "This BrsMain version requires a BrsHw package with a minimum template version of 1.03.00!" +# endif +# endif +#endif + +#if defined (BRS_ENABLE_OS_INTERRUPT_ONLY) && defined (BRS_ENABLE_OS_MULTICORESUPPORT) + #error "OS MultiCore support is not supported together with OS INTERRUPT_ONLY UseCase!" +#endif + +#if defined (BRS_ENABLE_OS_MULTICORESUPPORT) + #error "This file was filtered for SingleCore UseCase, but MultiCore UseCase is configured!" +#endif + +#if defined (BRS_ENABLE_HSM_UPDATER_SUPPORT) +# if !defined (BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED) +/* BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED was introduced in Brs_Template_HSM 1.05.00 - no check needed */ +# if (BRSHW_SOURCECODE_TEMPLATE_VERSION < 0x0104u) + #error "HSM Updater functionality requires a BrsHw package with a minimum template version of 1.04.00!" +# endif +# endif +#endif + +#if defined (BRS_ENABLE_HYPERVISOR_SUPPORT) || defined (BRS_HYPERVISOR_GUEST_EXECUTION_INSTANCE) +# if !defined (BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED) +/* BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED was introduced in Brs_Template 1.04.00 - no check needed */ +# if (BRSHW_SOURCECODE_TEMPLATE_VERSION < 0x0103u) || ((BRSHW_SOURCECODE_TEMPLATE_VERSION == 0x0103u) && \ + (BRSHW_SOURCECODE_TEMPLATE_BUGFIX_VERSION < 0x12u)) + #error "Hypervisor functionality requires a BrsHw package with a minimum template version of 1.03.12!" +# endif +# endif +#endif + +/********************************************************************************************************************** + * DEFINITION + MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ +#if defined (BRS_ENABLE_1MS_HANDLER) +# if !defined (BRSMAIN_CYCLIC_MAX_CALLBACKS) + #define BRSMAIN_CYCLIC_MAX_CALLBACKS 2u +# endif + + #define START_SEC_VAR_NOINIT_UNSPECIFIED + #include "MemMap.h" + typedef struct + { + void (*FunctionPointer[BRSMAIN_CYCLIC_MAX_CALLBACKS]) (void); + uint8 FunctionCounter; + } brsMain_Cyclic_Callbacks; + #define STOP_SEC_VAR + #include "MemMap.h" +#endif /* BRS_ENABLE_1MS_HANDLER */ + +#if !defined (VVIRTUALTARGET) +#define BRS_START_SEC_SHARED_VAR +#include "Brs_MemMap.h" +extern volatile brsMain_ResetReasonType brsMain_ResetReason; +#define BRS_STOP_SEC_SHARED_VAR +#include "Brs_MemMap.h" +#endif + +/********************************************************************************************************************** + * GLOBAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL VARIABLES + *********************************************************************************************************************/ +#if defined (BRS_ENABLE_1MS_HANDLER) + #define START_SEC_VAR_NOINIT_16BIT + #include "MemMap.h" + /* + * \var brsMain_CallCounter1ms + * Counter for calls of the function BrsMainCyclic1ms + */ + static volatile uint16 brsMain_CallCounter1ms; + + /* + * \var brsMain_CallCounter1sec + * Counter for 1000 calls of the function BrsMainCyclic1ms + */ + static volatile uint16 brsMain_CallCounter1sec; + #define STOP_SEC_VAR + #include "MemMap.h" + + #define START_SEC_VAR_NOINIT_UNSPECIFIED + #include "MemMap.h" + static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_Background; + static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_1ms; + static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_10ms; + static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_100ms; + static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_250ms; + static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_500ms; + static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_1000ms; + #define STOP_SEC_VAR + #include "MemMap.h" +#endif /* BRS_ENABLE_1MS_HANDLER */ + +#if defined (BRS_ENABLE_OS_INTERRUPT_ONLY) + #define START_SEC_VAR_NOINIT_32BIT + #include "MemMap.h" + static volatile uint32 brsMain_SuspendAllCounter; + #define STOP_SEC_VAR + #include "MemMap.h" +#endif + +/********************************************************************************************************************** + * LOCAL CONST VARIABLES + *********************************************************************************************************************/ +# if defined (VVIRTUALTARGET) + #define BRSMAIN_ERRORBUFFERSIZE 120 +#endif + +/********************************************************************************************************************** + * PROTOTYPES OF GLOBAL FUNCTIONS + *********************************************************************************************************************/ +#if defined (BRS_FBL_NO_ECUMINIT) +extern void FblMain(void); +#endif + +/********************************************************************************************************************** + * PROTOTYPES OF LOCAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * FUNCTION DEFINITIONS + *********************************************************************************************************************/ +#if !defined (VVIRTUALTARGET) +# if defined (BRS_ENABLE_SUPPORT_LEDS) +void BrsMainWrapperTogglePinLED(void) +{ + BrsMainTogglePin(BRSMAIN_TOGGLEPIN_LED); +} +# endif + +# if defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN) +void BrsMainWrapperTogglePinWD(void) +{ + BrsMainTogglePin(BRSMAIN_TOGGLEPIN_WD); +} +# endif + +# if defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN) +void BrsMainWrapperTogglePinCustom(void) +{ + BrsMainTogglePin(BRSMAIN_TOGGLEPIN_CUSTOM); +} +# endif +#endif /* !VVIRTUALTARGET */ + +/*****************************************************************************/ +/* @brief Main initialization routine. + * Contains configuration specific initialization of BrsHw parts + * and BrsMain specific mechanisms. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from main + *****************************************************************************/ +void BrsMainInit(void) +{ +#if defined (BRSMAIN_BRSMAININIT_CALLOUT) + BrsTestsuite_BrsMain_BrsMainInit(); +#endif + + BrsMain_Appl_Init(); + +#if (!defined (BRS_FBL_NO_ECUMINIT)) && (!defined (VVIRTUALTARGET)) +# if !defined (BRS_ENABLE_PREFER_PLL_WATCHDOG_INIT) + /* If preferred feature is acivated, initialization will take place in BrsMain_MemoryInit_StageOne_Hook(). */ +# if defined (BRSHW_PREINIT_AVAILABLE) + BrsHwPreInitPowerOn(); +# endif + +# if defined (BRS_ENABLE_WATCHDOG) + BrsHwWatchdogInitPowerOn(); +# endif + +# if defined (BRS_ENABLE_PLLCLOCKS) + BrsHwPllInitPowerOn(); +# endif +# endif /* !BRS_ENABLE_PREFER_PLL_WATCHDOG_INIT */ + +# if defined (BRS_ENABLE_PORT) + BrsHwPortInitPowerOn(); +# endif + +# if defined (BRS_ENABLE_FBL_SUPPORT) || defined (BRS_ENABLE_HSM_UPDATER_SUPPORT) +# if defined (BRSHW_DISABLE_ECC_AVAILABLE) + BrsHwDisableEccErrorReporting(); +# endif +# endif +#endif /* !BRS_FBL_NO_ECUMINIT&&!VVIRTUALTARGET */ + +#if defined (BRS_ENABLE_1MS_HANDLER) + brsMain_CallCounter1ms = 0u; + brsMain_CallCounter1sec = 0u; + + brsMain_Cyclic_Callbacks_Background.FunctionCounter = 0u; + brsMain_Cyclic_Callbacks_1ms.FunctionCounter = 0u; + brsMain_Cyclic_Callbacks_10ms.FunctionCounter = 0u; + brsMain_Cyclic_Callbacks_100ms.FunctionCounter = 0u; + brsMain_Cyclic_Callbacks_250ms.FunctionCounter = 0u; + brsMain_Cyclic_Callbacks_500ms.FunctionCounter = 0u; + brsMain_Cyclic_Callbacks_1000ms.FunctionCounter = 0u; +#endif /* BRS_ENABLE_1MS_HANDLER */ + +#if !defined (VVIRTUALTARGET) +# if defined (BRS_ENABLE_SUPPORT_LEDS) + BrsMainRegisterCyclic(&BrsMainWrapperTogglePinLED, BRSMAIN_CYCLETIME_500MS); +# endif + +# if defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN) + BrsMainRegisterCyclic(&BrsMainWrapperTogglePinWD, BRSMAIN_CYCLETIME_250MS); +# endif + +# if defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN) + BrsMainRegisterCyclic(&BrsMainWrapperTogglePinCustom, BRSMAIN_CYCLETIME_1000MS); +# endif +#endif /* !VVIRTUALTARGET */ + +#if defined (BRS_ENABLE_OS_INTERRUPT_ONLY) + brsMain_SuspendAllCounter = 0u; +#endif +} + +#if defined (BRS_ENABLE_1MS_HANDLER) +/*****************************************************************************/ +/* @brief Routine to register cyclic callbacks. + * @pre Initialization of BrsMain was done threw call of BrsMainInit(). + * @param[in] FunctionPointer has to be a pointer to a function of type + * void function(void). + * @param[in] Cycletime described the cycletime, the callback should be triggered. + * @param[out] - + * @return - + * @context Function is called from modules that need cyclic callbacks. + *****************************************************************************/ +void BrsMainRegisterCyclic(void (*FunctionPointer)(void), brsMain_Cyclic_Cycletime Cycletime) +{ +#if defined (BRSMAIN_BRSMAINREGISTERCYCLIC_CALLOUT) + BrsTestsuite_BrsMain_BrsMainRegisterCyclic(FunctionPointer, Cycletime); +#endif + + switch (Cycletime) + { + case BRSMAIN_CYCLETIME_BACKGROUND: + if (brsMain_Cyclic_Callbacks_Background.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS) + { + BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__)); + } + brsMain_Cyclic_Callbacks_Background.FunctionPointer[ + brsMain_Cyclic_Callbacks_Background.FunctionCounter] = FunctionPointer; + brsMain_Cyclic_Callbacks_Background.FunctionCounter++; + break; + + case BRSMAIN_CYCLETIME_1MS: + if (brsMain_Cyclic_Callbacks_1ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS) + { + BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__)); + } + brsMain_Cyclic_Callbacks_1ms.FunctionPointer[ + brsMain_Cyclic_Callbacks_1ms.FunctionCounter] = FunctionPointer; + brsMain_Cyclic_Callbacks_1ms.FunctionCounter++; + break; + + case BRSMAIN_CYCLETIME_10MS: + if (brsMain_Cyclic_Callbacks_10ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS) + { + BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__)); + } + brsMain_Cyclic_Callbacks_10ms.FunctionPointer[ + brsMain_Cyclic_Callbacks_10ms.FunctionCounter] = FunctionPointer; + brsMain_Cyclic_Callbacks_10ms.FunctionCounter++; + break; + + case BRSMAIN_CYCLETIME_100MS: + if (brsMain_Cyclic_Callbacks_100ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS) + { + BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__)); + } + brsMain_Cyclic_Callbacks_100ms.FunctionPointer[ + brsMain_Cyclic_Callbacks_100ms.FunctionCounter] = FunctionPointer; + brsMain_Cyclic_Callbacks_100ms.FunctionCounter++; + break; + + case BRSMAIN_CYCLETIME_250MS: + if (brsMain_Cyclic_Callbacks_250ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS) + { + BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__)); + } + brsMain_Cyclic_Callbacks_250ms.FunctionPointer[ + brsMain_Cyclic_Callbacks_250ms.FunctionCounter] = FunctionPointer; + brsMain_Cyclic_Callbacks_250ms.FunctionCounter++; + break; + + case BRSMAIN_CYCLETIME_500MS: + if (brsMain_Cyclic_Callbacks_500ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS) + { + BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__)); + } + brsMain_Cyclic_Callbacks_500ms.FunctionPointer[ + brsMain_Cyclic_Callbacks_500ms.FunctionCounter] = FunctionPointer; + brsMain_Cyclic_Callbacks_500ms.FunctionCounter++; + break; + + case BRSMAIN_CYCLETIME_1000MS: + if (brsMain_Cyclic_Callbacks_1000ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS) + { + BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__)); + } + brsMain_Cyclic_Callbacks_1000ms.FunctionPointer[ + brsMain_Cyclic_Callbacks_1000ms.FunctionCounter] = FunctionPointer; + brsMain_Cyclic_Callbacks_1000ms.FunctionCounter++; + break; + + default: + BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__)); + break; + } +} +#endif /* BRS_ENABLE_1MS_HANDLER */ + +#if (!defined (BRS_DISABLE_OS_USAGE)) && (!defined (BRS_ENABLE_OS_INTERRUPT_ONLY)) +/*****************************************************************************/ +/* @brief InitTask to call EcuM_StartupTwo() on the MasterCore. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context The task is started once by the OS. + *****************************************************************************/ +TASK(Default_Init_Task) +{ +#if defined (BRSMAIN_DEFAULT_INIT_TASK_CALLOUT) + BrsTestsuite_BrsMain_Default_Init_Task(); +#endif + +#if defined (BRS_ENABLE_TESTSUITE_SUPPORT) + BrsTestsuiteInit(); +#endif + +#if defined (BRS_ENABLE_HSM_SUPPORT) + vHsm_StartupTwo(); +#else + EcuM_StartupTwo(); +#endif + +#if defined (BRS_ENABLE_1MS_HANDLER) + (void)SetRelAlarm(BrsMainCyclicAlarm_1ms, OS_MS2TICKS_SystemTimer(1), OS_MS2TICKS_SystemTimer(1)); +#endif + + (void)TerminateTask(); +} + +/*****************************************************************************/ +/* @brief InitTask to call Os_InitialEnableInterruptSources() on the MasterCore. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context The task is started once by the OS. It is separated from + * Default_Init_Task() to allow the SafeContext partitioning UseCase. + *****************************************************************************/ +TASK(Default_Init_Task_Trusted) +{ +#if defined (BRSMAIN_DEFAULT_INIT_TASK_TRUSTED_CALLOUT) + BrsTestsuite_BrsMain_Default_Init_Task_Trusted(); +#endif + + Os_InitialEnableInterruptSources(FALSE); + + (void)TerminateTask(); +} + +#endif /* !BRS_DISABLE_OS_USAGE&&!BRS_ENABLE_OS_INTERRUPT_ONLY */ + +#if defined (BRS_ENABLE_1MS_HANDLER) +/*****************************************************************************/ +/* @brief One millisecond handler for BrsMain + * - Executes retransmission of BRS TCC messages + * - Toggling of LED (alive signal) + * - BRS Test code (1s cyclic negative TCC response message) + * @pre Initialization of BrsMain was done threw call of BrsMainInit(). + * @param[in] - + * @param[out] - + * @return - + * @context Function is called each millisecond either from the main loop + * or from the BRS main task (TASK(mainTask)) + *****************************************************************************/ +void BrsMainCyclic1ms(void) +{ + uint8 cycliccounter; + +#if defined (BRSMAIN_BRSMAINCYCLIC1MS_CALLOUT) + BrsTestsuite_BrsMain_BrsMainCyclic1ms(); +#endif + + brsMain_CallCounter1ms++; + + for (cycliccounter = 0u; cycliccounter < brsMain_Cyclic_Callbacks_1ms.FunctionCounter; cycliccounter++) + { + brsMain_Cyclic_Callbacks_1ms.FunctionPointer[cycliccounter](); + } + + if ((brsMain_CallCounter1ms % 10u) == 0u) + { + for (cycliccounter = 0u; cycliccounter1) + if (coreID == BRSHW_INIT_CORE_ID) +# endif +#endif /* !VVIRTUALTARGET */ + { + BrsMainInit(); + } + +#if defined (BRSMAIN_POSTBRSMAININIT_CALLOUT) + BrsTestsuite_BrsMain_PostBrsMainInit(); +#endif + +#if defined (BRS_FBL_NO_ECUMINIT) + FblMain(); /* never returns */ + +#else +# if (!defined (BRS_ENABLE_FBL_SUPPORT)) && (!defined (BRS_ENABLE_HSM_UPDATER_SUPPORT)) || (defined (VVIRTUALTARGET)) +# if defined (BRS_ENABLE_HYPERVISOR_SUPPORT) + BrsMain_Appl_HypervisorStartCoreApi(coreID); + + vHyp_InitMemory(); + vHyp_Init(); + +# elif defined (BRS_ENABLE_OS_INTERRUPT_ONLY) + /* OS is configured for UseCase Interrupt Only (/MICROSAR/Os/OsOS/OsUseCase) */ + Os_InitInterruptOnly(); + +# else + Os_InitMemory(); + Os_Init(); +# endif +# endif /* (!BRS_ENABLE_FBL_SUPPORT && !BRS_ENABLE_HSM_UPDATER_SUPPORT) || VVIRTUALTARGET */ + +# if defined (BRS_ENABLE_OS_MULTICORESUPPORT) && (!defined (VVIRTUALTARGET)) && \ + (!defined (BRS_ENABLE_HYPERVISOR_SUPPORT)) + if (triggerNonAsrHook) + { /* + * New callout API for non-Autosar-Cores that are not FBL/HSM-Updater related (core configured as non-ASR core + * in OS) + */ + BrsMain_NonAsrCore_Hook(); + } +# endif + +# if defined (BRS_ENABLE_HSM_SUPPORT) || defined (BRS_ENABLE_HSM_UPDATER_SUPPORT) + vHsm_Init(); /* never returns */ + +# elif defined (BRS_ENABLE_HYPERVISOR_SUPPORT) + BrsMain_Appl_HypervisorApi(coreID); + + vHyp_Start(); /* never returns */ + +# else + EcuM_Init(); /* never returns */ +# endif +#endif /* else BRS_FBL_NO_ECUMINIT */ + + BrsMainExceptionHandler(kBrsIllegalReturnFromMain, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__)); + + return 0; +} diff --git a/Source/appl/BrsMainStartup.c b/Source/appl/BrsMainStartup.c new file mode 100644 index 0000000..1c2323a --- /dev/null +++ b/Source/appl/BrsMainStartup.c @@ -0,0 +1,584 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsMainStartup.c + * Project: Vector Basic Runtime System + * Module: BrsMain + * + * \brief Description: Vector Basic Runtime System module source for startup routines. + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to BrsMain.h. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * EXAMPLE CODE ONLY + * ------------------------------------------------------------------------------------------------------------------- + * This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. + * The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither + * intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or + * implementations must be tested with diligent care and must comply with all quality requirements which are necessary + * according to the state of the art before their use. + *********************************************************************************************************************/ + +#define _BRSMAINSTARTUP_C_ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "BrsMain.h" + +#include "vLinkGen_Lcfg.h" + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ +#if (BRSMAIN_MAJOR_VERSION != 2u) || (BRSMAIN_MINOR_VERSION != 27u) + #error "Header and source file are inconsistent!" +#endif +#if (BRSMAIN_PATCH_VERSION != 0u) + #error "Different versions of patch in Header and Source used!" +#endif + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ +#if (!defined (BRS_INIT_PATTERN_BLOCKS)) || \ + (!defined (BRS_INIT_PATTERN_HARDRESET_BLOCKS)) || \ + (!defined (BRS_INIT_PATTERN_AREAS)) || \ + (!defined (BRS_INIT_PATTERN_HARDRESET_AREAS)) + #error "Your environment is missing the mandatory init pattern. They should be generated out of vBRS in Configurator5." +#endif + +#if (VLINKGEN_CFG_MAJOR_VERSION != 2u) + #error "This StartUpCode is dependent to the vLinkGen version! vLinkGen major version does not fit!" +#else +# if (VLINKGEN_CFG_MINOR_VERSION < 16u) + #error "This StartUpCode is dependent to the vLinkGen version! Your vLinkGen minor version is too old!" +# endif +#endif + +#if defined (BRS_ENABLE_OS_MULTICORESUPPORT) + #error "This file was filtered for SingleCore UseCase, but MultiCore UseCase is configured!" +#endif + +/* +* Starting with Brs_Template 01.03.13, BrsHw_UnlockCores() is only present if respective macro "BRSHW_CORES_AUTOSTART" +* is defined. Older versions have BrsHw_UnlockCores() as unconditional callout. +*/ +/* BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED was introduced in Brs_Template 1.04.00 - no check needed */ +#if !defined (BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED) +# if (BRSHW_SOURCECODE_TEMPLATE_VERSION < 0x0103) || ((BRSHW_SOURCECODE_TEMPLATE_VERSION == 0x0103) && \ + (BRSHW_SOURCECODE_TEMPLATE_BUGFIX_VERSION < 0x13)) + #define BRSHW_CORES_AUTOSTART +# endif +#endif + +/********************************************************************************************************************** + * DEFINITION + MACROS + *********************************************************************************************************************/ +#if defined (VLINKGEN_CFG_64BIT_MODE_ENABLED) +typedef uint64 BrsAddressType; +#else +typedef uint32 BrsAddressType; +#endif + +#if defined (BRS_ENABLE_64BIT_INIT_PATTERN) +typedef uint64 BrsInitType; +#else +typedef uint32 BrsInitType; +#endif + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ +#define BRS_START_SEC_SHARED_VAR +#include "Brs_MemMap.h" +volatile brsMain_ResetReasonType brsMain_ResetReason; +#define BRS_STOP_SEC_SHARED_VAR +#include "Brs_MemMap.h" + +/********************************************************************************************************************** + * GLOBAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * PROTOTYPES OF GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * PROTOTYPES OF LOCAL FUNCTIONS + *********************************************************************************************************************/ +BRSMAIN_MEMINIT_FUNC_PREFIX void Brs_MemoryZeroInit(const vLinkGen_MemAreaSet *memAreaSet, + BrsInitType InitPattern, uint32 coreId); +#if !defined (BRS_DISABLE_MEMORY_INIT_GLOBALLY) +BRSMAIN_MEMINIT_FUNC_PREFIX void Brs_MemoryInit(const vLinkGen_RamMemAreaSet *memAreaSet, uint32 coreId); +#endif +#if !defined (BRSHW_ASM_MEMORY_ZERO_INIT_LOOP_AVAILABLE) +BRSMAIN_MEMINIT_FUNC_PREFIX void BrsHw_AsmMemoryZeroInitLoop_64bit(volatile uint64 *memPtr64, + BrsAddressType memAreaEnd, + BrsInitType InitPattern); +#endif +#if defined (BRSMAINSTARTUP_64BIT_MEMORYINIT) || defined (VLINKGEN_CFG_64BIT_MODE_ENABLED) +BRSMAIN_MEMINIT_FUNC_PREFIX void BrsHw_AsmMemoryInitLoop_64bit(uint64 *memPtr64, uint64 *romPtr64, + BrsAddressType memAreaEnd); +#endif + +/********************************************************************************************************************** + * FUNCTION DEFINITIONS + *********************************************************************************************************************/ +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +/* This code is only needed for the first instance in the system */ +#define BRS_START_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +/*****************************************************************************/ +/* @brief Unified routine for Pre Main() Startup. + * @pre Stack pointer needs to be initilialized in StartUpCode before. + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from assembler startup code. + * Called by all cores from the booting execution instance. + * Through Brs_MemMap.h, the API is mapped into section + * brsMainStartup, which allows a fix memory allocation. + *****************************************************************************/ +void Brs_PreMainStartup(void) +{ +#if defined (BRSHW_EARLYINIT_AVAILABLE) + BrsHwEarlyInitPowerOn(); +#endif + +#if (BRS_CPU_CORE_AMOUNT>1) + if (BrsHw_GetCore() == BRSHW_INIT_CORE_ID) +#endif + { + brsMain_ResetReason = BrsHwGetResetReasonStartup(); + } + + Brs_ApplicationEntry(); + + BrsMainExceptionStartup(); /* Illegal return from main */ +} +#define BRS_STOP_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +#endif /* BRS_FIRST_EXECUTION_INSTANCE */ + +#define BRS_START_SEC_BRSAPPLENTRY_CODE +#include "Brs_MemMap.h" +/*****************************************************************************/ +/* @brief Unified application entry for Pre Main() Startup. + * @pre Stack pointer needs to be initilialized in StartUpCode before, + * brsMain_ResetReason needs to be initialized by booting execution + * instance (see Brs_PreMainStartup()). + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from Brs_PreMainStartup() of the booting + * execution instance or is the direct application entry of + * non-booting execution instances (e.g. FBL, with a previously + * running BootManager). Through Brs_MemMap.h, the API is mapped + * into section brsApplicationEntry, which allows a fix memory + * allocation. All APIs are called with current Core ID. + *****************************************************************************/ +void Brs_ApplicationEntry(void) +{ + uint32 coreID; + +#if defined (BRSHW_APPLICATIONINIT_AVAILABLE) + BrsHwApplicationInit(); +#endif + + coreID = BrsHw_GetCore(); + + BrsMain_MemoryInit_StageZero_Hook(coreID); + +#if (VLINKGEN_CFG_NUM_ZERO_INIT_ZERO_GROUPS > 1uL) + /* + * vLinkGen_ZeroInit_Zero_GroupsSet contains vLinkGen VarSectionGroups, configured with Init Policy "ZERO_INIT" and + * Init Stage "ZERO" + */ + Brs_MemoryZeroInit(&vLinkGen_ZeroInit_Zero_GroupsSet, BRS_INIT_PATTERN_AREAS, coreID); +#endif + +#if (VLINKGEN_CFG_NUM_INIT_ZERO_GROUPS > 1uL) && !defined (BRS_DISABLE_MEMORY_INIT_GLOBALLY) + /* + * vLinkGen_Init_Zero_GroupsSet contains vLinkGen VarSectionGroups, configured with Init Policy "INIT" and + * Init Stage "ZERO" + */ + Brs_MemoryInit(&vLinkGen_Init_Zero_GroupsSet, coreID); +#endif + + BrsMain_MemoryInit_StageHardReset_Hook(coreID); + + if (brsMain_ResetReason != BRSMAIN_RESET_SW) + { +#if (VLINKGEN_CFG_NUM_ZERO_INIT_HARD_RESET_BLOCKS > 1uL) + /* + * vLinkGen_ZeroInit_HardReset_BlocksSet contains vLinkGen memory region blocks, configured with + * Init Stage "HARD_RESET_ONLY" + */ + Brs_MemoryZeroInit(&vLinkGen_ZeroInit_HardReset_BlocksSet, BRS_INIT_PATTERN_HARDRESET_BLOCKS, coreID); +#endif + +#if (VLINKGEN_CFG_NUM_ZERO_INIT_HARD_RESET_GROUPS > 1uL) + /* + * vLinkGen_ZeroInit_HardReset_GroupsSet contains vLinkGen VarSectionGroups, configured with + * Init Policy "ZERO_INIT" and Init Stage "HARD_RESET_ONLY" + */ + Brs_MemoryZeroInit(&vLinkGen_ZeroInit_HardReset_GroupsSet, BRS_INIT_PATTERN_HARDRESET_AREAS, coreID); +#endif + +#if (VLINKGEN_CFG_NUM_INIT_HARD_RESET_GROUPS > 1uL) && !defined (BRS_DISABLE_MEMORY_INIT_GLOBALLY) + /* + * vLinkGen_Init_HardReset_GroupsSet contains vLinkGen VarSectionGroups, configured with + * Init Policy "INIT" and Init Stage "HARD_RESET_ONLY" + */ + Brs_MemoryInit(&vLinkGen_Init_HardReset_GroupsSet, coreID); +#endif + } + + BrsMain_MemoryInit_StageOne_Hook(coreID); + +#if (VLINKGEN_CFG_NUM_ZERO_INIT_ONE_BLOCKS > 1uL) + /* vLinkGen_ZeroInit_One_BlocksSet contains vLinkGen memory region blocks, configured with Init Stage "ONE" */ + Brs_MemoryZeroInit(&vLinkGen_ZeroInit_One_BlocksSet, BRS_INIT_PATTERN_BLOCKS, coreID); +#endif + +#if (VLINKGEN_CFG_NUM_ZERO_INIT_ONE_GROUPS > 1uL) + /* + * vLinkGen_ZeroInit_One_GroupsSet contains vLinkGen VarSectionGroups, configured with Init Policy "ZERO_INIT" and + * Init Stage "ONE" + */ + Brs_MemoryZeroInit(&vLinkGen_ZeroInit_One_GroupsSet, BRS_INIT_PATTERN_AREAS, coreID); +#endif + +#if (VLINKGEN_CFG_NUM_INIT_ONE_GROUPS > 1uL) && !defined (BRS_DISABLE_MEMORY_INIT_GLOBALLY) + /* + * vLinkGen_Init_One_GroupsSet contains vLinkGen VarSectionGroups, configured with Init Policy "INIT" and + * Init Stage "ONE" + */ + Brs_MemoryInit(&vLinkGen_Init_One_GroupsSet, coreID); +#endif + + BrsMain_MemoryInit_StageTwo_Hook(coreID); + +#if (VLINKGEN_CFG_NUM_ZERO_INIT_TWO_GROUPS > 1uL) + /* + * vLinkGen_ZeroInit_Two_GroupsSet contains vLinkGen VarSectionGroups, configured with Init Policy "ZERO_INIT" and + * Init Stage "TWO" + */ + Brs_MemoryZeroInit(&vLinkGen_ZeroInit_Two_GroupsSet, BRS_INIT_PATTERN_AREAS, coreID); +#endif + +#if (VLINKGEN_CFG_NUM_INIT_TWO_GROUPS > 1uL) && !defined (BRS_DISABLE_MEMORY_INIT_GLOBALLY) + /* + * vLinkGen_Init_Two_GroupsSet contains vLinkGen VarSectionGroups, configured with Init Policy "INIT" and + * Init Stage "TWO" + */ + Brs_MemoryInit(&vLinkGen_Init_Two_GroupsSet, coreID); +#endif + + BrsMain_MemoryInit_StageThree_Hook(coreID); + +#if (VLINKGEN_CFG_NUM_ZERO_INIT_THREE_GROUPS > 1uL) + /* + * vLinkGen_ZeroInit_Three_GroupsSet contains vLinkGen VarSectionGroups, configured with Init Policy "ZERO_INIT" and + * Init Stage "THREE" + */ + Brs_MemoryZeroInit(&vLinkGen_ZeroInit_Three_GroupsSet, BRS_INIT_PATTERN_AREAS, coreID); +#endif + +#if (VLINKGEN_CFG_NUM_INIT_THREE_GROUPS > 1uL) && !defined (BRS_DISABLE_MEMORY_INIT_GLOBALLY) + /* + * vLinkGen_Init_Three_GroupsSet contains vLinkGen VarSectionGroups, configured with Init Policy "INIT" and + * Init Stage "THREE" + */ + Brs_MemoryInit(&vLinkGen_Init_Three_GroupsSet, coreID); +#endif + + BrsMain_MemoryInit_StagePowerOn_Hook(coreID); + +/* +* --------------------------------------------------------------------------------------------------------------------- +* As there is no general condition available for POWER_ON initialization configured memory, these areas are always +* initialized as default. A project specific condition could be added here! +* +* Explanation from AR21-11 SWS_MemoryMapping: +* POWER_ON_CLEARED, used for variables that are not explicitly initialized (cleared) during normal start-up. +* Instead, these are cleared only after either a power on reset of the microcontroller or a power on reset of +* a battery backup memory itself after battery loss. +* --------------------------------------------------------------------------------------------------------------------- +*/ +#if (VLINKGEN_CFG_NUM_ZERO_INIT_POWER_ON_GROUPS > 1uL) + /* + * vLinkGen_ZeroInit_PowerOn_GroupsSet contains vLinkGen VarSectionGroups, configured with + * Init Policy "ZERO_INIT" and Init Stage "POWER_ON" + */ + Brs_MemoryZeroInit(&vLinkGen_ZeroInit_PowerOn_GroupsSet, BRS_INIT_PATTERN_AREAS, coreID); +#endif + +#if (VLINKGEN_CFG_NUM_INIT_POWER_ON_GROUPS > 1uL) && !defined (BRS_DISABLE_MEMORY_INIT_GLOBALLY) + /* + * vLinkGen_Init_PowerOn_GroupsSet contains vLinkGen VarSectionGroups, configured with + * Init Policy "INIT" and Init Stage "POWER_ON" + */ + Brs_MemoryInit(&vLinkGen_Init_PowerOn_GroupsSet, coreID); +#endif + + BrsMain_PreMainHook(coreID); + + main(); + + BrsMainExceptionHandler(kBrsIllegalReturnFromMain, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__)); +} +#define BRS_STOP_SEC_BRSAPPLENTRY_CODE +#include "Brs_MemMap.h" + +#if !defined (BRSHW_ASM_MEMORY_ZERO_INIT_LOOP_AVAILABLE) +/* +* This helper API is necessary, to get native 64-bit access on the HW (e.g. by getting "ldrd" and "strd" +* (or even "ldmia" and "stmia") assembly command on Arm Cortex-M platforms) reliable. +* That functionality is essential for memory areas with 8-byte aligned ECC! +*/ +BRSMAIN_MEMINIT_FUNC_PREFIX void BrsHw_AsmMemoryZeroInitLoop_64bit(volatile uint64 *memPtr64, + BrsAddressType memAreaEnd, + BrsInitType InitPattern) +{ + volatile uint64 InitPattern_64bit; + volatile const uint64 *memAreaEndPtr = (volatile uint64 *)(memAreaEnd); + + InitPattern_64bit = InitPattern; +# if !defined (BRS_ENABLE_64BIT_INIT_PATTERN) + InitPattern_64bit = (InitPattern_64bit << 32) | InitPattern; +# endif + + while (memPtr64 < memAreaEndPtr) + { + *memPtr64 = InitPattern_64bit; + memPtr64++; + } +} +#endif /* !BRSHW_ASM_MEMORY_ZERO_INIT_LOOP_AVAILABLE */ + +/*****************************************************************************/ +/* @brief Generic routine for RAM zeroing. + * @pre - + * @param[in] memAreaSet shall point to the first element of a vLinkGen_MemAreaSet struct array + * @param[in] InitPattern describes the pattern, to be used for the memory initialization + * @param[in] coreId shall describe the ID of the current CPU + * @param[out] - + * @return - + * @context Function is called from Brs_PreMainStartup() to initialize memory ares, + * generated out of vLinkGen configuration + *****************************************************************************/ +BRSMAIN_MEMINIT_FUNC_PREFIX void Brs_MemoryZeroInit(const vLinkGen_MemAreaSet *memAreaSet, + BrsInitType InitPattern, + uint32 coreId) +{ + uint32 i; +#if !defined (BRSHW_ASM_MEMORY_ZERO_INIT_LOOP_AVAILABLE) +# if !defined (BRS_ENABLE_64BIT_INIT_PATTERN) + volatile BrsAddressType *memPtr; +# endif + volatile uint64 *memPtr64; + volatile uint32 alignment; +#endif + + for (i=0; iNum; i++) + { + if ((memAreaSet->Areas[i].Core == coreId) && ((memAreaSet->Areas[i].End - memAreaSet->Areas[i].Start) > 0u)) + { +#if defined (BRSHW_ASM_MEMORY_ZERO_INIT_LOOP_AVAILABLE) + BrsHw_AsmMemoryZeroInitLoop(memAreaSet->Areas[i].Start, memAreaSet->Areas[i].End, InitPattern); + +#else + alignment = (uint32)memAreaSet->Areas[i].Alignment; + if ((alignment != 0u) && (alignment != 4u) && (alignment != 8u)) + { /* Handling for the configured alignment is not supported yet */ + BrsMainExceptionHandler(kBrsMissingFunctionality, BRSERROR_MODULE_BRSMAINSTARTUP, (uint16)(__LINE__)); + } + +# if !defined (BRS_ENABLE_64BIT_INIT_PATTERN) + if ((alignment == 0u) || (alignment == 4u)) + { /* 32-bit/4Byte default alignment */ + memPtr = (BrsAddressType*)memAreaSet->Areas[i].Start; + while ((BrsAddressType)memPtr < memAreaSet->Areas[i].End) + { + *memPtr = InitPattern; + memPtr++; + } + } + if (alignment == 8u) +# endif /* !BRS_ENABLE_64BIT_INIT_PATTERN */ + { /* 64-bit/8Byte alignment or 64-Bit Init Pattern enabled */ + memPtr64 = (uint64*)memAreaSet->Areas[i].Start; + BrsHw_AsmMemoryZeroInitLoop_64bit((volatile uint64*)memPtr64, memAreaSet->Areas[i].End, InitPattern); + } +#endif /* else BRSHW_ASM_MEMORY_ZERO_INIT_LOOP_AVAILABLE */ + } + } +} + +/* +* To prevent issues with not 8-Byte aligned memory areas, the 64-bit memory initialization is disabled per default. +* If you want to use it, take care about the alignment and enable BRSMAINSTARTUP_64BIT_MEMORYINIT. +* Or enable the 64-bit addressing in vLinkGen. +* For ECC-RAM with 8-Byte aligned ECC, the memory should be handled by ZeroInit in advance +*/ +#if defined (BRSMAINSTARTUP_64BIT_MEMORYINIT) || defined (VLINKGEN_CFG_64BIT_MODE_ENABLED) +/* +* This helper API is necessary, to get native 64-bit access on the HW (e.g. by getting "ldrd" and "strd" +* (or even "ldmia" and "stmia") assembly commands on Arm Cortex-M platforms) reliable. +* That functionality is essential for memory areas with 8-byte aligned ECC! +*/ +BRSMAIN_MEMINIT_FUNC_PREFIX void BrsHw_AsmMemoryInitLoop_64bit(uint64 *memPtr64, + uint64 *romPtr64, + BrsAddressType memAreaEnd) +{ + while ((uint64)romPtr64 < memAreaEnd) + { + *memPtr64 = *romPtr64; + memPtr64++; + romPtr64++; + } +} +#endif /* BRSMAINSTARTUP_64BIT_MEMORYINIT || VLINKGEN_CFG_64BIT_MODE_ENABLED */ + +#if !defined (BRS_DISABLE_MEMORY_INIT_GLOBALLY) +/*****************************************************************************/ +/* @brief Generic routine for ROM to RAM initialization. + * @pre - + * @param[in] memAreasSet shall point to the first element of a vLinkGen_RamMemAreaSet struct array + * @param[in] coreId shall describe the ID of the current CPU + * @param[out] - + * @return - + * @context Function is called from Brs_PreMainStartup() to initialize memory ares, + * generated out of vLinkGen configuration + *****************************************************************************/ +BRSMAIN_MEMINIT_FUNC_PREFIX void Brs_MemoryInit(const vLinkGen_RamMemAreaSet *memAreasSet, uint32 coreId) +{ +#if !defined (VLINKGEN_CFG_64BIT_MODE_ENABLED) + volatile uint32 *memPtr32; + volatile const uint32 *romPtr32; +#endif + uint32 i; + volatile uint32 alignment; + +#if defined (BRSMAINSTARTUP_64BIT_MEMORYINIT) || defined (VLINKGEN_CFG_64BIT_MODE_ENABLED) + volatile uint64 *memPtr64; + volatile const uint64 *romPtr64; +#endif + + for (i = 0; i < memAreasSet->Num; i++) + { + if ((memAreasSet->Areas[i].Core == coreId) && + ((memAreasSet->Areas[i].Romend - memAreasSet->Areas[i].Romstart) > 0u)) + { + if ((memAreasSet->Areas[i].End - memAreasSet->Areas[i].Start) < + (memAreasSet->Areas[i].Romend - memAreasSet->Areas[i].Romstart)) + { /* Defined size in RAM is smaller than the ROM size -> data will not fit */ + BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAINSTARTUP, (uint16)(__LINE__)); + } + + alignment = (uint32)memAreasSet->Areas[i].Alignment; + if ((alignment != 0u) && (alignment != 4u) && (alignment != 8u)) + { /* Handling for the configured alignment is not supported yet */ + BrsMainExceptionHandler(kBrsMissingFunctionality, BRSERROR_MODULE_BRSMAINSTARTUP, (uint16)(__LINE__)); + } + +#if defined (VLINKGEN_CFG_64BIT_MODE_ENABLED) + /* 64-Bit Init Pattern enabled */ + memPtr64 = (uint64*)memAreasSet->Areas[i].Start; + romPtr64 = (uint64*)memAreasSet->Areas[i].Romstart; + BrsHw_AsmMemoryInitLoop_64bit((uint64*)memPtr64, (uint64*)romPtr64, memAreasSet->Areas[i].Romend); + +#else +# if defined (BRSMAINSTARTUP_64BIT_MEMORYINIT) + if ((alignment == 0u) || (alignment == 4u)) + { /* 32-bit/4Byte default alignment */ +# endif + + memPtr32 = (uint32*)memAreasSet->Areas[i].Start; + romPtr32 = (uint32*)memAreasSet->Areas[i].Romstart; + + while ((BrsAddressType)romPtr32 < memAreasSet->Areas[i].Romend) + { + *memPtr32 = *romPtr32; + memPtr32++; + romPtr32++; + } + +# if defined (BRSMAINSTARTUP_64BIT_MEMORYINIT) + } + if (alignment == 8u) + { /* 64-bit/8Byte alignment */ + memPtr64 = (uint64*)memAreasSet->Areas[i].Start; + romPtr64 = (uint64*)memAreasSet->Areas[i].Romstart; + BrsHw_AsmMemoryInitLoop_64bit((uint64*)memPtr64, (uint64*)romPtr64, memAreasSet->Areas[i].Romend); + } +# endif /* BRSMAINSTARTUP_64BIT_MEMORYINIT */ +#endif /* VLINKGEN_CFG_64BIT_MODE_ENABLED */ + } + } +} +#endif /* !BRS_DISABLE_MEMORY_INIT_GLOBALLY */ + +#if !defined (VVIRTUALTARGET) +# if defined (BRS_FIRST_EXECUTION_INSTANCE) +/* This code is only needed for the first instance in the system */ +#define BRS_START_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +/*****************************************************************************/ +/* @brief This is the central exeption/issue handler of BRS, in startup + * phase. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context This function implements an endless loop. The recommendation is + * to set a breakpoint on top of this function to see if any check + * has failed during the startup code execution. + *****************************************************************************/ +void BrsMainExceptionStartup(void) +{ + volatile uint8 BrsMainStartup_Continue; + BrsMainStartup_Continue = 0; + while (BrsMainStartup_Continue == 0u) + { + /* + * Set BrsMainStartup_Continue to 1 to continue here. + * If the debugger is not able to show the stack properly, this mechanism can be used to find the + * source of the exception. + */ + } +} +#define BRS_STOP_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +# endif /* BRS_FIRST_EXECUTION_INSTANCE */ +#endif /* VVIRTUALTARGET */ diff --git a/Source/appl/BrsMain_Appl.c b/Source/appl/BrsMain_Appl.c new file mode 100644 index 0000000..a5f987b --- /dev/null +++ b/Source/appl/BrsMain_Appl.c @@ -0,0 +1,892 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsMain_Appl.c + * Project: Vector Basic Runtime System + * Module: BrsMain + * + * \brief Description: Additional, Application-specific, implementation + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to BrsMain.h. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * EXAMPLE CODE ONLY + * ------------------------------------------------------------------------------------------------------------------- + * This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. + * The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither + * intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or + * implementations must be tested with diligent care and must comply with all quality requirements which are necessary + * according to the state of the art before their use. + *********************************************************************************************************************/ + +#define _BRSMAIN_APPL_C_ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "BrsMain_Appl.h" + +#if defined (BRS_ENABLE_SCHM_STUB_GENERATION) +/* needed for SuspendAllInterrupts() and ResumeAllInterrupts() of SchM stub wrapper APIs + * BrsMain_Appl_SuspendAllInterrupts() and BrsMain_Appl_ResumeAllInterrupts() */ + #include "Os.h" +#endif + +#if defined (BRS_ENABLE_HYPERVISOR_SUPPORT) && defined (BRS_ENABLE_OS_MULTICORESUPPORT) + /* Needed for BrsMain_CoreConfig[] and BrsMain_CoreConfig_Size */ + #include "vBrs_Lcfg.h" +#endif + +#if !defined (BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING) +# if defined (BRS_ENABLE_CAN_SUPPORT) && defined (BRS_ENABLE_CAN_CLASSIC_SUPPORT) + /* with vCan drivers, only Can_30_Core.h needs to be included (see BrsMain_Appl.h) */ + #include BRS_DRVCAN_HEADER_FILENAME +# if defined (BRS_DRVCAN1_HEADER_FILENAME) + #include BRS_DRVCAN1_HEADER_FILENAME +# endif +# endif +#endif + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ +#if (BRSMAIN_MAJOR_VERSION != 2u) || (BRSMAIN_MINOR_VERSION != 27u) + #error "Header and source file are inconsistent!" +#endif +#if (BRSMAIN_PATCH_VERSION != 0u) + #error "Different versions of patch in Header and Source used!" +#endif + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ +/* COMPILER CHECK */ +/* Check if the DaVinci configured compiler fits to the used buildenvironment */ +#if defined (VVIRTUALTARGET) + /* For vVirtualTarget, the compier should always be configured to Ansi. + This is related to BRS_COMPILER_DFDD3B47_BB56_4B45_BEC9_BE0B2C58DC11. + But, as no MakeSupport is used for vVirtualTarget, we do not need to check this here. */ +#else +# if defined (BRS_COMPILER_UNDEFINED) + #error "No compiler is configured in DaVinci!" + #error "As several parts of vBaseEnv are compiler dependent, proper usage without a compiler selection is not possible." +# endif +# if defined (BRS_COMP_ARM5) && !defined (BRS_COMPILER_ACA8C365_6D1E_49FA_97F8_792D81C79C74) + #error "Buildenvironment for Arm5 compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_ARM6) && !defined (BRS_COMPILER_89D464F1_ECCF_4306_A854_BF45FB1D7441) + #error "Buildenvironment for Arm6 compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_ARMTFE) && !defined (BRS_COMPILER_B052FFB3_EA77_4E0B_ACB8_A77A4A0F24E8) + #error "Buildenvironment for ArmTfE compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_CCAC) && !defined (BRS_COMPILER_2526EC26_414A_4091_91D0_0442AF47D241) + #error "Buildenvironment for Ccac compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_DIABDATA) && !defined (BRS_COMPILER_44266E21_0E8C_4DDA_B800_91CE20104931) + #error "Buildenvironment for DiabData compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_GCCHIGHTEC) && !defined (BRS_COMPILER_E7BC1F6B_0DF4_4345_BE50_A9AE95AF99A7) + #error "Buildenvironment for GccHighTec compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_GCCNXP) && !defined (BRS_COMPILER_E832C52E_6625_4C6A_96D2_0BD6FFD35ECE) + #error "Buildenvironment for GccNxp compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_GHS) && !defined (BRS_COMPILER_BBC47DF5_C78B_4E8E_8F86_0EF503FD3198) + #error "Buildenvironment for GreenHills compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_GNU) && !defined (BRS_COMPILER_1350F673_6EFC_4394_917C_52F584E83ACE) + #error "Buildenvironment for GccGnu compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_IAR) && !defined (BRS_COMPILER_FA51A718_3ADB_438D_98F3_245101681392) + #error "Buildenvironment for Iar compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_LLVMDIAB) && !defined (BRS_COMPILER_E0E70C27_10E6_4169_9D2C_B9CAA4649C65) + #error "Buildenvironment for LlvmDiabData compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_LLVMHIGHTEC) && !defined (BRS_COMPILER_BEBEB212_6307_4BD8_A274_A517B187644E) + #error "Buildenvironment for LlvmHighTec compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) && !defined (BRS_COMPILER_051C3D73_B474_4677_9754_FBA372BF80EC) + #error "Buildenvironment for LlvmTexasInstruments compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_MICROCHIP) && !defined (BRS_COMPILER_82CA3A19_9A7A_49D6_9EFE_39486D0F6510) + #error "Buildenvironment for MicroChip compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_RENESAS) && !defined (BRS_COMPILER_5BCBEFDE_F5D2_49AA_B4DD_04AC02CE5A9A) + #error "Buildenvironment for Renesas compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_TASKING) && !defined (BRS_COMPILER_8DB6C5C5_6807_4601_B7B7_68A4A5B277F6) + #error "Buildenvironment for Tasking compiler is used, but DaVinci is configured for a different compiler!" +# endif +# if defined (BRS_COMP_TI) && !defined (BRS_COMPILER_B961F280_648C_45FF_A994_700EDE3B9F78) + #error "Buildenvironment for TexasInstruments compiler is used, but DaVinci is configured for a different compiler!" +# endif +#endif /* VVIRTUALTARGET */ + +/* If the template version for BrsHw is not at least 01.03.13, Hypervisor Multicore configuration is not supported. */ +#if defined (BRS_ENABLE_HYPERVISOR_SUPPORT) && defined (BRS_ENABLE_OS_MULTICORESUPPORT) +/* BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED was introduced in Brs_Template 1.04.00 - no check needed */ +# if !defined (BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED) +# if (BRSHW_SOURCECODE_TEMPLATE_VERSION < 0x0103) || ((BRSHW_SOURCECODE_TEMPLATE_VERSION == 0x0103) && \ + (BRSHW_SOURCECODE_TEMPLATE_BUGFIX_VERSION < 0x13)) + #error "Hypervisor Multicore is only supported with Brs_Template[01.03.13] onwards." +# endif +# endif +#endif + +/********************************************************************************************************************** + * DEFINITION + MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ +#if !defined (BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING) +# if defined (BRS_ENABLE_CAN_SUPPORT) && (!defined (BRS_ENABLE_FBL_SUPPORT)) +# if defined (BRS_ENABLE_CAN_CLASSIC_SUPPORT) + #define CAN_START_SEC_VAR_NOINIT_8BIT + /* + * to support CAN driver name infix, vBRS generator provides a wrapper + * for usage of the driver specific MemMap.h define in vBrsCfg.h + */ + #include "vBrsCfg.h" + static uint8 BrsAsrApplCanInterruptLockCtr; + #define CAN_STOP_SEC_VAR_NOINIT_8BIT + /* + * to support CAN driver name infix, vBRS generator provides a wrapper + * for usage of the driver specific MemMap.h define in vBrsCfg.h + */ + #include "vBrsCfg.h" +# endif /* BRS_ENABLE_CAN_CLASSIC_SUPPORT */ +# endif /* BRS_ENABLE_CAN_SUPPORT && !BRS_ENABLE_FBL_SUPPORT */ +#endif /* !BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING */ + +/********************************************************************************************************************** + * GLOBAL CONST VARIABLES + *********************************************************************************************************************/ +#if defined (BRS_FBL_INSTANCE_FBL) +/********************************************************************************************************************** + * FBL Instance Presence Pattern + * This presence pattern is only required when downloading the FBL with debugger. When using an updater (or an EOL + * programmer), this presence pattern is not required as part of the .hex file and should be removed. + *********************************************************************************************************************/ +#define BRS_START_SEC_FBL_PP_CONST +#include "Brs_MemMap.h" +const uint8 FblPresencePatternArray[4] = {0x73u, 0x6Au, 0x29u, 0x3Eu}; +#define BRS_STOP_SEC_FBL_PP_CONST +#include "Brs_MemMap.h" +#endif /* BRS_FBL_INSTANCE_FBL */ + +/********************************************************************************************************************** + * LOCAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * PROTOTYPES OF GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * PROTOTYPES OF LOCAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * FUNCTION DEFINITIONS + *********************************************************************************************************************/ +/*****************************************************************************/ +/* @brief Main initialization routine. + * Contains configuration specific initialization of BrsHw parts + * and BrsMain specific mechanisms. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from main + *****************************************************************************/ +void BrsMain_Appl_Init(void) +{ +#if !defined (BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING) +# if defined (BRS_ENABLE_CAN_SUPPORT) && (!defined (BRS_ENABLE_FBL_SUPPORT)) +# if defined (BRS_ENABLE_CAN_CLASSIC_SUPPORT) + /* UserDefined ExclusiveArea handling for CAN channels, according to AN-ISC-8-1149_ErrorHook_E_OS_DISABLED_INT.pdf */ + BrsAsrApplCanInterruptLockCtr = 0u; +# endif +# endif +#endif +} + +#if defined (BRS_ENABLE_SCHM_STUB_GENERATION) +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_START_SEC_RAM_CODE + #include "Brs_MemMap.h" +# endif +/*****************************************************************************/ +/* @brief Suspend all interrupts via OS call + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is used for SchM_Enter_* defines in vBrs generated + * SchM stub module specific header files. This allows the user to + * add project specific code. As default, SuspendAllInterrupts() is + * defined empty within BrsMain provided Os.h stub for delieveries + * w/o OS (no interrupt locking needed in polling environments) + *****************************************************************************/ +void BrsMain_Appl_SuspendAllInterrupts(void) +{ + SuspendAllInterrupts(); +} + +/*****************************************************************************/ +/* @brief Resume all interrupts via OS call + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is used for SchM_Exit_* defines in vBrs generated + * SchM stub module specific header files. This allows the user to + * add project specific code. As default, ResumeAllInterrupts() is + * defined empty within BrsMain provided Os.h stub for delieveries + * w/o OS (no interrupt locking needed in polling environments) + *****************************************************************************/ +void BrsMain_Appl_ResumeAllInterrupts(void) +{ + ResumeAllInterrupts(); +} +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_STOP_SEC_RAM_CODE + #include "Brs_MemMap.h" +# endif +#endif /* BRS_ENABLE_SCHM_STUB_GENERATION */ + +#if defined (BRS_ENABLE_HYPERVISOR_SUPPORT) +/*****************************************************************************/ +/* @brief Callout to let the additional configured cores started by the + * boot core, if necessary. This is just an initial template and + * may need project specific adaptions. It's called by every core. + * @pre - + * @param[in] coreID is the physical core ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from main, previously to vHyp_Init() + *****************************************************************************/ +void BrsMain_Appl_HypervisorStartCoreApi(uint32 coreID) +{ +#if defined (BRS_ENABLE_OS_MULTICORESUPPORT) && (!defined (BRSHW_CORES_AUTOSTART)) + /* + * If additional cores need to be started by the boot core, this needs to be done previously to the call of + * vHyp_Init(), to prevent issues, if boot core is not the same as vHyp init core (VHYP_CORE_INIT). + * As vHyp_RegisterCore() will wait until the additional core reaches a sync barrier, all configured cores should be + * started as early as possible. + */ + /* Check, if the actual running core is the boot core */ + if (coreID == BRSHW_INIT_CORE_ID) + { + for (uint32 i = 0u; i < BrsMain_CoreConfig_Size; i++) + { + if (BrsMain_CoreConfig[i].PhysicalCoreId != BRSHW_INIT_CORE_ID) + { + BrsHw_StartCore(BrsMain_CoreConfig[i].PhysicalCoreId); + } + } + } +#endif /* BRS_ENABLE_OS_MULTICORESUPPORT && !BRSHW_CORES_AUTOSTART */ +} + +/*****************************************************************************/ +/* @brief Callout to implement user code previous to the call of + * vHyp_Start(). This is just an initial template and may need + * project specific adaptions. It's called by every core. + * @pre - + * @param[in] coreID is the physical core ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from main, previously to vHyp_Start() + *****************************************************************************/ +void BrsMain_Appl_HypervisorApi(uint32 coreID) +{ +#if defined (BRS_ENABLE_OS_MULTICORESUPPORT) + /* Check, if the actual running core is the vHyp init core */ + if ((vHyp_CoreIdType)coreID == VHYP_CORE_INIT) + { + vHyp_CoreIdType core; + for (core = 0; core < VHYP_CORE_COUNT; core++) + { + if (core != VHYP_CORE_INIT) + { + vHyp_RegisterCore(core); + } + } + } +#endif /* BRS_ENABLE_OS_MULTICORESUPPORT */ +} +#endif /* BRS_ENABLE_HYPERVISOR_SUPPORT */ + +#if !defined (BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING) +# if defined (BRS_ENABLE_CAN_SUPPORT) +# if defined (BRS_ENABLE_CAN_CLASSIC_SUPPORT) +/********************************************************************************************************************** + * A classic (non-Gen3) DrvCan is part of the configuration. "Oldschool" implementation is needed + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * UserDefined ExclusiveArea handling for CAN channels, according to AN-ISC-8-1149_ErrorHook_E_OS_DISABLED_INT.pdf + *********************************************************************************************************************/ +/* +* Macro is generated in vBrsCfg.h, to support drivers with infix. +* Sample w/o infix: void SchM_Enter_Can_CAN_EXCLUSIVE_AREA_0(void) +* Can_DisableControllerInterrupts(0u); +* Sample w/ infix: void SchM_Enter_Can_30_Mcan_CAN_30_MCAN_EXCLUSIVE_AREA_0(void) +* Can_30_Mcan_DisableControllerInterrupts(0u); +*/ + +#define CAN_START_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Enter, EXCLUSIVE_AREA_0) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + if (++BrsAsrApplCanInterruptLockCtr == 1u) + { + BRS_DRVCAN_ControllerInterrupts_INFIX(Disable)(0u); + } +#endif +} + +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Exit, EXCLUSIVE_AREA_0) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + if (--BrsAsrApplCanInterruptLockCtr == 0u) + { + BRS_DRVCAN_ControllerInterrupts_INFIX(Enable)(0u); + } +#endif +} + +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Enter, EXCLUSIVE_AREA_6) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + if (++BrsAsrApplCanInterruptLockCtr == 1u) + { + BRS_DRVCAN_ControllerInterrupts_INFIX(Disable)(0u); + } +#endif +} + +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Exit, EXCLUSIVE_AREA_6) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + if (--BrsAsrApplCanInterruptLockCtr == 0u) + { + BRS_DRVCAN_ControllerInterrupts_INFIX(Enable)(0u); + } +#endif +} +#define CAN_STOP_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" + +# if !defined (BRS_ENABLE_FBL_SUPPORT) +#define CANIF_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_CanIf_CANIF_EXCLUSIVE_AREA_0(void) +{ + if (++BrsAsrApplCanInterruptLockCtr == 1u) + { + BRS_DRVCAN_ControllerInterrupts_INFIX(Disable)(0u); + } +} + +void SchM_Exit_CanIf_CANIF_EXCLUSIVE_AREA_0(void) +{ + if (--BrsAsrApplCanInterruptLockCtr == 0u) + { + BRS_DRVCAN_ControllerInterrupts_INFIX(Enable)(0u); + } +} +#define CANIF_STOP_SEC_CODE +#include "MemMap.h" + +#define CANSM_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_CanSM_CANSM_EXCLUSIVE_AREA_4(void) +{ + if (++BrsAsrApplCanInterruptLockCtr == 1u) + { + BRS_DRVCAN_ControllerInterrupts_INFIX(Disable)(0u); + } +} + +void SchM_Exit_CanSM_CANSM_EXCLUSIVE_AREA_4(void) +{ + if (--BrsAsrApplCanInterruptLockCtr == 0u) + { + BRS_DRVCAN_ControllerInterrupts_INFIX(Enable)(0u); + } +} + +void SchM_Enter_CanSM_CANSM_EXCLUSIVE_AREA_1(void) +{ + /* Protects against task interruptions -> no locking needed, because all main functions are on same task */ +} + +void SchM_Exit_CanSM_CANSM_EXCLUSIVE_AREA_1(void) +{ + /* Protects against task interruptions -> no locking needed, because all main functions are on same task */ +} +#define CANSM_STOP_SEC_CODE +#include "MemMap.h" + +#define COMM_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_ComM_COMM_EXCLUSIVE_AREA_1(void) +{ + /* Protects against task interruptions -> no locking needed, because all main functions are on same task */ +} + +void SchM_Exit_ComM_COMM_EXCLUSIVE_AREA_1(void) +{ + /* Protects against task interruptions -> no locking needed, because all main functions are on same task */ +} +#define COMM_STOP_SEC_CODE +#include "MemMap.h" +# endif /* !BRS_ENABLE_FBL_SUPPORT */ +# endif /* BRS_ENABLE_CAN_CLASSIC_SUPPORT */ + +# if defined (BRS_ENABLE_CAN_CORE_SUPPORT) +/********************************************************************************************************************** + * A new (Gen3) DrvCan is part of the configuration. New implementation is needed + *********************************************************************************************************************/ +# if (Can_30_Core_IsHardwareCancelByApplOfGeneralFeature(0u) && Can_30_Core_IsHardwareLoopCheckOfGeneralFeature(0u)) + /* If these do not exist, maybe Can_30_Core/Can/CanGeneral/CanConstantDataToDefine is deactivated. If so, please + choose the suitable implementation manually */ + +# if !defined (BRS_ENABLE_FBL_SUPPORT) + /* Within a FBL project, depending APIs are already available within Fbl_cw.c */ +/********************************************************************************************************************** + * Hardware Loop Check / Timeout Monitoring for CAN Driver, according to TechnicalReference_Can_30_Core.pdf, + * chapter 2.8.2 + *********************************************************************************************************************/ +#define CAN_30_CORE_START_SEC_VAR_NOCACHE_INIT_32 +# if defined (BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP) + #include "Can_30_Core_MemMap.h" +# else + #include "MemMap.h" +# endif +static uint32 BrsAsrApplCanTimerCount; +#define CAN_30_CORE_STOP_SEC_VAR_NOCACHE_INIT_32 +# if defined (BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP) +#include "Can_30_Core_MemMap.h" +# else + #include "MemMap.h" +# endif + +#define CAN_30_CORE_START_SEC_CODE +# if defined (BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP) + #include "Can_30_Core_MemMap.h" +# else + #include "MemMap.h" +# endif +void Appl_30_CoreCanTimerStart(uint8 Controller, uint8 source) +{ + BrsAsrApplCanTimerCount = 0u; +} + +void Appl_30_CoreCanTimerEnd(uint8 Controller, uint8 source) +{ + /* nothing to be done here; BrsAsrApplCanTimerCount will be set to 0 by next call of Appl_30_CoreCanTimerStart() */ +} + +Can_ReturnType Appl_30_CoreCanTimerLoop(uint8 Controller, uint8 source) +{ + BrsAsrApplCanTimerCount++; + + if (BrsAsrApplCanTimerCount > 10000u) + { + /* timeout detected! Something seems to block the DrvCan */ + return CAN_NOT_OK; + } else + return CAN_OK; +} +#define CAN_30_CORE_STOP_SEC_CODE +# if defined (BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP) + #include "Can_30_Core_MemMap.h" +# else + #include "MemMap.h" +# endif +# endif /* !BRS_ENABLE_FBL_SUPPORT */ + +# else + #error "Can_30_Core/Can/CanGeneral/CanHardwareCancelByAppl and/or Can_30_Core/Can/CanGeneral/CanHardwareLoopCheck are deactivated! If you really want to use customer specific exclusive area handling, implement them controller and project specific. The following APIs are only a generic sample and need to be adapted." + +/*********************************************************************************************************************** + * UserDefined ExclusiveArea handling for CAN Driver Core, according to TechnicalReference_Can_30_Core.pdf, Note within + * chapter 3.2 + **********************************************************************************************************************/ +/* +* BE AWARE, THIS IS ONLY A SAMPLE IMPLEMENTATION! +* To get a suitable implementation for your project, take account to the technical reference of Can_30_Core +* and implement them according to your specific project settings. +* The suitable implementation is highly configuration specific, e.g. amount of channels, postbuild, ... +*/ + +#define CAN_30_CORE_START_SEC_CODE +# if defined (BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP) + #include "Can_30_Core_MemMap.h" +# else + #include "MemMap.h" +# endif +void SchM_Enter_Can_30_Core_CAN_30_CORE_EXCLUSIVE_AREA_6(void) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + /* + * sample for singlechannel configuration: + * Can_30_Core_DisableControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_DisableControllerInterrupts(ch); + */ +#endif +} + +void SchM_Exit_Can_30_Core_CAN_30_CORE_EXCLUSIVE_AREA_6(void) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + /* + * sample for singlechannel configuration: + * Can_30_Core_EnableControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_EnableControllerInterrupts(ch); + */ +#endif +} +#define CAN_30_CORE_STOP_SEC_CODE +# if defined (BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP) + #include "Can_30_Core_MemMap.h" +# else + #include "MemMap.h" +# endif + +# if !defined (BRS_ENABLE_CAN_CLASSIC_SUPPORT) + /* + * If vCan and classic CAN is mixed within one config, the "old" DrvCan is expected to be the 1st one. So, the + * exclusive areas are already implemented earlier in this file + */ +/********************************************************************************************************************** + * UserDefined ExclusiveArea handling for vCAN Driver, according to TechnicalReference_vCan_30_Mcan.pdf, Note within + * chapter 3.2 + *********************************************************************************************************************/ +/* +* BE AWARE, THIS IS ONLY A SAMPLE IMPLEMENTATION! +* To get a suitable implementation for your project, take account to the technical reference of your specific DrvCan +* and implement them according to your specific project settings. +* The suitable implementation is highly configuration specific, e.g. amount of channels, postbuild, ... +*/ + +#define CAN_START_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Enter, EXCLUSIVE_AREA_0) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + /* + * sample for singlechannel configuration: + * Can_30_Core_DisableControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_DisableControllerInterrupts(ch); + */ +#endif +} + +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Exit, EXCLUSIVE_AREA_0) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + /* + * sample for singlechannel configuration: + * Can_30_Core_RestoreControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_RestoreControllerInterrupts(ch); + */ +#endif +} + +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Enter, EXCLUSIVE_AREA_1) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + /* + * sample for singlechannel configuration: + * Can_30_Core_DisableControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_DisableControllerInterrupts(ch); + */ +#endif +} + +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Exit, EXCLUSIVE_AREA_1) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + /* + * sample for singlechannel configuration: + * Can_30_Core_RestoreControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_RestoreControllerInterrupts(ch); + */ +#endif +} +#define CAN_STOP_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" +# endif /* !BRS_ENABLE_CAN_CLASSIC_SUPPORT */ + +# if defined (BRS_DRVCAN1_HEADER_FILENAME) + /* 2nd DrvCan instance detected */ +#define CAN1_START_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" +BRS_DRVCAN1_EXCLUSIVE_AREA_INFIX(Enter, EXCLUSIVE_AREA_0) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + /* + * sample for singlechannel configuration: + * Can_30_Core_DisableControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_DisableControllerInterrupts(ch); + */ +#endif +} + +BRS_DRVCAN1_EXCLUSIVE_AREA_INFIX(Exit, EXCLUSIVE_AREA_0) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + /* + * sample for singlechannel configuration: + * Can_30_Core_RestoreControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_RestoreControllerInterrupts(ch); + */ +#endif +} + +BRS_DRVCAN1_EXCLUSIVE_AREA_INFIX(Enter, EXCLUSIVE_AREA_1) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + /* + * sample for singlechannel configuration: + * Can_30_Core_DisableControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_DisableControllerInterrupts(ch); + */ +#endif +} + +BRS_DRVCAN1_EXCLUSIVE_AREA_INFIX(Exit, EXCLUSIVE_AREA_1) +{ +#if !defined (BRS_ENABLE_FBL_SUPPORT) + /* + * sample for singlechannel configuration: + * Can_30_Core_RestoreControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_RestoreControllerInterrupts(ch); + */ +#endif +} +#define CAN1_STOP_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" +# endif /* BRS_DRVCAN1_HEADER_FILENAME */ + +# if !defined (BRS_ENABLE_FBL_SUPPORT) +# if !defined (BRS_ENABLE_CAN_CLASSIC_SUPPORT) + /* + * If vCan and classic CAN is mixed within one config, these exclusive areas are already implemented earlier + * in this file + */ +#define CANIF_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_CanIf_CANIF_EXCLUSIVE_AREA_0(void) +{ + /* + * sample for singlechannel configuration: + * Can_30_Core_DisableControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_DisableControllerInterrupts(ch); + */ +} + +void SchM_Exit_CanIf_CANIF_EXCLUSIVE_AREA_0(void) +{ + /* + * sample for singlechannel configuration: + * Can_30_Core_RestoreControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_RestoreControllerInterrupts(ch); + */ +} +#define CANIF_STOP_SEC_CODE +#include "MemMap.h" + +#define CANSM_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_CanSM_CANSM_EXCLUSIVE_AREA_4(void) +{ + /* + * sample for singlechannel configuration: + * Can_30_Core_DisableControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_DisableControllerInterrupts(ch); + */ +} + +void SchM_Exit_CanSM_CANSM_EXCLUSIVE_AREA_4(void) +{ + /* + * sample for singlechannel configuration: + * Can_30_Core_RestoreControllerInterrupts(0u); + */ + + /* + * sample for multichannel configuration (be aware, this will have an effect on the runtime!): + * uint8 ch; + * for (ch = 0; ch < Can_30_Core_GetSizeOfControllerConfig(); ch++) { + * Can_30_Core_RestoreControllerInterrupts(ch); + */ +} + +void SchM_Enter_CanSM_CANSM_EXCLUSIVE_AREA_1(void) +{ + /* Protects against task interruptions -> no locking needed, because all main functions are on same task */ +} + +void SchM_Exit_CanSM_CANSM_EXCLUSIVE_AREA_1(void) +{ + /* Protects against task interruptions -> no locking needed, because all main functions are on same task */ +} +#define CANSM_STOP_SEC_CODE +#include "MemMap.h" + +#define COMM_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_ComM_COMM_EXCLUSIVE_AREA_1(void) +{ + /* Protects against task interruptions -> no locking needed, because all main functions are on same task */ +} + +void SchM_Exit_ComM_COMM_EXCLUSIVE_AREA_1(void) +{ + /* Protects against task interruptions -> no locking needed, because all main functions are on same task */ +} +#define COMM_STOP_SEC_CODE +#include "MemMap.h" +# endif /* !BRS_ENABLE_CAN_CLASSIC_SUPPORT */ +# endif /* !BRS_ENABLE_FBL_SUPPORT */ +# endif /* Can_30_Core_IsHardwareCancelByApplOfGeneralFeature(0u) && + Can_30_Core_IsHardwareLoopCheckOfGeneralFeature(0u) */ +# endif /* BRS_ENABLE_CAN_CORE_SUPPORT */ +# endif /* BRS_ENABLE_CAN_SUPPORT */ +#endif /* !BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING */ diff --git a/Source/appl/BrsMain_Callout_Stubs.c b/Source/appl/BrsMain_Callout_Stubs.c new file mode 100644 index 0000000..3240e53 --- /dev/null +++ b/Source/appl/BrsMain_Callout_Stubs.c @@ -0,0 +1,255 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsMain_Callout_Stubs.c + * Project: Vector Basic Runtime System + * Module: BrsMain + * + * \brief Description: UseCase specific implementation templates for several hooks out of BrsMain. + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to BrsMain.h. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * EXAMPLE CODE ONLY + * ------------------------------------------------------------------------------------------------------------------- + * This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. + * The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither + * intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or + * implementations must be tested with diligent care and must comply with all quality requirements which are necessary + * according to the state of the art before their use. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "BrsMain.h" + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ +#if (BRSMAIN_MAJOR_VERSION != 2u) || (BRSMAIN_MINOR_VERSION != 27u) + #error "Header and source file are inconsistent!" +#endif +#if (BRSMAIN_PATCH_VERSION != 0u) + #error "Different versions of patch in Header and Source used!" +#endif + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * DEFINITION + MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * PROTOTYPES OF GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * PROTOTYPES OF LOCAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * FUNCTION DEFINITIONS + *********************************************************************************************************************/ + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage zero. + *****************************************************************************/ +void BrsMain_MemoryInit_StageZero_Hook(uint32 coreId) +{ + /* nothing to be done up to now */ +} + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage hard reset. + *****************************************************************************/ +void BrsMain_MemoryInit_StageHardReset_Hook(uint32 coreId) +{ +#if defined (BRS_ENABLE_PREFER_PLL_WATCHDOG_INIT) + /* If preferred feature is not acivated, initialization will take place in BrsMainInit(). */ +# if (BRS_CPU_CORE_AMOUNT > 1) + if (coreId == BRSHW_INIT_CORE_ID) +# endif + { +# if defined (BRSHW_PREINIT_AVAILABLE) + BrsHwPreInitPowerOn(); +# endif + +# if defined (BRS_ENABLE_WATCHDOG) + BrsHwWatchdogInitPowerOn(); +# else + #error "To use the feature of preferred PLL and Watchdog initialization, add your DrvWd initialization here manually." +# endif + +# if defined (BRS_ENABLE_PLLCLOCKS) + BrsHwPllInitPowerOn(); +# else + #error "To use the feature of preferred PLL and Watchdog initialization, add your DrvMcu initialization here manually." +# endif + } +#endif /* BRS_ENABLE_PREFER_PLL_WATCHDOG_INIT */ +} + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage one. + *****************************************************************************/ +void BrsMain_MemoryInit_StageOne_Hook(uint32 coreId) +{ + /* nothing to be done up to now */ +} + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage two. + *****************************************************************************/ +void BrsMain_MemoryInit_StageTwo_Hook(uint32 coreId) +{ + /* nothing to be done up to now */ +} + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage three. + *****************************************************************************/ +void BrsMain_MemoryInit_StageThree_Hook(uint32 coreId) +{ + /* nothing to be done up to now */ +} + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage Power_On. + *****************************************************************************/ +void BrsMain_MemoryInit_StagePowerOn_Hook(uint32 coreId) +{ + /* nothing to be done up to now */ +} + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * after the memory initialization was done. + *****************************************************************************/ +void BrsMain_PreMainHook(uint32 coreId) +{ + /* nothing to be done up to now */ +} + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from BrsHwSoftwareResetECU(), before a + * SW reset is triggered. Implement code here to also reset + * peripherals, if necessary for your UseCase. + *****************************************************************************/ +void BrsMain_SoftwareResetECU_Hook(void) +{ +#if defined (BRS_HYPERVISOR_GUEST_EXECUTION_INSTANCE) && !defined (BRS_FIRST_EXECUTION_INSTANCE) +# if defined (BRS_COMP_TASKING) + #pragma message "#warning: As a hypervisor guest instance, the SW-Reset needs to be handled differently. Check the implementation project specific!" +# else + #warning "As a hypervisor guest instance, the SW-Reset needs to be handled differently. Check the implementation project specific!" +# endif +#endif + + /* nothing to be done up to now */ +} + +/*****************************************************************************/ +/* @brief This API is mandatory callout, if non-ASR cores are configured in OS. + * Project specific implementation for non-ASR cores should be added here. + * @pre non-ASR cores are configured in OS + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from main() for non-Autosar-cores. + *****************************************************************************/ +void BrsMain_NonAsrCore_Hook(void) +{ + /* nothing to be done up to now */ + volatile uint8 NonAsrCoreContinue; + NonAsrCoreContinue = 0; + + while (NonAsrCoreContinue == 0u) + { + /* This is the end of the preliminary non-Asr-Implementation */ + } +} diff --git a/Source/appl/BrsMain_FblOsStub.c b/Source/appl/BrsMain_FblOsStub.c new file mode 100644 index 0000000..2ff8135 --- /dev/null +++ b/Source/appl/BrsMain_FblOsStub.c @@ -0,0 +1,148 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsMain_FblOsStub.c + * Project: Vector Basic Runtime System + * Module: BrsMain + * + * \brief Description: FBL OS stub for usage of MSR4 modules, referencing several OS APIs + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to Os.h. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * EXAMPLE CODE ONLY + * ------------------------------------------------------------------------------------------------------------------- + * This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. + * The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither + * intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or + * implementations must be tested with diligent care and must comply with all quality requirements which are necessary + * according to the state of the art before their use. + *********************************************************************************************************************/ + +#define _BRSMAIN_FBLOSSTUB_C_ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Os.h" +#include "BrsHw.h" + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * DEFINITION + MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ +static volatile TickType currentCounterValue; + +/********************************************************************************************************************** + * GLOBAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL CONST VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * PROTOTYPES OF GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * PROTOTYPES OF LOCAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * FUNCTION DEFINITIONS + *********************************************************************************************************************/ +StatusType GetCounterValue(CounterType CounterID, TickRefType Value) +{ + while(1) + { + /* + * This part is not yet implemented. If you are stuck here, please implement these functions to provide the + * respective functionality to the caller. + * This can be done e.g. by using a free running timer or FblLookForWatchdog logic + */ + } + +#if 0 /* SAMPLE */ + currentCounterValue = 0; + *Value = 0; + return (StatusType) E_OK; +#endif +} + +StatusType GetElapsedValue(CounterType CounterID, TickRefType Value, TickRefType ElapsedValue) +{ + while(1) + { + /* + * This part is not yet implemented. If you are stuck here, please implement these functions to provide the + * respective functionality to the caller. + * This can be done e.g. by using a free running timer or FblLookForWatchdog logic + */ + } + +#if 0 /*SAMPLE */ + /* Check the OS_*_SystemTimer() macros in Os.h, they may need adaptions as well */ + if (FBL_TM_TRIGGERED == (FblLookForWatchdog() & FBL_TM_TRIGGERED)) + { + currentCounterValue += OS_TICKS2US_SystemTimer(1); + } + + *ElapsedValue = currentCounterValue; + + return (StatusType) E_OK; +#endif +} + +#define BRS_START_SEC_RAM_CODE +#include "Brs_MemMap.h" +void Appl_30_CoreCanInterruptDisable(uint8 Controller) +{ + /* + * As FBL is running in polling mode anyway, the controller specific + * interrupt disable/enable functionality is not needed at all + */ + DisableAllInterrupts() +} + +void Appl_30_CoreCanInterruptRestore(uint8 Controller) +{ + /* + * As FBL is running in polling mode anyway, the controller specific + * interrupt disable/enable functionality is not needed at all + */ + EnableAllInterrupts() +} +#define BRS_STOP_SEC_RAM_CODE +#include "Brs_MemMap.h" diff --git a/Source/appl/bm_ap.c b/Source/appl/bm_ap.c new file mode 100644 index 0000000..1d771d3 --- /dev/null +++ b/Source/appl/bm_ap.c @@ -0,0 +1,1032 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Application dependent routines + * + * \note Please note, that this file contains a collection of callback functions to be used with the + * Flash Bootloader. These functions may influence the behavior of the bootloader in principle. + * Therefore, great care must be taken to verify the correctness of the implementation. + * The contents of the originally delivered files are only examples resp. implementation proposals. + * With regard to the fact that these functions are meant for demonstration purposes only, Vector + * Informatik's liability shall be expressly excluded in cases of ordinary negligence, to the extent + * admissible by law or statute. + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2019-01-28 visrie - Initial version + * 01.01.00 2019-02-18 vismvi ESCAN00102171 Variable declared but never referenced + * visrie ESCAN00102310 Added callout to check reprogramming flag + * 01.01.01 2019-03-07 visrie ESCAN00102386 Fixed compiler error in ApplFbl_DetEntryHandler + * ESCAN00102399 Check NvPattern only for non-RAM blocks + * 02.00.00 2019-05-02 visrie ESCAN00102518 Added support to read block/application validity from NV-Memory + * ESCAN00102761 Added support for 3rd Party Tricore HSM + * ESCAN00103026 Provide BmHeader instead of StartAddress to ApplFblBmStartSoftware + * 03.00.00 2019-07-17 visrie ESCAN00103750 Removed target order list configuration + * 03.01.00 2019-08-14 visrie FBL-487 Exclude callouts if overwritten by OEM/HW layer + * 03.01.01 2019-09-04 visrcn ESCAN00103607 Memory qualifier mismatch + * 04.00.00 2019-12-04 visrie FBL-456 Updated to new LibSecBoot interface + * ESCAN00105135 Added support for new BRS API + * 04.01.00 2020-01-16 visrie FBL-524 Added support for vHsm SecBoot library + * 05.00.00 2020-04-09 visrie FBL-1016 Support new vBaseEnv, added support for VTT + * 05.01.00 2020-04-29 vistmo FBL-1584 Added OTA startup support + * 05.02.00 2020-08-13 vistmo FBL-1489 Added support for OTA swap activation + * 05.02.01 2021-03-17 vishor ESCAN00108386 ApplFblBmIsValidBlock implementation does not consider + * all possible use cases + * FBL-3018 No changes + * 05.03.00 2021-08-11 visrie FBL-3394 Move default implementation of CheckReprogFlag into FblBm_Ap + * 05.04.00 2021-09-17 visjdn FBL-3865 Add default SecBoot implementation for GHS/Escrypt + * 05.04.01 2022-04-06 vismix FBL-4773 Support THUMB mode + * 05.05.00 2022-04-07 vishor FBL-4822 Add support for new MagicFlag value and Swap API + * 05.05.01 2022-06-23 vismix ESCAN00111879 Boot manager does not wait for HSM update recovery + * 05.06.00 2022-07-13 vismix FBL-5391 Add callout for missing optional dependency + * 05.06.01 2022-11-29 vishor ESCAN00112986 Compiler error: Undefined symbols + * ApplFblPreMemDriver/ApplFblPostMemDriver + * 05.07.00 2023-06-29 vistbe FBL-7052 Add evaluation of ActivationPending + * 05.07.01 2023-12-18 visrie ESCAN00104829 Compiler error: Det.h missing in GENy based standalone BM + * ESCAN00111036 Compiler error: 'kFblApplicationValid' may be undeclared + * ESCAN00115752 No changes + * 05.08.00 2024-05-16 vishor FBL-8602 Add support for OEM updater solution + * 05.09.00 2025-05-23 dganesh FBL-9715 Extend presence pattern to connect validity information + **********************************************************************************************************************/ + +#define BM_AP_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ +#include "bm_ap.h" +#include "bm_main.h" +#include "fbl_inc.h" + +#include "fbl_main_types.h" + +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) +# include "Csm.h" +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ +# if defined( FBLBM_ENABLE_STANDALONE_MODE ) +# include "Det.h" +# endif +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# include "fbl_secboot.h" +# include "Csm.h" +# include "Crypto_30_vHsm.h" +#endif /* FBLBM_AP_ENABLE_3RD_PARTY_TRICORE_HSM_USED */ + +# include "BrsHw.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLBM_AP_VERSION != 0x0509u ) || \ + ( FBLBM_AP_RELEASE_VERSION != 0x00u ) +# error "Error in bm_ap.c: Source and Header file are inconsistent!" +#endif + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#if defined( _MICROSOFT_C_VTT_ ) +# define FBLBM_AP_ENABLE_VTT_USECASE +#endif /* _MICROSOFT_C_VTT_ */ + +/* If no explicit LB for the LBT exists use the bootloader LB */ +#if !defined( FBL_MTAB_LBT_BLOCK_NUMBER ) +# define FBL_MTAB_LBT_BLOCK_NUMBER FBL_MTAB_BOOTLOADER_BLOCK_NUMBER +#endif /* FBL_MTAB_LBT_BLOCK_NUMBER */ + +/* Helper macro to get number of array entries */ +#if defined( FBLBMAP_ARRAY_SIZE ) +#else +# define FBLBMAP_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ +#endif + +#if defined( FBLBM_AP_CALLOUT_CHECK_TARGET_VALIDITY ) && \ + !defined( FBL_ENABLE_PRESENCE_PATTERN ) +/** Compatibility define in case OEM layer uses different macro scheme */ +# if !defined( kFblApplicationValid ) +# if defined( kEepApplConsistent ) +# define kFblApplicationValid kEepApplConsistent +# else +# error "kFblApplicationValid not defined or can't be mapped to an equivalent define/value." +/* TODO_CUSTOMER: Adjust the following define to map kFblApplicationValid to the correct value/define used by the OEM */ +/* #define kFblApplicationValid */ +# endif +# endif /* !kFblApplicationValid */ +#endif /* FBLBM_AP_CALLOUT_CHECK_TARGET_VALIDITY && !FBL_ENABLE_PRESENCE_PATTERN */ + +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) +/** Key size of signed presence pattern */ +# define FBLBM_SIGNED_PP_KEY_SIZE 0x10u +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +#define FBLBMAP_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) +V_MEMRAM0 static V_MEMRAM1 vuintx V_MEMRAM2 g_ApplFblBmSearchUpdaterHeaderIndex; +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + +#define FBLBMAP_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# define FBLBMAP_RAMCODE_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +static void ApplFblBmWaitForHsm(void); +# define FBLBMAP_RAMCODE_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# define FBLBMAP_RAMCODE_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * ApplFblBmWaitForHsm + **********************************************************************************************************************/ +/*! \brief Wait until vHSM is ready + **********************************************************************************************************************/ +static void ApplFblBmWaitForHsm(void) +{ + Std_ReturnType retVal; + uint32 keyLength; + uint32 hsm2host; + uint32 host2hsm; + + /* Wait until vHsm has been started */ + do + { + keyLength = 4u; + retVal = Csm_KeyElementGet(0u, CRYPTO_KE_CUSTOM_VHSM_STATUS_HSM2HOST, (uint8 *)&hsm2host, &keyLength); + assertFblUser(retVal == E_OK, kFblSysAssertDet); + } while (hsm2host == 0u); + + /* When a vHsmUpd is pending */ + if ((hsm2host & (1uL << CRYPTO_30_VHSM_HSM2HOST_UPDATERRUNNING)) == (1uL << CRYPTO_30_VHSM_HSM2HOST_UPDATERRUNNING)) + { + keyLength = 4u; +# error "Comment this line if vHsmUpdater is not used. If vHsmUpdater is used, please assign the value configured in the vHsm-updater to host2hsm below" + host2hsm = 0x80000000u; + /* Set configured Bit pattern to signalize the vHsmUpd that update can be started */ + retVal = Csm_KeyElementSet(0u, CRYPTO_KE_CUSTOM_VHSM_STATUS_HOST2HSM, (uint8 *)&host2hsm, keyLength); + assertFblUser(retVal == E_OK, kFblSysAssertDet); + + /* Wait until vHsmUpd has been finished */ + do + { + FblLookForWatchdogVoid(); + + keyLength = 4u; + retVal = Csm_KeyElementGet(0u, CRYPTO_KE_CUSTOM_VHSM_STATUS_HSM2HOST, (uint8 *)&hsm2host, &keyLength); + assertFblUser(retVal == E_OK, kFblSysAssertDet); + } while ((hsm2host & ((1u << CRYPTO_30_VHSM_HSM2HOST_READY) | (1u << CRYPTO_30_VHSM_HSM2HOST_ACTIVE))) != ((1u << CRYPTO_30_VHSM_HSM2HOST_READY) | (1u << CRYPTO_30_VHSM_HSM2HOST_ACTIVE))); + } + + /* Wait until vHsm is ready */ + Crypto_30_vHsm_WaitForHsmRam(); +} +# define FBLBMAP_RAMCODE_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +#define FBLBMAP_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * ApplFblBmPowerOnPre + **********************************************************************************************************************/ +/*! \brief Initialization callout + **********************************************************************************************************************/ +void ApplFblBmPowerOnPre( void ) +{ + +} + +/*********************************************************************************************************************** + * ApplFblBmPowerOnPost + **********************************************************************************************************************/ +/*! \brief Initialization callout + **********************************************************************************************************************/ +void ApplFblBmPowerOnPost( void ) +{ +#if defined( FBL_ENABLE_OTA ) + vOtaM_InitMemory(); +#endif /* FBL_ENABLE_OTA */ +} + +/*********************************************************************************************************************** + * ApplFblBmInitPre + **********************************************************************************************************************/ +/*! \brief Initialization callout + **********************************************************************************************************************/ +void ApplFblBmInitPre( void ) +{ +# if defined( BRS_FBL_LEGACY ) +# if defined( BRSHW_PREINIT_AVAILABLE ) + /* HW specific pre-initialization. */ + BrsHwPreInitPowerOn(); +# endif /* BRSHW_PREINIT_AVAILABLE */ + +# if defined( BRS_ENABLE_WATCHDOG ) + /* Disable Watchdog */ + BrsHwWatchdogInitPowerOn(); +# endif /* BRS_ENABLE_WATCHDOG */ + +# if defined( BRS_ENABLE_PLLCLOCKS ) + /* Initialize the PLLs. */ + BrsHwPllInitPowerOn(); +# endif /* BRS_ENABLE_PLLCLOCKS */ + +# if defined( BRSHW_DISABLE_ECC_AVAILABLE ) + /* Disable Flash ECC error reporting. */ + BrsHwDisableEccErrorReporting(); +# endif /* BRSHW_DISABLE_ECC_AVAILABLE */ + +# if defined( FBL_ENABLE_PRE_TIMERINIT ) + /* Timer is stopped by mode switch and has to be re-initialized. */ + FblTimerInit(); +# endif /* FBL_ENABLE_PRE_TIMERINIT */ +# endif /* BRS_FBL_LEGACY */ +} + +/*********************************************************************************************************************** + * ApplFblBmInitPost + **********************************************************************************************************************/ +/*! \brief Initialization callout + **********************************************************************************************************************/ +void ApplFblBmInitPost( void ) +{ +#if defined( FBLBM_ENABLE_SECURE_BOOT ) + volatile vuint8 executeTestcode = kFblOk; + + /* Wait until vHSM is ready */ + ApplFblBmWaitForHsm(); + + if (executeTestcode == kFblOk) /* Testcode to initialize RAM key, to simulate written key */ + { + Std_ReturnType retVal; + uint8 version[3u] = {0u}; + uint32 versionLength = sizeof( version ); + Crypto_VerifyResultType result = CRYPTO_E_VER_NOT_OK; + const uint8 key[16u] = {0u}; + uint8 mac[16u] = {0u}; + const uint8 data[16u] = {0u}; + uint32 length = sizeof( mac ); + + /* Get the Version of the vHsm Firmware */ + retVal = Crypto_30_vHsm_KeyElementGet( CryptoConf_CryptoKey_vHsm_Info, CRYPTO_KE_CUSTOM_VHSM_VERSION, version, &versionLength ); + + /* Fill the key used for the CMAC and set it to valid */ + retVal |= Csm_KeyElementSet( CsmConf_CsmKey_CsmKey_SymmetricKey, CRYPTO_KE_MAC_KEY, key, sizeof( key ) ); + retVal |= Csm_KeySetValid( CsmConf_CsmKey_CsmKey_SymmetricKey ); + + /* Generate the CMAC with the software implementation on the vHsm */ + retVal |= Csm_MacGenerate( CsmConf_CsmJob_CsmJob_MacGen_Key1, CRYPTO_OPERATIONMODE_SINGLECALL, data, sizeof( data ), mac, &length ); + retVal |= Csm_MacVerify( CsmConf_CsmJob_CsmJob_MacVer_Key1, CRYPTO_OPERATIONMODE_SINGLECALL, data, sizeof( data ), mac, sizeof( mac ) * 8u, &result ); + + if (retVal != E_OK) + { + while (1u) + { + ; + } + } + } +#endif /* FBLBM_ENABLE_SECURE_BOOT */ +#if defined( FBL_ENABLE_OTA ) + if (vOtaM_Init() != E_OK) + { + /* PRQA S 2741, 4558 1 */ /* MD_FblBmAp_2741_4558 */ + assertFblUser(0u, kFblSysAssertInitializationFailed); + } +#endif /* FBL_ENABLE_OTA */ +} + +#if defined( FBLBM_AP_CALLOUT_RESET ) +/*********************************************************************************************************************** + * ApplFblBmReset + **********************************************************************************************************************/ +/*! \brief Issue Reset + **********************************************************************************************************************/ +void ApplFblBmReset(void) +{ + /* Reset ECU */ + BrsHwSoftwareResetECU(); +} +#endif /* FBLBM_AP_CALLOUT_RESET */ + +#if defined( FBLBM_AP_CALLOUT_CHECK_TARGET_VALIDITY ) +/*********************************************************************************************************************** + * ApplFblBmCheckTargetValidity + **********************************************************************************************************************/ +/*! \brief Checks the validity of the target (Usually: Is the Application Validity Presence Pattern set) + * \param[in] targetHandle Target handle (e.g. Bootloader, Application, Updater) + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise + **********************************************************************************************************************/ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +tFblResult ApplFblBmCheckTargetValidity(tFblBmHdrTargetHandle targetHandle) +{ + tFblResult result; +# if defined( FBL_ENABLE_PRESENCE_PATTERN ) + vuint8 blockNo; + tBlockDescriptor blockDescriptor; + vuint8 device; +# else + vuint8 applValidity; +# endif + + /* Check overall application validity for Application target */ + if (targetHandle == FBLBMHDR_TARGET_APPL) + { + result = kFblFailed; + +# if defined( FBL_ENABLE_PRESENCE_PATTERN ) + /* Check if any PP for appl validity is set */ + blockNo = 0u; + + while ((blockNo < FblLbtGetBlockCount()) && (result != kFblOk)) + { + if (kFblOk == FblLbtGetBlockDescriptorByNr(blockNo, &blockDescriptor)) + { + if (kFblOk == FblMemGetDeviceByRange(blockDescriptor.blockStartAddress, blockDescriptor.blockLength, &device)) + { +# if defined( kMioDeviceRam ) + /* Do not check the presence pattern for RAM */ + if (device != kMioDeviceRam) +# endif + { + result = FblNvPatternGet(&blockDescriptor, kFblNvPatternId_ApplValidity); + } + } + } + + /* Prepare index for next loop */ + blockNo++; + } +# else + /* Read validity from NV-memory */ + if (ApplFblNvReadApplValidity(&applValidity) == kFblOk) + { + if (applValidity == kFblApplicationValid) + { + result = kFblOk; + } + } +# endif + } + else + { + /* For all other targets, no overall validity is necessary */ + result = kFblOk; + } + + return result; +} +#endif /* FBLBM_AP_CALLOUT_CHECK_TARGET_VALIDITY */ + + +#if defined( FBLBM_AP_CALLOUT_IS_VALIDBLOCK ) +/*********************************************************************************************************************** + * ApplFblBmIsValidBlock + **********************************************************************************************************************/ +/*! \brief Checks the preconditions of a specific target + * \param[in] targetHandle Target handle (e.g. Bootloader, Application) + * \param[in] pLogicalBlock Pointer to current logical block + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult ApplFblBmIsValidBlock(tFblBmHdrTargetHandle targetHandle, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * pLogicalBlock) +{ + tFblResult result; +# if defined( FBL_ENABLE_PRESENCE_PATTERN ) || defined( FBLBM_ENABLE_STANDALONE_MODE ) + vuint8 device; +# endif /* FBL_ENABLE_PRESENCE_PATTERN || FBLBM_ENABLE_STANDALONE_MODE */ +# if !defined( FBL_ENABLE_PRESENCE_PATTERN ) + vuint8 validityFlags[kEepSizeValidityFlags]; + vuint8 validityMask; + vuint8 byteIdx; +# endif /* !FBL_ENABLE_PRESENCE_PATTERN */ + +# if (!defined( FBLBM_ENABLE_STANDALONE_MODE ) || defined( FBL_ENABLE_PRESENCE_PATTERN )) +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)targetHandle; +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ +# endif /* ( !FBLBM_ENABLE_STANDALONE_MODE || FBL_ENABLE_PRESENCE_PATTERN ) */ + + result = kFblFailed; + +# if defined( FBLBM_ENABLE_STANDALONE_MODE ) && !defined( FBL_ENABLE_PRESENCE_PATTERN) +# error "If presence pattern is disabled special handling must be configured for the FBL because \ + validity flags are not available for the FBL." + /* Perform presence pattern check only for FBL, use NV validity flags for other blocks */ + if (targetHandle == FBLBMHDR_TARGET_FBL) +# endif /* FBLBM_ENABLE_STANDALONE_MODE && !FBL_ENABLE_PRESENCE_PATTERN */ +# if defined( FBL_ENABLE_PRESENCE_PATTERN ) || defined( FBLBM_ENABLE_STANDALONE_MODE ) + { + /* Check the presence pattern value */ + if (kFblOk == FblMemGetDeviceByRange(pLogicalBlock->blockStartAddress, pLogicalBlock->blockLength, &device)) + { +# if defined( kMioDeviceRam ) + /* Do not check the presence pattern for RAM */ + if (device != kMioDeviceRam) +# endif /* kMioDeviceRam */ + { + result = FblNvPatternGetByBlockDescriptor(pLogicalBlock, kFblNvPatternId_BlockValidity ); + } + } + } +# endif /* FBL_ENABLE_PRESENCE_PATTERN || FBLBM_ENABLE_STANDALONE_MODE */ +# if !defined( FBL_ENABLE_PRESENCE_PATTERN ) +# if defined( FBLBM_ENABLE_STANDALONE_MODE ) + /* Check NV validity flags if block other than FBL is checked */ + else +# endif /* FBLBM_ENABLE_STANDALONE_MODE */ + { + /* Calculate index and mask for validity bit of logical block */ + byteIdx = (pLogicalBlock->blockNr >> 0x03u); + validityMask = (vuint8)(0x01u << (pLogicalBlock->blockNr & 0x07u)); + + /* Read validity information from non-volatile memory */ + if (ApplFblNvReadValidityFlags(validityFlags) == kFblOk) + { + if ((validityFlags[byteIdx] & validityMask) == 0u) + { + /* Block is valid */ + result = kFblOk; + } + } + } +# endif /* !FBL_ENABLE_PRESENCE_PATTERN */ + + return result; +} +#endif /* FBLBM_AP_CALLOUT_IS_VALIDBLOCK */ + +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) +# if defined( FBLBM_AP_CALLOUT_IS_VALIDPATTERN ) +/*********************************************************************************************************************** + * ApplFblBmCheckPresencePattern + **********************************************************************************************************************/ +/*! \brief Explicitly checks the presence pattern(excluding the CMAC) validity of the target + * \param[in] targetHandle Target handle (e.g. Bootloader, Application) + * \param[in] pLogicalBlock Pointer to current logical block + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult ApplFblBmCheckPresencePattern(tFblBmHdrTargetHandle targetHandle, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * pLogicalBlock) +{ + tFblResult result; + + vuint8 device; + IO_PositionType patternAddress; + IO_SizeType patternLength; + tFblNvPatternState patternState; + +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)targetHandle; +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + result = kFblFailed; + + /* Check the presence pattern value of Target */ + if (kFblOk == FblMemGetDeviceByRange(pLogicalBlock->blockStartAddress, pLogicalBlock->blockLength, &device)) + { +# if defined( kMioDeviceRam ) + /* Do not check the presence pattern for RAM */ + if (device != kMioDeviceRam) +# endif /* kMioDeviceRam */ + { + /* Check state of Target pattern */ + patternState = FblNvPatternGetPatternState(pLogicalBlock, kFblNvPatternId_BlockValidity, &patternAddress, &patternLength); + if ((patternState.markerState == FBL_NVPATTERN_STATE_EXPECTEDVALUE) && (patternState.maskState == FBL_NVPATTERN_STATE_ERASED)) + { + result = kFblOk; + } + } + } + + return result; +} +# endif /* FBLBM_AP_CALLOUT_IS_VALIDPATTERN */ + +# if defined( FBLBM_AP_CALLOUT_GET_PP_SIGN_KEYEMPTY ) +/*********************************************************************************************************************** + * ApplFblBmGetPresPattSignInitStatus + **********************************************************************************************************************/ +/*! \brief Checks if now keys has been programmed so far Presence pattern + * \return FBLBM_KEY_IS_AVAILABLE if the keys are already programmed + FBLBM_KEY_IS_NOT_AVAILABLE else + **********************************************************************************************************************/ +tFblBmKeyEmptyResult ApplFblBmGetPresPattSignInitStatus( void ) +{ + /* TODO_CUSTOMER: implement check if key is available here. This can be done by querying the HSM/SHE (depending + * on the used hardware) or e.g. by checking a pattern in the flash which indicates that the FBL has written the key + * into the Crypto. + */ + tFblBmKeyEmptyResult result; + vuint8 key[FBLBM_SIGNED_PP_KEY_SIZE]; + vuint32 keyLength; + + if (Csm_KeyElementGet(FblNvPattern_GetCsmKeyIdMac, CRYPTO_KE_CIPHER_KEY, key, (uint32*)&keyLength) != CRYPTO_E_KEY_NOT_AVAILABLE) + { + result = FBLBM_KEY_IS_AVAILABLE; + } + else + { + result = FBLBM_KEY_IS_NOT_AVAILABLE; + } + + return result; +} +# endif /* FBLBM_AP_CALLOUT_GET_PP_SIGN_KEYEMPTY */ +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + +#if defined( FBLBM_CALLOUT_IS_OPTIONALBLOCK ) +/*********************************************************************************************************************** + * ApplFblBmIsOptionalBlock + **********************************************************************************************************************/ +/*! \brief Callout when logical block is optional and not present + * \param[in] targetHandle Target handle (e.g. Bootloader, Application) + * \param[in] pLogicalBlock Pointer to current logical block + **********************************************************************************************************************/ +void ApplFblBmIsOptionalBlock(tFblBmHdrTargetHandle targetHandle, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * pLogicalBlock) +{ +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)targetHandle; + (void)pLogicalBlock; +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ +} +#endif /* FBLBM_CALLOUT_IS_OPTIONALBLOCK */ + +#if defined( FBLBM_AP_CALLOUT_START_SOFTWARE ) +/*********************************************************************************************************************** + * ApplFblBmStartSoftware + **********************************************************************************************************************/ +/*! \brief This function is called to start a software (e.g. Bootloader) + * \details Please note: The function will never return because control is handed over to the running software. + * \param[in] bmHeader Pointer to the targets BM Header structure, which shall be started + **********************************************************************************************************************/ +void ApplFblBmStartSoftware(const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader) +{ +# if defined( BRS_INSTRUCTION_SET_THUMB ) + JSR(bmHeader->bmEntryAddress | 1u); /* PRQA S 0305 */ /* MD_FblBmAp_0305 */ +# else + JSR(bmHeader->bmEntryAddress); /* PRQA S 0305 */ /* MD_FblBmAp_0305 */ +# endif + +# if defined( FBL_ENABLE_SYSTEM_CHECK ) + /* Code should never be reached */ + while (1u) + { + ; + } +# endif /* FBL_ENABLE_SYSTEM_CHECK */ +} +#endif /* FBLBM_AP_CALLOUT_START_SOFTWARE* */ + +#if defined( FBLBM_AP_CALLOUT_FAILSAFE_UPDATER_USER_CHECK ) && defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) +/*********************************************************************************************************************** + * ApplFblBmFailsafeUpdaterUserCheck + **********************************************************************************************************************/ +/*! \brief This function can be used to implement a user-defined updater and provide its entry address + * \details This function will be called if the user-defined updater feature is enabled and will control the rest + * of the bootmanager program flow + * \param[out] bmHeader Pointer to the BM Header structure whose jump address must be updated in case updater is found + * \return kFblOk: User-defined updater is available, jump to address given by bmHeader->bmEntryAddress + * kFblFailed: User-defined updater is not available, proceed to next state (failed state) + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +tFblResult ApplFblBmFailsafeUpdaterUserCheck(V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader) +{ +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)bmHeader; +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + /* TODO_CUSTOMER: Implement user updater check here. If the user updater is valid, set bmHeader->bmEntryAddress + * to the jump address of the updater entry function and set return value to kFblOk */ + + return kFblFailed; +} +#endif + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY ) +# if defined( FBLBM_AP_CALLOUT_GET_KEYEMPTY ) +/*********************************************************************************************************************** + * ApplFblBmGetKeyEmpty + **********************************************************************************************************************/ +/*! \brief Checks if now keys has been programmed so far + * \return FBLBM_KEY_IS_AVAILABLE if the keys are already programmed + FBLBM_KEY_IS_NOT_AVAILABLE else + **********************************************************************************************************************/ +tFblBmKeyEmptyResult ApplFblBmGetKeyEmpty( void ) +{ + /* TODO_CUSTOMER: implement check if key is available here. This can be done by querying the HSM/SHE (depending + * on the used hardware) or e.g. by checking a pattern in the flash which indicates that the FBL has written the key + * into the Crypto. + */ + tFblBmKeyEmptyResult result; + +# error "No default implementation for this variant available." + /* Per default assume that the key is available */ + result = FBLBM_KEY_IS_AVAILABLE; + + return result; +} +# endif /* FBLBM_AP_CALLOUT_GET_KEYEMPTY */ +# endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY */ + +# if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) +# if defined( FBLBM_AP_CALLOUT_GET_FBL_CMACERASED ) +/*********************************************************************************************************************** + * ApplFblBmGetFblCmacErased + **********************************************************************************************************************/ +/*! \brief Checks if MACs for the FBL has been programmed so far + * \return FBLBM_MAC_IS_AVAILABLE If the MACs of the FBL are already written + * FBLBM_MAC_IS_NOT_AVAILABLE Else. E.g. because the FBL is just flashed by a debugger + **********************************************************************************************************************/ +tFblBmMacEmptyResult ApplFblBmGetFblCmacErased( const tFblBmBlockInfo * fblBlockInfo ) +{ + /* TODO_CUSTOMER: implement check if CMAC is available here. This can be done by checking the CMAC content or e.g. + * by checking a pattern in the flash which indicates that the FBL CMAC was already written + */ + + tFblBmMacEmptyResult result; + + +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)fblBlockInfo; +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + if (ApplFblSbIsInitialStartup() == kFblOk) + { + /* This is the first startup, the SecureBootSegments needs to be updated */ + result = FBLBM_MAC_IS_NOT_AVAILABLE; + } + else + { + result = FBLBM_MAC_IS_AVAILABLE; + } + + return result; +} +# endif /* FBLBM_AP_CALLOUT_GET_FBL_CMACERASED */ +# endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + +#if defined( FBLBM_AP_CALLOUT_CHECKREPROGFLAG ) +/*********************************************************************************************************************** + * ApplFblBmCheckReprogFlag + **********************************************************************************************************************/ +/*! \brief Checks if a reprogramming request flag is set. + * \return Result of operation + * kFblOk when reprogramming request flag is set + * kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult ApplFblBmCheckReprogFlag( void ) +{ + tFblResult result = kFblFailed; +# if !defined( FBL_ENABLE_FBL_START ) + vuint8 progReqFlag = 0u; +# endif + +# if defined( FBL_ENABLE_FBL_START ) + if (FblBmChkFblStartMagicFlag()) + { + /* FblStart magic flag is set, do not clear flag as the Bootloader requires it as well */ + result = kFblOk; + } +# else + /* Check the reprogramming request flag */ + if (ApplFblNvReadProgReqFlag(&progReqFlag) == kFblOk) + { + if (progReqFlag == kEepFblReprogram) + { + /* UDS-Reprogramming flag is set, do not clear flag as the Bootloader requires it as well */ + result = kFblOk; + } +# if defined( FBL_ENABLE_XCP ) + else if (progReqFlag == kEepFblXcpProgram) + { + /* XCP-Reprogramming flag is set, do not clear flag as the Bootloader requires it as well */ + result = kFblOk; + } +# endif +# if defined( FBL_ENABLE_OTA ) + else if (progReqFlag == kEepFblOtaReprogram) + { + /* OTA-Reprogramming flag is set, do not clear flag as the Bootloader requires it as well */ + result = kFblOk; + } +# endif + else + { + /* Nothing to do */ + } + } +# endif /* FBL_ENABLE_FBL_START */ + +# if defined( FBLBM_MAIN_ENABLE_MAGICFLAG ) && \ + defined( FBLBM_ENABLE_SECURE_BOOT ) && \ + defined( FBLBM_MAIN_ENABLE_HARDWARE_SWAP ) + if (FblBmChkSBUpdateMagicFlag()) + { + /* Start FBL in case of secure boot update */ + result = kFblOk; + } +# endif + +# if defined( FBL_ENABLE_OTA ) + if (vOtaM_GetState() == vOtaM_State_OtaRequest) + { + /* OTA request is pending -> bootloader should be started */ + result = kFblOk; + } +# endif /* FBL_ENABLE_OTA */ + + return result; +} +#endif /* FBLBM_AP_CALLOUT_CHECKREPROGFLAG */ + +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) +# if defined( FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT ) +/*********************************************************************************************************************** + * ApplFblBmSearchUpdaterHeaderInit + **********************************************************************************************************************/ +/*! \brief Prepare search for updater BmHeader location + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult ApplFblBmSearchUpdaterHeaderInit(void) +{ + g_ApplFblBmSearchUpdaterHeaderIndex = 0u; + return kFblOk; +} +# endif /* FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT */ + +# if defined( FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS ) +/*********************************************************************************************************************** + * ApplFblBmSearchUpdaterHeaderAddress + **********************************************************************************************************************/ +/*! \brief Get address of possible location of a BmHeader for the Failsafe Updater + * \param[out] headerAddress Address where the BmHeader could possible be located + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult ApplFblBmSearchUpdaterHeaderAddress(vuint32 * headerAddress) +{ + vuint32 offset = 0u; + (* headerAddress) = FlashBlock[g_ApplFblBmSearchUpdaterHeaderIndex].begin + offset; + return kFblOk; +} +# endif /* FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS */ + +# if defined( FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT ) +/*********************************************************************************************************************** + * ApplFblBmSearchUpdaterHeaderNext + **********************************************************************************************************************/ +/*! \brief Get (next) possible location of a BmHeader for the Failsafe Updater + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult ApplFblBmSearchUpdaterHeaderNext(void) +{ + tFblResult result; + + g_ApplFblBmSearchUpdaterHeaderIndex++; + + if (g_ApplFblBmSearchUpdaterHeaderIndex < kNrOfFlashBlock) + { + result = kFblOk; + } + else + { + result = kFblFailed; + } + + return result; +} +# endif /* FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT */ +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + +#if defined( FBLBM_AP_CALLOUT_FATAL_ERROR ) +/*********************************************************************************************************************** + * ApplFblBmFatalError + **********************************************************************************************************************/ +/*! \brief This function is called in case no valid starting software was found + * \details Provide here some final tasks which shall be executed + **********************************************************************************************************************/ +void ApplFblBmFatalError(tFblBmError error) +{ +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)error; +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + +# if defined( FBL_ENABLE_SYSTEM_CHECK ) + /* Code should never be reached */ + while (1u) + { + ; + } +# endif /* FBL_ENABLE_SYSTEM_CHECK */ +} +#endif /* FBLBM_AP_CALLOUT_FATAL_ERROR */ + +/*-- Other callout functions -----------------------------------------------------------------------------------------*/ + +#if defined( FBLBM_ENABLE_STANDALONE_MODE ) +# if defined( FBL_ENABLE_ASSERTION ) +/*********************************************************************************************************************** + * ApplFblFatalError + **********************************************************************************************************************/ +/*! \brief Will be called in case of an urecoverable error + **********************************************************************************************************************/ +void ApplFblFatalError( FBL_DECL_ASSERT_EXTENDED_INFO(vuint8 errorCode) ) +{ + /* Change this variable in debugger in order to return to caller */ + volatile vuint8 stayInWhile = 1u; + +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)errorCode; +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + while (0u != stayInWhile) + { + FblLookForWatchdogVoid(); + } +} +# endif /* FBL_ENABLE_ASSERTION */ + +# if (DET_ENABLED == STD_ON) +/*********************************************************************************************************************** + * ApplFbl_DetEntryHandler + **********************************************************************************************************************/ +/*! \brief Called by DET module to check if a DET error is intended bootloader behavior or not. + * \param[in] ModuleId Code number of the encountered assertion + * \param[in] InstanceId Name of the affected module (Only if extended info is enabled) + * \param[in] ApiId Line number where the assertion occurred (Only if extended info is enabled) + * \param[in] ErrorId Line number where the assertion occurred (Only if extended info is enabled) + * \return Report if error should be handed over to DET or not + **********************************************************************************************************************/ +# if ((DET_AR_RELEASE_MAJOR_VERSION >= 4u) && (DET_AR_RELEASE_MINOR_VERSION >= 3u)) +FUNC(Std_ReturnType, DET_CODE) ApplFbl_DetEntryHandler( uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId ) +# else +FUNC(boolean, DET_APPL_CODE) ApplFbl_DetEntryHandler( uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId ) +# endif /* DET_AR_RELEASE_ */ +{ +# if ((DET_AR_RELEASE_MAJOR_VERSION >= 4u) && (DET_AR_RELEASE_MINOR_VERSION >= 3u)) + Std_ReturnType result = E_OK; + /* Use result value of E_NOT_OK to ignore the DET */ +# else + boolean result = FALSE; + /* Use result value of TRUE to ignore the DET */ +# endif /* DET_AR_RELEASE_ */ + +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)ModuleId; + (void)InstanceId; + (void)ApiId; + (void)ErrorId; +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + return result; +} +# endif /* DET_ENABLED == STD_ON */ + +# if defined( FBL_MIO_ENABLE_HOOKS ) +/*********************************************************************************************************************** + * ApplFblPreMemDriver + **********************************************************************************************************************/ +/*! \brief Function is called before the memory driver is executed. + * \param[in] device Memory device, which is going to be used. + * \param[in] function Function of the memory device, which is going to be called. + **********************************************************************************************************************/ +void ApplFblPreMemDriver( vuint8 device, vuint8 function ) +{ + uint8 opMode; + Std_ReturnType retVal; + +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)device; + (void)function; +# endif + /* TODO_CUSTOMER: Adapt this example implementation to project-specific needs/requirements */ + /* Suspend vHSM operations in data flash */ + opMode = CRYPTO_30_VHSM_DATAFLASH_START; + retVal = Csm_KeyElementSet(CsmConf_CsmKey_CsmKey_vHsm_Hardware, CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION, &opMode, 1u); + /* Suspend vHSM operations in code flash -> send it to RAM loop */ + opMode = CRYPTO_30_VHSM_CODEFLASH_START; + retVal |= Csm_KeyElementSet(CsmConf_CsmKey_CsmKey_vHsm_Hardware, CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION, &opMode, 1u); + + /* Simulate DET functionality in case of any error */ + assertFblUser(retVal == E_OK, kFblSysAssertDet); +} + +/*********************************************************************************************************************** + * ApplFblPostMemDriver + **********************************************************************************************************************/ +/*! \brief Function is called after the memory driver has finished the operation. + * \param[in] device Memory device, which is going to be used. + * \param[in] function Function of the memory device, which is going to be called. + **********************************************************************************************************************/ +void ApplFblPostMemDriver( vuint8 device, vuint8 function ) +{ + uint8 opMode; + Std_ReturnType retVal; +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)device; + (void)function; +# endif + /* TODO_CUSTOMER: Adapt this example implementation to project-specific needs/requirements */ + /* Get vHSM back from RAM loop */ + opMode = CRYPTO_30_VHSM_CODEFLASH_STOP; + retVal = Csm_KeyElementSet(CsmConf_CsmKey_CsmKey_vHsm_Hardware, CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION, &opMode, 1u); + /* Give vHSM access to data flash operations */ + opMode = CRYPTO_30_VHSM_DATAFLASH_STOP; + retVal |= Csm_KeyElementSet(CsmConf_CsmKey_CsmKey_vHsm_Hardware, CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION, &opMode, 1u); + + /* Simulate DET functionality in case of any error */ + assertFblUser(retVal == E_OK, kFblSysAssertDet); +} +# endif /* FBL_MIO_ENABLE_HOOKS */ +#endif /* FBLBM_ENABLE_STANDALONE_MODE */ + +#define FBLBMAP_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_FblBmAp_0305: + Reason: Boot manager needs to jump to a memory location to start a target/software. + Risk: Unintended jump to wrong memory location. + Prevention: No prevention possible, address is defined by the corresponding target. + + MD_FblBmAp_0306: + Reason: Address conversion between integer values and pointers is required to allow for hardware independent + configuration and address range checks. + Risk: The size of integer required to hold the result of a pointer cast is implementation-defined. + Prevention: The size of the respective integer data type which holds the address value is adapted on a hardware + specific basis. The correctness of the respective implementation is verified by runtime tests. + + MD_FblBmAp_2741_4558: + Reason: Assertion macros have to be disabled in production code and are used only for development. + Risk: Assertion code may be enabled in production code unintentionally. If a assertion condition is unexpectedly + false, the code is active. A problem may occur if the Macro is additionally changed from single statement + to multiple statement. + Prevention: Macro is not allowed to be changed without review. Development code is automatically disabled via + configuration of project state "Production". + +*/ + +/*********************************************************************************************************************** + * END OF FILE: BM_AP.C + **********************************************************************************************************************/ diff --git a/Source/appl/fbl_secboot_ap.c b/Source/appl/fbl_secboot_ap.c new file mode 100644 index 0000000..fe6f688 --- /dev/null +++ b/Source/appl/fbl_secboot_ap.c @@ -0,0 +1,232 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief SecureBoot implementation callback file + * + * \note Please note, that this file contains a collection of callback functions to be used with the + * Flash Bootloader. These functions may influence the behavior of the bootloader in principle. + * Therefore, great care must be taken to verify the correctness of the implementation. + * The contents of the originally delivered files are only examples resp. implementation proposals. + * With regard to the fact that these functions are meant for demonstration purposes only, Vector + * Informatik's liability shall be expressly excluded in cases of ordinary negligence, to the extent + * admissible by law or statute. + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2020-01-07 visrie FBL-524 Initial release + * 01.00.01 2020-04-27 visrie FBL-1773 No changes + * 02.00.00 2020-05-19 vistbe FBL-1016 No changes + * 02.01.00 2021-01-19 visrie FBL-2648 No changes + * FBL-2641 No changes + * 02.02.00 2021-09-03 visjdn FBL-3352 Support different default locations of the signature + * 02.03.00 2023-06-21 vistbe FBL-4814 Add support for OTA + * 02.03.01 2024-05-16 viswmo ESCAN00117059 No changes + * 02.04.00 2024-11-18 vismix FBL-9654 No changes + * 02.05.00 2025-01-30 vikatya PIO-1340 SecureBoot for selected blocks + * 02.06.00 2025-02-19 visrie FBL-10209 No changes + **********************************************************************************************************************/ + +#define FBL_SECBOOT_AP_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" +#include "bm_main.h" +#include "Csm.h" +#include "fbl_secboot_ap.h" + + /*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#define FBLSB_INITIAL_STARTUP_SET_VALUE 0xA5u + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ +#define FBLSB_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * ApplFblSbStartup + **********************************************************************************************************************/ +/*! \brief Secure boot initialization callback + * \details This function is called during Bootloader initialization to set up secure boot + **********************************************************************************************************************/ +void ApplFblSbStartup( void ) +{ +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) +# if defined( FBLBM_INSTANCE_BOOTLOADER ) + if (FblBmChkInitCmacMagicFlag()) + { + /* Clear the flag */ + FblBmClrMagicFlag(); + + /* Update the SecureBootSegments by using SecureBoot-ForceSequential */ + assertFbl(FblSb_UpdateInitialSegments() == kFblOk, 0u); + + /* Clear the initial startup flag */ + ApplFblSbClrInitialStartup(); + + /* Perform reset to enable secure boot on next startup */ + ApplFblReset(); + } +# endif /* FBLBM_INSTANCE_BOOTLOADER */ +#endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ +} + +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) +# if defined( FBLBM_INSTANCE_BOOTMANAGER ) +/*********************************************************************************************************************** + * ApplFblSbIsInitialStartup + **********************************************************************************************************************/ +/*! \brief Checks if this is an initial (first) startup of the ECU + * \return kFblOk if this is the first startup, otherwise kFblFailed + **********************************************************************************************************************/ +tFblResult ApplFblSbIsInitialStartup(void) +{ + tFblResult result = kFblFailed; + uint8 writeOnceKeyValue = 0u; + uint32 writeOnceKeyLength = 1u; + + /* Reads a write once key from the vHsm */ + if (Csm_KeyElementGet(FblSb_GetCsmKeyOfInitialStartup(), 1u, &writeOnceKeyValue, &writeOnceKeyLength) == E_OK) + { + /* Check if the key was already written */ + if (writeOnceKeyValue != FBLSB_INITIAL_STARTUP_SET_VALUE) + { + result = kFblOk; + } + } + + return result; +} +#endif /* FBLBM_INSTANCE_BOOTMANAGER */ + +/*********************************************************************************************************************** + * ApplFblSbClrInitialStartup + **********************************************************************************************************************/ +/*! \brief Clears the initial startup condition flag + **********************************************************************************************************************/ +void ApplFblSbClrInitialStartup(void) +{ + tFblResult result = kFblFailed; + uint8 writeOnceKeyValue = FBLSB_INITIAL_STARTUP_SET_VALUE; + uint32 writeOnceKeyLength = 1u; + + /* Reads a write once key from the vHsm */ + if (Csm_KeyElementSet(FblSb_GetCsmKeyOfInitialStartup(), 1u, &writeOnceKeyValue, writeOnceKeyLength) == E_OK) + { + if (Csm_KeySetValid(FblSb_GetCsmKeyOfInitialStartup()) == E_OK) + { + result = kFblOk; + } + } + + /* Writing of the key was not successful, which should not happen */ + assertFblUser((result == kFblOk), 1u); +} +#endif + +/*********************************************************************************************************************** + * ApplFblSbGetSignatureInfo + **********************************************************************************************************************/ +/*! \brief Gets the information of the signature + * \param[in] bmHdrHeader Pointer to the FblBmHdrHeader structure + * \param[in] macId ID of MacOperation + * \param[out] signatureAddress Address of the signature + * \param[out] signatureLength Length of the signature + **********************************************************************************************************************/ +tFblResult ApplFblSbGetSignatureInfo(const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHdrHeader, vuint32 macId, + V_MEMRAM1 vuint32 V_MEMRAM2 V_MEMRAM3 * signatureAddress, + V_MEMRAM1 vuint32 V_MEMRAM2 V_MEMRAM3 * signatureLength) +{ + tFblResult result = kFblOk; + + /* Check if mac operation is configured. */ + if (macId != FBLBMHDR_MAC_OP_REF_NOT_USED) + { + *signatureLength = FblSb_GetSignatureLengthOfMacOperation(macId); + + switch (FblSb_GetSignaturePositionOfMacOperation(macId)) + { + case FBLSB_SIGPOSITION_FRONT_SEGMENT_LIST: + { + *signatureAddress = bmHdrHeader->bmAuthenticationHeaderAddress - FblSb_GetSignatureLengthOfMacOperation(macId); + break; + } + case FBLSB_SIGPOSITION_START_LOGICAL_BLOCK: + { + *signatureAddress = bmHdrHeader->bmBlockStartAddress; + break; + } + case FBLSB_SIGPOSITION_END_LOGICAL_BLOCK: + { + *signatureAddress = bmHdrHeader->bmBlockStartAddress + bmHdrHeader->bmBlockLength - FblSb_GetSignatureLengthOfMacOperation(macId); + break; + } + case FBLSB_SIGPOSITION_END_SEGMENT_LIST: + { + /* This function should not be called for this signature position as vHsm handles this internally + --> This can be considered an error */ + result = kFblFailed; + break; + } + default: + { + /* TODO_CUSTOMER: A user specific signature position can be implemented here. */ + result = kFblFailed; + break; + } + } + } + + return result; +} + +#define FBLSB_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * MISRA + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_SECBOOT_AP.C + **********************************************************************************************************************/ diff --git a/Source/bsw/Common/Can_GeneralTypes.h b/Source/bsw/Common/Can_GeneralTypes.h new file mode 100644 index 0000000..ff410f4 --- /dev/null +++ b/Source/bsw/Common/Can_GeneralTypes.h @@ -0,0 +1,80 @@ +/******************************************************************************************************************** +| File Name: Can_GeneralTypes.H +| +| Description: Type definitions of the AUTOSAR CAN components Can, CanIf, CanTrcv +|-------------------------------------------------------------------------------------------------------------------- +| C O P Y R I G H T +|-------------------------------------------------------------------------------------------------------------------- +| Copyright (c) 1996-2012 by Vector Informatik GmbH. All rights reserved. +| +| This software is copyright protected and proprietary +| to Vector Informatik GmbH. Vector Informatik GmbH +| grants to you only those rights as set out in the +| license conditions. All other rights remain with +| Vector Informatik GmbH. +| +|-------------------------------------------------------------------------------------------------------------------- +| A U T H O R I D E N T I T Y +|-------------------------------------------------------------------------------------------------------------------- +| Initials Name Company +| -------- --------------------- ------------------------------------- +| visbir Holger Birke Vector Informatik GmbH +|-------------------------------------------------------------------------------------------------------------------- +| R E V I S I O N H I S T O R Y +|-------------------------------------------------------------------------------------------------------------------- +| Date Version Author Description +| ---------- -------- ------ ------------------------------------------------------------------------------------- +| 2012-05-31 1.00.00 visbir - Add Can types +| 2012-07-27 1.00.01 visbir - Add Trcv switch for include +| 2013-02-20 1.01.00 visbir - ESCAN00061193: Use static Trcv types +|*******************************************************************************************************************/ +#ifndef CAN_GENERAL_TYPES +#define CAN_GENERAL_TYPES + +/* Version of Can_GeneralTypes header */ +#define CAN_GENERAL_TYPES_MAJOR_VERSION 0x01 +#define CAN_GENERAL_TYPES_MINOR_VERSION 0x01 +#define CAN_GENERAL_TYPES_PATCH_VERSION 0x00 + +#include "ComStack_Types.h" + +/* CAN Transceiver Driver also available as generated file "CanTrcv_GeneralTypes.h" */ +/* !!! please remove this types when you use no Vector CAN Transceiver Driver */ +typedef enum CanTrcv_TrcvModeTypeTag +{ + CANTRCV_TRCVMODE_NORMAL = 0u, + CANTRCV_TRCVMODE_SLEEP, + CANTRCV_TRCVMODE_STANDBY +} CanTrcv_TrcvModeType; + +typedef enum CanTrcv_TrcvWakeupModeTypeTag +{ + CANTRCV_WUMODE_ENABLE = 0u, + CANTRCV_WUMODE_CLEAR, + CANTRCV_WUMODE_DISABLE +} CanTrcv_TrcvWakeupModeType; + +typedef enum CanTrcv_TrcvWakeupReasonTypeTag +{ + CANTRCV_WU_ERROR = 0u, + CANTRCV_WU_BY_BUS, + CANTRCV_WU_BY_PIN, + CANTRCV_WU_INTERNALLY, + CANTRCV_WU_NOT_SUPPORTED, + CANTRCV_WU_POWER_ON, + CANTRCV_WU_RESET, + CANTRCV_WU_BY_SYSERR +} CanTrcv_TrcvWakeupReasonType; +/* CAN Transceiver Driver end */ + + +/* CAN Driver generated File */ +#include "Can_DrvGeneralTypes.h" + + +/* CAN Interface generated File */ +#include "CanIf_GeneralTypes.h" + + + +#endif /* CAN_GENERAL_TYPES */ diff --git a/Source/bsw/Common/ComStack_Types.h b/Source/bsw/Common/ComStack_Types.h new file mode 100644 index 0000000..bc7a50e --- /dev/null +++ b/Source/bsw/Common/ComStack_Types.h @@ -0,0 +1,284 @@ +/*********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------ + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** + * File: ComStack_Types.h + * Component: - + * Module: - + * Generator: - + * + * Description: Provision of Comunication Stack Types + * + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2007-08-01 Jk Initial creation + * 03.00.00 2007-09-14 Jk Addaption for AUTOSAR 3.0 / NetworkHandleType added + * 03.00.01 2007-11-20 Jk Version defines for CFG management added + * 03.01.00 2008-03-18 Jk Version defines changed to specification version + * 03.01.01 2008-04-18 Ms ESCAN00026158 Support more than 255 Pdus per component + * Ms ESCAN00026165 COMSTACKTYPE_VENDOR_ID + * Ms ESCAN00028208 Remove non ISO-5.2.1 Characters + * 03.02.00 2008-07-16 Jk BUSTRCV_E_OK added (specification inconsistency ComStackTypes <-> + * FrTrcv) + * 03.02.01 2008-10-30 Lo Fixed COMSTACKTYPE_AR_MAJOR_VERSION + * 03.02.02 2009-06-15 Ht ESCAN00035189 Compiler Error due to storage qualifier used in struct definition + * 03.03.00 2010-03-23 Ht ESCAN00041756 support TPParameterType + * 03.03.01 2010-05-11 Ht ESCAN00042906 correct version defines COMMONASR__COMMON_IMPL_COMSTACKTYPES.. + * 03.04.00 2011-03-04 Ht support ASR 4.0R1 + * 03.04.01 2011-02-28 visht ESCAN00049578 incorrect BSW version scan information + * 03.04.02 2011-04-15 visht support TP_NORETRY for TpDataStateType (used in CANTP and PDURouter) + * 04.00.00 2012-07-19 visht ESCAN00058421 support ASR 4.0 R3 (support TPParameterType as enum, include generated + * ComStack_Cfg.h) + * 04.00.01 2012-08-31 visht version define corrected - replace PATCH by REVISION - + * (COMSTACKTYPE_AR_RELEASE_REVISION_VERSION, + * COMSTACKTYPE_AR_RELEASE_REVISION_VERSION) + * 2012-10-23 visseu Add COMSTACKTYPE_MODULE_ID as specified in + * "AUTOSAR_TR_BSWModuleList.pdf" (R4.0 Rev 3) + * 04.00.02 2013-01-10 visseu MISRA deviation comments added + * 04.00.03 2013-05-29 visseu ESCAN00067745 Add general defines with prefix: COMTYPE + * 04.01.00 2019-07-25 visdfe MSR4-28981 Change PNCHandleType to uint16 + * 04.02.00 2023-04-12 visbwa HALBE-7488 Removed outdated fragments of ASR3.x/ASR4.0.1 and file filtering, + * fixed copyright header, removed author identity, codestyle review + * 05.00.00 2023-11-30 virmfr OSHAL-723 Support PduInfoType with MetaData + * 2024-01-29 virrlu OSHAL-800 Rework return codes for NotifResultType + * 05.01.00 2024-04-17 visdep OSHAL-1410 Introduce ComStack Type definitions related to time stamping (AR23-11) + * 2024-05-27 virjas OSHAL-1410 Enter correct ASR version defines for 4.0 R3 + * 05.02.00 2024-10-22 visdep OSHAL-2156 Added #define TIME_STAMP_TYPE to indicate the availability of TimeStampType. + * 2024-11-05 virjas OSHAL-1715 Fix Misra warnings with BusTrcvErrorType defines. + * 05.03.00 2025-05-06 virjas OSHAL-2921 Add ListElemStructType to support R23-11 and R24-11. + * 05.03.01 2025-05-09 virjas OSHAL-3046 Fix definition of ListElemStructType. + * 05.03.02 2025-05-13 virjas OSHAL-3057 Fix definition of ListElemStructType. + **********************************************************************************************************************/ + +#ifndef COMSTACK_TYPES_H +# define COMSTACK_TYPES_H + +/* PRQA S 3453 COMSTACK_TYPES_3453_TAG */ /* MD_MSR_19.7 */ +/* PRQA S 0850 COMSTACK_TYPES_0850_TAG */ /* MD_MSR_19.8 */ + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ +# include "Std_Types.h" + +# include "ComStack_Cfg.h" + +/*********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + **********************************************************************************************************************/ +/* ##V_CFG_MANAGEMENT ##CQProject : CommonAsr__Common CQComponent : Impl_ComStackTypes */ +# define COMMONASR__COMMON_IMPL_COMSTACKTYPES_VERSION 0x0503 +# define COMMONASR__COMMON_IMPL_COMSTACKTYPES_RELEASE_VERSION 0x02 + +/* AUTOSAR Software Specification Version Information */ +/* AUTOSAR Classic Platform Release R24-11 */ +# define COMSTACKTYPE_AR_RELEASE_MAJOR_VERSION (4u) +# define COMSTACKTYPE_AR_RELEASE_MINOR_VERSION (10u) +# define COMSTACKTYPE_AR_RELEASE_REVISION_VERSION (0u) + +# if defined COMSTACKTYPE_AR_RELEASE_REVISION_VERSION +# define COMSTACKTYPE_AR_RELEASE_PATCH_VERSION COMSTACKTYPE_AR_RELEASE_REVISION_VERSION +/* ESCAN00067745 */ +# define COMTYPE_AR_RELEASE_MAJOR_VERSION COMSTACKTYPE_AR_RELEASE_MAJOR_VERSION +# define COMTYPE_AR_RELEASE_MINOR_VERSION COMSTACKTYPE_AR_RELEASE_MINOR_VERSION +# define COMTYPE_AR_RELEASE_REVISION_VERSION COMSTACKTYPE_AR_RELEASE_REVISION_VERSION +# define COMTYPE_AR_RELEASE_PATCH_VERSION COMSTACKTYPE_AR_RELEASE_REVISION_VERSION +# endif + +/* Component Version Information */ +# define COMSTACKTYPE_SW_MAJOR_VERSION (5u) +# define COMSTACKTYPE_SW_MINOR_VERSION (3u) +# define COMSTACKTYPE_SW_PATCH_VERSION (2u) + +/* ESCAN00067745 */ +# define COMTYPE_SW_MAJOR_VERSION COMSTACKTYPE_SW_MAJOR_VERSION +# define COMTYPE_SW_MINOR_VERSION COMSTACKTYPE_SW_MINOR_VERSION +# define COMTYPE_SW_PATCH_VERSION COMSTACKTYPE_SW_PATCH_VERSION + +# define COMSTACKTYPE_VENDOR_ID (30u) /* SREQ00015385, SREQ00015364, SREQ00015372 */ +# define COMSTACKTYPE_MODULE_ID (196u) /* SREQ00015385, SREQ00015364, SREQ00015372 */ + +/* ESCAN00067745 */ +# define COMTYPE_VENDOR_ID COMSTACKTYPE_VENDOR_ID +# define COMTYPE_MODULE_ID COMSTACKTYPE_MODULE_ID + +/*General return codes for NotifResultType*/ + +# define NTFRSLT_OK 0x00u /* Action has been successfully finished: + - message sent out (in case of confirmation), + - message received (in case of indication) */ +# define NTFRSLT_E_NOT_OK 0x01u /* Error notification: + - message not successfully sent out (in case of confirmation), + - message not successfully received (in case of indication) */ +# define NTFRSLT_E_TIMEOUT_A 0x02u /* Error notification: + - timer N_Ar/N_As (according to ISO specification [ISONM]) has passed its time-out value N_Asmax/N_Armax. + This value can be issued to service user on both the sender and receiver side. */ +# define NTFRSLT_E_TIMEOUT_BS 0x03u /* Error notification: + - timer N_Bs has passed its time-out value N_Bsmax (according to ISO specification [ISONM]). + This value can be issued to the service user on the sender side only. */ +# define NTFRSLT_E_TIMEOUT_CR 0x04u /* Error notification: + - timer N_Cr has passed its time-out value N_Crmax. + This value can be issued to the service user on the receiver side only. */ +# define NTFRSLT_E_WRONG_SN 0x05u /* Error notification: + - unexpected sequence number (PCI.SN) value received. + This value can be issued to the service user on the receiver side only. */ +# define NTFRSLT_E_INVALID_FS 0x06u /* Error notification: + - invalid or unknown FlowStatus value has been received in a flow control (FC) N_PDU. + This value can be issued to the service user on the sender side only. */ +# define NTFRSLT_E_UNEXP_PDU 0x07u /* Error notification: + - unexpected protocol data unit received. + This value can be issued to the service user on both the sender and receiver side. */ +# define NTFRSLT_E_WFT_OVRN 0x08u /* Error notification: + - flow control WAIT frame that exceeds the maximum counter N_WFTmax received. + This value can be issued to the service user on the receiver side. */ +# define NTFRSLT_E_ABORT 0x09u /* Error notification: + - Flow control (FC) N_PDU with FlowStatus = ABORT received. + It indicates an abort of a transmission. A possible reason for this is that the receiver is currently busy and + can not take the request at that point in time. */ +# define NTFRSLT_E_NO_BUFFER 0x0Au /* Error notification: + - flow control (FC) N_PDU with FlowStatus = OVFLW received. + It indicates that the buffer on the receiver side of a segmented message transmission + cannot store the number of bytes specified by the FirstFrame DataLength (FF_DL) parameter + in the FirstFrame and therefore the transmission of the 19 of 23 AUTOSAR_SWS_ComStackTypes + segmented message was aborted. + - no buffer within the TP available to transmit the segmented I-PDU. + This value can be issued to the service user on both the sender and receiver side. */ +# define NTFRSLT_E_CANCELATION_OK 0x0Bu /* Action has been successfully finished: + - Requested cancellation has been executed. */ +# define NTFRSLT_E_CANCELATION_NOT_OK 0x0Cu /* Error notification: + - Due to an internal error the requested cancelation has not been executed. This will happen e.g., if the to be canceled transmission has been executed already. */ + +/* extension since R4.0 R1 */ +# define NTFRSLT_PARAMETER_OK 0x0Du /* The parameter change request has been successfully executed */ +# define NTFRSLT_E_PARAMETER_NOT_OK 0x0Eu /* The request for the change of the parameter did not complete successfully */ +# define NTFRSLT_E_RX_ON 0x0Fu /* The parameter change request not executed successfully due to an ongoing reception */ +# define NTFRSLT_E_VALUE_NOT_OK 0x10u /* The parameter change request not executed successfully due to a wrong value */ + +/* 0x11-0x1E Reserved values for future usage. */ + +/* General return codes for BusTrcvErrorType */ +# define BUSTRCV_OK 0x00u +/* BUSTRCV_E_OK needed by FrTrcv specification inconcistency between ComStackTypes and FrTrcv */ +# define BUSTRCV_E_OK 0x00u +# define BUSTRCV_E_ERROR 0x01u + +/* PduInfoType MetaData handling */ +#define PDUINFOTYPE_INIT {NULL_PTR, NULL_PTR, 0} +#define PDUINFOTYPE_VERSION 43 + +/*********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + **********************************************************************************************************************/ +typedef P2VAR(uint8, TYPEDEF, AUTOSAR_COMSTACKDATA) SduDataPtrType; +typedef P2VAR(uint8, TYPEDEF, AUTOSAR_COMSTACKDATA) MetaDataPtrType; +typedef struct +{ + SduDataPtrType SduDataPtr; + MetaDataPtrType MetaDataPtr; + PduLengthType SduLength; +} PduInfoType; + +typedef enum +{ + BUFREQ_OK = 0u, /* Buffer request accomplished successful. */ + BUFREQ_E_NOT_OK = 1u, /* Buffer request not successful. Buffer cannot be accessed. */ + BUFREQ_E_BUSY = 2u, /* Temporarily no buffer available. It's up the requestor to retry request for a certain time. */ + BUFREQ_E_OVFL = 3u /* No Buffer of the required length can be provided. */ +} BufReq_ReturnType; + +typedef uint8 NotifResultType; + +typedef uint8 BusTrcvErrorType; + +typedef uint8 NetworkHandleType; + +typedef uint16 PNCHandleType; /* Neccessary for partial network. Deviation from SWS_COMTYPE_00036 for ASR Version <= 4.4.0 */ + +typedef enum +{ + TP_DATACONF = 0u, /* TP_DATACONF indicates that all data, that have been copied so far, are confirmed and can be + removed from the TP buffer. Data copied by this API call are excluded and will be confirmed later. */ + TP_DATARETRY = 1u, /* TP_DATARETRY indicates that this API call shall copy already copied data in order to recover from + an error. In this case TxTpDataCnt specifies the offset of the first byte to be copied by the API call. */ + TP_CONFPENDING = 2u +} TpDataStateType; + +typedef struct +{ + TpDataStateType TpDataState; /* The enum type to be used to store the state of Tp buffer. */ + PduLengthType TxTpDataCnt; /* Offset from the current position which identifies the number of bytes to be retransmitted. */ +} RetryInfoType; + +typedef enum +{ + TP_STMIN = 0u, /* Separation Time */ + TP_BS = 1u, /* Block Size */ + TP_BC = 2u /* The Band width control parameter used in FlexRay transport protocol module. */ +} TPParameterType; + +typedef struct +{ + uint32 nanoseconds; /* Nanoseconds part of the time */ + uint32 seconds; /* 32 bit LSB of the 48 bits Seconds part of the time */ + uint16 secondsHi; /* 16 bit MSB of the 48 bits Seconds part of the time */ +} TimeStampType; /* ASR CP R23-11 */ + +/* Define TIME_STAMP_TYPE to indicate that TimeStampType is available. */ +# define TIME_STAMP_TYPE + +typedef enum +{ + VALID = 0u, /* Timestamp is valid */ + INVALID = 1u, /* Timestamp is invalid */ + UNCERTAIN = 2u /* Status of timestamp is uncertain */ +} TimeStampQualType; /* ASR CP R23-11 */ + +typedef struct +{ + TimeStampType timestampClockValue; /* Value of the clock, which is used of ingress/egress timestamping */ + TimeStampType disciplinedClockValue; /* Value of the adjustable HW clock */ + TimeStampQualType timeQuality; /* Status of time tuple */ +} TimeTupleType; /* ASR CP R23-11 */ + +typedef struct ListElemStructType +{ + uint16 DataLength; /* Represents length of data */ + uint8* DataPtr; /* Represents pointer to data */ + struct ListElemStructType* NextListElemPtr; /* Pointer to next list element */ +} ListElemStructType; /* ASR CP R23-11 */ + +/*********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +/* PRQA L:COMSTACK_TYPES_3453_TAG */ +/* PRQA L:COMSTACK_TYPES_0850_TAG */ + +#endif /* COMSTACK_TYPES_H */ + +/*********************************************************************************************************************** + * END OF FILE: ComStack_Types.h + **********************************************************************************************************************/ diff --git a/Source/bsw/Common/Compiler.h b/Source/bsw/Common/Compiler.h new file mode 100644 index 0000000..59e1540 --- /dev/null +++ b/Source/bsw/Common/Compiler.h @@ -0,0 +1,191 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------- + * File: Compiler.h + * Component: - + * Module: - + * Generator: - + * + * Description: This file provides the AUTOSAR compiler abstraction for the Texas Instruments LLVM compiler + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2021-09-29 vishci HALBE-5003 Created initial version. + * 01.01.00 2023-07-18 virrlu HALBE-10062 Update to AUTOSAR Release 21-11 + * 01.01.01 2024-02-01 virmid OSHAL-990 Updated copyright year. + **********************************************************************************************************************/ + +#ifndef COMPILER_H +#define COMPILER_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Compiler_Cfg.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ +/* ##V_CFG_MANAGEMENT ##CQProject : CommonAsr_Arm32 CQComponent : Impl_CompAbstract_LlvmTexasInstruments */ +#define COMMONASR_ARM32_IMPL_COMPABSTRACT_VERSION 0x0101 +#define COMMONASR_ARM32_IMPL_COMPABSTRACT_RELEASE_VERSION 0x00 + +#define COMPILER_VENDOR_ID 30u /* Vendor ID of Vector */ +#define COMPILER_MODULE_ID 198u /* 198 is the ID of compiler abstraction */ + +/* AUTOSAR Software Specification Release Version Information */ +/* AUTOSAR Release 21-11 */ +#define COMPILER_AR_RELEASE_MAJOR_VERSION (4u) +#define COMPILER_AR_RELEASE_MINOR_VERSION (7u) +#define COMPILER_AR_RELEASE_REVISION_VERSION (0u) + +/* Component Version Information */ +#define COMPILER_SW_MAJOR_VERSION (1u) +#define COMPILER_SW_MINOR_VERSION (1u) +#define COMPILER_SW_PATCH_VERSION (1u) + +#define _TEXASINSTRUMENTS_LLVM_C_ARM32_ + +/* AUTOMATIC used for the declaration of local pointers */ +#define AUTOMATIC + +/* TYPEDEF shall be used within type definitions, where no memory qualifier can be specified.*/ +#define TYPEDEF + +/* NULL_PTR define with a void pointer to zero definition*/ +#ifndef NULL_PTR +# define NULL_PTR ((void *)0) +#endif + +/* INLINE define for abstraction of the keyword inline*/ +#ifndef INLINE +# define INLINE __inline__ +#endif + +/* LOCAL_INLINE define for abstraction of the keyword inline in functions with "static" scope. + Different compilers may require a different sequence of the keywords "static" and "inline" + if this is supported at all. */ +#ifndef LOCAL_INLINE +# define LOCAL_INLINE static __inline__ +#endif + +/* FUNC macro for the declaration and definition of functions, that ensures correct syntax of function declarations + rettype return type of the function + memclass classification of the function itself*/ +#define FUNC(rettype, memclass) rettype /* PRQA S 3410 */ /* MD_Compiler_19.10 */ + +/* FUNC_P2CONST macro for declaration and definition of functions returning a pointer to a constant, that ensures + correct syntax of function declarations. + rettype return type of the function + ptrclass defines the classification of the pointer�s distance + memclass classification of the function itself*/ +#define FUNC_P2CONST(rettype, ptrclass, memclass) const rettype* /* PRQA S 3410 */ /* MD_Compiler_19.10 */ + +/* FUNC_P2VAR macro for the declaration and definition of functions returning a pointer to a variable, that ensures + correct syntax of function declarations + rettype return type of the function + ptrclass defines the classification of the pointer�s distance + memclass classification of the function itself*/ +#define FUNC_P2VAR(rettype, ptrclass, memclass) rettype* /* PRQA S 3410 */ /* MD_Compiler_19.10 */ + +/* P2VAR macro for the declaration and definition of pointers in RAM, pointing to variables + ptrtype type of the referenced variable memory class + memclass classification of the pointer variable itself + ptrclass defines the classification of the pointer�s distance + */ +#define P2VAR(ptrtype, memclass, ptrclass) ptrtype* /* PRQA S 3410 */ /* MD_Compiler_19.10 */ + +/* P2CONST macro for the declaration and definition of pointers in RAM pointing to constants + ptrtype type of the referenced data + memclass classification of the pointer variable itself + ptrclass defines the classification of the pointer distance + */ +#define P2CONST(ptrtype, memclass, ptrclass) const ptrtype* /* PRQA S 3410 */ /* MD_Compiler_19.10 */ + +/* CONSTP2VAR macro for the declaration and definition of constant pointers accessing variables + ptrtype type of the referenced data + memclass classification of the pointer variable itself + ptrclass defines the classification of the pointer distance + */ +#define CONSTP2VAR(ptrtype, memclass, ptrclass) ptrtype* const /* PRQA S 3410 */ /* MD_Compiler_19.10 */ + +/* CONSTP2CONST macro for the declaration and definition of constant pointers accessing constants + ptrtype type of the referenced data + memclass classification of the pointer variable itself + ptrclass defines the classification of the pointer distance + */ +#define CONSTP2CONST(ptrtype, memclass, ptrclass) const ptrtype* const /* PRQA S 3410 */ /* MD_Compiler_19.10 */ + +/* P2FUNC macro for the type definition of pointers to functions + rettype return type of the function + ptrclass defines the classification of the pointer distance + fctname function name respectively name of the defined type + */ +#define P2FUNC(rettype, ptrclass, fctname) rettype (* fctname) /* PRQA S 3410 */ /* MD_Compiler_19.10 */ + +/* CONSTP2FUNC macro for the type definition of pointers to functions + rettype return type of the function + ptrclass defines the classification of the pointer distance + fctname function name respectively name of the defined type + Example (PowerPC): #define CONSTP2FUNC(rettype, ptrclass, fctname) rettype (* const fctname) + Example (IAR, R32C): #define CONSTP2FUNC(rettype, ptrclass, fctname) rettype (ptrclass * const fctname) + */ +#define CONSTP2FUNC(rettype, ptrclass, fctname) rettype (* const fctname) /* PRQA S 3410 */ /* MD_Compiler_19.10 */ + +/* CONST macro for the declaration and definition of constants + type type of the constant + memclass classification of the constant itself + */ +#define CONST(type, memclass) const type /* PRQA S 3410 */ /* MD_Compiler_19.10 */ + +/* VAR macro for the declaration and definition of variables + vartype type of the variable + memclass classification of the variable itself + */ +#define VAR(vartype, memclass) vartype /* PRQA S 3410 */ /* MD_Compiler_19.10 */ + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/****************************************************************************/ +/* MISRA deviations */ +/****************************************************************************/ +/* Justification for module-specific MISRA deviations: +MD_Compiler_19.10: + Reason: Macro used in structures, which depend on used compiler and which do not allow brackets e.g. declaration of functions and variables. + Risk: None atomic parameter lead to compile errors. + Prevention: Used parameter is always atomic. +*/ +#endif /* COMPILER_H */ + +/********************************************************************************************************************** + * END OF FILE: Compiler.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Common/Compiler_Cfg.h b/Source/bsw/Common/Compiler_Cfg.h new file mode 100644 index 0000000..0a30681 --- /dev/null +++ b/Source/bsw/Common/Compiler_Cfg.h @@ -0,0 +1,1014 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------- + * File: _Compiler_Cfg.h + * Component: - + * Module: - + * Generator: - + * + * Description: This File is a template for the Compiler_Cfg.h + * This file has to be extended with the memory and pointer classes for all BSW modules + * which where used. + * + * ------------------------------------------------------------------------------------------------------------------- + * MISRA VIOLATIONS + * ------------------------------------------------------------------------------------------------------------------- + * + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2007-08-01 Jk Initial creation + * 01.01.00 2007-12-14 Jk Component specific defines filtering added + * 01.01.01 2008-12-17 Ht Improve list of components (Tp_AsrTpCan,Tp_AsrTpFr,DrvMcu,DrvIcu added) + * 01.01.02 2009-04-27 Ht support OEM specific _compiler_cfg.inc file, improve list of components + * (Cp_XcpOnCanAsr, Il_AsrIpduM, If_VxFblDcm, If_VxFblVpm_Volvo_ab, DrvFls added) + * 01.01.03 2009-04-24 Msr Renamed J1939_AsrBase as TpJ1939_AsrBase + * 01.01.04 2009-06-03 Ht Improve list of components (Adc, Dio, Gpt, Pwm, Spi, Wdg, Fls, Port, Fim) + * 01.02.00 2009-08-01 Ht Improve list of components (Fee_30_Inst2, Can, ...Sub) + * Support filtering for RTE + * 01.02.01 2009-09-02 Lo add external Flash driver support + * 01.02.02 2009-09-21 Lo add DrvFls_Mcs12xFslftm01ExtVx + * Ht Improve list of components (CanTrcv_30_Tja1040dio, + * Eth, EthTrcv, EthIf, SoAd, TcpIp, EthSM) + * 01.03.00 2009-10-30 Ht support R8: change EthTrcv to EthTrcv_30_Canoeemu + * support EthTrcv_30_Dp83848 + * change CanTrcv_30_Xdio to CanTrcv_30___Your_Trcv__ + * change CanTrcv_30_Tja1040dio to CanTrcv_30_Tja1041 + * change name FrTrcv to FrTrcv_30_Tja1080dio + * Lo add Cp_AsrXcp + * Ht add Cp_XcpOnFrAsr + * 01.03.01 2010-01-13 Ht support SysService_AsrCal + * 01.03.02 2010-02-15 Ht support SysService_SswRcs_Daimler, SysService_Tls, Tp_Http, + * SysService_Dns, SysService_Json, DrvTrans_GenericLindioAsr + * Lo add Diag_AsrDem for all OEMs + * rename internal variables and filter methods + * 01.04.00 2010-03-04 Ht change name FrTrcv_30_Tja1080dio to FrTrcv_30_Tja1080 + * 01.04.01 2010-03-10 Ht support DrvTrans_GenericFrAsr, DrvTrans_As8223FrspiAsr, DrvEep and If_AsrIfEa + * 01.04.02 2010-04-07 Lo change IfFee to real components and add If_AsrIfWdV85xNec01Sub + * 01.04.03 2010-06-11 Ht add CanTrcv_30_Tja1043 + * Lo add Il_AsrIpduMEbBmwSub + * 01.04.04 2010-08-24 Ht add CanTrcv_30_Tle62512G, DrvEep_XAt25128EAsr, Tp_AsrTpFrEbBmwSub + * 01.05.00 2010-08-24 Ht support R10: + * change LinTrcv_30_Tle7259dio to LinTrcv_30_Tle7259 + * 01.05.01 2010-10-14 Ht add VStdLib, SysService_SswScc, SysService_IpBase, SysService_Crypto + * 01.05.02 2010-10-20 Ht support comments for Package Merge Tool + * 01.05.03 2010-11-03 Ht add SysService_E2eLibTttechSub, SysService_E2ePwTttechSub + * 01.05.04 2010-11-16 Ht add SysService_Exi, DrvTrans_Int6400EthAsr, Cdd_AsrCdd_Fiat, Diag_AsrDem_Fiat, + * 01.05.05 2010-12-17 Ht add SysService_AsrSchM, DrvEep_XXStubAsr, DrvIcu_Tms570Tinhet01ExtVx + * DrvWd_XTle4278gEAsr, DrvWd_XXStubAsr + * 01.05.06 2011-02-17 Ht add DrvEed, SysService_AsrBswM + * 01.05.07 2011-03-04 Ht add DrvTrans_Tja1055CandioAsr + * rename CanTrcv_30_Tja1040dio to CanTrcv_30_Tja1040 + * add SysService_XmlEngine + * 01.06.00 2011-03-04 Ht support ASR4.0 + * add Ccl_Asr4ComM, Ccl_Asr4SmCan, Nm_Asr4NmIf, Nm_AsrNmDirOsek + * 01.06.01 2011-04-15 Ht add Diag_AsrDcm_ + * 01.06.02 2011-06-17 Ht correct Diag_AsrDcm_ + * add Monitoring_AsrDlt and Monitoring_GenericMeasurement + * 01.06.03 2011-09-01 Ht add DrvTrans_Tja1145CanSpiAsr, DrvTrans_E52013CanspiAsr, DrvFls_XXStubAsr, + * If_AsrIfFeeV85xNec05Sub, If_AsrIfFeeV85xNec06Sub, If_AsrIfFeeV85xNec07Sub + * SysService_AsrWdMTttechSub and If_AsrIfWdTttechSub + * 01.06.04 2011-10-20 Ht ESCAN00054334: add If_AsrIfFeeTiSub + * ESCAN00054719: add Cdd_AsrCdd + * 01.06.05 2011-12-09 Ht add Tp_IpV4, Tp_IpV6 + * 01.06.06 2011-12-14 Ht add Monitoring_RuntimeMeasurement + * 01.06.07 2012-01-03 Ht add DrvI2c, SysService_Asr4BswM + * 01.06.08 2012-01-31 Ht add DrvTrans_Ar7000EthAsr, DrvTrans_GenericEthmiiAsr + * 01.06.09 2012-03-06 Ht add If_AsrIfFeeMb9df126Fuji01Sub, + * Infineon_Tc1767Inf01Sub, Infineon_Tc178xInf01Sub, Infineon_Tc1797Inf01Sub, Infineon_Tc1797Inf02Sub + * 01.06.10 2012-03-13 Ht add Gw_AsrPduRCfg5, Il_AsrComCfg5, Il_AsrIpduMCfg5, Cdd_AsrCddCfg5, + * Tp_Asr4TpCan, Diag_Asr4Dcm, Diag_Asr4Dem + * 01.06.11 2012-03-20 Ht add Cp_AsrCcp, Cp_XcpOnTcpIpAsr + * 01.07.00 2012-07-26 Ht add Nm_Asr4NmCan, Nm_Asr4NmFr, Infineon_Xc2000Inf01Sub, Ccl_Asr4ComMCfg5, SysService_Asr4BswMCfg5, SysService_Asr4EcuM, SysService_AsrRamTst, + * Ccl_Asr4SmLin + * add define REGSPACE - add support for ASR specification 4.0 R3 + * 01.07.01 2012-10-23 Seu add SysService_XmlSecurity + * 01.07.02 2013-12-16 Seu MISRA compliance: usage of character "'" removed, typos corrected + * 01.08.00 2025-10-13 virjas OSHAL-3696 Adaption for changed infrastructure (veHub) + *********************************************************************************************************************/ +#ifndef COMPILER_CFG_H +#define COMPILER_CFG_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +/* Package Merger: Start Section CompilerCfgIncludes */ + + + +/* Package Merger: Stop Section CompilerCfgIncludes */ + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +#define AUTOSAR_COMSTACKDATA + +#define MSR_REGSPACE REGSPACE + +/* Configurable memory class for pointers to registers (e.g. static volatile CONSTP2VAR(uint16, PWM_CONST, REGSPACE)). */ +#define REGSPACE + + +/* due to compatibility to ASR 2.1 */ +#define _STATIC_ STATIC +#define _INLINE_ INLINE + +/* Package Merger: Start Section CompilerCfgModuleList */ + + + +/********************************************************************************************************************** + * Cdd_AsrCdd START + *********************************************************************************************************************/ + +/* Copy the compiler abstraction defines for each of your configured CDDs and replace the prefix _CDD with the MSN of your configured CDD as higher case. */ + +#define _CDD_CODE +#define _CDD_APPL_DATA + +/* Add additional compiler abstraction defines for each of you configured CDDs here. */ + +/********************************************************************************************************************** + * Cdd_AsrCdd END + *********************************************************************************************************************/ + + + +/********************************************************************************************************************** + * CAN_30_CORE START + *********************************************************************************************************************/ + +#define CAN_30_CORE_CODE /* units public code */ +#define CANXL_30_CORE_CODE +#define CAN_30_CORE_STATIC_CODE /* units private code */ +#define CANXL_30_CORE_STATIC_CODE + +#define CAN_30_CORE_CONST +#define CAN_30_CORE_PBCFG + +#define CAN_30_CORE_VAR_INIT +#define CAN_30_CORE_VAR_NO_INIT +#define CAN_30_CORE_VAR_CLEARED + +#define CAN_30_CORE_APPL_CODE +#define CAN_30_CORE_APPL_VAR +#define CAN_30_CORE_VAR_PBCFG + +/********************************************************************************************************************** + * CAN_30_CORE END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * VCAN_30_MCAN START + **********************************************************************************************************************/ + +#define VCAN_30_MCAN_CODE /* should be same as CAN_30_CORE_CODE */ +#define VCAN_30_MCAN_CODE_ISR +#define VCAN_30_MCAN_REGSPACE +#define VCAN_30_MCAN_CONST +#define VCAN_30_MCAN_PBCFG + +#define VCAN_30_MCAN_APPL_CODE + +#define VCAN_30_MCAN_VAR_INIT +#define VCAN_30_MCAN_VAR_NO_INIT +#define VCAN_30_MCAN_VAR_ZERO_INIT +#define VCAN_30_MCAN_VAR_PBCFG + +#define VCAN_30_MCAN_MESSAGERAM + +/********************************************************************************************************************** + * VCAN_30_MCAN END + **********************************************************************************************************************/ + + +/********************************************************************************************************************** + * CRYPTO_30_LIBCV START + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_CODE +#define CRYPTO_30_LIBCV_APPL_CODE + +#define CRYPTO_30_LIBCV_CONST + +#define CRYPTO_30_LIBCV_VAR_NOINIT +#define CRYPTO_30_LIBCV_VAR_ZERO_INIT +#define CRYPTO_30_LIBCV_APPL_VAR +#define CRYPTO_30_LIBCV_APPL_DATA + +#define CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR + +/********************************************************************************************************************** + * CRYPTO_30_LIBCV END + *********************************************************************************************************************/ + + + +/********************************************************************************************************************** + * CRYPTO_30_VHSM START + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_CODE +#define CRYPTO_30_VHSM_APPL_CODE +#define CRYPTO_30_VHSM_CONST + +#define CRYPTO_30_VHSM_VAR_NOINIT +#define CRYPTO_30_VHSM_VAR_INIT +#define CRYPTO_30_VHSM_VAR_ZERO_INIT +#define CRYPTO_30_VHSM_APPL_VAR +#define CRYPTO_30_VHSM_APPL_DATA + +/********************************************************************************************************************** + * CRYPTO_30_VHSM END + *********************************************************************************************************************/ + + + +/********************************************************************************************************************** + * MEM_30_FBLHIS START + *********************************************************************************************************************/ + +#define MEM_30_FBLHIS_VAR_NOINIT + +#define MEM_30_FBLHIS_CONST + +/********************************************************************************************************************** + * MEM_30_FBLHIS END + *********************************************************************************************************************/ + + +/*********************************************************************************************************************** + * MEM_30_LEGACYADAPTER START + **********************************************************************************************************************/ + +#define MEM_30_LEGACYADAPTER_CODE +#define MEM_30_LEGACYADAPTER_CONST + +#define MEM_30_LEGACYADAPTER_VMEM_CODE +#define MEM_30_LEGACYADAPTER_VMEM_CONST + +#define MEM_30_LEGACYADAPTER_VAR_CLEARED + +#define MEM_30_LEGACYADAPTER_APPL_VAR +#define MEM_30_LEGACYADAPTER_APPL_VAR_NOINIT + +/*********************************************************************************************************************** + * MEM_30_LEGACYADAPTER END + **********************************************************************************************************************/ + + +/********************************************************************************************************************** + * CANTRCV_30_GENERICCAN START + *********************************************************************************************************************/ + +#define CANTRCV_30_GENERICCAN_CODE +#define CANTRCV_30_GENERICCAN_CODE_FAST +#define CANTRCV_30_GENERICCAN_CODE_ISR + +#define CANTRCV_30_GENERICCAN_CONST +#define CANTRCV_30_GENERICCAN_CONST_FAST +#define CANTRCV_30_GENERICCAN_PBCFG + +#define CANTRCV_30_GENERICCAN_VAR_PBCFG /* ESCAN00065502 */ + +#define CANTRCV_30_GENERICCAN_VAR_INIT +#define CANTRCV_30_GENERICCAN_VAR_NOINIT +#define CANTRCV_30_GENERICCAN_APPL_VAR +#define CANTRCV_30_GENERICCAN_APPL_CODE +#define CANTRCV_30_GENERICCAN_VAR_ZERO_INIT +#define CANTRCV_30_GENERICCAN_VAR_INIT_FAST +#define CANTRCV_30_GENERICCAN_VAR_NOINIT_FAST +#define CANTRCV_30_GENERICCAN_VAR_ZERO_INIT_FAST + +#define CANTRCV_30_GENERICCAN_VAR_INIT_NOCACHE +#define CANTRCV_30_GENERICCAN_VAR_NOINIT_NOCACHE +#define CANTRCV_30_GENERICCAN_VAR_ZERO_INIT_NOCACHE + + + +/********************************************************************************************************************** + * CANTRCV_30_GENERICCAN END + *********************************************************************************************************************/ /* PRQA S 0883 */ /* Appears only while testing */ + + + +/********************************************************************************************************************** + * BSWSTUB-COMM START + *********************************************************************************************************************/ + +#define COMM_CODE + +/********************************************************************************************************************** + * BSWSTUB-COMM END + *********************************************************************************************************************/ + + + +/********************************************************************************************************************** + * FBLBM_HDR START + *********************************************************************************************************************/ + +#define FBLBMHDR_CONST +#define FBLBMHDR_CODE + +/********************************************************************************************************************** + * FBLBM_HDR END + *********************************************************************************************************************/ + + + +/********************************************************************************************************************** + * FBLBM_MAIN START + *********************************************************************************************************************/ + +#define FBLBM_CONST +#define FBLBM_HEADER_CONST + +/********************************************************************************************************************** + * FBLBM_MAIN END + *********************************************************************************************************************/ + + + +/********************************************************************************************************************** + * FBLLIB_SECBOOT START + *********************************************************************************************************************/ + +#define FBLSB_CONST +#define FBLSB_CODE + +/********************************************************************************************************************** + * FBLLIB_SECBOOT END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * FblCw START + *********************************************************************************************************************/ + +/* Module Constant Data */ +#define FBLCW_CONST +/* Module Constant Data of the Postbuild Configuration */ +#define FBLCW_PBCFG +/* Module Var Data of the Postbuild Configuration */ +#define FBLCW_VAR_PBCFG + + +/* Module Implementation */ +#define FBLCW_CODE + +/* Module Variables which are initialized by the startup code or by the call of FblCw_InitMemory() */ +#define FBLCW_VAR_NO_INIT +/* Module Variables which are initialized by call of FblCw_Init() */ +#define FBLCW_VAR_CLEARED +/* Module Variables which are initialized by call of FblCw_Init() */ +#define FBLCW_VAR_INIT + +/* Application Code Implementation (e.g. Callbacks) */ +#define FBLCW_APPL_CODE +/* Application Buffer which is located in RAM */ +#define FBLCW_APPL_VAR +/* Application Buffer which is located in ROM or RAM */ +#define FBLCW_APPL_DATA + +/********************************************************************************************************************** + * FblCw END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * PDUR START + *********************************************************************************************************************/ + +#define PDUR_CODE +#define PDUR_VAR_NO_INIT +#define PDUR_VAR_CLEARED +#define PDUR_VAR +#define PDUR_CONST +#define PDUR_PBCFG +#define PDUR_VAR_PBCFG +#define PDUR_APPL_DATA +#define PDUR_APPL_CODE + +/********************************************************************************************************************** + * PDUR END + *********************************************************************************************************************/ + + + +/********************************************************************************************************************** + * CANIF START + *********************************************************************************************************************/ + +#define CANIF_CODE +#define CANIF_CODE_FAST +#define CANIF_CODE_ISR + + +#define CANIF_CONST +#define CANIF_CONST_FAST +#define CANIF_PBCFG + +#define CANIF_VAR_PBCFG /* ESCAN00065502 */ + +#define CANIF_VAR_INIT +#define CANIF_VAR_NOINIT +#define CANIF_VAR_ZERO_INIT + +#define CANIF_VAR_INIT_FAST +#define CANIF_VAR_NOINIT_FAST +#define CANIF_VAR_ZERO_INIT_FAST + +#define CANIF_VAR_INIT_NOCACHE +#define CANIF_VAR_NOINIT_NOCACHE +#define CANIF_VAR_ZERO_INIT_NOCACHE + + +#define CANIF_APPL_CODE +#define CANIF_APPL_VAR +#define CANIF_APPL_PBCFG + + +/*-------------------------------------------------------------------------------------------------------------------*/ + +/* Has to be kept in default section -> Default access */ +#define CANIF_VAR_STACK + + +/* VAR section of higher layers (TP / NM / PduR / CanSM / EcuM) automatically mapped to APPL_VAR */ +#define CANIF_APPL_STATE_VAR CANIF_APPL_VAR +#define CANIF_APPL_MSG_VAR CANIF_APPL_VAR + +/* VAR section of lower layers (CAN Driver / Transceiver Driver) automatically mapped to APPL_VAR */ +#define CANIF_CBK_VAR CANIF_APPL_VAR + +/* #define CANIF_CBK_TRCV_VAR CANIF_CBK_VAR not used yet */ +#define CANIF_CBK_DRV_VAR CANIF_CBK_VAR + +/* Code sections - DO NOT MODIFY */ +#define CANIF_CBK_TRCV_CODE CANIF_APPL_CODE +#define CANIF_CBK_CANDRV_CODE CANIF_APPL_CODE +#define CANIF_APPL_STATE_CODE CANIF_APPL_CODE +#define CANIF_APPL_MSG_CODE CANIF_APPL_CODE + + +/* Upper layer data pointer */ +#define CANIF_UL_STANDARD_VAR CANIF_APPL_VAR +#define CANIF_UL_ADVANCED_VAR CANIF_APPL_VAR +#define CANIF_UL_OSEKNM_VAR CANIF_APPL_VAR + +/********************************************************************************************************************** + * CANIF END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * CRYIF START + *********************************************************************************************************************/ + +#define CRYIF_CODE +#define CRYIF_CONST + +#define CRYIF_VAR_ZERO_INIT +#define CRYIF_APPL_VAR +#define CRYIF_APPL_DATA + +/********************************************************************************************************************** + * CRYIF END + *********************************************************************************************************************/ + + + +/*********************************************************************************************************************** + * MEMACC START + **********************************************************************************************************************/ + +#define MEMACC_CONST +#define MEMACC_VAR_NO_INIT + +/*********************************************************************************************************************** + * MEMACC END + **********************************************************************************************************************/ + + + +#ifndef STATIC +#define STATIC static +#endif + +#define _TEXAS_INSTRUMENTS_C_ARM_ + +/********************************************************************************************************************** + * ADC START + *********************************************************************************************************************/ + +#define ADC_APPL_CODE +#define ADC_APPL_CONST +#define ADC_APPL_DATA +#define ADC_CALLOUT_CODE +#define ADC_CODE +#define ADC_CONST +#define ADC_VAR +#define ADC_VAR_FAST +#define ADC_VAR_NOINIT +#define ADC_VAR_POWER_ON_INIT +#define ADC_PBCFG + + /********************************************************************************************************************** + * ADC END + *********************************************************************************************************************/ +/********************************************************************************************************************** + * CAN START + *********************************************************************************************************************/ + +#define CAN_APPL_CODE +#define CAN_APPL_CONST +#define CAN_APPL_DATA +#define CAN_CALLOUT_CODE +#define CAN_CODE +#define CAN_CONST +#define CAN_VAR +#define CAN_VAR_FAST +#define CAN_VAR_NOINIT +#define CAN_VAR_POWER_ON_INIT +#define CAN_PBCFG + + /********************************************************************************************************************** + * CAN END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * CDD START + *********************************************************************************************************************/ + +#define CDD_APPL_CODE +#define CDD_APPL_CONST +#define CDD_APPL_DATA +#define CDD_CALLOUT_CODE +#define CDD_CODE +#define CDD_CONST +#define CDD_VAR +#define CDD_VAR_FAST +#define CDD_VAR_NOINIT +#define CDD_VAR_POWER_ON_INIT +#define CDD_PBCFG + + /********************************************************************************************************************** + * CDD END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * DIO START + *********************************************************************************************************************/ + +#define DIO_APPL_CODE +#define DIO_APPL_CONST +#define DIO_APPL_DATA +#define DIO_CALLOUT_CODE +#define DIO_CODE +#define DIO_CONST +#define DIO_VAR +#define DIO_VAR_FAST +#define DIO_VAR_NOINIT +#define DIO_VAR_POWER_ON_INIT + + /********************************************************************************************************************** + * DIO END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * CDD_DMA START + *********************************************************************************************************************/ + +#define CDD_DMA_APPL_CODE +#define CDD_DMA_APPL_CONST +#define CDD_DMA_APPL_DATA +#define CDD_DMA_CALLOUT_CODE +#define CDD_DMA_CODE +#define CDD_DMA_CONST +#define CDD_DMA_VAR +#define CDD_DMA_VAR_FAST +#define CDD_DMA_VAR_NOINIT +#define CDD_DMA_VAR_POWER_ON_INIT + + /********************************************************************************************************************** + * CDD_DMA END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * ETH START + *********************************************************************************************************************/ + +#define ETH_APPL_CODE +#define ETH_APPL_CONST +#define ETH_APPL_DATA +#define ETH_CALLOUT_CODE +#define ETH_CODE +#define ETH_CONST +#define ETH_VAR +#define ETH_VAR_FAST +#define ETH_VAR_NOINIT +#define ETH_VAR_POWER_ON_INIT +#define ETH_PBCFG + + /********************************************************************************************************************** + * ETH END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * FLS START + *********************************************************************************************************************/ + +#define FLS_APPL_CODE +#define FLS_APPL_CONST +#define FLS_APPL_DATA +#define FLS_CALLOUT_CODE +#define FLS_CODE +#define FLS_CONST +#define FLS_VAR +#define FLS_VAR_FAST +#define FLS_VAR_NOINIT +#define FLS_VAR_POWER_ON_INIT +#define FLS_CONFIG_DATA + + /********************************************************************************************************************** + * FLS END + *********************************************************************************************************************/ +/********************************************************************************************************************** + * GPT START + *********************************************************************************************************************/ + +#define GPT_APPL_CODE +#define GPT_APPL_CONST +#define GPT_APPL_DATA +#define GPT_CALLOUT_CODE +#define GPT_CODE +#define GPT_CONST +#define GPT_VAR +#define GPT_VAR_FAST +#define GPT_VAR_NOINIT +#define GPT_VAR_POWER_ON_INIT + +/********************************************************************************************************************** + * GPT END + *********************************************************************************************************************/ /********************************************************************************************************************** + * I2C START + *********************************************************************************************************************/ + +#define I2C_APPL_CODE +#define I2C_APPL_CONST +#define I2C_APPL_DATA +#define I2C_CALLOUT_CODE +#define I2C_CODE +#define I2C_CONST +#define I2C_VAR +#define I2C_VAR_FAST +#define I2C_VAR_NOINIT +#define I2C_VAR_POWER_ON_INIT + + /********************************************************************************************************************** + * I2C END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * CDD_I2C START + *********************************************************************************************************************/ + +#define CDD_I2C_APPL_CODE +#define CDD_I2C_APPL_CONST +#define CDD_I2C_APPL_DATA +#define CDD_I2C_CALLOUT_CODE +#define CDD_I2C_CODE +#define CDD_I2C_CONST +#define CDD_I2C_VAR +#define CDD_I2C_VAR_FAST +#define CDD_I2C_VAR_NOINIT +#define CDD_I2C_VAR_POWER_ON_INIT + + /********************************************************************************************************************** + * CDD_I2C END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * ICU START + *********************************************************************************************************************/ + +#define ICU_APPL_CODE +#define ICU_APPL_CONST +#define ICU_APPL_DATA +#define ICU_CALLOUT_CODE +#define ICU_CODE +#define ICU_CONST +#define ICU_VAR +#define ICU_VAR_FAST +#define ICU_VAR_NOINIT +#define ICU_VAR_POWER_ON_INIT +#define ICU_PBCFG + + /********************************************************************************************************************** + * ICU END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * CDD_IPC START + *********************************************************************************************************************/ + +#define CDD_IPC_APPL_CODE +#define CDD_IPC_APPL_CONST +#define CDD_IPC_APPL_DATA +#define CDD_IPC_CALLOUT_CODE +#define CDD_IPC_CODE +#define CDD_IPC_CONST +#define CDD_IPC_VAR +#define CDD_IPC_VAR_FAST +#define CDD_IPC_VAR_NOINIT +#define CDD_IPC_VAR_POWER_ON_INIT +#define CDD_IPC_CFG + + /********************************************************************************************************************** + * CDD_IPC END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * LIN START + *********************************************************************************************************************/ + +#define LIN_APPL_CODE +#define LIN_APPL_CONST +#define LIN_APPL_DATA +#define LIN_CALLOUT_CODE +#define LIN_CODE +#define LIN_CONST +#define LIN_VAR +#define LIN_VAR_FAST +#define LIN_VAR_NOINIT +#define LIN_VAR_POWER_ON_INIT +#define LIN_PBCFG + +/********************************************************************************************************************** + * LIN END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * MCU START + *********************************************************************************************************************/ + +#define MCU_APPL_CODE +#define MCU_APPL_CONST +#define MCU_APPL_DATA +#define MCU_CALLOUT_CODE +#define MCU_CODE +#define MCU_CONST +#define MCU_VAR +#define MCU_VAR_FAST +#define MCU_VAR_NOINIT +#define MCU_VAR_POWER_ON_INIT +#define MCU_PBCFG + +/********************************************************************************************************************** + * MCU END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * PORT START + *********************************************************************************************************************/ + +#define PORT_APPL_CODE +#define PORT_APPL_CONST +#define PORT_APPL_DATA +#define PORT_CALLOUT_CODE +#define PORT_CODE +#define PORT_CONST +#define PORT_VAR +#define PORT_VAR_FAST +#define PORT_VAR_NOINIT +#define PORT_VAR_POWER_ON_INIT +#define PORT_PBCFG + +/********************************************************************************************************************** + * PORT END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * PWM START + *********************************************************************************************************************/ + +#define PWM_APPL_CODE +#define PWM_APPL_CONST +#define PWM_APPL_DATA +#define PWM_CALLOUT_CODE +#define PWM_CODE +#define PWM_CONST +#define PWM_VAR +#define PWM_VAR_FAST +#define PWM_VAR_NOINIT +#define PWM_VAR_POWER_ON_INIT +#define PWM_PBCFG + +/********************************************************************************************************************** + * PWM END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * CDD_PWM START + *********************************************************************************************************************/ + +#define CDD_PWM_APPL_CODE +#define CDD_PWM_APPL_CONST +#define CDD_PWM_APPL_DATA +#define CDD_PWM_CALLOUT_CODE +#define CDD_PWM_CODE +#define CDD_PWM_CONST +#define CDD_PWM_VAR +#define CDD_PWM_VAR_FAST +#define CDD_PWM_VAR_NOINIT +#define CDD_PWM_VAR_POWER_ON_INIT +#define CDD_PWM_PBCFG + +/********************************************************************************************************************** + * CDD_PWM END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * SPI START + *********************************************************************************************************************/ + +#define SPI_APPL_CODE +#define SPI_APPL_CONST +#define SPI_APPL_DATA +#define SPI_CALLOUT_CODE +#define SPI_CODE +#define SPI_CONST +#define SPI_VAR +#define SPI_VAR_FAST +#define SPI_VAR_NOINIT +#define SPI_VAR_POWER_ON_INIT +#define SPI_CONFIG_DATA + +/********************************************************************************************************************** + * SPI END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * CDD_UART START + *********************************************************************************************************************/ + +#define CDD_UART_APPL_CODE +#define CDD_UART_APPL_CONST +#define CDD_UART_APPL_DATA +#define CDD_UART_CALLOUT_CODE +#define CDD_UART_CODE +#define CDD_UART_CONST +#define CDD_UART_VAR +#define CDD_UART_VAR_FAST +#define CDD_UART_VAR_NOINIT +#define CDD_UART_VAR_POWER_ON_INIT + + /********************************************************************************************************************** + * CDD_UART END + *********************************************************************************************************************/ + /********************************************************************************************************************** + * WDG START + *********************************************************************************************************************/ + +#define WDG_APPL_CODE +#define WDG_APPL_CONST +#define WDG_APPL_DATA +#define WDG_CALLOUT_CODE +#define WDG_CODE +#define WDG_CONST +#define WDG_VAR +#define WDG_VAR_FAST +#define WDG_VAR_NOINIT +#define WDG_VAR_POWER_ON_INIT + +/********************************************************************************************************************** + * WDG END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * CSM START + *********************************************************************************************************************/ + +#define CSM_CODE +#define CSM_APPL_CODE +#define CSM_RTE_CODE + +#define CSM_CONST + +#define CSM_VAR_NOINIT +#define CSM_VAR_ZERO_INIT +#define CSM_APPL_VAR +#define CSM_APPL_CONST + +/********************************************************************************************************************** + * CSM END + *********************************************************************************************************************/ + + + +/********************************************************************************************************************** + * VSECPRIM START + *********************************************************************************************************************/ + +#define VSECPRIM_CODE +#define VSECPRIM_CONST +#define VSECPRIM_APPL_CONST +#define VSECPRIM_APPL_VAR +#define VSECPRIM_APPL_DATA + +/********************************************************************************************************************** + * VSECPRIM END + *********************************************************************************************************************/ + + +# define DET_CODE +# define DET_VAR +# define DET_APPL_DATA +# define DET_CONST + + + +/********************************************************************************************************************** + * WRAPNV START + *********************************************************************************************************************/ + +#define WRAPNV_CODE +#define WRAPNV_VAR_NOINIT +#define WRAPNV_CONST +#define WRAPNV_DATA +#define WRAPNV_NVM_APPL_DATA + +/********************************************************************************************************************** + * WRAPNV END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * CANTP START + *********************************************************************************************************************/ + +#define CANTP_CODE +#define CANTP_CONST + +#define CANTP_PBCFG +#define CANTP_VAR_PBCFG + +#define CANTP_VAR_CLEARED +#define CANTP_VAR_NO_INIT + +#define CANTP_APPL_CODE +#define CANTP_APPL_DATA + +/********************************************************************************************************************** + * CANTP END + *********************************************************************************************************************/ + + + +/********************************************************************************************************************** + * VSTDLIB START + *********************************************************************************************************************/ + +#define VSTDLIB_CODE +#define VSTDLIB_VAR_FAR +#define VSTDLIB_APPL_VAR +#define VSTDLIB_CONST + +/********************************************************************************************************************** + * VSTDLIB END + *********************************************************************************************************************/ + + + + +/* Package Merger: Stop Section CompilerCfgModuleList */ + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + + +#endif /* COMPILER_CFG_H */ + +/********************************************************************************************************************** + * END OF FILE: Compiler_Cfg.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Common/EthSwt_GeneralTypes.h b/Source/bsw/Common/EthSwt_GeneralTypes.h new file mode 100644 index 0000000..b9a15d2 --- /dev/null +++ b/Source/bsw/Common/EthSwt_GeneralTypes.h @@ -0,0 +1,393 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file EthSwt_GeneralTypes.h + * \brief General Type Header of MICROSAR Ethernet Switch Driver + * + * \details The General Type Header contains the data types used. + * + *********************************************************************************************************************/ +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to Eth_GeneralTypes.h + *********************************************************************************************************************/ + +#if !defined (ETHSWT_GENERALTYPES_H) +# define ETHSWT_GENERALTYPES_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# ifndef ETH_GENERAL_TYPES_H +# include "Eth_GeneralTypesDefs.h" +# include "EthTrcv_GeneralTypes.h" +# endif + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/*! Vendor and module identification */ +# define ETHSWT_30_VECTOR_VENDOR_ID (30u) +# define ETHSWT_30_VECTOR_MODULE_ID (89u) + +/*! EthSwt_StateType values */ +/*! \trace SPEC-2265331 */ +# define ETHSWT_STATE_UNINIT (0x00u) +# define ETHSWT_STATE_INIT (0x01u) +# define ETHSWT_STATE_ACTIVE (0x02u) + +/*! EthSwt_MacLearningType values */ +/*! \trace SPEC-2265334 */ +# define ETHSWT_MACLEARNING_HWDISABLED (0x00u) +# define ETHSWT_MACLEARNING_HWENABLED (0x01u) +# define ETHSWT_MACLEARNING_SWENABLED (0x02u) + +/*! EthSwt_PortModeType values */ +# define ETHSWT_MODE_DOWN_SWITCHPORT ETHTRCV_MODE_DOWN +# define ETHSWT_MODE_ACTIVE_SWITCHPORT ETHTRCV_MODE_ACTIVE + +/*! EthSwt_VlanFwType values */ +# define ETHSWT_NOT_SENT (0x00u) +# define ETHSWT_SENT_TAGGED (0x01u) +# define ETHSWT_SENT_UNTAGGED (0x02u) + +/*! Enumeration values for type EthSwt_PhysicalLayerType */ +# define ETHSWT_PORT_BROAD_R_REACH (0u) +# define ETHSWT_PORT_BASE_T (1u) +# define ETHSWT_PORT_RTPGE (2u) +# define ETHSWT_PORT_X_MII (3u) +# define ETHSWT_PORT_INTERNAL (4u) +# define ETHSWT_PORT_10BASE_T1S (5u) + +/*! Enumeration values for the different possible speed configurations of a switch port */ +# define ETHSWT_PORT_SPEED_10 ETHTRCV_BAUD_RATE_10MBIT +# define ETHSWT_PORT_SPEED_100 ETHTRCV_BAUD_RATE_100MBIT +# define ETHSWT_PORT_SPEED_1000 ETHTRCV_BAUD_RATE_1000MBIT +# define ETHSWT_PORT_SPEED_2500 ETHTRCV_BAUD_RATE_2500MBIT +# define ETHSWT_PORT_SPEED_5000 ETHTRCV_BAUD_RATE_5000MBIT +# define ETHSWT_PORT_SPEED_10000 ETHTRCV_BAUD_RATE_10000MBIT +# define ETHSWT_PORT_SPEED_DONT_CARE (0xFFu) + +/*! Enumeration values for the different possible duplex mode configurations of a switch port */ +#define ETHSWT_DUPLEX_MODE_HALF ETHTRCV_DUPLEX_MODE_HALF +#define ETHSWT_DUPLEX_MODE_FULL ETHTRCV_DUPLEX_MODE_FULL + +/*! Enumeration values for type EthSwt_XMiiPortMgmtType */ +# define ETHSWT_NO_PHY (0u) +# define ETHSWT_PHY_MANAGED_BY_MCU (1u) +# define ETHSWT_PHY_MANAGED_BY_SWITCH (2u) + +/*! Enumeration values for type EthSwt_XMiiPortConnectionType */ +#define ETHSWT_RVMII (0x00u) +#define ETHSWT_MII (0x01u) +#define ETHSWT_RGMII (0x02u) +#define ETHSWT_SGMII (0x03u) +#define ETHSWT_USXGMII (0x04u) +#define ETHSWT_HISGMII (0x05u) +#define ETHSWT_RMII (0x06u) +#define ETHSWT_XGMII (0x07u) + +/*! Enumeration values for type EthSwt_MCastPortAssignActionType */ +# define ETHSWT_MCAST_PORT_ASSIGN_ACTION_ADD (0u) +# define ETHSWT_MCAST_PORT_ASSIGN_ACTION_REMOVE (1u) + +/*! Enumeration values for type EthSwt_ArlEntryTypeType */ +# define ETHSWT_ARL_TABLE_ENTRY_TYPE_ANY (0u) +# define ETHSWT_ARL_TABLE_ENTRY_TYPE_LEARNED (1u) +# define ETHSWT_ARL_TABLE_ENTRY_TYPE_STATIC (2u) + +/*! Hardware port identification */ +# define ETHSWT_PORT_0 (0u) +# define ETHSWT_PORT_1 (1u) +# define ETHSWT_PORT_2 (2u) +# define ETHSWT_PORT_3 (3u) +# define ETHSWT_PORT_4 (4u) +# define ETHSWT_PORT_5 (5u) +# define ETHSWT_PORT_6 (6u) +# define ETHSWT_PORT_7 (7u) +# define ETHSWT_PORT_8 (8u) +# define ETHSWT_PORT_9 (9u) +# define ETHSWT_PORT_10 (10u) +# define ETHSWT_PORT_11 (11u) +# define ETHSWT_PORT_12 (12u) +# define ETHSWT_PORT_13 (13u) +# define ETHSWT_PORT_14 (14u) +# define ETHSWT_PORT_15 (15u) +# define ETHSWT_PORT_16 (16u) +# define ETHSWT_PORT_17 (17u) +# define ETHSWT_PORT_18 (18u) +# define ETHSWT_PORT_19 (19u) +# define ETHSWT_PORT_20 (20u) +# define ETHSWT_PORT_21 (21u) +# define ETHSWT_PORT_22 (22u) +# define ETHSWT_PORT_23 (23u) +# define ETHSWT_PORT_24 (24u) +# define ETHSWT_PORT_25 (25u) +# define ETHSWT_PORT_26 (26u) +# define ETHSWT_PORT_27 (27u) +# define ETHSWT_PORT_28 (28u) +# define ETHSWT_PORT_29 (29u) +# define ETHSWT_PORT_30 (30u) +# define ETHSWT_PORT_31 (31u) + +/*! Highest valid VLAN ID */ +# define ETHSWT_VLAN_MAX_VID (4094u) +/*! Invalid VLAN ID */ +# define ETHSWT_VLAN_INV_VID (ETHSWT_VLAN_MAX_VID + 1u) + +# define ETHSWT_MAX_ARL_ENTRIES (65535u) + +# define ETHSWT_DROP_COUNT_NUM (14u) +# define ETHSWT_ETHERT_STATS_NUM (17u) + +/*! Identification of invalid/unused switch ports */ +# define ETHSWT_INV_PORT_IDX (0xFFu) +# define ETHSWT_PORT_NOT_CONFIGURED ETHSWT_INV_PORT_IDX +# define ETHSWT_PORT_NO_TRCV_DRV_USED ETHSWT_INV_PORT_IDX +# define ETHSWT_PORT_NO_MII_ACCESS ETHSWT_INV_PORT_IDX +# define ETHSWT_NO_XMII_PORT ETHSWT_INV_PORT_IDX + +/*! Enumeration values for type EthSwt_PortMirrorStateType */ +# define ETHSWT_PORT_MIRROR_DISABLED (0x00u) +# define ETHSWT_PORT_MIRROR_ENABLED (0x01u) +# define ETHSWT_PORT_MIRROR_INVALID (0x02u) + +/*! Enumeration values for MirroringMode */ +# define ETHSWT_MIRROR_MODE_NO_VLAN_RETAGGING (0x00u) +# define ETHSWT_MIRROR_MODE_VLAN_RETAGGING (0x01u) +# define ETHSWT_MIRROR_MODE_DOUBLE_VLAN_RETAGGING (0x02u) + +/*! Enumeration values for EthSwt_MgmtOwner */ +# define ETHSWT_MGMT_OBJ_UNUSED (0x00u) +# define ETHSWT_MGMT_OBJ_OWNED_BY_ETHSWT (0x01u) +# define ETHSWT_MGMT_OBJ_OWNED_BY_UPPER_LAYER (0x02u) + +/*! User Defined return value returned by Hardware Filter interface */ +# define ETHSWT_HW_FILTER_E_STATE_PENDING (2u) +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ +/* PRQA S 0342,0881 ETHSWT_GENERAL_GLUE_OPERATOR */ /* MD_MSR_19.13_0342 */ + +/*! Macro for better readability of start of exclusive area */ +# define EthSwt_EnterExclusiveArea(Derivative, Area) \ + SchM_Enter_EthSwt_30_##Derivative##_EXCLUSIVE_AREA_##Area() + +/*! Macro for better readability of end of exclusive area */ +# define EthSwt_ExitExclusiveArea(Derivative, Area) \ + SchM_Exit_EthSwt_30_##Derivative##_EXCLUSIVE_AREA_##Area() + +/* PRQA L:ETHSWT_GENERAL_GLUE_OPERATOR */ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ +/*! Dummy type for multiple configuration. (Isn't supported by AUTOSAR at the moment) */ +/*! \trace SPEC-2265332 */ +typedef struct +{ + uint8 DummyData; /**< dummy data because multiple configuration isn't supported */ +} EthSwt_ConfigType; + +/*! AUTOSAR type (deviation) for holding MAC address, VLAN ID and port mapping information. */ +/*! \trace SPEC-2265333 */ +typedef struct +{ + uint8 MacAddr[6]; /**< MAC address */ + uint16 VlanId; /**< VLAN ID */ + uint32 SwitchPort; /**< Switch port bitmask, bit indices correspond to EthSwtPortIdx (deviation) */ +} EthSwt_MacVlanType; + +/*! AUTOSAR type for module state. */ +/*! \trace SPEC-2265331 */ +typedef uint8 EthSwt_StateType; + +/*! AUTOSAR type for switch index. */ +typedef uint8 EthSwt_SwitchIdxType; + +/*! AUTOSAR type for port index. */ +typedef uint8 EthSwt_PortIdxType; + +/*! AUTOSAR type for buffer level. */ +typedef uint32 EthSwt_BufferLevelType; + +/*! AUTOSAR type for MAC learning type. */ +/*! \trace SPEC-2265334 */ +typedef uint8 EthSwt_MacLearningType; + +/*! AUTOSAR type for port mode. */ +typedef uint8 EthSwt_PortModeType; + +/*! Type of VLAN forwarding */ +typedef uint8 EthSwt_VlanFwType; + +/*! Type of the phyiscal layer of a port */ +typedef uint8 EthSwt_PhysicalLayerType; + +/*! Type for indicating which interface is used for managing a PHY connected to a xMii port */ +typedef uint8 EthSwt_XMiiPortMgmtType; + +/*! Type for indicating which connection type is used for a PHY connected to a xMii port */ +typedef uint8 EthSwt_XMiiPortConnectionType; + +/*! AUTOSAR type for holding the management information for Ethernet frames received/transmitted on switch ports. */ +typedef struct +{ + EthSwt_SwitchIdxType SwitchIdx; /**< EthSwt switch index */ + uint8 PortIdx; /**< EthSwt port index, config view (SNV) */ +} EthSwt_MgmtInfoType; + +/*! AUTOSAR type for holding validity information of the management information contained in EthSwt_MgmtObjectType */ +typedef struct +{ + Std_ReturnType IngressTimestampValid; + Std_ReturnType EgressTimestampValid; + Std_ReturnType MgmtInfoValid; +} EthSwt_MgmtObjectValidType; + +/*! AUTOSAR type for holding ownership information of EthSwt_MgmtObjectType */ +typedef uint8 EthSwt_MgmtOwner; + +/*! Type for holding egress timestamp information for asymmetric time synchronization */ +typedef struct +{ + uint8 CfgPortIdx; /*!< EthSwt port index, config view (SNV) */ + Std_ReturnType EgressTimestampValid; + Eth_TimeStampType EgressTimestamp; +} EthSwt_VMgmtEgrTsInfoType; + +/*! Type for holding additional information for asymmetric time synchronization of EthSwt_MgmtObjectType */ +typedef struct +{ + uint8 NumEgrTsInfos; + EthSwt_VMgmtEgrTsInfoType *EgrTsInfoPtr; +} EthSwt_VMgmtObjectAddInfoType; + +/*! AUTOSAR type (deviation) for sharing management information with protocol stack (upper layers) */ +/*! \trace SPEC-20655611 */ +typedef struct +{ + EthSwt_MgmtObjectValidType Validation; + Eth_TimeStampType IngressTimestamp; + Eth_TimeStampType EgressTimestamp; + EthSwt_MgmtInfoType MgmtInfo; + EthSwt_MgmtOwner Ownership; + EthSwt_VMgmtObjectAddInfoType AddInfo; /*!< For asymmetric time synchronization */ +} EthSwt_MgmtObjectType; + +/*! Type for defining the action that is applied during EthSwt_UpdateMCastPortAssignment() */ +typedef uint8 EthSwt_MCastPortAssignActionType; + +/*! Type of address resolution table entry */ +typedef uint8 EthSwt_ArlEntryTypeType; + +/*! MAC address forwarding type */ +typedef struct +{ + uint32 PortFwVector; /*!< Bitmask defining the port forwarding vector: Bit 0 -> HwPort 0, Bit 1 -> HwPort 1, ... */ + uint8 Mac[ETH_PHYS_ADDR_LEN_BYTE]; /*!< Related MAC address */ +} EthSwt_MacFwInfoType; + +/*! VLAN modification type */ +typedef struct +{ + uint32 EgressAllowed; /*!< Bit mask defining egress allowed ports: Bit 0 -> HwPort 0, Bit 1 -> HwPort 1, ... */ + uint32 IngressAllowed; /*!< Bit mask defining ingress allowed ports: Bit 0 -> HwPort 0, Bit 1 -> HwPort 1, ... */ + uint32 EgressTagged; /*!< Bit mask defining egress tagged ports: Bit 0 -> HwPort 0, Bit 1 -> HwPort 1, ... */ + uint16 VlanId; /*!< Related VLAN ID */ +} EthSwt_VlanModType; + +/*! Port mirroring configuration type */ +typedef struct +{ + uint8 CapturePortIdx; /*!< Switch port which captures mirrored traffic + - symbolic name value from configuration must be used */ + uint8 srcMacAddrFilter[ETH_PHYS_ADDR_LEN_BYTE]; /*!< Source MAC address of packets which shall be mirrored */ + uint8 dstMacAddrFilter[ETH_PHYS_ADDR_LEN_BYTE]; /*!< Destination MAC address of packets which shall be mirrored */ + uint16 VlanIdFilter; /*!< VLAN ID of frames which shall be mirrored */ + uint8 MirroringPacketDivider; /*!< Limits mirrored frames: 1 -> all frames, 2 -> every second frame, ... */ + uint8 MirroringMode; /*!< Retagging of mirrored frames: 0x00 == no VLAN retagging, + * 0x01 == VLAN retagging, 0x02 == VLAN double retagging */ + uint16 VlanOuterTag; /*!< VLAN ID used for VLAN retagging or as outer tag for VLAN double retagging */ + uint16 VlanInnerTag; /*!< VLAN ID used as inner tag for VLAN double retagging */ + uint32 MirroredSwitchEgressPortIdxBitMask; /*!< Bit mask defining ports where egress frames shall be mirrored + - symbolic name values from configuration must be used */ + uint32 MirroredSwitchIngressPortIdxBitMask; /*!< Bit mask defining ports where ingress frames shall be mirrored + - symbolic name values from configuration must be used */ +} EthSwt_PortMirrorCfgType; + +/*! Switch port mirroring state type */ +typedef uint8 EthSwt_PortMirrorStateType; + +/*! Type for Hardware Filter match data */ +typedef uint8 FilterEntryMatchDataType; + +/*! Type for Hardware Filter mask data */ +typedef uint8 FilterEntryMaskDataType; + +/*! Type for total lenth of hardware filter match and mask data */ +typedef uint16 FilterEntryLengthType; + +/*! Type for indicating which Hardware Filter Action needs to be selected */ +typedef enum +{ + ETHSWT_FILTER_ACTION_NONE, + ETHSWT_FILTER_ACTION_ALLOW, + ETHSWT_FILTER_ACTION_FORWARD, + ETHSWT_FILTER_ACTION_BLOCK, + ETHSWT_FILTER_ACTION_VLAN_MODIFICATION, + ETHSWT_FILTER_ACTION_VLAN_MODIFICATION_FORWARD +} EthSwt_HwFilterEntryActionType; + +/*! Type for indicating which Destination Port Modification type is used when Destination Port Modification is selected */ +typedef enum +{ + ETHSWT_STREAM_EGRESS_DESTINATION_TYPE_DONT_CARE, + ETHSWT_STREAM_EGRESS_DESTINATION_EXTEND, + ETHSWT_STREAM_EGRESS_DESTINATION_LIMIT, + ETHSWT_STREAM_EGRESS_DESTINATION_OVERWRITE +} EthSwt_StreamFiltActionDPVType; + +/*! Type for configuring mask and match data for Hardware Filter entry */ +typedef struct +{ + const FilterEntryMatchDataType *FilterEntryMatchDataPtr; + const FilterEntryMaskDataType *FilterEntryMaskDataPtr; + FilterEntryLengthType FilterEntryLength; +} EthSwt_FilterEntryInfoType; + +/*! Type for configuring entries in hardware using Hardware Filter interface */ +typedef struct +{ + EthSwt_FilterEntryInfoType HwFilterEntryInfo; + uint32 UsedPortsMask; + uint32 DestPortsMask; + uint32 RxQueueId; + uint16 ModifiedVlanID; + uint16 StreamId; + uint16 FlowMeterId; + EthSwt_HwFilterEntryActionType HwFilterAction; + EthSwt_StreamFiltActionDPVType DPVType; +} EthSwt_HwFilterEntryConfigType; + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +#endif /* ETHSWT_GENERALTYPES_H */ + +/********************************************************************************************************************** + * END OF FILE: EthSwt_GeneralTypes.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Common/EthTrcv_GeneralTypes.h b/Source/bsw/Common/EthTrcv_GeneralTypes.h new file mode 100644 index 0000000..f542b6c --- /dev/null +++ b/Source/bsw/Common/EthTrcv_GeneralTypes.h @@ -0,0 +1,176 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file EthTrcv_GeneralTypes.h + * \brief Ethernet transceiver general types header + * + * \details General types header for Ethernet Transceiver Driver + * + *********************************************************************************************************************/ +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to Eth_GeneralTypes.h + *********************************************************************************************************************/ + +#if !defined (ETHTRCV_GENERAL_TYPES_H) +# define ETHTRCV_GENERAL_TYPES_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Std_Types.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ +/* ETHTRCV modes */ +# define ETHTRCV_MODE_DOWN (0x00U) +# define ETHTRCV_MODE_ACTIVE (0x01U) +# define ETHTRCV_MODE_ACTIVE_WITH_WAKEUP_REQUEST (0x02U) + +/* ETHTRCV link states */ +# define ETHTRCV_LINK_STATE_DOWN (0x00U) +# define ETHTRCV_LINK_STATE_ACTIVE (0x01U) + +/* ETHTRCV baud rates */ +# define ETHTRCV_BAUD_RATE_10MBIT (0x00U) +# define ETHTRCV_BAUD_RATE_100MBIT (0x01U) +# define ETHTRCV_BAUD_RATE_1000MBIT (0x02U) +# define ETHTRCV_BAUD_RATE_2500MBIT (0x03U) +# define ETHTRCV_BAUD_RATE_5000MBIT (0x04U) +# define ETHTRCV_BAUD_RATE_10000MBIT (0x05U) + +/* ETHTRCV duplex modes */ +# define ETHTRCV_DUPLEX_MODE_HALF (0x00U) +# define ETHTRCV_DUPLEX_MODE_FULL (0x01U) + +/* ETHTRCV state */ +# define ETHTRCV_STATE_UNINIT (0x00U) +# define ETHTRCV_STATE_INIT (0x01U) +# define ETHTRCV_STATE_ACTIVE (0x02U) +# define ETHTRCV_STATE_DOWN (0x03U) + +/* ETHTRCV wakeup types */ +# define ETHTRCV_WAKEUP_NOT_SUPPORTED (0x00U) +# define ETHTRCV_WAKEUP_BY_INTERRUPT (0x01U) +# define ETHTRCV_WAKEUP_BY_POLLING (0x02U) +# define ETHTRCV_WAKEUP_BY_ASYNCHRONOUS_CHECK (0x03U) + +/* ETHTRCV wakeup modes */ +# define ETHTRCV_WUM_DISABLE (0x00U) +# define ETHTRCV_WUM_ENABLE (0x01U) +# define ETHTRCV_WUM_CLEAR (0x02U) + +/* ETHTRCV wakeup reasons */ +# define ETHTRCV_WUR_NONE (0x00U) +# define ETHTRCV_WUR_GENERAL (0x01U) +# define ETHTRCV_WUR_BUS (0x02U) +# define ETHTRCV_WUR_INTERNAL (0x03U) +# define ETHTRCV_WUR_RESET (0x04U) +# define ETHTRCV_WUR_POWER_ON (0x05U) +# define ETHTRCV_WUR_PIN (0x06U) +# define ETHTRCV_WUR_SYSERR (0x07U) +# define ETHTRCV_WUR_WODL_WUP (0x08U) +# define ETHTRCV_WUR_WODL_WUR (0x09U) +# define ETHTRCV_WUR_TRANSFER (0x0AU) +/* count of AUTOSAR wakeup reasons defined for the transceiver */ +# define ETHTRCV_WUR_NUM (0x0AU) + +/* Masks defining the bitpositions of the AUTOSAR wakeup reasons for type EthTrcv_WakeupReasonFlagsType. */ +# define ETHTRCV_WUR_GENERAL_FLAGS_MASK (0x01U) +# define ETHTRCV_WUR_BUS_FLAGS_MASK (0x02U) +# define ETHTRCV_WUR_INTERNAL_FLAGS_MASK (0x04U) +# define ETHTRCV_WUR_RESET_FLAGS_MASK (0x08U) +# define ETHTRCV_WUR_POWER_ON_FLAGS_MASK (0x10U) +# define ETHTRCV_WUR_PIN_FLAGS_MASK (0x20U) +# define ETHTRCV_WUR_SYSERR_FLAGS_MASK (0x40U) +# define ETHTRCV_WUR_WODL_WUP_FLAGS_MASK (0x80U) +# define ETHTRCV_WUR_WODL_WUR_FLAGS_MASK (0x100U) +# define ETHTRCV_WUR_TRANSFER_FLAGS_MASK (0x200U) +# define ETHTRCV_WUR_CLEAR_MASK (0x00U) + +/* EthTrcv wakeup inspection types */ +# define ETHTRCV_ICU_CHANNEL (0x01U) +# define ETHTRCV_TRCV_REGISTERS (0x02U) +# define ETHTRCV_USER_CODE (0x03U) + +/* ETHTRCV MII modes */ +# define ETHTRCV_MII_MODE (0x00U) +# define ETHTRCV_LIGHT_MII_MODE (0x01U) +# define ETHTRCV_RMII_MODE (0x02U) +# define ETHTRCV_RMII_XTAL_MODE (0x03U) +# define ETHTRCV_GMII_MODE (0x04U) +# define ETHTRCV_RGMII_MODE (0x05U) +# define ETHTRCV_RGMII_XTAL_MODE (0x06U) +# define ETHTRCV_STRAPPING_CONFIG_ONLY (0x07U) +# define ETHTRCV_DONT_CARE (0xFFU) + +/* ETHTRCV CONN NEG modes*/ +# define ETHTRCV_CONN_NEG_AUTO (0x00U) +# define ETHTRCV_CONN_NEG_MASTER (0x01U) +# define ETHTRCV_CONN_NEG_SLAVE (0x02U) +# define ETHTRCV_CONN_NEG_MANUAL (0x03U) + +# define ETHTRCV_PHYS_ADDR_LEN_BYTE (0x06U) + +/* ETHTRCV Phy Test Modes */ +# define ETHTRCV_PHYTESTMODE_NONE (0x00U) /* Normal operation*/ +# define ETHTRCV_PHYTESTMODE_1 (0x01U) /* Test transmitter drop */ +# define ETHTRCV_PHYTESTMODE_2 (0x02U) /* Test master timing jitter */ +# define ETHTRCV_PHYTESTMODE_3 (0x03U) /* Test slave timing jitter */ +# define ETHTRCV_PHYTESTMODE_4 (0x04U) /* Test transmitter distortion */ +# define ETHTRCV_PHYTESTMODE_5 (0x05U) /* Test power spectral density */ + +/* ETHTRCV Phy Loopback Modes */ +# define ETHTRCV_PHYLOOPBACK_NONE (0x00U) /* Normal operation */ +# define ETHTRCV_PHYLOOPBACK_INTERNAL (0x01U) /* Internal Loopback */ +# define ETHTRCV_PHYLOOPBACK_EXTERNAL (0x02U) /* External Loopback */ +# define ETHTRCV_PHYLOOPBACK_REMOTE (0x03U) /* Remote loopback */ + +/* ETHTRCV Phy Tx Modes */ +# define ETHTRCV_PHYTXMODE_NORMAL (0x00U) /* Normal Operation */ +# define ETHTRCV_PHYTXMODE_TX_OFF (0x01U) /* Transmitter disabled */ +# define ETHTRCV_PHYTXMODE_SCRAMBLER_OFF (0x02U) /* Scrambler disabled */ + +/* ETHTRCV Cable Diagnostic Status */ +# define ETHTRCV_CABLEDIAG_OK (0x00U) /* Cable diagnostic ok */ +# define ETHTRCV_CABLEDIAG_ERROR (0x01U) /* Cable diagnostic failed*/ +# define ETHTRCV_CABLEDIAG_SHORT (0x02U) /* Short circuit detected */ +# define ETHTRCV_CABLEDIAG_OPEN (0x03U) /* Open circuit detected */ +# define ETHTRCV_CABLEDIAG_PENDING (0x04U) /* Cable diagnostic is still running */ +# define ETHTRCV_CABLEDIAG_WRONG_POLARITY (0x05U) /* Wrong polarity detected */ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ +typedef uint8 EthTrcv_ModeType; +typedef uint8 EthTrcv_LinkStateType; +typedef uint8 EthTrcv_BaudRateType; +typedef uint8 EthTrcv_DuplexModeType; +typedef uint8 EthTrcv_StateType; +typedef uint8 EthTrcv_WakeupModeType; +typedef uint8 EthTrcv_WakeupReasonType; +typedef uint8 EthTrcv_WakeupReasonFlagsType; +typedef uint8 EthTrcv_WakeupInspectionType; +typedef uint8 EthTrcv_PhysAddrType[ETHTRCV_PHYS_ADDR_LEN_BYTE]; +typedef uint8 EthTrcv_PhyTestModeType; +typedef uint8 EthTrcv_PhyLoopbackModeType; +typedef uint8 EthTrcv_PhyTxModeType; +typedef uint8 EthTrcv_CableDiagResultType; + +#endif /* ETHTRCV_GENERAL_TYPES_H */ + +/********************************************************************************************************************** + * END OF FILE: EthTrcv_GeneralTypes.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Common/Eth_GeneralTypes.h b/Source/bsw/Common/Eth_GeneralTypes.h new file mode 100644 index 0000000..e7069bd --- /dev/null +++ b/Source/bsw/Common/Eth_GeneralTypes.h @@ -0,0 +1,91 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file Eth_GeneralTypes.h + * \brief General types header for the Ethernet stack + * + * \details Holds general data types and defines provided to and used by multiple components of the Vector + * Ethernet stack. + * + *********************************************************************************************************************/ +/********************************************************************************************************************** + * REVISION HISTORY + * ---------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ---------------------------------------------------------------------------------------------------------------------- + * 00.01.00 2017-07-14 visfer - Initial creation based on merge of Eth_GeneralTypes.h, + * EthTrcv_GeneralTypes.hand EthSwt_GeneralTypes.h, + * adaptions for AUTOSAR compliance + * 00.02.00 2017-10-04 visfer - Reorder members of Eth_TimeStampType, added Eth_CounterType and + * Eth_TxErrorCounterValuesType + * 03.00.00 2018-11-20 visnhe STORYC-5875 Release Impl_EthGeneralTypes of CommonAsr__Common + * 03.00.01 2019-02-25 vismha ESCAN00102246 Compiler error: EthSwt_GeneralTypes.h missing identifiers + * 04.00.00 2019-04-29 visdrr STORYC-7881 Interface between DrvEth__coreAsr and DrvEthSwitch__coreAsr according to ASR4.4.x (DrvEthSwitch__coreAsr) + * STORYC-7882 Interface between DrvEth__coreAsr and DrvEthSwitch__coreAsr according to ASR4.4.x (DrvEth__coreAsr) + * 04.00.01 2019-05-22 visdrr ESCAN00103216 Unused types and struct members defined in Eth_GeneralTypes and + * EthSwt_GeneralTypes + * 2019-07-02 vismha STORYC-7864 Introduce management object retrieval in reception path + * STORYC-7865 Introduce management object retrieval in transmission path + * 04.01.00 2020-04-16 visdrr ETH-1255 Provide information about dropped frames due to insufficient Tx/Rx + * software buffers + * 2020-04-23 visken ESCAN00105580 SGMII configuration incomplete - Added type and defenitions in + * EthSwt_GeneralTypes to store xMII connection type of a switch port + * 04.02.00 2021-05-11 visken ETHPLAY-28 Allow basic switching based on MAC address only - Added new definitions + * for PortSpeed, BaudRate and XMiiPortConnectionType + * 04.03.00 2021-11-17 virpab ETHPLAY-1759 Introduction of new definitions for CableDiagResult to CommonAsr__Common + * 04.04.00 2022-08-09 visapp ETHPLAY-2576 Change typedef EthSwt_MacVlanType in EthSwt_GeneralTypes.h to support + * uint32 bitmask in element SwitchPort + * 04.05.00 2022-11-25 dkeswani ETHPLAY-1788 Add asymmetric time synchronization support + * 04.06.00 2023-03-01 baubeck ETHCIF-2465 Added missing types from ASR 4.3.0, 4.6.0 and 4.7.0. + * Changed Eth_RateRatioType to struct. + * 04.07.00 2023-04-03 mloy ETHCIF-1591 Implement USXGMII support. + * 04.08.00 2023-06-12 mmares ETHCIF-4052 Communication speeds 5Gbit/s and 10 Gbit/s were added + * 04.09.00 2023-07-10 dkeswani ETHPLAY-4899 Add Destination Port Modification Types in EthSwtGeneralTypes.h + * 04.10.00 2024-10-22 visdep OSHAL-2156 Introduced conditional typedef for Eth_TimeStampType based on the + * existence of TimeStampType to avoid type redefinition conflicts. + * 04.11.00 2024-11-05 dkeswani ETHPLAY-5526 Define EthSwt_HwFilterEntryConfigType at EthSwt_GeneralTypes.h + * 2024-11-06 pkotteti DADC-145 WODL feature supportive Transceiver Macros + * 2024-11-11 dkeswani ETHPLAY-3532 Analyse how to configure half duplex mode and implement it - Added new + * types for Half and Full Duplex + * 04.12.00 2024-11-22 visdep OSHAL-2322 Conditionally introduced TimeStamp types from AR23-11 if they are not + * already defined in ComStack_Types.h + * 04.13.00 2024-11-22 pkotteti DADC-145 WODL feature supportive Transceiver Macros + * 04.14.00 2025-02-25 baubeck ETHCIF-10194 Introduce Eth_RateDeviationType and Eth_StreamStatisticCounterType + * 04.15.00 2025-02-27 viraid ETHPLAY-5370 Change the Eth_DataType from uint32 to uint8 + * 04.16.00 2025-02-27 pkotteti PS-7666 WODL feature supportive Transceiver Macros + * 04.17.00 2025-06-23 baubeck ETHCIF-11432 Add Preprocessor Conditionals Around Eth_SpiStatusType and + * Eth_RateDeviationType + * 04.18.00 2025-06-25 mbodenstein ENOVA-59 Introduce Eth_TimestampQualType and #define ETH_TIMESTAMP_QUAL_TYPE_IN_ETH_GENERAL_TYPES + * to indicate that Eth_TimestampQualType is available in Eth_GeneralTypes. + * 04.18.01 2025-07-03 mbodenstein ENOVA-1256 Fix Typo in Eth_TimeStampQualType. + * 04.19.00 2025-07-07 mschmitt ETHPLAY-7001 Add PhysicalLayerType for 10BASE-T1S + * 04.20.00 2025-08-07 jgrandhi ETHPLAY-1710 Move All SWS EthernetDriver related Definations to new file Eth_GeneralTypesDefs.h + * 04.21.00 2025-10-24 dkeswani ETHPLAY-7948 Introduction of PENDING state as return value for HW Filter APIs + **********************************************************************************************************************/ +#ifndef ETH_GENERAL_TYPES_H +# define ETH_GENERAL_TYPES_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Std_Types.h" +# include "ComStack_Types.h" +# include "Eth_GeneralTypesDefs.h" +# include "EthTrcv_GeneralTypes.h" +# include "EthSwt_GeneralTypes.h" + +#endif /* ETH_GENERAL_TYPES_H */ + +/********************************************************************************************************************** + * END OF FILE: Eth_GeneralTypes.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Common/Eth_GeneralTypesDefs.h b/Source/bsw/Common/Eth_GeneralTypesDefs.h new file mode 100644 index 0000000..4e0714d --- /dev/null +++ b/Source/bsw/Common/Eth_GeneralTypesDefs.h @@ -0,0 +1,315 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file Eth_GeneralTypesDefs.h + * \brief General types header for the Ethernet stack + * + * \details Holds general data types and defines provided to and used by multiple components of the Vector + * Ethernet stack. + * + *********************************************************************************************************************/ +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to Eth_GeneralTypes.h + *********************************************************************************************************************/ + +#ifndef ETH_GENERAL_TYPES_DEFS_H +# define ETH_GENERAL_TYPES_DEFS_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Std_Types.h" +# include "ComStack_Types.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ +/* ETH modes */ +# define ETH_MODE_DOWN (0x00u) +# define ETH_MODE_ACTIVE (0x01u) +# define ETH_MODE_ACTIVE_WITH_WAKEUP_REQUEST (0x02u) +# define ETH_MODE_ACTIVE_TX_OFFLINE (0x03u) + +/* ETH return type */ +# define ETH_OK (0x00u) +# define ETH_E_NOT_OK (0x01u) +# define ETH_E_NO_ACCESS (0x02u) + +/* ETH RX status type */ +# define ETH_RECEIVED (0x00u) +# define ETH_NOT_RECEIVED (0x01u) +# define ETH_RECEIVED_MORE_DATA_AVAILABLE (0x02u) +# define ETH_RECEIVED_FRAMES_LOST (0x03u) + +/* ETH filter action types */ +# define ETH_ADD_TO_FILTER (0x00u) +# define ETH_REMOVE_FROM_FILTER (0x01u) + +/* ETH states */ +# define ETH_STATE_UNINIT (0x00u) +# define ETH_STATE_INIT (0x01u) +# define ETH_STATE_ACTIVE (0x02u) +# define ETH_STATE_MODE_DOWN (0x03u) +# define ETH_STATE_MODE_ACTIVE (0x04u) + +/* ETH MII modes */ +# define ETH_MII_MODE (0x00u) +# define ETH_RMII_MODE (0x01u) +# define ETH_GMII_MODE (0x02u) +# define ETH_RGMII_MODE (0x03u) +# define ETH_SGMII_MODE (0x04u) +# define ETH_USXGMII_MODE (0x05u) + +# define ETH_INVALID_FRAME_ID (0x00u) + +# define ETH_PHYS_ADDR_LEN_BYTE (6u) +# define ETH_ETHER_TYPE_LEN_BYTE (2u) +# define ETH_HEADER_LEN_BYTE (14u) + +/* ETH Timestamp Quality Types */ +# define ETH_TIMESTAMP_VALID (0u) +# define ETH_TIMESTAMP_INVALID (1u) +# define ETH_TIMESTAMP_UNCERTAIN (2u) + +/* ETH Timestamp Quality Types */ +# define ETH_VALID (0u) /* Timestamp is valid */ +# define ETH_INVALID (1u) /* Timestamp is invalid */ +# define ETH_UNCERTAIN (2u) /* Status of timestamp is uncertain */ + +/*! Value defining that the counter isn't supported */ +# define ETH_RXTX_STATS_INV_COUNTER_VAL (0xFFFFFFFFu) +/*! Value defining that the counter has overflown */ +# define ETH_RXTX_STATS_COUNTER_OVERFLOW_VAL (0xFFFFFFFEu) +/*! Value defining the maximum possible counter value */ +# define ETH_RXTX_STATS_MAX_COUNTER_VAL (0xFFFFFFFDu) + +/* Transceiver speeds in [bit/s] */ +# define ETH_TRCV_SPEED_10MBITS_IN_BITS (10000000u) +# define ETH_TRCV_SPEED_100MBITS_IN_BITS (100000000u) +# define ETH_TRCV_SPEED_1000MBITS_IN_BITS (1000000000u) +# define ETH_TRCV_SPEED_2500MBITS_IN_BITS (2500000000u) +# define ETH_TRCV_SPEED_5000MBITS_IN_BITS (5000000000u) +# define ETH_TRCV_SPEED_10000MBITS_IN_BITS (10000000000u) +# define ETH_TRCV_SPEED_DONT_CARE (0xFFFFFFFFu) + +/* ETH Measurement Index Types */ +# define ETH_MEAS_ALL (0xFFu) +# define ETH_MEAS_VENDOR_SPECIFIC_DROP_INSUFF_TX_BUFFER (0x90u) +# define ETH_MEAS_VENDOR_SPECIFIC_WARN_FULL_RX_BUFFER (0x91u) +# define ETH_MEAS_VENDOR_SPECIFIC_DROP_INSUFF_RX_BUFFER (0x92u) + +# ifndef NO_ETH_RATE_DEVIATION_TYPE_IN_ETH_GENERAL_TYPES +/* Type that indicates the current status of the rate calculation */ +# define ETH_RATE_OK (0x00u) /* A valid rate deviaton value is available/calculated */ +# define ETH_RATE_NOT_AVAILABLE (0xFEu) /* No valid rate deviation value available/calculated */ +# define ETH_RATE_EXCEEDED (0xFFu) /* The calculated rate deviation value exceeds limits */ +# endif /* NO_ETH_RATE_DEVIATION_TYPE_IN_ETH_GENERAL_TYPES */ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ +typedef uint8 Eth_ReturnType; +typedef uint8 Eth_ModeType; +typedef uint16 Eth_FrameType; +typedef uint8 Eth_DataType; +typedef uint8 Eth_RxStatusType; +typedef uint8 Eth_FilterActionType; +typedef uint32 Eth_BufIdxType; +typedef uint8 Eth_StateType; +typedef uint8 Eth_MeasurementIdxType; +# ifndef NO_ETH_RATE_DEVIATION_TYPE_IN_ETH_GENERAL_TYPES +typedef uint8 Eth_RateDeviationStatusType; +# endif /* NO_ETH_RATE_DEVIATION_TYPE_IN_ETH_GENERAL_TYPES */ + +/* ETH Physical Address Type */ +typedef uint8 Eth_PhysAddrType[ETH_PHYS_ADDR_LEN_BYTE]; + +/* If the TimeStampType is defined in ComStack_Types.h then typedef the Eth_TimeStampType to TimeStampType. + Otherwise define the Eth_TimeStampType explicitly */ +# ifdef TIME_STAMP_TYPE +typedef TimeStampType Eth_TimeStampType; +# else +/*! \brief Type defining a time stamp according to AUTOSAR 4.2 */ +typedef struct +{ + uint32 nanoseconds; + uint32 seconds; + uint16 secondsHi; +} Eth_TimeStampType; + +/* Definition of AR23-11 TimeStamp types if they are not defined through ComStack_Types.h to provide backward + compatibility */ +typedef struct +{ + uint32 nanoseconds; /* Nanoseconds part of the time */ + uint32 seconds; /* 32 bit LSB of the 48 bits Seconds part of the time */ + uint16 secondsHi; /* 16 bit MSB of the 48 bits Seconds part of the time */ +} TimeStampType; /* ASR CP R23-11 */ + +typedef enum +{ + VALID = 0, /* Timestamp is valid */ + INVALID = 1, /* Timestamp is invalid */ + UNCERTAIN = 2 /* Status of timestamp is uncertain */ +} TimeStampQualType; /* ASR CP R23-11 */ + +typedef struct +{ + TimeStampType timestampClockValue; /* Value of the clock, which is used of ingress/egress timestamping */ + TimeStampType disciplinedClockValue; /* Value of the adjustable HW clock */ + TimeStampQualType timeQuality; /* Status of time tuple */ +} TimeTupleType; +# endif /* TIME_STAMP_TYPE */ + +/*! \brief Type defining the quality of a time stamp */ +typedef uint8 Eth_TimestampQualityType; + +/*! \brief Type defining the quality of a time stamp */ +typedef uint8 Eth_TimeStampQualType; + +/* Define ETH_TIMESTAMP_QUAL_TYPE_IN_ETH_GENERAL_TYPES to indicate that Eth_TimestampQualType is available in Eth_GeneralTypes. */ +#define ETH_TIMESTAMP_QUAL_TYPE_IN_ETH_GENERAL_TYPES + +/*! \brief Vector type defining the difference between time stamps */ +typedef sint32 Eth_TimediffType; + +/*! \brief AUTOSAR type defining the difference between time stamps */ +typedef struct +{ + Eth_TimeStampType diff; + boolean sign; +} Eth_TimeIntDiffType; + +/*! \brief Type defining the drift of a clock related to another clock */ +typedef struct +{ + Eth_TimeIntDiffType IngressTimeStampDelta; + Eth_TimeIntDiffType OriginTimeStampDelta; +} Eth_RateRatioType; + +/*! brief Type to read out addresses from the address resolution logic (ARL) table of the switch */ +typedef struct +{ + uint8 MacAddr[6]; + uint16 VlanId; + uint32 SwitchPort; +} Eth_MacVlanType; + +/*! brief Structure holding statistic counters for diagnostics */ +typedef struct +{ + uint32 DropPktBufOverrun; + uint32 DropPktCrc; + uint32 UndersizePkt; + uint32 OversizePkt; + uint32 AlgnmtErr; + uint32 SqeTestErr; + uint32 DiscInbdPkt; + uint32 ErrInbdPkt; + uint32 DiscOtbdPkt; + uint32 ErrOtbdPkt; + uint32 SnglCollPkt; + uint32 MultCollPkt; + uint32 DfrdPkt; + uint32 LatCollPkt; + uint32 HwDepCtr0; + uint32 HwDepCtr1; + uint32 HwDepCtr2; + uint32 HwDepCtr3; +} Eth_CounterType; + +/*! \brief Structure holding transmission statistic counters related to the Eth controller. */ +typedef struct +{ + uint32 TxNumberOfOctets; + uint32 TxNUcastPkts; + uint32 TxUniCastPkts; +} Eth_TxStatsType; + +/*! brief Structure holding reception statistic counters related to the Eth controller. */ +typedef struct +{ + uint32 RxStatsDropEvents; + uint32 RxStatsOctets; + uint32 RxStatsPkts; + uint32 RxStatsBroadcastPkts; + uint32 RxStatsMulticastPkts; + uint32 RxStatsCrcAlignErrors; + uint32 RxStatsUndersizePkts; + uint32 RxStatsOversizePkts; + uint32 RxStatsFragments; + uint32 RxStatsJabbers; + uint32 RxStatsCollisions; + uint32 RxStatsPkts64Octets; + uint32 RxStatsPkts65to127Octets; + uint32 RxStatsPkts128to255Octets; + uint32 RxStatsPkts256to511Octets; + uint32 RxStatsPkts512to1023Octets; + uint32 RxStatsPkts1024to1518Octets; + uint32 RxUnicastFrames; +} Eth_RxStatsType; + +/*! brief Type for statistic counters for tx diagnostics. */ +typedef struct +{ + uint32 TxDroppedNoErrorPkts; + uint32 TxDroppedErrorPkts; + uint32 TxDeferredTrans; + uint32 TxSingleCollision; + uint32 TxMultipleCollision; + uint32 TxLateCollision; + uint32 TxExcessiveCollison; +} Eth_TxErrorCounterValuesType; + +# ifndef NO_ETH_SPI_STATUS_TYPE_IN_ETH_GENERAL_TYPES +/*! brief Type to return the Spi status, errors and configuration state. */ +typedef struct +{ + uint32 SpiStatusRegister; + boolean Sync; + uint8 BufferStatusTxCredit; + uint8 BufferStatusRxCredit; +} Eth_SpiStatusType; +# endif /* NO_ETH_SPI_STATUS_TYPE_IN_ETH_GENERAL_TYPES */ + +# ifndef NO_ETH_RATE_DEVIATION_TYPE_IN_ETH_GENERAL_TYPES +/*! brief Rate deviation value and status */ +typedef struct +{ + sint32 rateDeviationValue; /* Rate deviation value (resolution: 2^{-32}) */ + Eth_RateDeviationStatusType rateDeviationStatus; /* Current state of the rate deviation calculation */ +} Eth_RateDeviationType; +# endif /* NO_ETH_RATE_DEVIATION_TYPE_IN_ETH_GENERAL_TYPES */ + +/*! brief Type for holding the bucket counter values for a stream */ +typedef struct +{ + uint8 BucketIdx; /* Bucket Index */ + uint32 CounterValue; /* Bucket counter value */ +} Eth_StreamStatisticCounterType; + +/*! brief Type to return the pre-correction time, applied rate deviation and new PHC rate. */ +typedef struct +{ + TimeStampType PreCorrTime; /* Value of the PHC right before the correction is applied. */ + sint32 AppliedRateDeviation; /* The actual applied rate deviation (resolution: 2^{-32}). Although this parameter could be calculated using "NewPhcRate", it is explicitly returned to avoid inaccuracies in the calculation on UL side. */ + sint32 NewPhcRate; /* The resulting new rate of the PHC compared to initialization (1.0) (resolution: 2^{-32}). */ +} Eth_PhcCorrInfoType; + +#endif /* ETH_GENERAL_TYPES_DEFS_H */ + +/********************************************************************************************************************** + * END OF FILE: Eth_GeneralTypesDefs.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Common/Fr_GeneralTypes.h b/Source/bsw/Common/Fr_GeneralTypes.h new file mode 100644 index 0000000..39ae390 --- /dev/null +++ b/Source/bsw/Common/Fr_GeneralTypes.h @@ -0,0 +1,322 @@ +/* ***** STARTSINGLE_OF_MULTIPLE_COMMENT ***** */ + + +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------- + * File: Fr_GeneralTypes.h + * Project: FlexRay Stack + * Module: - + * Generator: - + * + * Description: Datatype definitions according to AUTOSAR 3.0 FlexRay Driver SWS + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * AUTHOR IDENTITY + * ------------------------------------------------------------------------------------------------------------------- + * Name Initials Company + * ------------------------------------------------------------------------------------------------------------------- + * Sebastian Schmar Ssr Vector Informatik GmbH + * Juergen Schaeffer Jsr Vector Informatik GmbH + * Sebastian Gaertner Seg Vector Informatik GmbH + * Klaus Bergdolt Ber Vector Informatik GmbH + * Matthias Mueller Mmu Vector Informatik GmbH + * ------------------------------------------------------------------------------------------------------------------- + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2006-05-17 Ber Generated filed according to AUTOSAR FlexRay Driver SWS. + * 01.00.01 2008-03-19 Jsr Changed enum types to u8 types + * 01.00.02 2008-06-24 Jsr ESCAN00027841 Fr_VErrorStatusType added + * 01.01.00 2008-11-04 Seg ESCAN00030471 Name of Fr_GeneralTypes.h + * 01.02.00 2009-03-11 Seg ESCAN00032698 Missing versionstring for licence database + * 01.03.00 2009-07-30 Ssr ESCAN00036317 FlexRay Driver shall support FIFOs (Asr 4.0) + * Jsr ESCAN00031969 update function headers + * 01.03.01 2009-10-22 Jsr ESCAN00035424 Compiler errors in Enabled "Extended Version checks and Link Time" Variant + * 01.04.00 2009-11-13 Jsr ESCAN00037151 Read and verification of the FlexRay configuration + * 01.04.01 2009-11-26 Jsr Update Fr_CCLLParamIndexType + * 01.05.00 2010-02-19 Jsr Update comments according coding rules (CDK) + * ESCAN00040841 Add Trcv Types + * Ssr Resolve compiler errors at header include protection + * 01.06.00 2010-07-23 Jsr Update ReadCCConfig Values according Autosar + * ESCAN00043900 Enhancement parameters for ReadCCConfig + * ESCAN00044864 Truncation of parameter values at ReadCCConfig + * Review finding in in DocTechRef: replace Fr_CCLLParamIndexType with uint8 + * 01.07.00 2011-06-17 Seg ESCAN00048747 Missing declaration of Fr_ConfigType + * ESCAN00050556 Update ReadCCConfig Values according Autosar 3.2 + * ESCAN00051495 Extend FrTrcv_TrcvWUReasonType in Fr_GeneralTypes.h + * 01.08.00 2014-01-13 Mmu ESCAN00070897 AR3-2508: Support Fr_TxConflictStatusType + * 02.00.00 2025-10-23 Mte CANCORE-2233 Support Fr_SlotAssignmentType + **************************************************************************************************/ +#if (!defined FR_GENERALTYPES_H) +# define FR_GENERALTYPES_H + +/************************************************************************************************** +* INCLUDES +**************************************************************************************************/ +# include "Std_Types.h" + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : DrvFr__baseAsr CQComponent : Implementation */ +# define DRVFR__BASEASR_VERSION 0x0200u/* BCD coded version number */ +# define DRVFR__BASEASR_RELEASE_VERSION 0x00u /* BCD coded release version number */ + +typedef void Fr_ConfigType; + +/** The values of this enumeration are used to provide information + whether or not the local FlexRay CC is synchronous to the FR global time */ + +typedef uint8 Fr_SyncStateType; +# define FR_ASYNC ((Fr_SyncStateType)0) /** The local FlexRay CC is asynchronous to the FR global time */ +# define FR_SYNC ((Fr_SyncStateType)1) /** The local FlexRay CC is synchronous to the FR global time */ + +typedef uint8 Fr_OffsetCorrectionType; +# define FR_OFFSET_INC ((Fr_OffsetCorrectionType)0) /** add predefined correction value vOffsetCorrection */ +# define FR_OFFSET_DEC ((Fr_OffsetCorrectionType)1) /** subtract predefined correction value vOffsetCorrection */ +# define FR_OFFSET_NOCHANGE ((Fr_OffsetCorrectionType)2) /** apply no offset correction value */ + +typedef uint8 Fr_RateCorrectionType; +# define FR_RATE_INC ((Fr_RateCorrectionType)0) /** add predefined correction value vRateCorrection. */ +# define FR_RATE_DEC ((Fr_RateCorrectionType)1) /** subtract predefined correction value vRateCorrection. */ +# define FR_RATE_NOCHANGE ((Fr_RateCorrectionType)2) /** apply no rate correction value */ + +typedef uint8 Fr_POCStateType; +# define FR_POCSTATE_CONFIG ((Fr_POCStateType)0) /** Configuration state */ +# define FR_POCSTATE_DEFAULT_CONFIG ((Fr_POCStateType)1) /** State prior to config, only left with an explicit configuration request */ +# define FR_POCSTATE_HALT ((Fr_POCStateType)2) /** Error state, can only be left by a re-initialization */ +# define FR_POCSTATE_NORMAL_ACTIVE ((Fr_POCStateType)3) /** Normal operation */ +# define FR_POCSTATE_NORMAL_PASSIVE ((Fr_POCStateType)4) /** Errors detected, no transmission of data, but attempting to return to normal operation */ +# define FR_POCSTATE_READY ((Fr_POCStateType)5) /** State reached from FR_POCSTATE_CONFIG after concluding the configuration */ +# define FR_POCSTATE_STARTUP ((Fr_POCStateType)6) /** CC transmits only startup frames */ +# define FR_POCSTATE_WAKEUP ((Fr_POCStateType)7) /** CC sends a wakeup pattern if it couldn't find anything on the bus */ + +typedef uint8 Fr_TxLPduStatusType; +# define FR_TRANSMITTED ((Fr_TxLPduStatusType)0) /** LSdu has been transmitted */ +# define FR_NOT_TRANSMITTED ((Fr_TxLPduStatusType)1) /** LSdu has not been transmitted */ + +/** These values are used to determine if a LSdu has been received */ +typedef uint8 Fr_RxLPduStatusType; +# define FR_RECEIVED ((Fr_RxLPduStatusType)0) /** LSdu has been received */ +# define FR_NOT_RECEIVED ((Fr_RxLPduStatusType)1) /** LSdu has not been received */ +# define FR_RECEIVED_MORE_DATA_AVAILABLE ((Fr_RxLPduStatusType)2) + +/** This formal definition refers to chapter "2.2.1.3 POC status" of FlexRay Protocol Specification */ +typedef uint8 Fr_WakeupStateType; +# define FR_WAKEUPSTATE_UNDEFINED ((Fr_WakeupStateType)0) +# define FR_WAKEUPSTATE_RECEIVED_HEADER ((Fr_WakeupStateType)1) +# define FR_WAKEUPSTATE_RECEIVED_WUP ((Fr_WakeupStateType)2) +# define FR_WAKEUPSTATE_COLLISION_HEADER ((Fr_WakeupStateType)3) +# define FR_WAKEUPSTATE_COLLISION_WUP ((Fr_WakeupStateType)4) +# define FR_WAKEUPSTATE_COLLISION_UNKNOWN ((Fr_WakeupStateType)5) +# define FR_WAKEUPSTATE_TRANSMITTED ((Fr_WakeupStateType)6) + +/** These values are derived from Table 9-1 of Version 2.1 of the FlexRay Protocol Specification */ +typedef uint8 Fr_MTSStatusType; +# define FR_MTS_RCV ((Fr_MTSStatusType)0)/** A valid MTS has been received */ +# define FR_MTS_RCV_SYNERR ((Fr_MTSStatusType)1)/** A valid MTS has been received and a Syntax Error was detected */ +# define FR_MTS_RCV_BVIO ((Fr_MTSStatusType)2)/** A valid MTS has been received and a Boundary Violation has been detected */ +# define FR_MTS_RCV_SYNERR_BVIO ((Fr_MTSStatusType)3)/** A valid MTS has been received and a Syntax Error and a Boundary Violation has been detected */ +# define FR_MTS_NOT_RCV ((Fr_MTSStatusType)4)/** No valid MTS has been received */ +# define FR_MTS_NOT_RCV_SYNERR ((Fr_MTSStatusType)5)/** No valid MTS has been received and a Syntax Error was detected */ +# define FR_MTS_NOT_RCV_BVIO ((Fr_MTSStatusType)6)/** No valid MTS has been received and a Boundary Violation has been detected */ +# define FR_MTS_NOT_RCV_SYNERR_BVIO ((Fr_MTSStatusType)7)/** No valid MTS has been received and a Syntax Error and a Boundary Violation has been detected */ + +/** The values are used to reference a channel on a CC */ +typedef uint8 Fr_ChannelType; +# define FR_CHANNEL_A ((Fr_ChannelType)0)/** Refers to channel A of a CC */ +# define FR_CHANNEL_B ((Fr_ChannelType)1)/** Refers to channel B of a CC */ +# define FR_CHANNEL_AB ((Fr_ChannelType)2)/** Refers to both channels of a CC */ + +typedef uint8 Fr_SlotModeType; +# define FR_SLOTMODE_SINGLE ((Fr_SlotModeType)0) +# define FR_SLOTMODE_ALL_PENDING ((Fr_SlotModeType)1) +# define FR_SLOTMODE_ALL ((Fr_SlotModeType)2) + +typedef uint8 Fr_ErrorModeType; +# define FR_ERRORMODE_ACTIVE ((Fr_ErrorModeType)0) +# define FR_ERRORMODE_PASSIVE ((Fr_ErrorModeType)1) +# define FR_ERRORMODE_COMM_HALT ((Fr_ErrorModeType)2) + +typedef uint8 Fr_WakeupStatusType; +# define FR_WAKEUP_UNDEFINED ((Fr_WakeupStatusType)0) +# define FR_WAKEUP_RECEIVED_HEADER ((Fr_WakeupStatusType)1) +# define FR_WAKEUP_RECEIVED_WUP ((Fr_WakeupStatusType)2) +# define FR_WAKEUP_COLLISION_HEADER ((Fr_WakeupStatusType)3) +# define FR_WAKEUP_COLLISION_WUP ((Fr_WakeupStatusType)4) +# define FR_WAKEUP_COLLISION_UNKNOWN ((Fr_WakeupStatusType)5) +# define FR_WAKEUP_TRANSMITTED ((Fr_WakeupStatusType)6) + +typedef uint8 Fr_StartupStateType; +# define FR_STARTUP_UNDEFINED ((Fr_StartupStateType)0) +# define FR_STARTUP_COLDSTART_LISTEN ((Fr_StartupStateType)1) +# define FR_STARTUP_INTEGRATION_COLDSTART_CHECK ((Fr_StartupStateType)2) +# define FR_STARTUP_COLDSTART_JOIN ((Fr_StartupStateType)3) +# define FR_STARTUP_COLDSTART_COLLISION_RESOLUTION ((Fr_StartupStateType)4) +# define FR_STARTUP_COLDSTART_CONSISTENCY_CHECK ((Fr_StartupStateType)5) +# define FR_STARTUP_INTEGRATION_LISTEN ((Fr_StartupStateType)6) +# define FR_STARTUP_INITIALIZE_SCHEDULE ((Fr_StartupStateType)7) +# define FR_STARTUP_INTEGRATION_CONSISTENCY_CHECK ((Fr_StartupStateType)8) +# define FR_STARTUP_COLDSTART_GAP ((Fr_StartupStateType)9) + +typedef struct +{ + boolean ColdstartNoise; + boolean CHIHaltRequest; + boolean Freeze; + Fr_SlotModeType SlotMode; + Fr_WakeupStatusType WakeupStatus; + Fr_ErrorModeType ErrorMode; + Fr_StartupStateType StartupState; + Fr_POCStateType State; +} Fr_POCStatusType; + +/* This structure contains information about the assignment of a FlexRay frame to a cycle, a slot ID and a channel. */ +typedef struct +{ + uint8 Cycle; + uint16 SlotId; + Fr_ChannelType ChannelId; +} Fr_SlotAssignmentType; + +typedef uint32 Fr_VErrorStatusType; + +/** Data type to provide information about Tx conflicts. */ +typedef enum +{ + FR_NO_CONFLICT = 0u, + FR_CONFLICT +} Fr_TxConflictStatusType; + +/* uint32 values */ +#define FR_CIDX_GDCYCLE 0 +#define FR_CIDX_PMICROPERCYCLE 1 +#define FR_CIDX_PDLISTENTIMEOUT 2 + +/* uint16 values */ +#define FR_CIDX_GMACROPERCYCLE 3 +#define FR_CIDX_GDMACROTICK 4 +#define FR_CIDX_GNUMBEROFMINISLOTS 5 +#define FR_CIDX_GNUMBEROFSTATICSLOTS 6 +#define FR_CIDX_GDNIT 7 +#define FR_CIDX_GDSTATICSLOT 8 +#define FR_CIDX_GDWAKEUPRXWINDOW 9 +#define FR_CIDX_PKEYSLOTID 10 +#define FR_CIDX_PLATESTTX 11 +#define FR_CIDX_POFFSETCORRECTIONOUT 12 +#define FR_CIDX_POFFSETCORRECTIONSTART 13 +#define FR_CIDX_PRATECORRECTIONOUT 14 +#define FR_CIDX_PSECONDKEYSLOTID 15 +#define FR_CIDX_PDACCEPTEDSTARTUPRANGE 16 + +/* uint8 values */ +#define FR_CIDX_GCOLDSTARTATTEMPTS 17 +#define FR_CIDX_GCYCLECOUNTMAX 18 +#define FR_CIDX_GLISTENNOISE 19 +#define FR_CIDX_GMAXWITHOUTCLOCKCORRECTFATAL 20 +#define FR_CIDX_GMAXWITHOUTCLOCKCORRECTPASSIVE 21 +#define FR_CIDX_GNETWORKMANAGEMENTVECTORLENGTH 22 +#define FR_CIDX_GPAYLOADLENGTHSTATIC 23 +#define FR_CIDX_GSYNCFRAMEIDCOUNTMAX 24 +#define FR_CIDX_GDACTIONPOINTOFFSET 25 +#define FR_CIDX_GDBIT 26 +#define FR_CIDX_GDCASRXLOWMAX 27 +#define FR_CIDX_GDDYNAMICSLOTIDLEPHASE 28 +#define FR_CIDX_GDMINISLOTACTIONPOINTOFFSET 29 +#define FR_CIDX_GDMINISLOT 30 +#define FR_CIDX_GDSAMPLECLOCKPERIOD 31 +#define FR_CIDX_GDSYMBOLWINDOW 32 +#define FR_CIDX_GDSYMBOLWINDOWACTIONPOINTOFFSET 33 +#define FR_CIDX_GDTSSTRANSMITTER 34 +#define FR_CIDX_GDWAKEUPRXIDLE 35 +#define FR_CIDX_GDWAKEUPRXLOW 36 +#define FR_CIDX_GDWAKEUPTXACTIVE 37 +#define FR_CIDX_GDWAKEUPTXIDLE 38 +#define FR_CIDX_PALLOWPASSIVETOACTIVE 39 +#define FR_CIDX_PCHANNELS 40 +#define FR_CIDX_PCLUSTERDRIFTDAMPING 41 +#define FR_CIDX_PDECODINGCORRECTION 42 +#define FR_CIDX_PDELAYCOMPENSATIONA 43 +#define FR_CIDX_PDELAYCOMPENSATIONB 44 +#define FR_CIDX_PMACROINITIALOFFSETA 45 +#define FR_CIDX_PMACROINITIALOFFSETB 46 +#define FR_CIDX_PMICROINITIALOFFSETA 47 +#define FR_CIDX_PMICROINITIALOFFSETB 48 +#define FR_CIDX_PPAYLOADLENGTHDYNMAX 49 +#define FR_CIDX_PSAMPLESPERMICROTICK 50 +#define FR_CIDX_PWAKEUPCHANNEL 51 +#define FR_CIDX_PWAKEUPPATTERN 52 +#define FR_CIDX_PDMICROTICK 53 +#define FR_CIDX_PDEXTERNRATECORRECTION 54 +#define FR_CIDX_PDEXTERNOFFSETCORRECTION 55 +#define FR_CIDX_GDIGNOREAFTERTX 56 + +/* boolean values */ +#define FR_CIDX_PALLOWHALTDUETOCLOCK 57 +#define FR_CIDX_PEXTERNALSYNC 58 +#define FR_CIDX_PFALLBACKINTERNAL 59 +#define FR_CIDX_PKEYSLOTONLYENABLED 60 +#define FR_CIDX_PKEYSLOTUSEDFORSTARTUP 61 +#define FR_CIDX_PKEYSLOTUSEDFORSYNC 62 +#define FR_CIDX_PNMVECTOREARLYUPDATE 63 +#define FR_CIDX_PTWOKEYSLOTMODE 64 + + + + + +/* FrTrcv252: FrTrcv048: */ +/*! Transceiver is in an unknown state */ +#define FRTRCV_TRCVMODE_UNKNOWN (FrTrcv_TrcvModeType)0u +/*! Transceiver is in state NORMAL */ +#define FRTRCV_TRCVMODE_NORMAL (FrTrcv_TrcvModeType)1u +/*! Transceiver is in state STANDBY */ +#define FRTRCV_TRCVMODE_STANDBY (FrTrcv_TrcvModeType)2u +/*! Transceiver is in state SLEEP */ +#define FRTRCV_TRCVMODE_SLEEP (FrTrcv_TrcvModeType)3u +/*! Transceiver is in state RECEIVEONLY */ +#define FRTRCV_TRCVMODE_RECEIVEONLY (FrTrcv_TrcvModeType)4u +/*! The FrTrcv_TrcvModeType defines all modes the Transceiver driver can be set in */ +typedef uint8 FrTrcv_TrcvModeType; + +/* FrTrcv074: */ +/*! The transceiver does not support any information for the wake up reason. */ +#define FRTRCV_WU_NOT_SUPPORTED (FrTrcv_TrcvWUReasonType)0u +/*! The transceiver has detected that the bus has caused the wake up of the ECU. */ +#define FRTRCV_WU_BY_BUS (FrTrcv_TrcvWUReasonType)1u +/*! The transceiver has detected that the bus has woken up by the ECU via FrTrcv_GotoNormalMode API call */ +#define FRTRCV_WU_INTERNALLY (FrTrcv_TrcvWUReasonType)2u +/*! The transceiver has detected that the "wake up" is due to an ECU reset. */ +#define FRTRCV_WU_RESET (FrTrcv_TrcvWUReasonType)3u +/*! The transceiver has detected that the "wake up" is due to an ECU reset after power on. */ +#define FRTRCV_WU_POWER_ON (FrTrcv_TrcvWUReasonType)4u +/*! The transceiver has detected a wake-up event at one of the transceiver's pins (not at the FlexRay bus). */ +#define FRTRCV_WU_BY_PIN (FrTrcv_TrcvWUReasonType)5u +/*! The type determines last wake up reason of the transceiver driver */ +typedef uint8 FrTrcv_TrcvWUReasonType; + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/***** end of header file ************************************************************************/ +#endif /* FR_GENERALTYPES_H */ diff --git a/Source/bsw/Common/Lin_GeneralTypes.h b/Source/bsw/Common/Lin_GeneralTypes.h new file mode 100644 index 0000000..5062883 --- /dev/null +++ b/Source/bsw/Common/Lin_GeneralTypes.h @@ -0,0 +1,254 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file Lin_GeneralTypes.h + * \brief AUTOSAR LIN General types header + * + * \details AUTOSAR LIN General types header for the LIN stack + * + *********************************************************************************************************************/ +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 1.00.00 2020-01-08 visjgl create new Lin General Types + * 1.00.01 2020-03-27 visjgl rework Review findings + * 2.00.00 2024-12-11 visjgl added compatibility support for the Frame Response Type + * 2.01.00 2025-07-21 visjgl LIN-1393 include Std_Types and add numerical representation of enum + *********************************************************************************************************************/ + +#if !defined (LIN_GENERALTYPES_H) +# define LIN_GENERALTYPES_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Std_Types.h" + +/*! + \name LIN General Types + \{ +*/ + +/********************************************************************************************************************** + * LIN General Types + *********************************************************************************************************************/ + +/*! [Defined by AUTOSAR]: LIN operation states for a LIN channel or frame, as returned by the API service + Lin_GetStatus(). */ +typedef enum Lin_StatusTypeTag +{ + /*! LIN frame operation return value. + Development or production error occurred. */ + LIN_NOT_OK = 0x00u, + + /*! LIN frame operation return value. + Successful transmission. */ + LIN_TX_OK = 0x01u, + + /*! LIN frame operation return value. + Ongoing transmission (Header or Response). */ + LIN_TX_BUSY = 0x02u, + + /*! LIN frame operation return value. + Erroneous header transmission such as: + - Mismatch between sent and read back data + - Identifier parity error or + - Physical bus error */ + LIN_TX_HEADER_ERROR = 0x03u, + + /*! LIN frame operation return value. + Erroneous response transmission such as: + - Mismatch between sent and read back data + - Physical bus error */ + LIN_TX_ERROR = 0x04u, + + /*! LIN frame operation return value. + Successful frame response reception. */ + LIN_RX_OK = 0x05u, + + /*! LIN frame operation return value. + Ongoing reception: at least one response byte has been received, but the checksum byte has not been received. */ + LIN_RX_BUSY = 0x06u, + + /*! LIN frame operation return value. + Erroneous response reception such as: + - Framing error + - Overrun error + - Checksum error or + - Short response */ + LIN_RX_ERROR = 0x07u, + + /*! LIN frame operation return value. + No response byte has been received. */ + LIN_RX_NO_RESPONSE = 0x08u, + + /*! LIN channel state return value. + Normal operation; the related LIN channel is ready to transmit next header. No data from previous frame available + (e.g. after initialization). */ + LIN_OPERATIONAL = 0x09u, + + /*! LIN channel state return value. + Sleep state operation; in this state wake-up detection from responder nodes is enabled. */ + LIN_CH_SLEEP = 0x0Au +} Lin_StatusType; + +/*! [Defined by AUTOSAR]: This type represents the slave error types that are detected during header reception and + response transmission / reception. */ +typedef enum Lin_SlaveErrorTypeTag +{ + /*! Error in header. */ + LIN_ERR_HEADER = 0x00u, + + /*! Framing error in response. */ + LIN_ERR_RESP_STOPBIT = 0x01u, + + /*! Checksum error. */ + LIN_ERR_RESP_CHKSUM = 0x02u, + + /*! Monitoring error of transmitted data bit in response. */ + LIN_ERR_RESP_DATABIT = 0x03u, + + /*! No response. */ + LIN_ERR_NO_RESP = 0x04u, + + /*! Incomplete response. */ + LIN_ERR_INC_RESP = 0x05u +} Lin_SlaveErrorType; + + +/*! [Defined by Vector]: Pointer to a shadow buffer or memory mapped LIN hardware receive buffer where the current SDU + is stored. */ +typedef P2VAR(uint8, TYPEDEF, AUTOMATIC) Lin_u8PtrType; + +/*! [Defined by Vector]: Pointer to pointer to a shadow buffer or memory mapped LIN hardware receive buffer where the + current SDU is stored. */ +typedef P2VAR(Lin_u8PtrType, TYPEDEF, AUTOMATIC) Lin_u8PtrPtrType; + + +/*! [Defined by AUTOSAR]: Represents all valid protected identifier used by Lin_SendFrame(). */ +typedef uint8 Lin_FramePidType; + + +/*! [Defined by AUTOSAR]: This type is used to specify the checksum model to be used for the LIN frame. */ +typedef enum Lin_FrameCsModelTypeTag +{ + /*! Enhanced checksum model. */ + LIN_ENHANCED_CS = 0x00u, + /*! Classic checksum model. */ + LIN_CLASSIC_CS = 0x01u +} Lin_FrameCsModelType; + + +/*! [Defined by AUTOSAR, extended by Vector]: This type is used to specify whether the frame processor is required to + transmit the response part of the LIN frame. */ +typedef enum Lin_FrameResponseTypeTag +{ + /*! Lin_FrameResponseType according to AUTOSAR <= 4.3.1 */ + LIN_MASTER_RESPONSE = 0x00u, /*!< Response is generated from this (master) node */ + LIN_SLAVE_RESPONSE = 0x01u, /*!< Response is generated from a remote slave node */ + LIN_SLAVE_TO_SLAVE = 0x02u, /*!< Response is generated from one slave to another slave */ + + /*! Lin_FrameResponseType according to AUTOSAR >= 4.4.0 */ + LIN_FRAMERESPONSE_TX = 0x00u, /*!< Response is generated by this node. */ + LIN_FRAMERESPONSE_RX = 0x01u, /*!< Response is generated by another node. */ + LIN_FRAMERESPONSE_IGNORE = 0x02u /*!< Response is ignored by this node. */ +} Lin_FrameResponseType; + + + +/*! [Defined by AUTOSAR]: This type is used to specify the number of SDU data bytes to copy. + Range: 1 - 8, data length of a LIN frame. */ +typedef uint8 Lin_FrameDlType; + + +/*! [Defined by AUTOSAR]: This type is used to provide PID, checksum model, data length and SDU pointer of a LIN frame + from the LIN Interface to the LIN driver. */ +typedef struct Lin_PduTypeTag +{ + /*! Valid protected identifier. */ + VAR(Lin_FramePidType, TYPEDEF) Pid; + /*! Specified Checksum model. */ + VAR(Lin_FrameCsModelType, TYPEDEF) Cs; + /*! Type of response part. */ + VAR(Lin_FrameResponseType, TYPEDEF) Drc; + /*! Number of SDU data bytes to copy. */ + VAR(Lin_FrameDlType, TYPEDEF) Dl; + /*! Pointer to SDU data bytes. */ + P2VAR(uint8, TYPEDEF, AUTOMATIC) SduPtr; +} Lin_PduType; + +/*! [Defined by Vector]: Pointer Type for the Lin_PduType */ +typedef P2VAR(Lin_PduType, TYPEDEF, AUTOMATIC) Lin_PduPtrType; + +/*! \} */ + +/*! + \name LIN Transceiver General Types + \{ +*/ + +/********************************************************************************************************************** + * LIN Transceiver General Types + *********************************************************************************************************************/ + +/*! [Defined by AUTOSAR]: This type is used to indicate and set the operation mode of the transceiver. */ +typedef enum LinTrcv_TrcvModeTypeTag +{ + /*! Normal mode. */ + LINTRCV_TRCV_MODE_NORMAL = 0x00u, + /*! Standby mode. */ + LINTRCV_TRCV_MODE_STANDBY = 0x01u, + /*! Sleep mode. */ + LINTRCV_TRCV_MODE_SLEEP = 0x02u +} LinTrcv_TrcvModeType; + +/*! [Defined by AUTOSAR]: This type is used to configure the wakeup setting of the transceiver. */ +typedef enum LinTrcv_TrcvWakeupModeTypeTag +{ + /*! Enable wakeup reporting. */ + LINTRCV_WUMODE_ENABLE = 0x00u, + /*! Disable wakeup reporting. */ + LINTRCV_WUMODE_DISABLE = 0x01u, + /*! Clear the stored wakeup reason. */ + LINTRCV_WUMODE_CLEAR = 0x02u +} LinTrcv_TrcvWakeupModeType; + +/*! [Defined by AUTOSAR]: This type is used to indicate the wakeup reason. */ +typedef enum LinTrcv_TrcvWakeupReasonTypeTag +{ + /*! Error, wakeup reason was not detected. */ + LINTRCV_WU_ERROR = 0x00u, + /*! Wakeup reporting is not supported. */ + LINTRCV_WU_NOT_SUPPORTED = 0x01u, + /*! Wakeup caused by the network was detected. */ + LINTRCV_WU_BY_BUS = 0x02u, + /*! Wakeup caused by a transceiver pin was detected. */ + LINTRCV_WU_BY_PIN = 0x03u, + /*! Wakeup caused by a ECU request was detected. */ + LINTRCV_WU_INTERNALLY = 0x04u, + /*! Wakeup caused by a ECU reset was detected. */ + LINTRCV_WU_RESET = 0x05u, + /*! Wakeup caused by a ECU reset after power on was detected. */ + LINTRCV_WU_POWER_ON = 0x06u +} LinTrcv_TrcvWakeupReasonType; + +/*! \} */ + +#endif /* LIN_GENERALTYPES_H */ + +/********************************************************************************************************************** + * END OF FILE: Lin_GeneralTypes.h + *********************************************************************************************************************/ + diff --git a/Source/bsw/Common/MemMap.h b/Source/bsw/Common/MemMap.h new file mode 100644 index 0000000..2f8c0fa --- /dev/null +++ b/Source/bsw/Common/MemMap.h @@ -0,0 +1,2993 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------- + * File: _MemMap.h + * Component: - + * Module: - + * Generator: - + * + * Description: This File is a template for the MemMap.h + * This file has to be extended with the memory section defined for all BSW modules + * which are used. + * + * ------------------------------------------------------------------------------------------------------------------- + * MISRA VIOLATIONS + * ------------------------------------------------------------------------------------------------------------------- + * + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * ------------------------------------------------------------------------------------------------------------------- + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2007-08-01 Jk Initial creation + * 01.01.00 2007-12-14 Jk Component specific defines filtering added + * 01.01.02 2008-11-04 Jk Component specific defines filtering added + * 01.01.03 2008-12-17 Ht Improve list of components (Tp_AsrTpCan,Tp_AsrTpFr,DrvMcu,DrvIcu added) + * 01.01.04 2009-04-27 Ht improve list of components (Cp_XcpOnCanAsr, Il_AsrIpduM, If_VxFblDcm, + * If_VxFblVpm_Volvo_ab, DrvFls added) + * 01.01.05 2009-04-24 Msr Renamed J1939_AsrBase as TpJ1939_AsrBase + * 01.01.06 2009-06-03 Ht Improve list of components (Adc, Dio, Gpt, Pwm, Spi, Wdg, Fls, Port, Fim) + * 01.02.00 2009-08-01 Ht Improve list of components (Fee_30_Inst2, Can, ...Sub) + * Support filtering for RTE + * 01.02.01 2009-08-18 HH replaced C++ comment by C comment + * 01.02.02 2009-09-02 Lo add external Flash driver support + * 01.02.03 2009-09-12 Lo add DrvFls_Mcs12xFslftm01ExtVx + * Ht Improve list of components (CanTrcv_30_Tja1040dio, + * Eth, EthTrcv, EthIf, SoAd, TcpIp, EthSM) + * 01.03.00 2009-10-30 Ht support R8: change EthTrcv to EthTrcv_30_Canoeemu + * support EthTrcv_30_Dp83848 + * change CanTrcv_30_Xdio to CanTrcv_30___Your_Trcv__ + * change CanTrcv_30_Tja1040dio to CanTrcv_30_Tja1041 + * change name FrTrcv to FrTrcv_30_Tja1080dio + * Lo add Cp_AsrXcp + * Ht add Cp_XcpOnFrAsr + * 01.03.01 2010-01-13 Ht support SysService_AsrCal + * 01.03.02 2010-02-15 Ht support SysService_SswRcs_Daimler, SysService_Tls, Tp_Http, + * SysService_Dns, SysService_Json, DrvTrans_GenericLindioAsr + * Lo add Diag_AsrDem for all OEMs + * rename internal variables and filter methods + * 01.04.00 2010-03-04 Ht change name FrTrcv_30_Tja1080dio to FrTrcv_30_Tja1080 + * 01.04.01 2010-03-10 Ht support DrvTrans_GenericFrAsr, DrvTrans_As8223FrspiAsr, DrvEep and If_AsrIfEa + * 01.04.02 2010-04-07 Lo change IfFee to real components and add If_AsrIfWdV85xNec01Sub + * 01.04.03 2010-06-11 Ht add CanTrcv_30_Tja1043 + * Lo add Il_AsrIpduMEbBmwSub + * 01.04.04 2010-08-24 Ht add CanTrcv_30_Tle62512G, DrvEep_XAt25128EAsr, Tp_AsrTpFrEbBmwSub + * 01.05.00 2010-08-24 Ht support R10: + * change LinTrcv_30_Tle7259dio to LinTrcv_30_Tle7259 + * 01.05.01 2010-10-14 Ht add VStdLib, SysService_SswScc, SysService_IpBase, SysService_Crypto + * 01.05.02 2010-10-20 Ht support comments for Package Merge Tool + * 01.05.03 2010-11-03 Ht add SysService_E2eLibTttechSub, SysService_E2ePwTttechSub + * 01.05.04 2010-11-16 Ht add SysService_Exi, DrvTrans_Int6400EthAsr, Cdd_AsrCdd_Fiat, Diag_AsrDem_Fiat + * 01.05.05 2010-12-17 Ht add SysService_AsrSchM, DrvEep_XXStubAsr, DrvIcu_Tms570Tinhet01ExtVx + * DrvWd_XTle4278gEAsr, DrvWd_XXStubAsr + * 01.05.06 2011-02-17 Ht add DrvEed, SysService_AsrBswM + * 01.05.07 2011-03-04 Ht add DrvTrans_Tja1055CandioAsr + * rename CanTrcv_30_Tja1040dio to CanTrcv_30_Tja1040 + * add SysService_XmlEngine + * 01.06.00 2011-03-15 Ht support ASR4.0 + * add Ccl_Asr4ComM, Ccl_Asr4SmCan, Nm_Asr4NmIf, Nm_AsrNmDirOsek + * 01.06.01 2011-04-15 Ht add Diag_AsrDcm_ + * 01.06.02 2011-06-17 Ht correct Diag_AsrDcm_ + * add Monitoring_AsrDlt and Monitoring_GenericMeasurement + * 01.06.03 2011-09-20 Ht add DrvTrans_Tja1145CanSpiAsr, DrvTrans_E52013CanspiAsr, DrvFls_XXStubAsr, + * If_AsrIfFeeV85xNec05Sub, If_AsrIfFeeV85xNec06Sub, If_AsrIfFeeV85xNec07Sub + * SysService_AsrWdMTttechSub and If_AsrIfWdTttechSub + * 01.06.04 2011-11-22 Ht add If_AsrIfFeeTiSub, + * ESCAN00054718: add Cdd_AsrCdd + * 01.06.05 2011-12-09 Ht add Tp_IpV4, Tp_IpV6 + * 01.06.06 2011-12-14 Ht add Monitoring_RuntimeMeasurement + * 01.06.07 2012-01-03 Ht add DrvI2c, SysService_Asr4BswM + * 01.06.08 2012-01-31 Ht add DrvTrans_Ar7000EthAsr, DrvTrans_GenericEthmiiAsr + * 01.06.09 2012-03-06 Ht add If_AsrIfFeeMb9df126Fuji01Sub, + * Infineon_Tc1767Inf01Sub, Infineon_Tc178xInf01Sub, Infineon_Tc1797Inf01Sub, Infineon_Tc1797Inf02Sub + * 01.06.10 2012-03-13 Ht add Gw_AsrPduRCfg5, Il_AsrComCfg5, Il_AsrIpduMCfg5, Cdd_AsrCddCfg5, + * Tp_Asr4TpCan, Diag_Asr4Dcm, Diag_Asr4Dem + * 01.06.11 2012-03-20 Ht add Cp_AsrCcp, Cp_XcpOnTcpIpAsr + * 01.07.00 2012-07-26 Ht ESCAN00059365: [AUTOSAR4, compiler warning]: Wrong define name in #undef statement causes re-definition warning + * add Nm_Asr4NmCan, Nm_Asr4NmFr, Infineon_Xc2000Inf01Sub, Ccl_Asr4ComMCfg5, SysService_Asr4BswMCfg5, SysService_Asr4EcuM, SysService_AsrRamTst, + * Ccl_Asr4SmLin + * 2012-09-04 Ht add support for ASR specification 4.0 R3 + * 01.07.01 2012-10-23 Seu add SysService_XmlSecurity + * 01.07.02 2013-01-10 Seu MISRA deviation comments added + * 01.08.00 2013-03-01 Seu ESCAN00065501 AR4-325: Add support for Post-build RAM memory section + * 2013-04-12 Seu ESCAN00066614 Add the deviation for violation of MISRA rule 19.6 + * 01.09.00 2013-12-10 Seu ESCAN00072537 Add *_NOCACHE_* memory sections for variables + * 2013-12-16 Seu MISRA compliance: usage of character "'" removed, typos corrected + * 01.10.00 2016-09-27 Seu FEATC-317: FEAT-2002: CommonAsr__Common: Support 64 Bit Signal Types for COM according to ASR 4.2.2 + * 01.11.00 2017-07-05 Seu ESCAN00095756 FEAT-2455: Support ASR4.2 compatible MemMap for MCALs + * 2017-08-01 Seu ESCAN00096129 MEMMAP_SW_MINOR_VERSION / MEM_SW_MINOR_VERSION is not correct + * 01.12.00 2018-10-17 visdfe ESCAN00095695 Add support for Os_CoreGen7 within _MemMap.h (Include of Os_MemMap.h) + * TASK-78775 Change MemMap_Common.h to Template + * 01.13.00 2021-05-06 virmfr HALBE-3985 CommonAsr_MemMap shall include Common_MemMap generated compatibility header + * 02.00.00 2021-06-09 visto HALBE-4594 Create a branch for >=R27 Features + * 02.01.00 2021-08-25 virmfr HALBE-4526 MemMap_Common.h removed + * 02.01.01 2021-09-07 virmfr HALBE-5304 MemMapIncludesList removed + * 02.02.00 2022-08-18 virmfr HALBE-7504 Interchange include order of MemMap_Common.h and MemMap_Compatibility.h + * 2022-08-18 virmfr ASR3 defines removed + * 02.02.01 2022-08-26 virmfr Correction of small non-functional findings + * 03.00.00 2024-11-05 virjas OSHAL-1936 Adaption for new ASR Mem module + * 03.01.00 2025-10-13 virjas OSHAL-3696 Adaption for changed infrastructure (veHub) + *********************************************************************************************************************/ + +/* PRQA S 0841 MEMMAP_0841_TAG */ /* MD_MSR_19.6 */ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + + /* PRQA S 0883 1 */ /* MD_MemMap_19.15 */ +#undef MEMMAP_VENDOR_ID /* PRQA S 0841 */ /* MD_MSR_19.6 */ + +#define MEMMAP_VENDOR_ID (30u) + +/* AUTOSAR Software Specification Version Information */ +#undef MEMMAP_AR_RELEASE_MAJOR_VERSION /* PRQA S 0841 */ /* MD_MSR_19.6 */ +#undef MEMMAP_AR_RELEASE_MINOR_VERSION /* PRQA S 0841 */ /* MD_MSR_19.6 */ +#undef MEMMAP_AR_RELEASE_REVISION_VERSION /* PRQA S 0841 */ /* MD_MSR_19.6 */ + +/* AUTOSAR release 4.0 R3 */ +#define MEMMAP_AR_RELEASE_MAJOR_VERSION (4u) +#define MEMMAP_AR_RELEASE_MINOR_VERSION (0u) +#define MEMMAP_AR_RELEASE_REVISION_VERSION (3u) + +#undef MEMMAP_SW_MAJOR_VERSION /* PRQA S 0841 */ /* MD_MSR_19.6 */ +#undef MEMMAP_SW_MINOR_VERSION /* PRQA S 0841 */ /* MD_MSR_19.6 */ +#undef MEMMAP_SW_PATCH_VERSION /* PRQA S 0841 */ /* MD_MSR_19.6 */ + +#define MEMMAP_SW_MAJOR_VERSION (3u) +#define MEMMAP_SW_MINOR_VERSION (1u) +#define MEMMAP_SW_PATCH_VERSION (0u) + +#define MEMMAP_ERROR + +/* Package Merger: Start Section MemMapModuleList */ + + +/********************************************************************************************************************** + * MEM_30_FBLHIS START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ +#if defined( MEM_30_FBLHIS_START_SEC_CODE ) +# undef MEM_30_FBLHIS_START_SEC_CODE +# define START_SEC_CODE +#endif + +#if defined( MEM_30_FBLHIS_STOP_SEC_CODE ) +# undef MEM_30_FBLHIS_STOP_SEC_CODE +# define STOP_SEC_CODE +#endif + +/******* VAR sections ***********************************************************************************************/ +#if defined( MEM_30_FBLHIS_START_SEC_VAR ) +# undef MEM_30_FBLHIS_START_SEC_VAR +# define START_SEC_VAR_NOINIT_UNSPECIFIED +#endif + +#if defined( MEM_30_FBLHIS_STOP_SEC_VAR ) +# undef MEM_30_FBLHIS_STOP_SEC_VAR +# define STOP_SEC_VAR +#endif + +/******* CONST sections *********************************************************************************************/ +#if defined( MEM_30_FBLHIS_START_SEC_CONST ) +# undef MEM_30_FBLHIS_START_SEC_CONST +# define START_SEC_CONST_UNSPECIFIED +#endif + +#if defined( MEM_30_FBLHIS_STOP_SEC_CONST ) +# undef MEM_30_FBLHIS_STOP_SEC_CONST +# define STOP_SEC_CONST +#endif + +/********************************************************************************************************************** + * MEM_30_FBLHIS END + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * CANTRCV_30_GENERICCAN START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_CODE) +# undef CANTRCV_30_GENERICCAN_START_SEC_CODE /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CODE /* mapped to default code section */ +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_CODE) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_CODE /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CODE /* default code stop section */ +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_CODE_FAST) +# undef CANTRCV_30_GENERICCAN_START_SEC_CODE_FAST /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CODE_FAST /* mapped to default fast code section */ +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_CODE_FAST) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_CODE_FAST /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CODE /* default code stop section */ +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_CODE_ISR) +# undef CANTRCV_30_GENERICCAN_START_SEC_CODE_ISR /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CODE_ISR /* mapped to default ISR code section */ +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_CODE_ISR) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_CODE_ISR /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CODE /* default code stop section */ +#endif + + +/******* CONST sections ********************************************************************************************/ + +/* CONST sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_CONST_8BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_CONST_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_8BIT /* mapped to default const 8bit section */ +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_CONST_8BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_CONST_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST /* default const stop section */ +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_CONST_16BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_CONST_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_16BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_CONST_16BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_CONST_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_CONST_32BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_CONST_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_32BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_CONST_32BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_CONST_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_CONST_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_START_SEC_CONST_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_UNSPECIFIED +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_CONST_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_CONST_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST +#endif + + +/* FAST CONST sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_CONST_FAST_8BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_CONST_FAST_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_FAST_8BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_CONST_FAST_8BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_CONST_FAST_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_CONST_FAST_16BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_CONST_FAST_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_FAST_16BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_CONST_FAST_16BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_CONST_FAST_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_CONST_FAST_32BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_CONST_FAST_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_FAST_32BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_CONST_FAST_32BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_CONST_FAST_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_CONST_FAST_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_START_SEC_CONST_FAST_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_FAST_UNSPECIFIED +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_CONST_FAST_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_CONST_FAST_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST +#endif + + +/* Postbuild CFG CONST sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_PBCFG) +# undef CANTRCV_30_GENERICCAN_START_SEC_PBCFG /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_PBCFG +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_PBCFG) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_PBCFG /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST +#endif + + +/******* VAR sections **********************************************************************************************/ + +/* VAR INIT sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_INIT_8BIT /* mapped to default var init 8bit section */ +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR /* default var stop section */ +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_INIT_16BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_INIT_32BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_INIT_UNSPECIFIED +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + + +/* VAR NOINIT sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOINIT_8BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOINIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOINIT_8BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOINIT_8BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOINIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOINIT_16BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOINIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOINIT_16BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOINIT_16BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOINIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOINIT_32BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOINIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOINIT_32BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOINIT_32BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOINIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOINIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOINIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOINIT_UNSPECIFIED +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOINIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOINIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +/* ESCAN00065501 */ +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_PBCFG) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_PBCFG /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_PBCFG +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_PBCFG) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_PBCFG /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + + +/* VAR ZERO INIT sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_ZERO_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_ZERO_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_ZERO_INIT_8BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_ZERO_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_ZERO_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_ZERO_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_ZERO_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_ZERO_INIT_16BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_ZERO_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_ZERO_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_ZERO_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_ZERO_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_ZERO_INIT_32BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_ZERO_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_ZERO_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_ZERO_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_ZERO_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_ZERO_INIT_UNSPECIFIED +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_ZERO_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_ZERO_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + + +/* VAR FAST INIT sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_INIT_8BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_INIT_16BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_INIT_32BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_INIT_UNSPECIFIED +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + + +/* VAR FAST NOINIT sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_NOINIT_8BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_NOINIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_NOINIT_8BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_NOINIT_8BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_NOINIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_NOINIT_16BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_NOINIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_NOINIT_16BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_NOINIT_16BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_NOINIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_NOINIT_32BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_NOINIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_NOINIT_32BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_NOINIT_32BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_NOINIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_NOINIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_NOINIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_NOINIT_UNSPECIFIED +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_NOINIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_NOINIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +/* VAR FAST ZERO INIT sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_ZERO_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_ZERO_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_ZERO_INIT_8BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_ZERO_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_ZERO_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_ZERO_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_ZERO_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_ZERO_INIT_16BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_ZERO_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_ZERO_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_ZERO_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_ZERO_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_ZERO_INIT_32BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_ZERO_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_ZERO_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_ZERO_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_FAST_ZERO_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_FAST_ZERO_INIT_UNSPECIFIED +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_ZERO_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_FAST_ZERO_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +/* VAR NOCACHE INIT sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_INIT_8BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_INIT_16BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_INIT_32BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_INIT_UNSPECIFIED +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +/* VAR NOCACHE NOINIT sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_NOINIT_8BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_NOINIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_NOINIT_8BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_NOINIT_8BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_NOINIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_NOINIT_16BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_NOINIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_NOINIT_16BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_NOINIT_16BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_NOINIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_NOINIT_32BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_NOINIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_NOINIT_32BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_NOINIT_32BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_NOINIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_NOINIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_NOINIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_NOINIT_UNSPECIFIED +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_NOINIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_NOINIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +/* VAR NOCACHE ZERO INIT sections */ + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_ZERO_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_ZERO_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_ZERO_INIT_8BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_ZERO_INIT_8BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_ZERO_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_ZERO_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_ZERO_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_ZERO_INIT_16BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_ZERO_INIT_16BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_ZERO_INIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_ZERO_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_ZERO_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_ZERO_INIT_32BIT +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_ZERO_INIT_32BIT) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_ZERO_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined(CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_ZERO_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_START_SEC_VAR_NOCACHE_ZERO_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOCACHE_ZERO_INIT_UNSPECIFIED +#endif +#if defined(CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_ZERO_INIT_UNSPECIFIED) +# undef CANTRCV_30_GENERICCAN_STOP_SEC_VAR_NOCACHE_ZERO_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +/********************************************************************************************************************** + * CANTRCV_30_GENERICCAN END + *********************************************************************************************************************/ /* PRQA S 0883 */ /* Appears only while testing */ + + +/********************************************************************************************************************** + * BSWSTUB-COMM START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ + +#ifdef FBLASRSTUBS_COMM_START_SEC_CODE + #undef FBLASRSTUBS_COMM_START_SEC_CODE + #define START_SEC_CODE /* Mapped to default code section */ +#endif + +#ifdef FBLASRSTUBS_COMM_STOP_SEC_CODE + #undef FBLASRSTUBS_COMM_STOP_SEC_CODE + #define STOP_SEC_CODE /* Default code stop section */ +#endif + +/********************************************************************************************************************** + * BSWSTUB-COMM END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * BSWSTUB-DEM START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ + +#ifdef FBLASRSTUBS_DEM_START_SEC_CODE + #undef FBLASRSTUBS_DEM_START_SEC_CODE + #define START_SEC_CODE /* Mapped to default code section */ +#endif + +#ifdef FBLASRSTUBS_DEM_STOP_SEC_CODE + #undef FBLASRSTUBS_DEM_STOP_SEC_CODE + #define STOP_SEC_CODE /* Default code stop section */ +#endif + +/********************************************************************************************************************** + * BSWSTUB-DEM END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * FBLBM_HDR START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ + +#ifdef FBLBMHDR_START_SEC_CODE + #undef FBLBMHDR_START_SEC_CODE + #define START_SEC_CODE /* Mapped to default code section */ +#endif + +#ifdef FBLBMHDR_STOP_SEC_CODE + #undef FBLBMHDR_STOP_SEC_CODE + #define STOP_SEC_CODE /* Default code stop section */ +#endif + +/******* CONST sections ********************************************************************************************/ + +#ifdef FBLBMHDR_BMHEADER_START_SEC_CONST + #undef FBLBMHDR_BMHEADER_START_SEC_CONST + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef FBLBMHDR_BMHEADER_STOP_SEC_CONST + #undef FBLBMHDR_BMHEADER_STOP_SEC_CONST + #define STOP_SEC_CONST +#endif + +#ifdef FBLBMHDR_START_SEC_CONST + #undef FBLBMHDR_START_SEC_CONST + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef FBLBMHDR_STOP_SEC_CONST + #undef FBLBMHDR_STOP_SEC_CONST + #define STOP_SEC_CONST +#endif + +#ifdef FBLBMHDR_BMHEADER_IMAGE_START_SEC_CONST + #undef FBLBMHDR_BMHEADER_IMAGE_START_SEC_CONST + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef FBLBMHDR_BMHEADER_IMAGE_STOP_SEC_CONST + #undef FBLBMHDR_BMHEADER_IMAGE_STOP_SEC_CONST + #define STOP_SEC_CONST +#endif + +/********************************************************************************************************************** + * FBLBM_HDR END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * FBLBM_MAIN START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ + +#ifdef FBLBM_START_SEC_CODE + #undef FBLBM_START_SEC_CODE + #define START_SEC_CODE /* Mapped to default code section */ +#endif + +#ifdef FBLBM_STOP_SEC_CODE + #undef FBLBM_STOP_SEC_CODE + #define STOP_SEC_CODE /* Default code stop section */ +#endif + +#ifdef FBLBM_MAIN_FBLSTART_START_SEC_CODE + #undef FBLBM_MAIN_FBLSTART_START_SEC_CODE + #define START_SEC_CODE /* Mapped to default code section */ +#endif + +#ifdef FBLBM_MAIN_FBLSTART_STOP_SEC_CODE + #undef FBLBM_MAIN_FBLSTART_STOP_SEC_CODE + #define STOP_SEC_CODE /* Default code stop section */ +#endif + +#ifdef FBLBM_MAIN_APPLSTART_START_SEC_CODE + #undef FBLBM_MAIN_APPLSTART_START_SEC_CODE + #define START_SEC_CODE /* Mapped to default code section */ +#endif + +#ifdef FBLBM_MAIN_APPLSTART_STOP_SEC_CODE + #undef FBLBM_MAIN_APPLSTART_STOP_SEC_CODE + #define STOP_SEC_CODE /* Default code stop section */ +#endif + +/******* CONST sections ********************************************************************************************/ + +#ifdef FBLBM_HEADER_START_SEC_CONST + #undef FBLBM_HEADER_START_SEC_CONST + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef FBLBM_HEADER_STOP_SEC_CONST + #undef FBLBM_HEADER_STOP_SEC_CONST + #define STOP_SEC_CONST +#endif + +#ifdef FBLBM_START_SEC_CONST + #undef FBLBM_START_SEC_CONST + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef FBLBM_STOP_SEC_CONST + #undef FBLBM_STOP_SEC_CONST + #define STOP_SEC_CONST +#endif + +/******* VAR sections **********************************************************************************************/ + +#ifdef FBLBM_START_SEC_VAR + #undef FBLBM_START_SEC_VAR + #define START_SEC_VAR_NOINIT_UNSPECIFIED +#endif + +#ifdef FBLBM_STOP_SEC_VAR + #undef FBLBM_STOP_SEC_VAR + #define STOP_SEC_VAR +#endif + +#ifdef FBLBM_MAIN_MAGICFLAG_START_SEC_VAR_NOINIT + #undef FBLBM_MAIN_MAGICFLAG_START_SEC_VAR_NOINIT + #define START_SEC_VAR_NOINIT_UNSPECIFIED +#endif + +#ifdef FBLBM_MAIN_MAGICFLAG_STOP_SEC_VAR_NOINIT + #undef FBLBM_MAIN_MAGICFLAG_STOP_SEC_VAR_NOINIT + #define STOP_SEC_VAR +#endif + +/********************************************************************************************************************** + * FBLBM_MAIN END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * FBLLIB_SECBOOT START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ + +#ifdef FBLSB_START_SEC_CODE + #undef FBLSB_START_SEC_CODE + #define START_SEC_CODE /* Mapped to default code section */ +#endif + +#ifdef FBLSB_STOP_SEC_CODE + #undef FBLSB_STOP_SEC_CODE + #define STOP_SEC_CODE /* Default code stop section */ +#endif + +/******* CONST sections ********************************************************************************************/ + +#ifdef FBLSB_START_SEC_CONST + #undef FBLSB_START_SEC_CONST + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef FBLSB_STOP_SEC_CONST + #undef FBLSB_STOP_SEC_CONST + #define STOP_SEC_CONST +#endif + +/******* VAR sections **********************************************************************************************/ + +#ifdef FBLSB_START_SEC_VAR + #undef FBLSB_START_SEC_VAR + #define START_SEC_VAR_NOINIT_UNSPECIFIED +#endif + +#ifdef FBLSB_STOP_SEC_VAR + #undef FBLSB_STOP_SEC_VAR + #define STOP_SEC_VAR +#endif + +/********************************************************************************************************************** + * FBLLIB_SECBOOT END + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * FblCw START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ + +#ifdef FBLCW_START_SEC_CODE +# undef FBLCW_START_SEC_CODE +# define START_SEC_CODE +#endif +#ifdef FBLCW_STOP_SEC_CODE +# undef FBLCW_STOP_SEC_CODE +# define STOP_SEC_CODE +#endif +/* FBCW application callback code section */ +#ifdef FBLCW_START_SEC_APPL_CODE +# undef FBLCW_START_SEC_APPL_CODE +# define START_SEC_CODE +#endif +#ifdef FBLCW_STOP_SEC_APPL_CODE +# undef FBLCW_STOP_SEC_APPL_CODE +# define STOP_SEC_CODE +#endif +#ifdef FBLCW_CAN_START_SEC_CODE +# undef FBLCW_CAN_START_SEC_CODE +# define START_SEC_CODE +#endif +#ifdef FBLCW_CAN_STOP_SEC_CODE +# undef FBLCW_CAN_STOP_SEC_CODE +# define STOP_SEC_CODE +#endif +#ifdef FBLCW_FR_START_SEC_CODE +# undef FBLCW_FR_START_SEC_CODE +# define START_SEC_CODE +#endif +#ifdef FBLCW_FR_STOP_SEC_CODE +# undef FBLCW_FR_STOP_SEC_CODE +# define STOP_SEC_CODE +#endif +#ifdef FBLCW_LIN_START_SEC_CODE +# undef FBLCW_LIN_START_SEC_CODE +# define START_SEC_CODE +#endif +#ifdef FBLCW_LIN_STOP_SEC_CODE +# undef FBLCW_LIN_STOP_SEC_CODE +# define STOP_SEC_CODE +#endif + +/******* CONST sections ********************************************************************************************/ + +/* CONST sections */ + +#ifdef FBLCW_START_SEC_CONST_8 +# undef FBLCW_START_SEC_CONST_8 +# define START_SEC_CONST_8 +#endif +#ifdef FBLCW_STOP_SEC_CONST_8 +# undef FBLCW_STOP_SEC_CONST_8 +# define STOP_SEC_CONST +#endif + +#ifdef FBLCW_START_SEC_CONST_16 +# undef FBLCW_START_SEC_CONST_16 +# define START_SEC_CONST_16 +#endif +#ifdef FBLCW_STOP_SEC_CONST_16 +# undef FBLCW_STOP_SEC_CONST_16 +# define STOP_SEC_CONST +#endif + +#ifdef FBLCW_START_SEC_CONST_32 +# undef FBLCW_START_SEC_CONST_32 +# define START_SEC_CONST_32 +#endif +#ifdef FBLCW_STOP_SEC_CONST_32 +# undef FBLCW_STOP_SEC_CONST_32 +# define STOP_SEC_CONST +#endif + +#ifdef FBLCW_START_SEC_CONST_64 +# undef FBLCW_START_SEC_CONST_64 +# define START_SEC_CONST_64 +#endif +#ifdef FBLCW_STOP_SEC_CONST_64 +# undef FBLCW_STOP_SEC_CONST_64 +# define STOP_SEC_CONST +#endif + +#ifdef FBLCW_START_SEC_CONST_UNSPECIFIED +# undef FBLCW_START_SEC_CONST_UNSPECIFIED +# define START_SEC_CONST_UNSPECIFIED +#endif +#ifdef FBLCW_STOP_SEC_CONST_UNSPECIFIED +# undef FBLCW_STOP_SEC_CONST_UNSPECIFIED +# define STOP_SEC_CONST +#endif + +#ifdef FBLCW_START_SEC_PBCFG +# undef FBLCW_START_SEC_PBCFG +# define START_SEC_CONST_PBCFG +#endif +#ifdef FBLCW_STOP_SEC_PBCFG +# undef FBLCW_STOP_SEC_PBCFG +# define STOP_SEC_CONST +#endif + +#ifdef FBLCW_START_SEC_VAR_PBCFG +# undef FBLCW_START_SEC_VAR_PBCFG +# define START_SEC_VAR_PBCFG +#endif +#ifdef FBLCW_STOP_SEC_VAR_PBCFG +# undef FBLCW_STOP_SEC_VAR_PBCFG +# define STOP_SEC_VAR +#endif + + +/******* VAR sections **********************************************************************************************/ + +#ifdef FBLCW_START_SEC_VAR +# undef FBLCW_START_SEC_VAR +# define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif +#ifdef FBLCW_STOP_SEC_VAR +# undef FBLCW_STOP_SEC_VAR +# define STOP_SEC_VAR +#endif + +/* VAR INIT sections */ + +#ifdef FBLCW_START_SEC_VAR_INIT_UNSPECIFIED +# undef FBLCW_START_SEC_VAR_INIT_UNSPECIFIED +# define START_SEC_VAR_INIT_UNSPECIFIED +#endif +#ifdef FBLCW_STOP_SEC_VAR_INIT_UNSPECIFIED +# undef FBLCW_STOP_SEC_VAR_INIT_UNSPECIFIED +# define STOP_SEC_VAR +#endif + +#ifdef FBLCW_START_SEC_VAR_CLEARED_UNSPECIFIED +# undef FBLCW_START_SEC_VAR_CLEARED_UNSPECIFIED +# define START_SEC_VAR_CLEARED_UNSPECIFIED +#endif +#ifdef FBLCW_STOP_SEC_VAR_CLEARED_UNSPECIFIED +# undef FBLCW_STOP_SEC_VAR_CLEARED_UNSPECIFIED +# define STOP_SEC_VAR +#endif + +#ifdef FBLCW_START_SEC_VAR_CLEARED_8 +# undef FBLCW_START_SEC_VAR_CLEARED_8 +# define START_SEC_VAR_CLEARED_8 +#endif +#ifdef FBLCW_STOP_SEC_VAR_CLEARED_8 +# undef FBLCW_STOP_SEC_VAR_CLEARED_8 +# define STOP_SEC_VAR +#endif + +/* VAR NO_INIT sections */ + +#ifdef FBLCW_START_SEC_VAR_NO_INIT_BOOLEAN +# undef FBLCW_START_SEC_VAR_NO_INIT_BOOLEAN +# define START_SEC_VAR_NO_INIT_8 +#endif +#ifdef FBLCW_STOP_SEC_VAR_NO_INIT_BOOLEAN +# undef FBLCW_STOP_SEC_VAR_NO_INIT_BOOLEAN +# define STOP_SEC_VAR +#endif + +#ifdef FBLCW_START_SEC_VAR_NO_INIT_8 +# undef FBLCW_START_SEC_VAR_NO_INIT_8 +# define START_SEC_VAR_NO_INIT_8 +#endif +#ifdef FBLCW_STOP_SEC_VAR_NO_INIT_8 +# undef FBLCW_STOP_SEC_VAR_NO_INIT_8 +# define STOP_SEC_VAR +#endif + +#ifdef FBLCW_START_SEC_VAR_NO_INIT_16 +# undef FBLCW_START_SEC_VAR_NO_INIT_16 +# define START_SEC_VAR_NO_INIT_16 +#endif +#ifdef FBLCW_STOP_SEC_VAR_NO_INIT_16 +# undef FBLCW_STOP_SEC_VAR_NO_INIT_16 +# define STOP_SEC_VAR +#endif + +#ifdef FBLCW_START_SEC_VAR_NO_INIT_32 +# undef FBLCW_START_SEC_VAR_NO_INIT_32 +# define START_SEC_VAR_NO_INIT_32 +#endif +#ifdef FBLCW_STOP_SEC_VAR_NO_INIT_32 +# undef FBLCW_STOP_SEC_VAR_NO_INIT_32 +# define STOP_SEC_VAR +#endif + +#ifdef FBLCW_START_SEC_VAR_NO_INIT_64 +# undef FBLCW_START_SEC_VAR_NO_INIT_64 +# define START_SEC_VAR_NO_INIT_64 +#endif +#ifdef FBLCW_STOP_SEC_VAR_NO_INIT_64 +# undef FBLCW_STOP_SEC_VAR_NO_INIT_64 +# define STOP_SEC_VAR +#endif + +#ifdef FBLCW_START_SEC_VAR_NO_INIT_UNSPECIFIED +# undef FBLCW_START_SEC_VAR_NO_INIT_UNSPECIFIED +# define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif +#ifdef FBLCW_STOP_SEC_VAR_NO_INIT_UNSPECIFIED +# undef FBLCW_STOP_SEC_VAR_NO_INIT_UNSPECIFIED +# define STOP_SEC_VAR +#endif + + +/* VAR ZERO INIT sections */ + + + +/* VAR FAST INIT sections */ + + + +/* VAR FAST NO_INIT sections */ + + +/* VAR FAST ZERO INIT sections */ + + + +/********************************************************************************************************************** + * FblCw END + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * FBLVIRTUALIO START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ + +#ifdef FBLVIRTUALIO_START_SEC_CODE + #undef FBLVIRTUALIO_START_SEC_CODE + #define START_SEC_CODE /* Mapped to default code section */ +#endif + +#ifdef FBLVIRTUALIO_STOP_SEC_CODE + #undef FBLVIRTUALIO_STOP_SEC_CODE + #define STOP_SEC_CODE /* Default code stop section */ +#endif + +/******* CONST sections ********************************************************************************************/ + +#ifdef FBLVIRTUALIO_START_SEC_CONST + #undef FBLVIRTUALIO_START_SEC_CONST + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef FBLVIRTUALIO_STOP_SEC_CONST + #undef FBLVIRTUALIO_STOP_SEC_CONST + #define STOP_SEC_CONST +#endif + + +/********************************************************************************************************************** + * FBLVIRTUALIO END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** +* 3rdParty_Mcal START +*********************************************************************************************************************/ + +#ifdef ADC_START_SEC_CODE + #undef ADC_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef ADC_STOP_SEC_CODE + #undef ADC_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef ADC_START_SEC_CONFIG_DATA + #undef ADC_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef ADC_STOP_SEC_CONFIG_DATA + #undef ADC_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef ADC_START_SEC_ISR_CODE + #undef ADC_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef ADC_STOP_SEC_ISR_CODE + #undef ADC_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef ADC_START_SEC_VAR_INIT_32 + #undef ADC_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef ADC_STOP_SEC_VAR_INIT_32 + #undef ADC_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef ADC_START_SEC_VAR_INIT_UNSPECIFIED + #undef ADC_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef ADC_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef ADC_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef ADC_START_SEC_VAR_NO_INIT_8 + #undef ADC_START_SEC_VAR_NO_INIT_8 + #define START_SEC_VAR_NO_INIT_8 +#endif + +#ifdef ADC_STOP_SEC_VAR_NO_INIT_8 + #undef ADC_STOP_SEC_VAR_NO_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef ADC_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef ADC_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef ADC_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef ADC_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CAN_START_SEC_CODE + #undef CAN_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef CAN_STOP_SEC_CODE + #undef CAN_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CAN_START_SEC_CONFIG_DATA + #undef CAN_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef CAN_STOP_SEC_CONFIG_DATA + #undef CAN_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef CAN_START_SEC_CONST_32 + #undef CAN_START_SEC_CONST_32 + #define START_SEC_CONST_32 +#endif + +#ifdef CAN_STOP_SEC_CONST_32 + #undef CAN_STOP_SEC_CONST_32 + #define STOP_SEC_CONST +#endif + +#ifdef CAN_START_SEC_CONST_8 + #undef CAN_START_SEC_CONST_8 + #define START_SEC_CONST_8 +#endif + +#ifdef CAN_STOP_SEC_CONST_8 + #undef CAN_STOP_SEC_CONST_8 + #define STOP_SEC_CONST +#endif + +#ifdef CAN_START_SEC_CONST_UNSPECIFIED + #undef CAN_START_SEC_CONST_UNSPECIFIED + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef CAN_STOP_SEC_CONST_UNSPECIFIED + #undef CAN_STOP_SEC_CONST_UNSPECIFIED + #define STOP_SEC_CONST +#endif + +#ifdef CAN_START_SEC_ISR_CODE + #undef CAN_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef CAN_STOP_SEC_ISR_CODE + #undef CAN_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CAN_START_SEC_VAR_INIT_32 + #undef CAN_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef CAN_STOP_SEC_VAR_INIT_32 + #undef CAN_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef CAN_START_SEC_VAR_INIT_8 + #undef CAN_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef CAN_STOP_SEC_VAR_INIT_8 + #undef CAN_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef CAN_START_SEC_VAR_INIT_UNSPECIFIED + #undef CAN_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef CAN_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef CAN_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CAN_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CAN_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef CAN_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CAN_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CDD_DMA_START_SEC_CODE + #undef CDD_DMA_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef CDD_DMA_STOP_SEC_CODE + #undef CDD_DMA_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CDD_DMA_START_SEC_CONFIG_DATA + #undef CDD_DMA_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef CDD_DMA_STOP_SEC_CONFIG_DATA + #undef CDD_DMA_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef CDD_DMA_START_SEC_ISR_CODE + #undef CDD_DMA_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef CDD_DMA_STOP_SEC_ISR_CODE + #undef CDD_DMA_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CDD_DMA_START_SEC_VAR_INIT_32 + #undef CDD_DMA_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef CDD_DMA_STOP_SEC_VAR_INIT_32 + #undef CDD_DMA_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_DMA_START_SEC_VAR_INIT_8 + #undef CDD_DMA_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef CDD_DMA_STOP_SEC_VAR_INIT_8 + #undef CDD_DMA_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_DMA_START_SEC_VAR_INIT_UNSPECIFIED + #undef CDD_DMA_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef CDD_DMA_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef CDD_DMA_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CDD_DMA_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CDD_DMA_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef CDD_DMA_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CDD_DMA_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CDD_I2C_START_SEC_CODE + #undef CDD_I2C_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef CDD_I2C_STOP_SEC_CODE + #undef CDD_I2C_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CDD_I2C_START_SEC_CONFIG_DATA + #undef CDD_I2C_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef CDD_I2C_STOP_SEC_CONFIG_DATA + #undef CDD_I2C_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef CDD_I2C_START_SEC_CONST_32 + #undef CDD_I2C_START_SEC_CONST_32 + #define START_SEC_CONST_32 +#endif + +#ifdef CDD_I2C_STOP_SEC_CONST_32 + #undef CDD_I2C_STOP_SEC_CONST_32 + #define STOP_SEC_CONST +#endif + +#ifdef CDD_I2C_START_SEC_ISR_CODE + #undef CDD_I2C_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef CDD_I2C_STOP_SEC_ISR_CODE + #undef CDD_I2C_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CDD_I2C_START_SEC_VAR_INIT_16 + #undef CDD_I2C_START_SEC_VAR_INIT_16 + #define START_SEC_VAR_INIT_16 +#endif + +#ifdef CDD_I2C_STOP_SEC_VAR_INIT_16 + #undef CDD_I2C_STOP_SEC_VAR_INIT_16 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_I2C_START_SEC_VAR_INIT_32 + #undef CDD_I2C_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef CDD_I2C_STOP_SEC_VAR_INIT_32 + #undef CDD_I2C_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_I2C_START_SEC_VAR_INIT_8 + #undef CDD_I2C_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef CDD_I2C_STOP_SEC_VAR_INIT_8 + #undef CDD_I2C_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_I2C_START_SEC_VAR_INIT_UNSPECIFIED + #undef CDD_I2C_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef CDD_I2C_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef CDD_I2C_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CDD_I2C_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CDD_I2C_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef CDD_I2C_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CDD_I2C_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CDD_IPC_START_SEC_CODE + #undef CDD_IPC_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef CDD_IPC_STOP_SEC_CODE + #undef CDD_IPC_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CDD_IPC_START_SEC_CONFIG_DATA + #undef CDD_IPC_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef CDD_IPC_STOP_SEC_CONFIG_DATA + #undef CDD_IPC_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef CDD_IPC_START_SEC_ISR_CODE + #undef CDD_IPC_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef CDD_IPC_STOP_SEC_ISR_CODE + #undef CDD_IPC_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CDD_IPC_START_SEC_VAR_INIT_32 + #undef CDD_IPC_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef CDD_IPC_STOP_SEC_VAR_INIT_32 + #undef CDD_IPC_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_IPC_START_SEC_VAR_INIT_8 + #undef CDD_IPC_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef CDD_IPC_STOP_SEC_VAR_INIT_8 + #undef CDD_IPC_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_IPC_START_SEC_VAR_INIT_UNSPECIFIED + #undef CDD_IPC_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef CDD_IPC_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef CDD_IPC_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CDD_IPC_START_SEC_VAR_NO_INIT_8 + #undef CDD_IPC_START_SEC_VAR_NO_INIT_8 + #define START_SEC_VAR_NO_INIT_8 +#endif + +#ifdef CDD_IPC_STOP_SEC_VAR_NO_INIT_8 + #undef CDD_IPC_STOP_SEC_VAR_NO_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_IPC_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CDD_IPC_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef CDD_IPC_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CDD_IPC_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CDD_PWM_START_SEC_CODE + #undef CDD_PWM_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef CDD_PWM_STOP_SEC_CODE + #undef CDD_PWM_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CDD_PWM_START_SEC_CONFIG_DATA + #undef CDD_PWM_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef CDD_PWM_STOP_SEC_CONFIG_DATA + #undef CDD_PWM_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef CDD_PWM_START_SEC_ISR_CODE + #undef CDD_PWM_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef CDD_PWM_STOP_SEC_ISR_CODE + #undef CDD_PWM_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CDD_PWM_START_SEC_VAR_INIT_32 + #undef CDD_PWM_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef CDD_PWM_STOP_SEC_VAR_INIT_32 + #undef CDD_PWM_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_PWM_START_SEC_VAR_INIT_8 + #undef CDD_PWM_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef CDD_PWM_STOP_SEC_VAR_INIT_8 + #undef CDD_PWM_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_PWM_START_SEC_VAR_NO_INIT_16 + #undef CDD_PWM_START_SEC_VAR_NO_INIT_16 + #define START_SEC_VAR_NO_INIT_16 +#endif + +#ifdef CDD_PWM_STOP_SEC_VAR_NO_INIT_16 + #undef CDD_PWM_STOP_SEC_VAR_NO_INIT_16 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_PWM_START_SEC_VAR_NO_INIT_32 + #undef CDD_PWM_START_SEC_VAR_NO_INIT_32 + #define START_SEC_VAR_NO_INIT_32 +#endif + +#ifdef CDD_PWM_STOP_SEC_VAR_NO_INIT_32 + #undef CDD_PWM_STOP_SEC_VAR_NO_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_PWM_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CDD_PWM_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef CDD_PWM_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CDD_PWM_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CDD_START_SEC_CODE + #undef CDD_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef CDD_STOP_SEC_CODE + #undef CDD_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CDD_START_SEC_VAR_INIT_UNSPECIFIED + #undef CDD_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef CDD_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef CDD_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CDD_UART_START_SEC_CODE + #undef CDD_UART_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef CDD_UART_STOP_SEC_CODE + #undef CDD_UART_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CDD_UART_START_SEC_CONFIG_DATA + #undef CDD_UART_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef CDD_UART_STOP_SEC_CONFIG_DATA + #undef CDD_UART_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef CDD_UART_START_SEC_ISR_CODE + #undef CDD_UART_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef CDD_UART_STOP_SEC_ISR_CODE + #undef CDD_UART_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef CDD_UART_START_SEC_VAR_INIT_32 + #undef CDD_UART_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef CDD_UART_STOP_SEC_VAR_INIT_32 + #undef CDD_UART_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_UART_START_SEC_VAR_INIT_8 + #undef CDD_UART_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef CDD_UART_STOP_SEC_VAR_INIT_8 + #undef CDD_UART_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_UART_START_SEC_VAR_INIT_UNSPECIFIED + #undef CDD_UART_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef CDD_UART_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef CDD_UART_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef CDD_UART_START_SEC_VAR_NO_INIT_32 + #undef CDD_UART_START_SEC_VAR_NO_INIT_32 + #define START_SEC_VAR_NO_INIT_32 +#endif + +#ifdef CDD_UART_STOP_SEC_VAR_NO_INIT_32 + #undef CDD_UART_STOP_SEC_VAR_NO_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef CDD_UART_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CDD_UART_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef CDD_UART_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef CDD_UART_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef DIO_START_SEC_CODE + #undef DIO_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef DIO_STOP_SEC_CODE + #undef DIO_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef DIO_START_SEC_CONFIG_DATA + #undef DIO_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef DIO_STOP_SEC_CONFIG_DATA + #undef DIO_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef DIO_START_SEC_CONST_32 + #undef DIO_START_SEC_CONST_32 + #define START_SEC_CONST_32 +#endif + +#ifdef DIO_STOP_SEC_CONST_32 + #undef DIO_STOP_SEC_CONST_32 + #define STOP_SEC_CONST +#endif + +#ifdef DIO_START_SEC_CONST_UNSPECIFIED + #undef DIO_START_SEC_CONST_UNSPECIFIED + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef DIO_STOP_SEC_CONST_UNSPECIFIED + #undef DIO_STOP_SEC_CONST_UNSPECIFIED + #define STOP_SEC_CONST +#endif + +#ifdef ETH_START_SEC_CODE + #undef ETH_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef ETH_STOP_SEC_CODE + #undef ETH_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef ETH_START_SEC_CONFIG_DATA + #undef ETH_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef ETH_STOP_SEC_CONFIG_DATA + #undef ETH_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef ETH_START_SEC_CONST_8 + #undef ETH_START_SEC_CONST_8 + #define START_SEC_CONST_8 +#endif + +#ifdef ETH_STOP_SEC_CONST_8 + #undef ETH_STOP_SEC_CONST_8 + #define STOP_SEC_CONST +#endif + +#ifdef ETH_START_SEC_CONST_UNSPECIFIED + #undef ETH_START_SEC_CONST_UNSPECIFIED + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef ETH_STOP_SEC_CONST_UNSPECIFIED + #undef ETH_STOP_SEC_CONST_UNSPECIFIED + #define STOP_SEC_CONST +#endif + +#ifdef ETH_START_SEC_ISR_CODE + #undef ETH_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef ETH_STOP_SEC_ISR_CODE + #undef ETH_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef ETH_START_SEC_VAR_INIT_32 + #undef ETH_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef ETH_STOP_SEC_VAR_INIT_32 + #undef ETH_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef ETH_START_SEC_VAR_INIT_8 + #undef ETH_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef ETH_STOP_SEC_VAR_INIT_8 + #undef ETH_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef ETH_START_SEC_VAR_INIT_UNSPECIFIED + #undef ETH_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef ETH_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef ETH_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef ETH_START_SEC_VAR_NO_INIT_8 + #undef ETH_START_SEC_VAR_NO_INIT_8 + #define START_SEC_VAR_NO_INIT_8 +#endif + +#ifdef ETH_STOP_SEC_VAR_NO_INIT_8 + #undef ETH_STOP_SEC_VAR_NO_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef ETH_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef ETH_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef ETH_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef ETH_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef FLS_START_SEC_CODE + #undef FLS_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef FLS_STOP_SEC_CODE + #undef FLS_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef FLS_START_SEC_CONFIG_DATA + #undef FLS_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef FLS_STOP_SEC_CONFIG_DATA + #undef FLS_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef FLS_START_SEC_ISR_CODE + #undef FLS_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef FLS_STOP_SEC_ISR_CODE + #undef FLS_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef FLS_START_SEC_VAR_INIT_32 + #undef FLS_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef FLS_STOP_SEC_VAR_INIT_32 + #undef FLS_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef FLS_START_SEC_VAR_INIT_8 + #undef FLS_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef FLS_STOP_SEC_VAR_INIT_8 + #undef FLS_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef FLS_START_SEC_VAR_INIT_UNSPECIFIED + #undef FLS_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef FLS_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef FLS_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef FLS_START_SEC_VAR_NO_INIT_32 + #undef FLS_START_SEC_VAR_NO_INIT_32 + #define START_SEC_VAR_NO_INIT_32 +#endif + +#ifdef FLS_STOP_SEC_VAR_NO_INIT_32 + #undef FLS_STOP_SEC_VAR_NO_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef FLS_START_SEC_VAR_NO_INIT_8 + #undef FLS_START_SEC_VAR_NO_INIT_8 + #define START_SEC_VAR_NO_INIT_8 +#endif + +#ifdef FLS_STOP_SEC_VAR_NO_INIT_8 + #undef FLS_STOP_SEC_VAR_NO_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef FLS_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef FLS_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef FLS_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef FLS_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef GPT_START_SEC_CODE + #undef GPT_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef GPT_STOP_SEC_CODE + #undef GPT_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef GPT_START_SEC_CONFIG_DATA + #undef GPT_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef GPT_STOP_SEC_CONFIG_DATA + #undef GPT_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef GPT_START_SEC_CONST_32 + #undef GPT_START_SEC_CONST_32 + #define START_SEC_CONST_32 +#endif + +#ifdef GPT_STOP_SEC_CONST_32 + #undef GPT_STOP_SEC_CONST_32 + #define STOP_SEC_CONST +#endif + +#ifdef GPT_START_SEC_CONST_PTR + #undef GPT_START_SEC_CONST_PTR + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef GPT_STOP_SEC_CONST_PTR + #undef GPT_STOP_SEC_CONST_PTR + #define STOP_SEC_CONST +#endif + +#ifdef GPT_START_SEC_CONST_UNSPECIFIED + #undef GPT_START_SEC_CONST_UNSPECIFIED + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef GPT_STOP_SEC_CONST_UNSPECIFIED + #undef GPT_STOP_SEC_CONST_UNSPECIFIED + #define STOP_SEC_CONST +#endif + +#ifdef GPT_START_SEC_ISR_CODE + #undef GPT_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef GPT_STOP_SEC_ISR_CODE + #undef GPT_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef GPT_START_SEC_VAR_INIT_16 + #undef GPT_START_SEC_VAR_INIT_16 + #define START_SEC_VAR_INIT_16 +#endif + +#ifdef GPT_STOP_SEC_VAR_INIT_16 + #undef GPT_STOP_SEC_VAR_INIT_16 + #define STOP_SEC_VAR +#endif + +#ifdef GPT_START_SEC_VAR_INIT_PTR + #undef GPT_START_SEC_VAR_INIT_PTR + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef GPT_STOP_SEC_VAR_INIT_PTR + #undef GPT_STOP_SEC_VAR_INIT_PTR + #define STOP_SEC_VAR +#endif + +#ifdef GPT_START_SEC_VAR_INIT_UNSPECIFIED + #undef GPT_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef GPT_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef GPT_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef GPT_START_SEC_VAR_NO_INIT_16 + #undef GPT_START_SEC_VAR_NO_INIT_16 + #define START_SEC_VAR_NO_INIT_16 +#endif + +#ifdef GPT_STOP_SEC_VAR_NO_INIT_16 + #undef GPT_STOP_SEC_VAR_NO_INIT_16 + #define STOP_SEC_VAR +#endif + +#ifdef GPT_START_SEC_VAR_NO_INIT_32 + #undef GPT_START_SEC_VAR_NO_INIT_32 + #define START_SEC_VAR_NO_INIT_32 +#endif + +#ifdef GPT_STOP_SEC_VAR_NO_INIT_32 + #undef GPT_STOP_SEC_VAR_NO_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef GPT_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef GPT_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef GPT_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef GPT_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef I2C_START_SEC_CODE + #undef I2C_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef I2C_STOP_SEC_CODE + #undef I2C_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef I2C_START_SEC_CONFIG_DATA_UNSPECIFIED + #undef I2C_START_SEC_CONFIG_DATA_UNSPECIFIED + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef I2C_STOP_SEC_CONFIG_DATA_UNSPECIFIED + #undef I2C_STOP_SEC_CONFIG_DATA_UNSPECIFIED + #define STOP_SEC_CONST +#endif + +#ifdef I2C_START_SEC_VAR_CLEARED_16 + #undef I2C_START_SEC_VAR_CLEARED_16 + #define START_SEC_VAR_CLEARED_16 +#endif + +#ifdef I2C_STOP_SEC_VAR_CLEARED_16 + #undef I2C_STOP_SEC_VAR_CLEARED_16 + #define STOP_SEC_VAR +#endif + +#ifdef I2C_START_SEC_VAR_CLEARED_UNSPECIFIED + #undef I2C_START_SEC_VAR_CLEARED_UNSPECIFIED + #define START_SEC_VAR_CLEARED_UNSPECIFIED +#endif + +#ifdef I2C_STOP_SEC_VAR_CLEARED_UNSPECIFIED + #undef I2C_STOP_SEC_VAR_CLEARED_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef I2C_START_SEC_VAR_INIT_UNSPECIFIED + #undef I2C_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef I2C_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef I2C_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef ICU_START_SEC_CODE + #undef ICU_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef ICU_STOP_SEC_CODE + #undef ICU_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef ICU_START_SEC_CONFIG_DATA + #undef ICU_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef ICU_STOP_SEC_CONFIG_DATA + #undef ICU_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef ICU_START_SEC_ISR_CODE + #undef ICU_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef ICU_STOP_SEC_ISR_CODE + #undef ICU_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef ICU_START_SEC_VAR_INIT_32 + #undef ICU_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef ICU_STOP_SEC_VAR_INIT_32 + #undef ICU_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef ICU_START_SEC_VAR_INIT_8 + #undef ICU_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef ICU_STOP_SEC_VAR_INIT_8 + #undef ICU_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef ICU_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef ICU_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef ICU_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef ICU_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef LIN_START_SEC_CODE + #undef LIN_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef LIN_STOP_SEC_CODE + #undef LIN_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef LIN_START_SEC_CONFIG_DATA + #undef LIN_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef LIN_STOP_SEC_CONFIG_DATA + #undef LIN_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef LIN_START_SEC_ISR_CODE + #undef LIN_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef LIN_STOP_SEC_ISR_CODE + #undef LIN_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef LIN_START_SEC_VAR_INIT_UNSPECIFIED + #undef LIN_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef LIN_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef LIN_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef LIN_START_SEC_VAR_NO_INIT_8 + #undef LIN_START_SEC_VAR_NO_INIT_8 + #define START_SEC_VAR_NO_INIT_8 +#endif + +#ifdef LIN_STOP_SEC_VAR_NO_INIT_8 + #undef LIN_STOP_SEC_VAR_NO_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef LIN_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef LIN_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef LIN_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef LIN_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef LIN_START_SEC_VAR_NOINIT_UNSPECIFIED + #undef LIN_START_SEC_VAR_NOINIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef LIN_STOP_SEC_VAR_NOINIT_UNSPECIFIED + #undef LIN_STOP_SEC_VAR_NOINIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef MCAL_LIB_START_SEC_CODE + #undef MCAL_LIB_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef MCAL_LIB_STOP_SEC_CODE + #undef MCAL_LIB_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef MCU_START_SEC_CODE + #undef MCU_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef MCU_STOP_SEC_CODE + #undef MCU_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef MCU_START_SEC_CONFIG_DATA + #undef MCU_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef MCU_STOP_SEC_CONFIG_DATA + #undef MCU_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef MCU_START_SEC_VAR_INIT_8 + #undef MCU_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef MCU_STOP_SEC_VAR_INIT_8 + #undef MCU_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef MCU_START_SEC_VAR_INIT_PTR + #undef MCU_START_SEC_VAR_INIT_PTR + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef MCU_STOP_SEC_VAR_INIT_PTR + #undef MCU_STOP_SEC_VAR_INIT_PTR + #define STOP_SEC_VAR +#endif + +#ifdef MCU_START_SEC_VAR_INIT_UNSPECIFIED + #undef MCU_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef MCU_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef MCU_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef PORT_START_SEC_CODE + #undef PORT_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef PORT_STOP_SEC_CODE + #undef PORT_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef PORT_START_SEC_CONFIG_DATA + #undef PORT_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef PORT_STOP_SEC_CONFIG_DATA + #undef PORT_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef PORT_START_SEC_CONST_32 + #undef PORT_START_SEC_CONST_32 + #define START_SEC_CONST_32 +#endif + +#ifdef PORT_STOP_SEC_CONST_32 + #undef PORT_STOP_SEC_CONST_32 + #define STOP_SEC_CONST +#endif + +#ifdef PORT_START_SEC_CONST_UNSPECIFIED + #undef PORT_START_SEC_CONST_UNSPECIFIED + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef PORT_STOP_SEC_CONST_UNSPECIFIED + #undef PORT_STOP_SEC_CONST_UNSPECIFIED + #define STOP_SEC_CONST +#endif + +#ifdef PORT_START_SEC_ISR_CODE + #undef PORT_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef PORT_STOP_SEC_ISR_CODE + #undef PORT_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef PORT_START_SEC_VAR_INIT_UNSPECIFIED + #undef PORT_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef PORT_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef PORT_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef PORT_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef PORT_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef PORT_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef PORT_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef PWM_START_SEC_CODE + #undef PWM_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef PWM_STOP_SEC_CODE + #undef PWM_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef PWM_START_SEC_CONFIG_DATA + #undef PWM_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef PWM_STOP_SEC_CONFIG_DATA + #undef PWM_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef PWM_START_SEC_ISR_CODE + #undef PWM_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef PWM_STOP_SEC_ISR_CODE + #undef PWM_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef PWM_START_SEC_VAR_INIT_32 + #undef PWM_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef PWM_STOP_SEC_VAR_INIT_32 + #undef PWM_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef PWM_START_SEC_VAR_INIT_8 + #undef PWM_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef PWM_STOP_SEC_VAR_INIT_8 + #undef PWM_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef PWM_START_SEC_VAR_INIT_PTR + #undef PWM_START_SEC_VAR_INIT_PTR + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef PWM_STOP_SEC_VAR_INIT_PTR + #undef PWM_STOP_SEC_VAR_INIT_PTR + #define STOP_SEC_VAR +#endif + +#ifdef PWM_START_SEC_VAR_NO_INIT_32 + #undef PWM_START_SEC_VAR_NO_INIT_32 + #define START_SEC_VAR_NO_INIT_32 +#endif + +#ifdef PWM_STOP_SEC_VAR_NO_INIT_32 + #undef PWM_STOP_SEC_VAR_NO_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef PWM_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef PWM_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef PWM_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef PWM_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef SPI_START_SEC_CODE + #undef SPI_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef SPI_STOP_SEC_CODE + #undef SPI_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef SPI_START_SEC_CONFIG_DATA + #undef SPI_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef SPI_STOP_SEC_CONFIG_DATA + #undef SPI_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef SPI_START_SEC_CONST_32 + #undef SPI_START_SEC_CONST_32 + #define START_SEC_CONST_32 +#endif + +#ifdef SPI_STOP_SEC_CONST_32 + #undef SPI_STOP_SEC_CONST_32 + #define STOP_SEC_CONST +#endif + +#ifdef SPI_START_SEC_CONST_UNSPECIFIED + #undef SPI_START_SEC_CONST_UNSPECIFIED + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef SPI_STOP_SEC_CONST_UNSPECIFIED + #undef SPI_STOP_SEC_CONST_UNSPECIFIED + #define STOP_SEC_CONST +#endif + +#ifdef SPI_START_SEC_ISR_CODE + #undef SPI_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef SPI_STOP_SEC_ISR_CODE + #undef SPI_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef SPI_START_SEC_UDMA_RING + #undef SPI_START_SEC_UDMA_RING + #define START_SEC_VAR_NOINIT_UNSPECIFIED +#endif + +#ifdef SPI_STOP_SEC_UDMA_RING + #undef SPI_STOP_SEC_UDMA_RING + #define STOP_SEC_VAR +#endif + +#ifdef SPI_START_SEC_VAR_INIT_32 + #undef SPI_START_SEC_VAR_INIT_32 + #define START_SEC_VAR_INIT_32 +#endif + +#ifdef SPI_STOP_SEC_VAR_INIT_32 + #undef SPI_STOP_SEC_VAR_INIT_32 + #define STOP_SEC_VAR +#endif + +#ifdef SPI_START_SEC_VAR_INIT_8 + #undef SPI_START_SEC_VAR_INIT_8 + #define START_SEC_VAR_INIT_8 +#endif + +#ifdef SPI_STOP_SEC_VAR_INIT_8 + #undef SPI_STOP_SEC_VAR_INIT_8 + #define STOP_SEC_VAR +#endif + +#ifdef SPI_START_SEC_VAR_INIT_UNSPECIFIED + #undef SPI_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef SPI_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef SPI_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef SPI_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef SPI_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef SPI_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef SPI_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef WDG_START_SEC_CODE + #undef WDG_START_SEC_CODE + #define START_SEC_CODE +#endif + +#ifdef WDG_STOP_SEC_CODE + #undef WDG_STOP_SEC_CODE + #define STOP_SEC_CODE +#endif + +#ifdef WDG_START_SEC_CONFIG_DATA + #undef WDG_START_SEC_CONFIG_DATA + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef WDG_STOP_SEC_CONFIG_DATA + #undef WDG_STOP_SEC_CONFIG_DATA + #define STOP_SEC_CONST +#endif + +#ifdef WDG_START_SEC_CONST_32 + #undef WDG_START_SEC_CONST_32 + #define START_SEC_CONST_32 +#endif + +#ifdef WDG_STOP_SEC_CONST_32 + #undef WDG_STOP_SEC_CONST_32 + #define STOP_SEC_CONST +#endif + +#ifdef WDG_START_SEC_CONST_UNSPECIFIED + #undef WDG_START_SEC_CONST_UNSPECIFIED + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef WDG_STOP_SEC_CONST_UNSPECIFIED + #undef WDG_STOP_SEC_CONST_UNSPECIFIED + #define STOP_SEC_CONST +#endif + +#ifdef WDG_START_SEC_ISR_CODE + #undef WDG_START_SEC_ISR_CODE + #define START_SEC_CODE_ISR +#endif + +#ifdef WDG_STOP_SEC_ISR_CODE + #undef WDG_STOP_SEC_ISR_CODE + #define STOP_SEC_CODE +#endif + +#ifdef WDG_START_SEC_VAR_INIT_UNSPECIFIED + #undef WDG_START_SEC_VAR_INIT_UNSPECIFIED + #define START_SEC_VAR_INIT_UNSPECIFIED +#endif + +#ifdef WDG_STOP_SEC_VAR_INIT_UNSPECIFIED + #undef WDG_STOP_SEC_VAR_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +#ifdef WDG_START_SEC_VAR_NO_INIT_UNSPECIFIED + #undef WDG_START_SEC_VAR_NO_INIT_UNSPECIFIED + #define START_SEC_VAR_NO_INIT_UNSPECIFIED +#endif + +#ifdef WDG_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #undef WDG_STOP_SEC_VAR_NO_INIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +/********************************************************************************************************************** +* 3rdParty_Mcal END +*********************************************************************************************************************/ + + +/********************************************************************************************************************** + * CSM START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ + +#if defined (CSM_START_SEC_CODE) +# undef CSM_START_SEC_CODE /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CODE /* mapped to default code section */ +#endif +#if defined (CSM_STOP_SEC_CODE) +# undef CSM_STOP_SEC_CODE /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CODE /* default code stop section */ +#endif + +#if defined (CSM_START_SEC_APPL_CODE) +# undef CSM_START_SEC_APPL_CODE /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CODE /* mapped to default code section */ +#endif +#if defined (CSM_STOP_SEC_APPL_CODE) +# undef CSM_STOP_SEC_APPL_CODE /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CODE /* default code stop section */ +#endif + +/******* CONST sections ********************************************************************************************/ + +/* CONST sections */ + +#if defined (CSM_START_SEC_CONST_8BIT) +# undef CSM_START_SEC_CONST_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_8BIT +#endif + +#if defined (CSM_STOP_SEC_CONST_8BIT) +# undef CSM_STOP_SEC_CONST_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST +#endif + +#if defined (CSM_START_SEC_CONST_UNSPECIFIED) +# undef CSM_START_SEC_CONST_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_UNSPECIFIED +#endif +#if defined (CSM_STOP_SEC_CONST_UNSPECIFIED) +# undef CSM_STOP_SEC_CONST_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST +#endif + +/******* VAR sections **********************************************************************************************/ + +/* VAR NOINIT sections */ + +#if defined (CSM_START_SEC_VAR_NOINIT_8BIT) +# undef CSM_START_SEC_VAR_NOINIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOINIT_8BIT +#endif +#if defined (CSM_STOP_SEC_VAR_NOINIT_8BIT) +# undef CSM_STOP_SEC_VAR_NOINIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined (CSM_START_SEC_VAR_NOINIT_16BIT) +# undef CSM_START_SEC_VAR_NOINIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOINIT_16BIT +#endif +#if defined (CSM_STOP_SEC_VAR_NOINIT_16BIT) +# undef CSM_STOP_SEC_VAR_NOINIT_16BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +/* VAR ZERO INIT sections */ +#if defined (CSM_START_SEC_VAR_ZERO_INIT_8BIT) +# undef CSM_START_SEC_VAR_ZERO_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_ZERO_INIT_8BIT +#endif +#if defined (CSM_STOP_SEC_VAR_ZERO_INIT_8BIT) +# undef CSM_STOP_SEC_VAR_ZERO_INIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined (CSM_START_SEC_VAR_ZERO_INIT_32BIT) +# undef CSM_START_SEC_VAR_ZERO_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_ZERO_INIT_32BIT +#endif +#if defined (CSM_STOP_SEC_VAR_ZERO_INIT_32BIT) +# undef CSM_STOP_SEC_VAR_ZERO_INIT_32BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#if defined (CSM_START_SEC_VAR_NOINIT_UNSPECIFIED) +# undef CSM_START_SEC_VAR_NOINIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOINIT_UNSPECIFIED +#endif +#if defined (CSM_STOP_SEC_VAR_NOINIT_UNSPECIFIED) +# undef CSM_STOP_SEC_VAR_NOINIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +/********************************************************************************************************************** + * CSM END + *********************************************************************************************************************/ + + +#ifdef DET_START_SEC_CODE +# undef DET_START_SEC_CODE /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CODE +#endif +#ifdef DET_STOP_SEC_CODE +# undef DET_STOP_SEC_CODE /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CODE +#endif + +#ifdef DET_START_SEC_VAR_NOINIT_UNSPECIFIED +# undef DET_START_SEC_VAR_NOINIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOINIT_UNSPECIFIED +#endif +#ifdef DET_STOP_SEC_VAR_NOINIT_UNSPECIFIED +# undef DET_STOP_SEC_VAR_NOINIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#ifdef DET_START_SEC_VAR_NOINIT_8BIT +# undef DET_START_SEC_VAR_NOINIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_NOINIT_8BIT +#endif +#ifdef DET_STOP_SEC_VAR_NOINIT_8BIT +# undef DET_STOP_SEC_VAR_NOINIT_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#ifdef DET_START_SEC_VAR_INIT_UNSPECIFIED +# undef DET_START_SEC_VAR_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_VAR_INIT_UNSPECIFIED +#endif +#ifdef DET_STOP_SEC_VAR_INIT_UNSPECIFIED +# undef DET_STOP_SEC_VAR_INIT_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_VAR +#endif + +#ifdef DET_START_SEC_CONST_UNSPECIFIED +# undef DET_START_SEC_CONST_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_UNSPECIFIED +#endif +#ifdef DET_STOP_SEC_CONST_UNSPECIFIED +# undef DET_STOP_SEC_CONST_UNSPECIFIED /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST +#endif + + +/********************************************************************************************************************** + * WRAPNV START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ + +#ifdef SECM_RAMCODE_START_SEC_CODE + #undef SECM_RAMCODE_START_SEC_CODE + #define START_SEC_CODE /* Mapped to default code section */ +#endif + +#ifdef SECM_RAMCODE_STOP_SEC_CODE + #undef SECM_RAMCODE_STOP_SEC_CODE + #define STOP_SEC_CODE /* Default code stop section */ +#endif + +#ifdef SECM_START_SEC_CODE + #undef SECM_START_SEC_CODE + #define START_SEC_CODE /* Mapped to default code section */ +#endif + +#ifdef SECM_STOP_SEC_CODE + #undef SECM_STOP_SEC_CODE + #define STOP_SEC_CODE /* Default code stop section */ +#endif + +/******* CONST sections ********************************************************************************************/ + +#ifdef SECM_START_SEC_CONST + #undef SECM_START_SEC_CONST + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef SECM_STOP_SEC_CONST + #undef SECM_STOP_SEC_CONST + #define STOP_SEC_CONST +#endif + +/******* VAR sections **********************************************************************************************/ + +#ifdef SECM_START_SEC_VAR + #undef SECM_START_SEC_VAR + #define START_SEC_VAR_NOINIT_UNSPECIFIED +#endif + +#ifdef SECM_STOP_SEC_VAR + #undef SECM_STOP_SEC_VAR + #define STOP_SEC_VAR +#endif + +/********************************************************************************************************************** + * WRAPNV END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * WRAPNV START + *********************************************************************************************************************/ + +/******* CODE sections **********************************************************************************************/ + +#ifdef WRAPNV_START_SEC_CODE + #undef WRAPNV_START_SEC_CODE + #define START_SEC_CODE /* Mapped to default code section */ +#endif + +#ifdef WRAPNV_STOP_SEC_CODE + #undef WRAPNV_STOP_SEC_CODE + #define STOP_SEC_CODE /* Default code stop section */ +#endif + +/******* CONST sections ********************************************************************************************/ + +#ifdef WRAPNV_START_SEC_CONST_UNSPECIFIED + #undef WRAPNV_START_SEC_CONST_UNSPECIFIED + #define START_SEC_CONST_UNSPECIFIED +#endif + +#ifdef WRAPNV_STOP_SEC_CONST_UNSPECIFIED + #undef WRAPNV_STOP_SEC_CONST_UNSPECIFIED + #define STOP_SEC_CONST +#endif + +/******* VAR sections **********************************************************************************************/ + +#ifdef WRAPNV_START_SEC_VAR_NOINIT_UNSPECIFIED + #undef WRAPNV_START_SEC_VAR_NOINIT_UNSPECIFIED + #define START_SEC_VAR_NOINIT_UNSPECIFIED +#endif + +#ifdef WRAPNV_STOP_SEC_VAR_NOINIT_UNSPECIFIED + #undef WRAPNV_STOP_SEC_VAR_NOINIT_UNSPECIFIED + #define STOP_SEC_VAR +#endif + +/********************************************************************************************************************** + * WRAPNV END + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * VSTDLIB START + *********************************************************************************************************************/ + +#if defined(VSTDLIB_START_SEC_CODE) +# undef VSTDLIB_START_SEC_CODE /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CODE /* mapped to default code section */ +#endif +#if defined(VSTDLIB_STOP_SEC_CODE) +# undef VSTDLIB_STOP_SEC_CODE /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CODE +#endif + +#if defined(VSTDLIB_START_SEC_CONST_8BIT) +# undef VSTDLIB_START_SEC_CONST_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define START_SEC_CONST_8BIT /* mapped to const 8 bit section */ +#endif +#if defined(VSTDLIB_STOP_SEC_CONST_8BIT) +# undef VSTDLIB_STOP_SEC_CONST_8BIT /* PRQA S 0841 */ /* MD_MSR_Undef */ +# define STOP_SEC_CONST /* default const stop section */ +#endif + +/********************************************************************************************************************** + * VSTDLIB END + *********************************************************************************************************************/ + + + +/* PRQA L:MEMMAP_0841_TAG */ + +/* MEMMAP_REMAPPING_ONLY is set if the MemMap is only used to remap Memory Allocation Keywords. + If not set the Memory Allocation Keywords will be resolved to pragmas */ +#ifndef MEMMAP_REMAPPING_ONLY +# include "MemMap_Common.h" + +/* MEMMAP_ERROR is + - still defined if MemMap_Common.h did not contain a matching section + - undefined, if MemMap_Common.h handled the section define. */ +# ifdef MEMMAP_ERROR +/* contains all configured MemMap Sections */ +# include "MemMap_Compatibility.h" /* generated by module MemMap */ +# endif + +# ifdef MEMMAP_ERROR +# error No MemMap section found in MemMap_Common.h and MemMap_Compatibility.h. Check your section define for validity. +# endif +#endif + + +/********************************************************************************************************************** + * END OF FILE: MemMap.h + *********************************************************************************************************************/ + diff --git a/Source/bsw/Common/Platform_Types.h b/Source/bsw/Common/Platform_Types.h new file mode 100644 index 0000000..1e7b896 --- /dev/null +++ b/Source/bsw/Common/Platform_Types.h @@ -0,0 +1,216 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------- + * File: Platform_Types.h + * Component: - + * Module: - + * Generator: - + * + * Description: Provision of Platform Types for Arm32 + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2007-11-06 Jk Template creation + * 01.00.01 2008-12-03 Ces Update version of AUTOSAR software specification document in template + * 01.00.02 2010-01-07 Ht comment about handling of float 64 in case floating point type with size 8 + * byte is not supported by a platform/Compiler + * 01.01.00 2011-03-04 visht support ASR 4.0R1 + * 01.02.00 2012-06-29 visht support ASR 4.0R3 ( no change ) + * 01.03.00 2012-08-23 visht version define corrected - replace PATCH by REVISION - (PLATFORM_AR_RELEASE_REVISION_VERSION) + * 01.03.01 2012-11-05 visseu PLATFORM_MODULE_ID added as specified in "AUTOSAR_TR_BSWModuleList.pdf" (R4.0 Rev 3), component version corrected + * 02.00.00 2015-03-13 vispl Setup for CommonAsr_Arm32 + * 02.00.01 2015-09-04 vispl Add suffix "u" in compliance with MISRA-C:2004 rule 10.6. + * AR4-667: Support sint64 and uint64 + * 02.01.00 2020-11-16 visbwa Removed AUTHOR IDENTITY, changed filter mechanism (Product instead of + * AutosarVersion) + * 02.01.01 2020-11-17 visbwa Fix of PLATFORM_SW_MINOR_VERSION + * 02.02.00 2023-07-18 virrlu HALBE-10062 Update to AUTOSAR Release 21-11 + * 02.02.01 2023-08-28 virrlu ESCAN00115495 Compiler warning: __STDC_VERSION__ not defined + * 02.02.02 2023-09-20 virjas ESCAN00115709 PostBuild generator fails when the AUTOSAR boolean type (_Bool) is used + * 02.02.03 2024-02-01 virmid OSHAL-990 Updated copyright year. + * 02.02.04 2024-03-15 virjas OSHAL-1016 Encapsulate UINTx_MAX definitions. + * 02.02.05 2024-10-09 virjas ESCAN00118247 Incorrect definition of SINT8_MIN. + *********************************************************************************************************************/ + +#ifndef PLATFORM_TYPES_H +#define PLATFORM_TYPES_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ +/* ##V_CFG_MANAGEMENT ##CQProject : CommonAsr_Arm32 CQComponent : Impl_PlatformTypes */ +#define COMMONASR_ARM32_IMPL_PLATFORMTYPES_VERSION 0x0202 +#define COMMONASR_ARM32_IMPL_PLATFORMTYPES_RELEASE_VERSION 0x05 + +#define PLATFORM_VENDOR_ID 30u /* Vendor ID of Vector */ +#define PLATFORM_MODULE_ID 199u /* 199 is the ID of Platform types */ + +/* AUTOSAR Software Specification Document Version Information */ + +#define PLATFORM_AR_RELEASE_MAJOR_VERSION (4u) +#define PLATFORM_AR_RELEASE_MINOR_VERSION (8u) +#define PLATFORM_AR_RELEASE_REVISION_VERSION (0u) + +/* Component Version Information */ +#define PLATFORM_SW_MAJOR_VERSION (2u) +#define PLATFORM_SW_MINOR_VERSION (2u) +#define PLATFORM_SW_PATCH_VERSION (5u) + +#define CPU_TYPE_8 8u +#define CPU_TYPE_16 16u +#define CPU_TYPE_32 32u +#define CPU_TYPE_64 64u + +#define MSB_FIRST 0u /* big endian bit ordering */ +#define LSB_FIRST 1u /* little endian bit ordering */ + +#define HIGH_BYTE_FIRST 0u /* big endian byte ordering */ +#define LOW_BYTE_FIRST 1u /* little endian byte ordering */ + +#ifndef TRUE +# define TRUE 1u +#endif + +#ifndef FALSE +# define FALSE 0u +#endif + +#define CPU_TYPE CPU_TYPE_32 +#define CPU_BIT_ORDER LSB_FIRST +#define CPU_BYTE_ORDER LOW_BYTE_FIRST + +/* data type limitation defines */ +#ifndef UINT8_MIN +# define UINT8_MIN 0u +#endif +#ifndef UINT8_MAX +# define UINT8_MAX 255u +#endif +#ifndef UINT16_MIN +# define UINT16_MIN 0u +#endif +#ifndef UINT16_MAX +# define UINT16_MAX 65535u +#endif +#ifndef UINT32_MIN +# define UINT32_MIN 0ul +#endif +#ifndef UINT32_MAX +# define UINT32_MAX 4294967295ul +#endif +#ifndef UINT64_MIN +# define UINT64_MIN 0ull +#endif +#ifndef UINT64_MAX +# define UINT64_MAX 18446744073709551615ull +#endif + +#ifndef SINT8_MIN +# define SINT8_MIN -128 +#endif +#ifndef SINT8_MAX +# define SINT8_MAX 127 +#endif +#ifndef SINT16_MIN +# define SINT16_MIN -32768 +#endif +#ifndef SINT16_MAX +# define SINT16_MAX 32767 +#endif +#ifndef SINT32_MIN +# define SINT32_MIN -2147483648 +#endif +#ifndef SINT32_MAX +# define SINT32_MAX 2147483647 +#endif +#ifndef SINT64_MIN +# define SINT64_MIN -9223372036854775808 +#endif +#ifndef SINT64_MAX +# define SINT64_MAX 9223372036854775807 +#endif + +#ifndef FLOAT32_MIN +# define FLOAT32_MIN 1.17549435e-38f +#endif +#ifndef FLOAT32_MAX +# define FLOAT32_MAX 3.40282347e+38f +#endif +#ifndef FLOAT32_EPSILON +# define FLOAT32_EPSILON 1.19209290e-07f +#endif + +#ifndef FLOAT64_MIN +# define FLOAT64_MIN 2.2250738585072014e-308l +#endif +#ifndef FLOAT64_MAX +# define FLOAT64_MAX 1.7976931348623157e+308l +#endif +#ifndef FLOAT64_EPSILON +# define FLOAT64_EPSILON 2.2204460492503131e-16l +#endif + + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ +typedef unsigned char boolean; /* for use with TRUE/FALSE */ + +typedef signed char sint8; /* -128 .. +127 */ +typedef unsigned char uint8; /* 0 .. 255 */ +typedef signed short sint16; /* -32768 .. +32767 */ +typedef unsigned short uint16; /* 0 .. 65535 */ +typedef signed long sint32; /* -2147483648 .. +2147483647 */ +typedef unsigned long uint32; /* 0 .. 4294967295 */ +#define PLATFORM_SUPPORT_SINT64_UINT64 +typedef signed long long sint64; /* \brief 64-bit unsigned integer */ +typedef unsigned long long uint64; +typedef unsigned long uint8_least; /* At least 8 bit */ +typedef unsigned long uint16_least; /* At least 16 bit */ +typedef unsigned long uint32_least; /* At least 32 bit */ +typedef signed long sint8_least; /* At least 7 bit + 1 bit sign */ +typedef signed long sint16_least; /* At least 15 bit + 1 bit sign */ +typedef signed long sint32_least; /* At least 31 bit + 1 bit sign */ + +typedef float float32; +typedef double float64; + +typedef void* VoidPtr; +typedef const void* ConstVoidPtr; + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#endif /* PLATFORM_TYPES_H */ + +/********************************************************************************************************************** + * END OF FILE: Platform_Types.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Common/Std_Types.h b/Source/bsw/Common/Std_Types.h new file mode 100644 index 0000000..342b9de --- /dev/null +++ b/Source/bsw/Common/Std_Types.h @@ -0,0 +1,198 @@ +/*********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2023 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------ + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** + * File: Std_Types.h + * Component: - + * Module: - + * Generator: - + * + * Description: Provision of Standard Types + * + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2007-08-01 Jk Initial creation + * 03.00.00 2007-10-10 Jk Changes for AUTOSAR 3.0 + * 03.00.01 2007-11-20 Jk Version defines for CFG management added + * 03.01.00 2008-03-05 Jk Include order changed + * 03.02.00 2008-03-18 Jk Version defines changed to specification version + * 03.03.00 2008-06-03 Jk changed ModuleId Type in Std_VersionInfoType from uint8 to uint16 + * 03.03.01 2009-11-11 visht ESCAN00038201 Support the Standard Type E_PENDING + * 03.04.00 2011-02-15 visht support ASR 4.0R1 + * 03.04.01 2011-02-28 visht ESCAN00049579 incorrect BSW version scan information + * 03.04.02 2012-08-23 visht version define corrected - replace PATCH by REVISION - + * (STD_TYPES_AR_RELEASE_REVISION_VERSION) + * 2012-10-23 visseu Add _VENDOR_ID and _MODULE_ID as specified in + * "AUTOSAR_TR_BSWModuleList.pdf" (R4.0 Rev 3) + * 03.04.03 2013-02-13 visseu No changes, only SW version corrected + * 03.04.04 2013-05-29 visseu ESCAN00067740 Add general defines with prefix: STD + * 03.04.05 2019-03-18 visdfe OI-10000 Remove E_PENDING from Std_Types.h + * 03.05.00 2022-05-05 visto HALBE-6470 Add support for Std_TransformerError according to AUTOSAR 20-11 + * 03.06.00 2023-04-12 visbwa HALBE-7488 Removed outdated fragments of ASR3.x and file filtering, + * fixed copyright header, codestyle review + **********************************************************************************************************************/ + +#ifndef STD_TYPES_H +# define STD_TYPES_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ +# include "Platform_Types.h" + +# include "Compiler.h" + +/*********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + **********************************************************************************************************************/ +# define STD_TYPES_VENDOR_ID (30u) /* SREQ00015345, SREQ00015361 */ +# define STD_TYPES_MODULE_ID (197u) /* SREQ00015345, SREQ00015361 */ + +/* ESCAN00067740 */ +# define STD_VENDOR_ID STD_TYPES_VENDOR_ID +# define STD_MODULE_ID STD_TYPES_MODULE_ID + +/* ##V_CFG_MANAGEMENT ##CQProject : CommonAsr__Common CQComponent : Impl_StdTypes */ +# define COMMONASR__COMMON_IMPL_STDTYPES_VERSION 0x0306 +# define COMMONASR__COMMON_IMPL_STDTYPES_RELEASE_VERSION 0x00 + +/* AUTOSAR Software Specification Version Information */ +/* AUTOSAR release R21-11 -> 4.7.0 */ +# define STD_TYPES_AR_RELEASE_MAJOR_VERSION (4u) +# define STD_TYPES_AR_RELEASE_MINOR_VERSION (7u) +# define STD_TYPES_AR_RELEASE_REVISION_VERSION (0u) + +/* ESCAN00067740 */ +# define STD_AR_RELEASE_MAJOR_VERSION STD_TYPES_AR_RELEASE_MAJOR_VERSION +# define STD_AR_RELEASE_MINOR_VERSION STD_TYPES_AR_RELEASE_MINOR_VERSION +# define STD_AR_RELEASE_REVISION_VERSION STD_TYPES_AR_RELEASE_REVISION_VERSION + +/* Component Version Information */ +# define STD_TYPES_SW_MAJOR_VERSION (3u) +# define STD_TYPES_SW_MINOR_VERSION (6u) +# define STD_TYPES_SW_PATCH_VERSION (0u) + +/* ESCAN00067740 */ +# define STD_SW_MAJOR_VERSION STD_TYPES_SW_MAJOR_VERSION +# define STD_SW_MINOR_VERSION STD_TYPES_SW_MINOR_VERSION +# define STD_SW_PATCH_VERSION STD_TYPES_SW_PATCH_VERSION + +# define STD_HIGH 1u /* Physical state 5V or 3.3V */ +# define STD_LOW 0u /* Physical state 0V */ + +# define STD_ACTIVE 1u /* Logical state active */ +# define STD_IDLE 0u /* Logical state idle */ + +# define STD_ON 1u +# define STD_OFF 0u + +/*********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + **********************************************************************************************************************/ +/* This typedef has been added for OSEK compliance */ +# ifndef STATUSTYPEDEFINED +# define STATUSTYPEDEFINED +# define E_OK 0u +typedef unsigned char StatusType; /* OSEK compliance */ +# endif + +# define E_NOT_OK 1u + +typedef uint8 Std_ReturnType; + +typedef struct +{ + uint16 vendorID; + uint16 moduleID; + uint8 sw_major_version; + uint8 sw_minor_version; + uint8 sw_patch_version; +} Std_VersionInfoType; + +typedef uint8 Std_TransformerErrorCode; + +typedef uint8 Std_TransformerClass; +# define STD_TRANSFORMER_UNSPECIFIED 0u +# define STD_TRANSFORMER_SERIALIZER 1u +# define STD_TRANSFORMER_SAFETY 2u +# define STD_TRANSFORMER_SECURITY 3u +# define STD_TRANSFORMER_CUSTOM 0xFFu + +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + */ + +typedef uint8 Std_MessageTypeType; +# define STD_MESSAGETYPE_REQUEST 0u +# define STD_MESSAGETYPE_RESPONSE 1u + +typedef uint8 Std_MessageResultType; +# define STD_MESSAGERESULT_OK 0u +# define STD_MESSAGERESULT_ERROR 1u + +typedef struct +{ + Std_TransformerErrorCode errorCode; + Std_TransformerClass transformerClass; +} Std_TransformerError; + +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ + +typedef Std_ReturnType (*Std_ExtractProtocolHeaderFieldsType) ( + const uint8* buffer, + uint32 bufferLength, + Std_MessageTypeType* messageType, + Std_MessageResultType* messageResult +); + +/*********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#endif /* STD_TYPES_H */ + +/*********************************************************************************************************************** + * END OF FILE: Std_Types.h + **********************************************************************************************************************/ diff --git a/Source/bsw/Common/v_def.h b/Source/bsw/Common/v_def.h new file mode 100644 index 0000000..92aef1e --- /dev/null +++ b/Source/bsw/Common/v_def.h @@ -0,0 +1,1175 @@ +/* STARTSINGLE_OF_MULTIPLE */ +/***************************************************************************** +| Project Name: V E C T O R - Common module type definition header +| File Name: v_def.h +| +| Description: Declares types and definitions common to all +| VECTOR CANbedded modules. +| +| Note: +| ===== +| that some hardware dependent settings are included in this file. +| Never mix up files with same namings but intended for +| other hardware platforms. +| +| +|----------------------------------------------------------------------------- +| C O P Y R I G H T +|----------------------------------------------------------------------------- +| Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +| +| This software is copyright protected and proprietary +| to Vector Informatik GmbH. Vector Informatik GmbH +| grants to you only those rights as set out in the +| license conditions. All other rights remain with +| Vector Informatik GmbH. +| +|----------------------------------------------------------------------------- +| R E V I S I O N H I S T O R Y +|----------------------------------------------------------------------------- +| Date Ver Author Description +| --------- ---- ------ -------------------------------------------------- +| 13-Mar-01 1.00 Hp Creation +| 04-Apr-01 1.01 Ht general rework +| 05-Apr-01 1.02 dH added Fujitsu FFMC16LX +| 05-Apr-01 1.03 HH added COMP_GHS_V85X +| 11-Apr-01 1.04 Et added LIN components +| 23-Apr-01 1.05 Si corrections for C_COMP_IAR_78K0 +| lint comments added +| 29-Mai-01 1.06 Pl added ARM7 STMICRO +| 22-Jun-01 1.07 Ht added ANSI CANoe +| 03-Jul-01 Wr added C_COMP_OKI_CC665S +| 12-Jul-01 Et support combination of "old" CAN driver and "new" LIN driver +| 13-Jul-01 1.08 Ht error check for supported systems and switches added +| 16-Jul-01 dH added C_COMP_HEW_SH7055 / C_COMP_HEW_H8S +| 17-Aug-01 1.09 Et deleted keywords __near and __far for C_COMP_FUJITSU_8L +| 21-Aug-01 1.10 Ht/Vg added C_COMP_DIABDATA_PPC +| 25-Aug-01 1.11 Ml added #pragma MESSAGE DISABLE C1106 for Hiware HC08 compiler +| 06-Sep-01 1.12 Ht/Vg added C_COMP_GNU_ST9 +| 11-Sep-01 1.13 Fr added C_COMP_ANSI_TMS_470 +| 21-Sep-01 1.14 Pl added C_COMP_MCP18_PIC_INT +| 25-Sep-01 1.15 Vg added C_COMP_MICROTEC_MC376 and C_COMP_TASKING_MC376 +| 28-Sep-01 1.16 Hp added C_COMP_GHS_TX39 and C_COMP_TOSHIBA_TLC900 +| 23-Oct-01 1.17 Js added C_COMP_DIABDATA_MCORE +| 23-Oct-01 1.18 dH changed ..._SH705X to ..._SH705X +| 05-Nov-01 1.19 dH added M32R +| 19-Nov-01 1.20 Ht added C_COMP_xxx_XC16X +| 22-Nov-01 1.21 dH added C_COMP_IAR_H8S +| 11-Nov-01 1.22 Fz added C_COMP_MITSUBISHI_M32C/C_COMP_NEC_V85X +| 19-Dec-01 1.23 dH changed Fujitsu FFMC16LX +| 28-Jan-02 1.24 Ml 00002160: added paging keywords for HC12 +| 31-Jan-02 1.25 Pl added C_COMP_KEIL_T89C51C +| 07-Mar-02 1.26 Vg/Rn added C_COMP_METROWERKS_PPC +| 27-Mar-02 1.27 Fz added C_COMP_IAR_V85X +| 09-Apr-02 1.28 Ht addaption to LI 1.3 +| 02-Apr-02 1.29 Ml added C_COMP_METROWERKS_MGT5100 +| added C_COMP_METROWERKS_DSP56F80X +| 13-May-02 1.30 LS MEMORY_HUGE added for C_COMP_TASKING_C16X +| 21-May-02 1.31 Ml canbittype for HC12 is now unsigned short +| 10-Jul-02 1.32 Ml canbittype for HC12 changed to unsigned char +| 16-Jul-02 1.33a Fz canbittype for V850 changed to unsigend int +| _c_bits32 added +| 31-Jul-02 Ts added C_COMP_HEW_SH70XX_HCAN2 +| 31-Jul-02 1.33 Ht _c_bits16 added for C_CPUTYPE_BITORDER_MSB2LSB +| 31-Jul-02 1.34 Si pc-lint comments for 78K0 changed +| 02-Aug-02 1.33 Sf 00003192: Memory qualifier for M16C changed +| 08-Aug-02 1.34 Zw ESCAN00003456 added STmicro ST7 (beCAN) / Hiware +| 18-Aug-02 Pet ESCAN00003530 delete keyword near for HC08 +| 06-Sep-02 1.35 Zw 00003688: MEMORY_NEAR defined to nothing for ST7_beCAN +| 09-Sep-02 1.36 Bs controller OKI MSM9225B (C_COMP_GHS_ARM7TM) added (needed for FBL) +| 10-Sep-02 1.37 Ds added C_COMP_COSMIC_ST7_BECAN +| and C_COMP_HIWARE_ST7_BECAN +| 13-Sep-02 1.38 Ht rework the module +| 17-Sep-02 1.39 Stu add the C_COMP_NEC_78K0 +| 17-Sep-02 1.40 Vg ESCAN00003614 added __declspec() to place const +| variables into ROM for Metrowerks +| 18-Sep-02 1.41 Stu added C_COMP_NEC_78K0 +| 07-Oct-02 1.42 dH added C_COMP_GAIO_SH705X +| 11-Oct-02 1.43 dH added C_COMP_FUJITSU_16LX_HL +| 14-Oct-02 1.44 Ml changed vbittype for MGT5100 into unsigned short +| 14-Oct-02 1.45 Stu changed vbittype for 78k0 into unsigned char +| 18-Oct-02 1.46 Pl added C_COMP_TASKING_ST10_CCAN +| added C_COMP_ARM_ST30_CCAN +| 30-Oct-02 1.47 Ml added C_COMP_ARM_470 and C_COMP_TI_470 +| 06-Nov-02 1.48 Wr added C_COMP_NATIONAL_CR16 +| 07-Nov-02 1.49 RAP added C_COMP_DIABDATA_MPC823 +| RAP added C_COMP_GHS_STARFISH +| 14-Nov-02 1.50 An corrected the banking defines for Cosmic and Hiware +| 27-Nov-02 1.50 Pl added C_COMP_FUJITSU_FR50 +| 02-Dec-02 1.51 Si MEMORY_NEAR changed for C_COMP_NEC_78K0 +| 11-Dec-02 Pet added C_COMP_IAR_CEVF +| 18-Dec-02 1.52 Si added C_COMP_NEC_78K0 +| 04-Jan-03 Et added memory qualifier for C_COMP_IAR_CEVF +| 22-Jan-03 Ap added C_COMP_ARM_EASYCAN +| 28-Jan-03 1.53 Pl added C_COMP_KEIL_ST10_CCAN +| delete C_COMP_ARM_ARM7STM +| 03-Apr-04 1.54 To added C_COMP_METROWERKS_DSP5683X +| ZW canbittype for CEVG is now unsigned char +| Hp Add MEMORY_HUGE for XC16x +| Fz added C_COMP_IAR_CR16 and C_COMP_NATIONAL_CR16 changed +| Ml added C_COMP_TI_TMS320 +| 2003-05-13 1.60 Ht support V_MEMROM0 +| 2003-05-14 1.61 Tri added V_MEMROM0 definition for MGT5100 +| 2003-05-15 1.62 Pl added C_COMP_FUJITSU_FR60_CCAN +| 2003-05-20 1.63 WM added near/far memory defines for C_COMP_HIWARE_12 +| 2003-06-11 1.64 CB MEMORY_HUGE added for C_COMP_TASKING_ST10_CCAN +| 2003-06-18 1.65 Bir added C_COMP_MICROCHIP_DSPIC30 +| 2003-07-08 1.66 Bir no local lint command +| 2003-08-15 1.67 Rr changed MEMORY_FAR for M32C +| 2003-08-18 1.68 BWR added support for MAC710X +| 2003-09-02 1.69 BWR added support for MC332 with external Intel 82527 +| 2003-09-09 1.70 Bir added C_COMP_TASKING_TRICORE_MULTICAN & C_COMP_GNU_TRICORE_MULTICAN +| 2003-10-30 1.71 RAP added C_COMP_MICROCHIP_PIC18 +| 2003-11-13 2.00 Ht memory qualifier changed to new definition +| 2004-01-08 2.01 BWR added support for MPC55XX +| 2004-01-16 2.02 Ml added cast macros +| 2004-01-22 2.03 dH added C_COMP_HEW_SH2_HCAN1 and C_COMP_HEW_H8S_HCAN1 +| 2004-02-13 2.04 WM Added banking support for C_COMP_IAR_12 +| 2004-02-18 2.05 RAP Update for C_COMP_MICROCHIP_PIC18 +| 2004-03-12 2.06 Ml changed canbittype for TMS470 +| 2004-03-13 2.07 dH added C_COMP_HEW_H8TINY +| 2004-04-20 2.08 dH added C_COMP_HEW_H8SX_HCAN1 +| 2004-04-08 2.09 Rna Memoryclassifier V_MEMROM0 and MEMORY_ROM for Metrowerks PPC changed +| 2004-05-14 2.10 Ms added Release Version define +| added include for vstdlib.h +| 2004-05-18 2.11 Ml changed plattform check to work in any case (NO_ELSE) +| Ml added V_NULL +| 2004-06-17 2.12 Ms changed C_COMP_SUPPORTED_PLATTFORM -> V_COMP_SUPPORTED_PLATTFORM +| 2004-06-26 2.13 RAP added C_COMP_GHS_SJA2020 +| 2004-06-30 2.14 Ml added C_COMP_COSMIC_MCS12X_MSCAN12 +| 2004-08-17 2.15 Pl Memoryclassifier V_MEMROM0/1/2 for the C_COMP_TOSHIBA_TLC900 changed +| 2004-08-31 2.16 Ml changed bitfieldtype for MCS12X +| 2004-09-08 2.17 RAP changed vbittype for C_COMP_GHS_SJA2020 +| 2004-09-12 2.18 BWR added C_COMP_GHS_PPC +| 2004-09-20 2.19 Ces added C_COMP_GHS_ST30_CCAN +| 2004-09-27 2.20 Ms -ESCAN00009636: Naming Conventions +| 2004-09-28 2.21 Bir changed bitfieldtype for TriCore MultiCAN +| 2004-09-30 2.22 Ht Review +| 2004-10-06 2.23 Ml Added C_COMP_MTRWRKS_MCS12X_MSCAN12 +| 2004-10-27 2.24 Ml changed V_ENABLE_VSTDLIB -> VGEN_ENABLE_VSTDLIB +| 2004-10-29 2.25 Pl Added C_COMP_GHS_TX19 +| 2004-11-05 2.26 Ml Added C_COMP_COSMIC_MCS12X_MSCAN12 and C_COMP_COSMIC_MCS12_MSCAN12 +| 2004-11-08 2.27 Et support compiler option -fNP (C_COMP_MITSUBISHI_M32C) +| 2004-11-10 2.28 Ml Added compatibility for VStdLib +| 2004-11-15 2.29 dH new memoryclassifier for C_COMP_FUJITSU_16LX/C_COMP_FUJITSU_16LX_HL +| 2004-11-15 2.30 Ms ESCAN00010228: Support C_COMP specific V_NULL definition +| 2004-11-19 2.31 Ml bitfields for TMS470 are now int +| Ths ESCAN00010435: Due to compatibility V_DEF_VERSION added +| 2005-01-31 2.32 Ml Added C_COMP_IAR_TMS430_SCCHECC +| 2005-02-09 2.33 Ht support V_NULL for C_COMP_KEIL_C5X5C +| 2005-03-10 2.34 Ces Memory qualifier MEMORY_SADDR and MEMORY_NEAR for IAR 78K0 compiler +| 2005-03-22 2.35 Pl support V_NULL for C_COMP_TASKING_ST10_CCAN +| 2005-03-22 2.36 Ces support C_COMP_IAR_78K0_AFCAN +| support V_NULL for Tasking C16x/ST10, Mitsubishi M16C, IAR 78K0, +| Metrowerks DSP5683x and GreenHills ST30 +| 2005-03-24 2.37 Krt Set cast macros for M32C controller, to avoid compiler warnings +| Bir support V_NULL for C_COMP_TASKING_C16X, C_COMP_TASKING_XC16X, C_COMP_GNU_TRICORE_MULTICAN +| Ces MEMORY_NEAR corrections for IAR 78K0 AFCAN +| 2005-06-17 2.38 Ht remove duplicated compiler switch +| dH added C_COMP_HEW_SH2_RCAN +| Pl added C_COMP_GNU_ST10_CCAN +| Ds Added support for ADI Blackfin (BF5xx) +| Ml Added QNX platforms +| Fz MEMORY_HUGE changed for V85X IAR compiler in case tiny memory model +| Ht default definition of NULL +| 2005-06-20 2.39 BWR Added support for MAC7100 IAR compiler +| dH changed bittype for C_COMP_HEW_SH2_RCAN to unsigned char +| 2005-08-24 2.40 Rna position for NULL definitions moved to prevent redefinitions for HC12 cosmic (string.h) +| 2005-10-05 2.41 Ces adaptions for IAR compiler M16C +| 2005-10-14 2.42 Fn added C_COMP_IAR_AVR_CANARY +| Ces corrections for C_COMP_IAR_M16C +| Ces added C_COMP_IAR_M32C +| Ces added V_MEMROM3 for C_COMP_MITSUBISHI_M16C +| 2005-10-25 2.43 Ces IAR M32C: MEMORY_ROM is always far const +| 2005-12-02 2.44 dH added C_COMP_HEW_H8S_RCAN +| Fn added C_COMP_MICROCHIP_PIC18 for V_NULL +| Ht V_COMP_SUPPORTED_PLATTFORM changed to V_DEF_SUPPORTED_PLATFORM +| Pl added C_COMP_MATSUSHITA_MN103S_CCAN +| Svh added C_COMP_TOSHIBA_TLCS870 +| Ces changed compiler version check of IAR M16C and IAR M32C +| 2005-12-20 2.45 Ml Added C_COMP_METROWERKS_MGT5X00 +| Ces changed MEMORY_NORMAL for IAR M16C and IAR M32C +| 2006-01-27 2.46 Ml ESCAN00014816: Added cast defines for MCS12x with comsic +| Ml 00015045: Added support for constants in global pages +| Ml Added C_COMP_MTRWRKS_MPC5X00 +| Svh Added C_COMP_ARM_ADUC703X +| 2006-02-08 2.47 Pl Added C_COMP_IAR_ML67Q25XX_CCAN +| 2006-02-09 Ml Changed check for XGate compiler +| 2006-02-10 2.48 Ces Added #define V_NULL for MITSUBISHI M32C and MITSUBISHI M32R +| 2006-02-20 2.49 Ml Changes for dependency builder to accept XGate compiler specific preprocessor +| 2006-03-28 2.50 Ard Added C_COMP_ARM_OMAP +| Pl Added C_COMP_TOSHIBA_TLCS900 +| Svh Added C_COMP_HPINFOTECH_AVR_CANARY +| 2006-04-27 2.51 dH added C_COMP_MATSUSHITA_MN101E_CCAN +| Ap added C_COMP_HITECH_PIC18 +| Fn modifications for C_COMP_MICROCHIP_PIC18 +| Ces Added C_COMP_GHS_TX49 and C_COMP_NEC_78K0_AFCAN +| 2006-05-02 2.52 Ces Change MEMORY_NEAR and MEMORY_SADDR for C_COMP_NEC_78K0_AFCAN +| Svh Added C_COMP_IAR_ADUC703X +| 2006-05-19 2.53 Ces Change MEMORY_NEAR for C_COMP_NEC_78K0_AFCAN +| Ces Change define V_NULL for C_COMP_MITSUBISHI_M32R +| 2006-08-03 2.54 Her Added type cast for C_COMP_: COSMIC_08/NEC_78K0_AFCAN/COSMIC_MCS12X_MSCAN12 +| Fn Added C_COMP_MICROCHIP_DSPIC33 +| Ap Added C_COMP_MTRWRKS_MCS08_MSCAN and C_COMP_COSMIC_MCS08_MSCAN +| BWR Added C_COMP_GAIO_MPC55XX +| Pl Added C_COMP_FUJITSU_16FX_CCAN +| 2006-08-04 2.55 Ces Added C_COMP_GHS_LPC2XXX +| 2006-08-09 2.56 Svh Added V_MEMRAM1_NEAR for C_COMP_NEC_78K0 +| 2006-08-13 2.57 Ml Changed bitfield type for C_COMP_COSMIC_MCS08_MSCAN +| Pl Added C_COMP_ARM_AVCCORE1_CCAN +| 2006-08-30 2.58 Wr Added C_COMP_GNU_VR55XX_AFCAN +| 2.58 Ml Added C_COMP_DIABDATA_MPC5X00_MSCAN +| 2006-09-22 2.59 swk Added C_COMP_KEIL_ST10_CCAN +| Ml Changed bitfield type for C_COMP_COSMIC_MCS08_MSCAN back to vuint8 +| 2006-10-23 2.60 BWR Added C_COMP_GNU_MICROBLAZE_LOGICORECAN +| Ard Added C_COMP_GHS_MAC710X +| 2006-10-23 2.61 Bir Added C_COMP_TASKING_XC2000_MULTICAN +| 2006-11-14 Ml Added function near/far qualifier for platform MCS12X +| 2006-11-20 BWR Added C_COMP_METROWERKS_MPC55XX_FLEXCAN +| Added C_COMP_DIABDATA_MCORE_FLEXCAN +| 2006-11-20 Bir changes for C_COMP_TASKING_XC2000_MULTICAN +| 2006-12-14 Pl Added C_COMP_TI_TMS470_DCAN +| 2007-01-10 Bir changes for C_COMP_TASKING_XC2000_MULTICAN +| 2007-01-11 Ces Added C_COMP_IAR_MCS12_MSCAN12 +| 2007-02-01 2.62 Svh Added C_COMP_FUJITSU_8FX +| 2007-02-19 2.63 Ces Added C_COMP_GHS_SAF7780_PELICAN +| Ces Changed MEMORY_NORMAL for C_COMP_MITSUBISHI_M32C +| 2007-06-21 2.64 Ces Changed MEMORY_NORMAL for C_COMP_MITSUBISHI_M16C +| Fn Added C_COMP_IAR_R32C +| BWR Added C_COMP_DIABDATA_MCF_FLEXCAN +| Awh Added C_COMP_KEIL_XC16X +| Ou Changed vbittype for C_COMP_MTRWRKS_MCS12X_MSCAN12 to unsigned char, additionally disabled warning C1106 for this compiler (see #pragma MESSAGE DISABLE C1106) +| 2007-09-07 2.65 Ou Changed back vbittype for C_COMP_MTRWRKS_MCS12X_MSCAN12 to unsigned int +| Ard Added C_COMP_GHS_TMS470 +| 2007-09-28 2.66 Fn Added C_COMP_COSMIC_ST79_BECAN3 +| Ces Added V_MEMROMx_NEAR and V_MEMROMx_FAR for C_COMP_IAR_M16C +| Added V_MEMROMx_NEAR and V_MEMROMx_FAR for C_COMP_IAR_M32C +| Use predefined compiler macros __VX__ and _C166 for C_COMP_TASKING_XC2000_MULTICAN +| 2007-10-24 2.67 Fn Changed C_COMP_COSMIC_ST79_BECAN3 to C_COMP_COSMIC_STM8A_BECAN3 +| Fn Added C_COMP_RENESAS_R32C +| 2007-11-09 2.68 Wr Added C_COMP_KEIL_SLC8051 +| 2007-11-14 2.69 Svh Added C_COMP_KEIL_ADUC703X +| 2007-11-27 2.70 Fn Adapted rom qualifier for: C_COMP_RENESAS_R32C, C_COMP_IAR_R32C and C_COMP_MICROCHIP_DSPIC33 +| Ml Added memory mapping defines for C_COMP_MTRWRKS_MCS12X_MSCAN12 +| 2007-12-03 2.71 Ard Added C_COMP_MICROSOFT_TMS320ARM +| 2008-01-14 2.72 Ou Added memory mapping defines for C_COMP_MTRWRKS_MCS08_MSCAN and C_COMP_COSMIC_MCS08_MSCAN +| Ces Added C_COMP_GHS_MPC55XX and C_COMP_GHS_MPC55XX_FLEXCAN2 +| Added C_COMP_GAIO_MPC55XX_FLEXCAN2 +| Added C_COMP_DIABDATA_MPC55XX_FLEXCAN2 +| Changed memory qualifier for IAR M16C and IAR M32C +| 2008-02-19 2.73 Ces Corrected V_NULL for DIABDATA_MPC55XX +| 2008-03-05 2.74 Pl Added C_COMP_GNU_NIOS_DCAN +| 2008-03-12 Fn Added V_MEMROM2_FAR and V_MEMROM2_NEAR for C_COMP_IAR_AVR_CANARY +| 2008-04-18 Ap Added C_COMP_GNU_AVR_CANARY +| 2008-05-05 2.75 Bir Possibility to change V_MEMROM2 for XC2000 (user config) +| 2008-05-05 2.76 Ou Change the behavior for V_MEMROM3 on MCS12X (relevant just for Cosmic compiler, global constants feature) +| 2008-05-06 2.77 Ces Changed V_MEMRAM2_FAR for IAR compiler M16C/R8C +| Added P_MEM_ROM for IAR compiler M16C +| Ap Added C_COMP_IAR_78K0R +| 2008-07-24 2.78 Ht Memory qualifier for C_COMP_COSMIC_STM8A_BECAN3 added +| 2008-08-27 2.79 Ces Adapt memory qualifier for C_COMP_MITSUBISHI_M16C and C_COMP_MITSUBISHI_M32C +| 2008-09-18 2.80 Ard Added C_COMP_QCC_TMS320ARM +| 2008-10-15 2.81 Bir Added C_COMP_GHS_TRICORE_MULTICAN +| BWR Adapt memory qualifier for C_COMP_GNU_MPC5X00_MSCAN +| 2008-11-14 2.82 Pl Added C_COMP_GNU_MB86R0X_CCAN +| Ou V_MEMROMx have the default behavior for C_COMP_MICROCHIP_DSPIC33 +| 2008-11-21 2.83 Ces Added C_COMP_GNU_IMX_FLEXCAN2 +| Added V_MEMROM2 for C_COMP_MITSUBISHI_M32C +| 2009-01-19 2.84 Ou Change the behavior of data pointer buffers in order to meet the global data expectations in case of C_COMP_COSMIC_MCS12X_MSCAN12 +| Change the default behavior for V_MEMRAM1_FAR and V_MEMRAM3_FAR in case of C_COMP_COSMIC_MCS12X_MSCAN12 +| Tvi Added C_COMP_IAR_M16C_RCAN2 and C_COMP_RENESAS_M16C_RCAN2 +| 2009-01-23 2.85 Ou Adjust the behavior of V_MEMRAM1_FAR and V_MEMRAM3_FAR in case of C_COMP_COSMIC_MCS12X_MSCAN12 in order to have an unified behavior +| 2009-01-29 2.86 Pl For the TI_TMS470_DCAN changed vuint32 from unsigned long to unsigned int and vsint32 int from signed long to signed int +| Added C_COMP_GNU_ST30_CCAN +| 2009-02-18 Ou Added C_COMP_MTRWRKS_MPC5X00_MSCAN +| 2009-03-19 2.87 Kk Added C_COMP_GAIO_SH2_RCAN +| Pl Some V_MEMROM and V_MEMRAM defines for the C_COMP_FUJITSU_16FX_CCAN added ( only in the case VGEN_ENABLE_CANFBL is defined ) +| 2009-03-25 2.88 Aj Added C_COMP_ARM_TCC800X_CCAN +| 2009-07-08 2.89 Bir Added Compiler abstraction like ASR +| Ou Added C_COMP_KEIL_PSOC3_CANMODULE3 +| Ces Added C_COMP_METROWERKS_MPC55XX and C_COMP_METROWERKS_MPC55XX_FLEXCAN2 +| Pl For the TI_TMS470_DCAN changed back vuint32 from unsigned int to unsigned long and vsint32 from signed int to signed long +| Reason is to be compatible with TI_TMS470 and with Platform_Types.h +| 2009-07-08 2.90 Bir change Compiler abstraction "V_DEF_P2SFR_CAN" +| Ou Rework the V_MEMROMx and V_MEMRAMx for C_COMP_KEIL_PSOC3_CANMODULE3 +| Seg Added C_COMP_ARM_TMS470_DCAN +| Ou Added C_COMP_QCC_MPC5X00_MSCAN +| 2009-09-03 2.91 Bir Added C_COMP_IAR_AVR32_CANIF +| Kk Added C_COMP_RENESAS_SH4_RCAN +| 2009-09-04 2.92 Tvi Added C_COMP_GHS_V85X_FCN +| 2009-10-06 2.93 Tvi Added C_COMP_GHS_SH4_RCAN2 +| 2009-10-16 2.94 Ou,Ht Fixed V_NULL for C_COMP_KEIL_PSOC3_CANMODULE3, C_COMP_KEIL_C5X5C and +| C_COMP_KEIL_SLC8051 +| 2009-10-27 2.95 Ou Map the reentrant keyword to C_API_3 in case of C_COMP_KEIL_PSOC3_CANMODULE3 +| 2009-10-30 2.96 Rna Support C_COMP_ARM_STM32_BXCAN +| 2009-11-10 2.97 Ht ESCAN00039030: Support V_MEMRAM2_FAR for XC2000 Tasking +| Seg Support C_COMP_GNU_TX49 +| 2009-11-20 2.98 Tvi ESCAN00039020: Renesas: support "-fansi" option +| Ou Fixed the standard memory qualifier definitions (vuintx/ vsintx) in combination with CAN-Driver for ASR +| 2009-11-23 2.98.01 Ht correct COMMON_VDEF_RELEASE_VERSION +| 2010-02-03 2.99 Tvi ESCAN00039371: [M16C/R8C with RENESAS]: Warnings about incompatible pointer types for Compiler versions >= V5.45 +| Ht Support C_COMP_KEIL_SJA2020 +| 2010-02-03 3.00.00 Ht change version number +| 2010-03-02 3.01.00 Ou Rework the V_MEMROMx and V_MEMRAMx for C_COMP_IAR_78K0R +| vadaba Added V_MEMROM0 to place const variables into ROM for C_COMP_METROWERKS_MPC55XX_FLEXCAN2 +| 2010-03-10 3.02.00 Tvi ESCAN00041468: [SH4Rcan2 w. GHS] "-Ospace" leads to a runtime exception due to incorrect bitfield access +| Kk Added C_COMP_QCC_SH4_RCAN +| Kk Added C_COMP_IAR_SH2_RCAN +| 2010-05-12 3.03.00 Pl Added C_COMP_QCC_MB86R0X_CCAN +| Ces Support C_COMP_GNU_MPC55XX and C_COMP_GNU_MPC55XX_FLEXCAN2 +| 2010-06-09 3.04.00 Tvi Added C_COMP_NEC_78K0R +| 2010-07-01 3.05.00 Ht Added support of MEMORY_HUGE for C_COMP_KEIL_C16X +| 2010-07-12 3.06.00 Ces Support C_COMP_GHS_IMX_FLEXCAN2 +| Tvi ESCAN00044064: [R32C with RENESAS]: Warnings about incompatible pointer types for Compiler versions >= V1.02 r00 +| 2010-09-06 3.07.00 Ces ESCAN00044378: added check for V_NULL definiton if default is not used +| Tvi Misra warning due to wrong characters in history removed +| Kk Added C_COMP_ARM_TRITON_AFCAN +| Ap Added C_PROCESSOR_R8C_XX to distinguish different derivatives +| 2010-10-01 3.08.00 Tvi Added C_COMP_RENESAS_V85X_FCN +| 2010-10-17 3.09.00 Bir Added C_COMP_KEIL_XC800 +| 2010-12-13 3.10.00 Tvi Added C_COMP_RENESAS_78K0R +| 2011-01-28 3.11.00 Ht M16C Compiler switch for Organi added +| Added C_COMP_GHS_SH2_RCAN +| Tvi Changed V_MEMROM1 for C_COMP_RENESAS_78K0R when memory model MEDIUM is used +| Rna Support TMS320(canbedded) with Geny +| 2011-02-25 3.12.00 Ces Added C_COMP_ARM_TX03_TXCAN +| Pl Added C_COMP_FUJITSU_FR81_CCAN +| Tkr Added C_COMP_GHS_SH2_RCAN2A +| 2011-04-08 3.13.00 Ou Added C_COMP_IAR_MCS12X_MSCAN12 +| Tvi Support C_PROCESSOR_R8C again (removed in 3.07.00) +| Aj Added C_COMP_RENESAS_V85X_AFCAN +| 2011-05-20 3.14.00 Tvi Added C_COMP_IAR_V85X_FCN +| Was Added C_COMP_TI_TMS320C64X_HECCSCC +| 2011-05-31 3.15.00 Aj Added C_COMP_GNU_SH2_RCAN +| 2011-07-11 3.16.00 Ht replace V_NONE with V_STORAGE_NONE in case of V_CPU_TMS320ARM +| 2011-08-08 3.17.00 Pl Added C_COMP_GHS_FCR4_CCAN +| Eta Added C_COMP_IAR_ADUCM33X +| 2011-09-26 3.18.00 Aj Added C_COMP_HEW_SH2_RCAN2 +| 2011-11-24 3.19.00 Aj Added C_COMP_ARM_AVNA_CCAN +| 2012-01-12 3.20.00 Rse Added C_COMP_QCC_IMX_FLEXCAN2, C_COMP_GNU_IMX_FLEXCAN3, C_COMP_QCC_IMX_FLEXCAN3, C_COMP_GHS_IMX_FLEXCAN3 +| 2012-02-15 3.21.00 Aj Added C_COMP_KEIL_FM3_CCAN +| Ht Header changed +| remove C_COMP_MCP18_PIC_INT (old driver version) +| Tvi Added C_COMP_RENESAS_SH4_RCAN2 +| 2012-02-24 3.22.00 Tvi Change VEMROM2_NEAR to __near for C_COMP_IAR_78K0R +| 2012-03-23 3.23.00 Ht Add C_COMP_IAR_RL78_AFCAN +| 2012-03-30 3.24.00 bir Add CAN_STATIC define for AutoSar4 compatible LL +| 2012-04-18 3.25.00 Seu Added C_COMP_TASKING_XC800_MULTICAN +| 2012-06-18 3.26.00 Aj Set vbittype=char for Sh4/Rcan2 in order to support littleendian +| 2012-08-01 3.27.00 Was Added C_COMP_KEIL_XC2000_MULTICAN +| 2012-08-22 3.28.00 Pl Added C_COMP_KEIL_SLC8051_CCAN, integration of C_COMP_KEIL_ switches +| QPs Added C_COMP_RENESAS_RL78_AFCAN +| 2012-09-20 3.29.00 Rse Added C_COMP_GNU_MPC5700_MCAN +| 2012-09-24 3.30.00 Tkr Added C_COMP_GHS_RH850_RSCAN, C_COMP_HEW_SH2_RSCAN and C_COMP_GHS_SH2_RSCAN +| 2012-10-08 3.30.01 Was ESCAN00061961: Compiler error: Using of V_MEMROM2_FAR and V_MEMROM2_NEAR leads to an compile error (Keil compiler/ XC2000) +| 2012-11-06 3.31.00 Ht ESCAN00062762: Remove function memory qualifier for 78K0R and RL78 +| 2012-11-08 3.32.00 Pl Added C_COMP_TI_TMS320ARM_DCAN +| 2012-12-12 3.33.00 Pl Added C_COMP_QCC_TMS320ARM_DCAN +| 2012-12-18 3.34.00 Rna Added C_COMP_IAR_STM32_BXCAN +| Bmo Added C_COMP_KEIL_TLE986X +| 2013-03-06 3.35.00 Rse Added C_COMP_GHS_MPC5700_FLEXCAN3, C_COMP_DIABDATA_MPC5700_FLEXCAN3 +| Rna VUINTx_CAST for STM8A with Cosmic added +| 2013-03-26 3.36.00 Tkr Added C_COMP_RENESAS_RL78_RSCAN +| Ht improve RL78 and 78K0R +| 2013-04-02 3.37.00 Was Added V_COMP_COSMIC_MCS12Z +| 2013-06-11 3.38.00 Ht Replace C_COMP_xxx_MPC5700_yyy with V_COMP_xxx_MPC5700 +| Replace C_COMP_xxx_IMX_yyyy with V_COMP_xxx_IMX +| Replace C_COMP_GHS_RH850_RSCAN with V_COMP_GHS_RH850 +| Replace canbittype by vbittype in this file -> no change of API +| Was Support IAR HCS12 Compiler Version 3.x +| 2013-06-21 3.38.01 Ht Remove comment +| 2013-07-02 3.39.00 Tkr Replace C_COMP_IAR_RL78_AFCAN with V_COMP_IAR_RL78 +| Tkr merge and adapt RL78 and 78K0R memory qualifier definitions for IAR compiler +| Replace C_COMP_RENESAS_RL78_xxx with V_COMP_RENESAS_RL78 +| 2013-08-20 3.40.00 Pl Added V_COMP_ARM_STA8088 +| Tkr Added V_COMP_DIABDATA_RH850 +| Rse Added V_COMP_GNU_VYBRID +| 2014-04-11 3.41.00 Rse Added V_COMP_GHS_VYBRID +| Was Added V_COMP_ARM_ZYNQ7000 +| Rse Added V_COMP_MICROSOFT_IMX +| Rse Added V_COMP_GHS_IMX +| Rse Added V_COMP_ARM_VYBRID +| QPs Added C_COMP_GNU_STM32_BXCAN +| Rna Added V_COMP_DIAB_TRICORE +| 2014-04-29 3.42.00 Rse Added V_COMP_IAR_VYBRID +| Tkr Added V_COMP_IAR_RH850 +| 2014-06-06 3.43.00 Zam Added V_COMP_GNU_TMS320ARM +| Was Added V_COMP_FREESCALE_MCS12Z +| 2014-07-25 3.44.00 Tkr Added V_COMP_RENESAS_RH850 +| Uce Added V_COMP_RENESAS_RCARSH4 +| 2014-09-03 3.45.00 Ap Added V_COMP_KEIL_ZSSC +| Ht adapt V_NULL definition for KEIL_FM3, KEIL_SJA2020, KEIL_ZSSC +| 2014-12-01 3.46.00 Pl Added V_COMP_GNU_ACCORDO2 +| 2014-12-17 3.47.00 CEl Added V_COMP_ARM_RZ +| 2015-02-25 3.48.00 Her Added V_COMP_GHS_TRAVEO +| 2015-05-12 3.49.00 Eta Added V_COMP_KEIL_ADUCM33X +| 2015-06-11 3.50.00 Zam Added V_COMP_TI_TMS320 +| 2015-09-30 3.51.00 Pl Added V_COMP_GHS_S32 +| Tkr Added Renesas CC-RL compiler for RL78 +| 2015-10-12 3.52.00 Eta Added V_COMP_GNU_SAM +| 2015-10-19 3.53.00 Bmo Added V_COMP_IAR_STM8A +| 2016-01-21 3.54.00 Aj Added V_COMP_KEIL_SAM +| Eta Added V_COMP_IAR_SAM +| 2016-03-21 3.55.00 Ht default definition of LOCAL_INLINE added +| Her Added V_COMP_GNU_SPC5800, V_COMP_GHS_SPC5800 +| 2016-04-27 3.56.00 Was LOCAL_INLINE definition for MSCAN based platforms added +| 2016-04-27 3.57.00 Rse LOCAL_INLINE definition for MPC5700 with DIABDATA +| 2016-06-07 3.58.00 Hzo Added V_COMP_IAR_TMPR4XX +| 2016-07-01 3.59.00 Her Added V_COMP_DIABDATA_SPC5800 +| Neb Added V_COMP_IAR_S32 +| 2016-08-22 3.60.00 Neb Added V_COMP_GHS_SAM +| 2016-11-16 3.61.00 Tkr Added LOCAL_INLINE definition for RH850 and RL78 +| 2016-12-21 3.62.00 Jan Added V_COMP_GNU_CSRATLAS7 +| 2017-02-21 3.63.00 Rse Added V_COMP_GHS_TCC802X +| Ap Added V_COMP_KEIL_HVC4223 +| 2017-05-08 3.64.00 Jgl Added V_COMP_QCC_INTEL64CPU and 64 Bit vuintx +| 2017-07-17 3.65.00 Ap Added V_COMP_GHS_SPC5800 +| Bmo Added V_COMP_GNU_PSOC4, V_COMP_IAR_CC26X0 +| 2017-08-08 3.65.01 Bmo Corrected version +| 2017-09-29 3.66.00 Aj Added V_COMP_ARM_TCC802X +| 2017-12-08 3.67.00 Ap Added C_COMP_IAR_TLE986X +| 2018-01-15 3.68.00 Rli Added V_COMP_GNU_S32 +| Bmo Added V_COMP_IAR_RX +| 2018-02-28 3.69.00 Ap Added Microchip XC8 compiler support +| 2018-03-02 3.70.00 Rli LOCAL_INLINE definition for FlexCAN3 and FlexCAN2 based derivatives with GHS, GNU, IAR added +| 2018-08-17 3.71.00 Ht Added V_COMP_GNU_BCM8910X +| 2018-09-24 3.72.00 Hum Added V_COMP_IAR_TRAVEO2 +| 2018-09-28 3.72.01 Hum Added ALM filter attribute for V_COMP_IAR_TRAVEO2 +| 2019-03-04 3.73.00 Ap Added V_COMP_IAR_MKW35 +| Hum Added LOCAL_INLINE definition for V_COMP_IAR_SAM +| 2019-03-04 3.74.00 Bns Added LOCAL_INLINE definition for TRICORE +| Jan Added V_COMP_GHS_RCARARM +| Jan Change LOCAL_INLINE definition for V_COMP_GHS_TRAVEO +| 2019-07-16 3.75.00 Ht Added V_COMP_GHS_TRAVEO2 +| Hum Added V_COMP_TI_AWR1 +| 2019-09-02 3.76.00 Bmo Added V_COMP_GHS_KEA +| 2019-11-27 3.77.00 Bmo Added V_COMP_ARM_TLE986X +| 2019-12-04 3.78.00 Pl Added V_COMP_GNU_TCC800X +| Ht replace C_COMP_ARM_TCC800X_CCAN with V_COMP_ARM_TCC800X +| 2019-12-20 3.79.00 Ht replace C_COMP_ARM_STM32_BXCAN with V_COMP_ARM_STM32 +| replace C_COMP_IAR_STM32_BXCAN with V_COMP_IAR_STM32 +| replace C_COMP_GNU_STM32_BXCAN with V_COMP_GNU_STM32 +| 2020-01-22 3.80.00 Pl Added V_COMP_IAR_TRAVEO +| Ht Replace C_COMP_GNU_TRICORE_MULTICAN by V_COMP_GNU_TRICORE +| Replace C_COMP_TASKING_TRICORE_MULTICAN by V_COMP_TASKING_TRICORE +| Replace C_COMP_GHS_TRICORE_MULTICAN by V_COMP_GHS_TRICORE +| 2020-02-21 3.81.00 Ap Added V_COMP_GNU_AVR +| 2020-03-05 3.82.00 TMo Added V_COMP_CADENCE_GW5 +| Ht Removed support for C_COMP_HIWARE_08, C_COMP_HIWARE_12, C_COMP_HIWARE_ST7, C_COMP_HIWARE_ST7_BECAN +| Ht Removed support for C_COMP_NEC_78K0_AFCAN, C_COMP_NEC_78K0, C_COMP_NEC_78K0R +| Ht Removed support for C_COMP_TOSHIBA_TLC900, C_COMP_TOSHIBA_TLCS900, C_COMP_TOSHIBA_TLCS870 +| Ht Removed support for C_COMP_HITECH_PIC18 +| 2020-03-11 3.83.00 Bmo Added V_COMP_IAR_PSOC4 +| 2020-05-05 3.84.00 Ap Added V_COMP_NXP_DSP56800EX +| 2020-06-15 3.85.00 Pl Added V_COMP_GNU_TCC802X +| 2020-07-23 3.86.00 Ap Added V_COMP_MICROCHIP_SAM +| 2020-09-30 3.87.00 Naj Added V_COMP_TI_JACINTO7 +| 2020-11-04 3.88.00 TMo Added V_COMP_ARM6_RCARARM +| TMo Added V_COMP_GNU_XMC4 +| TMo Added V_COMP_GNU_TRAVEO2 +| 2021-04-19 3.89.00 Ht Added V_COMP_TI_AWRGEN2 +| Ap Added V_COMP_GNU_TLE986X +| Ap Added V_COMP_MICROCHIP_AVR +| Ap Added V_COMP_ARM6_TLE986X +| 2021-05-26 3.90.00 Ht Added V_COMP_IAR_IMX +| JDn Added V_COMP_LLVMDIAB_ZYNQ7000 +| JDn Added V_COMP_GHS_ZYNQ7000 +| JDn Added V_COMP_GNU_ZYNQ7000 +| 2021-07-07 3.91.00 Ht Added V_COMP_IAR_TAYRONA +| Ht Added V_COMP_IAR_KW4 +| Ht Added V_COMP_LLVMDIAB_AWRGEN2 +| Ht Added V_COMP_GHS_JACINTO7 +| Ht Replace C_COMP_TI_TMS320ARM_DCAN with V_COMP_TI_TMS320ARM +| 2021-10-06 3.92.00 Ht Added V_COMP_ARM6_BCM8910X +| Ht Added V_COMP_LLVMTI_JACINTO7 +| 2022-03-11 3.93.00 Ht CANCORE-1117: Added V_COMP_LLVMTI_AWRGEN2 +| Ht Added V_COMP_GNU_LINUXFORARM32 +| Ht CANCORE-1125: Added V_COMP_ARM_ACCORDO2, V_COMP_ARM_ACCORDO2 +| 2022-07-06 3.94.00 Ht CANCORE-1377: Added V_COMP_GNU_LPC54 +| Ht CANCORE-1375: Added V_COMP_GHS_SAF85 +| 2022-10-13 3.95.00 Ap CANCORE-1555: Added V_COMP_ARM6_S32 +| 2022-11-17 3.96.00 Bmo Added V_COMP_IAR_MSPM0 +| 2023-02-14 3.97.00 Ht CANCORE-1818: Added V_COMP_GHS_TCC70XX +| 2023-03-03 3.98.00 Ap Added V_COMP_LLVMTI_MSPM0 +| 2023-03-31 4.00.00 Ht CANCORE-1848: Added V_COMP_IAR_ASX +| Ht Added V_COMP_TI_MSPM0 +| Ht Improvements related to compiler for ARM platforms +| Ht Removed: C_COMP_IAR_78K0_AFCAN, C_COMP_IAR_78K0 +| 2023-08-10 4.01.00 Ht Removed: C_COMP_COSMIC_08, C_COMP_COSMIC_ST7, C_COMP_COSMIC_ST7_BECAN +| Removed: C_COMP_GNU_ST9, C_COMP_FUJITSU_8FX, C_COMP_FUJITSU_8L +| Removed: C_COMP_MICROCHIP_DSPIC30, C_COMP_ARM_MAC710X, C_COMP_IAR_MAC710X, C_COMP_GHS_MAC710X +| Removed: C_COMP_IAR_CEVF, C_COMP_IAR_M32C, C_COMP_MITSUBISHI_M32C +| Removed: C_COMP_KEIL_C5X5C, C_COMP_KEIL_C16X, C_COMP_TASKING_C16X, +| Removed: C_COMP_MICROTEC_MC376, C_COMP_TASKING_MC376, C_COMP_GHS_ARM7TM +| Removed: C_COMP_MITSUBISHI_M32R, C_COMP_GAIO_M32R, C_COMP_OKI_CC665S +| Removed: C_COMP_GHS_CEVG, C_COMP_GHS_STARFISH, C_COMP_IAR_CR16, C_COMP_NATIONAL_CR16 +| Removed: C_COMP_ARM_EASYCAN, C_COMP_MICROTEC_332_82527, C_COMP_DIABDATA_MPC823 +| Removed: C_COMP_TI_OMAP, C_COMP_ARM_OMAP, C_COMP_HEW_H8TINY, C_COMP_FUJITSU_FR50 +| Removed: C_COMP_ARM_ST30_CCAN, C_COMP_GHS_ST30_CCAN, C_COMP_GNU_ST30_CCAN +| Removed: C_COMP_FUJITSU_FR60_CCAN, C_COMP_HEW_SH70XX_HCAN2, C_COMP_QCC_SH70XX_HCAN2 +| Removed: C_COMP_HEW_SH2_HCAN1, C_COMP_DIABDATA_MCF_FLEXCAN +| Removed: C_COMP_METROWERKS_MGT5100, C_COMP_METROWERKS_MGT5X00, C_COMP_HPINFOTECH_AVR_CANARY +| Removed: C_COMP_MTRWRKS_MPC5X00_MSCAN, C_COMP_MTRWRKS_MPC5X00, C_COMP_QCC_MGT5X00_MSCAN12 +| Removed: C_COMP_GNU_VR55XX_AFCAN, C_COMP_KEIL_SJA2020, C_COMP_GHS_SJA2020 +| Removed: C_COMP_METROWERKS_DSP56F80X, C_COMP_IAR_TMS430_SCCHECC, C_COMP_ARM_TRITON_AFCAN +| CANCORE-2110: Added V_COMP_ARM6_NCJ29D6 +| Pwf Added V_COMP_ARM6_MSPM0 +| 2023-09-15 4.02.00 Ht CANCORE-2179: Added V_COMP_LLVMTI_SITARA, V_COMP_LLVMDIAB_SITARA, V_COMP_TI_SITARA +| 2023-10-26 4.03.00 Ht CANCORE-2223: Added V_COMP_ARM6_RCARGEN4ARM +| 2023-11-30 4.04.00 Bmo LIN-988: Added V_COMP_ARM6_E53306 +| 2024-01-10 4.05.00 Ht Added V_COMP_GNU_KW4 +| CANCORE-2401: Added V_COMP_TI_TM4C +| 2024-03-12 4.06.00 Ht CANCORE-2520: Added V_COMP_QCC_QNXFORARM64 +| 2024-05-22 4.07.00 Ht CANCORE-2616: Added V_COMP_GHS_QPF51 +| CANCORE-2663: Added V_COMP_LLVMDIAB_S32 +| 2024-06-25 4.07.01 Kja CANCORE-2765: Added V_MEMRAM2_NEAR as user definable for RL78+IAR compiler +| 2024-07-08 4.08.00 Ht CANCORE-2770: Added V_COMP_ARM6_VAYYAR720X +| Kja CANCORE-2800: Added V_MEMRAM1_NEAR as user definable for RL78+Renesas compiler +| 2024-12-04 4.09.00 Ht CANCORE-2959: Added V_COMP_IAR_PIC32C, V_COMP_MICROCHIP_PIC32C, V_COMP_GNU_PIC32C, V_COMP_GHS_PIC32C +| Ht CANCORE-2961: Added V_COMP_GHS_VISCONTI5 +| Ht CANCORE-3019: Added V_COMP_LLVMHIGHTEC_STELLARSR6 +| Ht CANCORE-3012: Added V_COMP_GHS_SAF90 +| 2025-01-08 4.10.00 Ht CANCORE-3053: Added V_COMP_IAR_HC32A4 +| CANCORE-3074: Added V_COMP_LLVMHIGHTEC_TRICORE +| 2025-03-04 4.11.00 Ht CANCORE-3217: Added V_COMP_IAR_XHSCXC2 +| 2025-03-10 4.12.00 Ht CANCORE-3250: Added V_COMP_LLVMDIAB_SAF85 +| 2025-08-08 4.13.00 Ht CANCORE-3320: Added V_COMP_LLVMTI_TMS320ARM +| CANCORE-3544: Added Generic ARM implementation (MSR4 FBL usecase) +| Pwf LIN-1436: Added V_COMP_GNU_MSPM0 +| LIN-1438: Added V_COMP_ARM6_A89XXX, V_COMP_GNU_A89XXX, V_COMP_IAR_A89XXX +| 2025-10-22 4.14.00 Ht CANCORE-3649: Added V_COMP_GHS_RCARGEN5ARM, V_COMP_IAR_RCARGEN5ARM +| CANCORE-3260: Added V_COMP_LLVMTI_AWRGEN2LOW, V_COMP_LLVMDIAB_AWRGEN2LOW, V_COMP_TI_AWRGEN2LOW +|****************************************************************************/ + + + +#ifndef V_DEF_H +# define V_DEF_H + +/***************************************************************************/ +/* Version (abcd: Main version=ab, Sub Version=cd ) */ +/***************************************************************************/ +# define COMMON_VDEF_VERSION 0x0414 +# define COMMON_VDEF_RELEASE_VERSION 0x00 + +/* compatibility for IL versions < 3.52 */ +# define V_DEF_VERSION COMMON_VDEF_VERSION + + +/***************************************************************************/ +/* Supported Systems */ +/***************************************************************************/ + + + +/* compatibility define due to older implementations */ + + + +/* ARM32 with ARM6 compiler */ + +/* ARM32 with GHS compiler */ + +/* ARM32 with GNU compiler */ + +/* ARM32 with IAR compiler */ + +/* ARM32 with Microchip compiler */ + +/* ARM32 with LLVMDIAB compiler */ + +/* ARM32 with LLVMHighTec compiler */ + +/* ARM32 with LLVMTI compiler */ +# if defined( V_COMP_LLVMTI_SITARA ) +# define V_DEF_COMP_LLVMTI_ARM +# define V_DEF_SUPPORTED_PLATFORM +# endif + +/* ARM32 with TI compiler */ + + +/* all other supported plattform compiler combination */ + + +# if !defined V_DEF_SUPPORTED_PLATFORM +# error "Plattform unknown or V_COMP_xxx_yyy not defined" +# endif + + + + + +/***************************************************************************/ +/***************************************************************************/ +/**** General and platform dependent type definitions ********************/ +/***************************************************************************/ +/***************************************************************************/ +/*--- standard memory qualifier definition --------------------------------*/ + +/* 8-Bit qualifier */ +# if !defined( vuint8 ) /* ASR compatibility */ +typedef unsigned char vuint8; +# endif +# define canuint8 vuint8 + +# if !defined( vsint8 ) /* ASR compatibility */ +typedef signed char vsint8; +# endif +# define cansint8 vsint8 + +/* 16-Bit qualifier */ +# if !defined( vuint16 ) /* ASR compatibility */ +typedef unsigned short vuint16; +# endif +# define canuint16 vuint16 + +# if !defined( vsint16 ) /* ASR compatibility */ +typedef signed short vsint16; +# endif +# define cansint16 vsint16 + + +/* 32-Bit qualifier */ +# if !defined( vuint32 ) /* ASR compatibility */ +typedef unsigned long vuint32; +# endif +# define canuint32 vuint32 + +# if !defined( vsint32 ) /* ASR compatibility */ +typedef signed long vsint32; +# endif +# define cansint32 vsint32 + + + +typedef unsigned char *TxDataPtr; /* ptr to transmission data buffer */ +typedef unsigned char *RxDataPtr; /* ptr to receiving data buffer */ + +/***************************************************************************/ +/* Defines */ +/***************************************************************************/ + + +/***************************************************************************/ +/***************************************************************************/ +/**** Hardware/Compiler dependent settings ******************************/ +/***************************************************************************/ +/***************************************************************************/ + +/* data type according to the CPU type */ +# if defined( C_CPUTYPE_8BIT ) +/* 8-Bit qualifier */ +# ifndef vuintx +# define vuintx vuint8 +# endif +# ifndef vsintx +# define vsintx vsint8 +# endif +# else +# if defined( C_CPUTYPE_16BIT ) +/* 16-Bit qualifier */ +# ifndef vuintx +# define vuintx vuint16 +# endif +# ifndef vsintx +# define vsintx vsint16 +# endif +# else +# if defined( C_CPUTYPE_32BIT ) +/* 32-Bit qualifier */ +# ifndef vuintx +# define vuintx vuint32 +# endif +# ifndef vsintx +# define vsintx vsint32 +# endif +# else +# if defined( C_CPUTYPE_64BIT ) +/* 64-Bit qualifier */ +# ifndef vuintx +# define vuintx vuint32 +# endif +# ifndef vsintx +# define vsintx vsint32 +# endif +# endif +# endif +# endif +# endif + +/* qualifier for bitfield definition */ +typedef unsigned int vbittype; +# define canbittype vbittype + + + +# if defined( C_SUPPORT_MIXED_CAN_LIN ) +/* support combination of "old" CAN driver and "new" LIN driver */ +# else +/* Structure for bit accessed memory. */ +/* The bit-order is hardware/compiler dependent */ +# if defined( C_CPUTYPE_BITORDER_LSB2MSB ) +struct _c_bits8 +{ + vbittype b0:1; /* LSB-Bits (lower adr!) */ + vbittype b1:1; + vbittype b2:1; + vbittype b3:1; + vbittype b4:1; + vbittype b5:1; + vbittype b6:1; + vbittype b7:1; /* MSB-Bits (higher address) unused */ + }; + +struct _c_bits16 +{ + vbittype b0:1; /* lower adr */ + vbittype b1:1; + vbittype b2:1; + vbittype b3:1; + vbittype b4:1; + vbittype b5:1; + vbittype b6:1; + vbittype b7:1; + + vbittype b10:1; /* higher adr */ + vbittype b11:1; + vbittype b12:1; + vbittype b13:1; + vbittype b14:1; + vbittype b15:1; + vbittype b16:1; + vbittype b17:1; +}; + +struct _c_bits32 +{ + vbittype b0:1; /* lower adr */ + vbittype b1:1; + vbittype b2:1; + vbittype b3:1; + vbittype b4:1; + vbittype b5:1; + vbittype b6:1; + vbittype b7:1; + + vbittype b10:1; /* mid low adr */ + vbittype b11:1; + vbittype b12:1; + vbittype b13:1; + vbittype b14:1; + vbittype b15:1; + vbittype b16:1; + vbittype b17:1; + + vbittype b20:1; /* mid high adr */ + vbittype b21:1; + vbittype b22:1; + vbittype b23:1; + vbittype b24:1; + vbittype b25:1; + vbittype b26:1; + vbittype b27:1; + + vbittype b30:1; /* higher adr */ + vbittype b31:1; + vbittype b32:1; + vbittype b33:1; + vbittype b34:1; + vbittype b35:1; + vbittype b36:1; + vbittype b37:1; +}; + +# else /* MSB2LSB */ +# if defined( C_CPUTYPE_BITORDER_MSB2LSB ) +struct _c_bits8 +{ + vbittype b7:1; /* MSB-Bits (Higher addr!) */ + vbittype b6:1; + vbittype b5:1; + vbittype b4:1; + vbittype b3:1; + vbittype b2:1; + vbittype b1:1; + vbittype b0:1; /* LSB-Bits (higher address) unused */ +}; + +struct _c_bits16 +{ + vbittype b7:1; /* lower adr */ + vbittype b6:1; + vbittype b5:1; + vbittype b4:1; + vbittype b3:1; + vbittype b2:1; + vbittype b1:1; + vbittype b0:1; + + vbittype b17:1; /* higher adr */ + vbittype b16:1; + vbittype b15:1; + vbittype b14:1; + vbittype b13:1; + vbittype b12:1; + vbittype b11:1; + vbittype b10:1; +}; + + +struct _c_bits32 +{ + vbittype b7:1; /* lower adr */ + vbittype b6:1; + vbittype b5:1; + vbittype b4:1; + vbittype b3:1; + vbittype b2:1; + vbittype b1:1; + vbittype b0:1; + + vbittype b17:1; /* mid low adr */ + vbittype b16:1; + vbittype b15:1; + vbittype b14:1; + vbittype b13:1; + vbittype b12:1; + vbittype b11:1; + vbittype b10:1; + + vbittype b27:1; /* mid high adr */ + vbittype b26:1; + vbittype b25:1; + vbittype b24:1; + vbittype b23:1; + vbittype b22:1; + vbittype b21:1; + vbittype b20:1; + + vbittype b37:1; /* higher adr */ + vbittype b36:1; + vbittype b35:1; + vbittype b34:1; + vbittype b33:1; + vbittype b32:1; + vbittype b31:1; + vbittype b30:1; +}; +# else +# error "Bitorder unknown: C_CPUTYPE_BITORDER_MSB2LSB or C_CPUTYPE_BITORDER_LSB2MSB has to be defined" +# endif /* C_CPUTYPE_BITORDER_MSB2LSB */ +# endif /* C_CPUTYPE_BITORDER_LSB2MSB */ +# endif + + + + +/***************************************************************************/ +/* Memory qualifier */ +/***************************************************************************/ + + + + + + +# if defined ( VGEN_ENABLE_CANFBL ) +# endif + + + + + + + + + + + + + + + + + +# ifndef MEMORY_HUGE +# define MEMORY_HUGE /* no entry */ +# endif + + + + + +/* *********************** default defines - used to store permanent data **************************************** */ +# ifndef V_MEMROM0 +# define V_MEMROM0 /* addition qualifier data access in ROM */ +# endif + +# ifndef V_MEMROM1_NEAR +# define V_MEMROM1_NEAR /* fast data access in ROM */ +# endif + +# ifndef V_MEMROM1 +# define V_MEMROM1 /* fast data access in ROM */ +# endif + +# ifndef V_MEMROM1_FAR +# define V_MEMROM1_FAR /* slow addressing mode in ROM */ +# endif + + +# ifndef MEMORY_ROM_NEAR +# ifndef V_MEMROM2_NEAR +# define V_MEMROM2_NEAR const /* fast data access in ROM */ +# endif +/* compatibility for modules which use old definition of memory qualifer */ +# define MEMORY_ROM_NEAR V_MEMROM2_NEAR +# else +# define V_MEMROM2_NEAR MEMORY_ROM_NEAR +# endif + +# ifndef MEMORY_ROM +# ifndef V_MEMROM2 +# define V_MEMROM2 const /* fast data access in ROM */ +# endif +/* compatibility for modules which use old definition of memory qualifer */ +# define MEMORY_ROM V_MEMROM2 +# else +# define V_MEMROM2 MEMORY_ROM +# endif + +# ifndef MEMORY_ROM_FAR +# ifndef V_MEMROM2_FAR +# define V_MEMROM2_FAR const /* slow addressing mode in ROM */ +# endif +/* compatibility for modules which use old definition of memory qualifer */ +# define MEMORY_ROM_FAR V_MEMROM2_FAR +# else +# define V_MEMROM2_FAR MEMORY_ROM_FAR +# endif + +# ifndef V_MEMROM3 +# define V_MEMROM3 +# endif + + +/* *********************** default defines - used to store volatile data **************************************** */ +# ifndef V_MEMRAM0 +# define V_MEMRAM0 /* addition qualifier data access in RAM */ +# endif + +# ifndef V_MEMRAM1_NEAR +# define V_MEMRAM1_NEAR /* fast data access in RAM */ +# endif + +# ifndef V_MEMRAM1 +# define V_MEMRAM1 /* fast data access in RAM */ +# endif + +# ifndef V_MEMRAM1_FAR +# define V_MEMRAM1_FAR /* slow addressing mode in RAM */ +# endif + + +# ifndef MEMORY_NEAR +# ifndef V_MEMRAM2_NEAR +# define V_MEMRAM2_NEAR /* fast data access in RAM */ +# endif +/* compatibility for modules which use old definition of memory qualifer */ +# define MEMORY_NEAR V_MEMRAM2_NEAR +# else +# define V_MEMRAM2_NEAR MEMORY_NEAR +# endif + +# ifndef MEMORY_NORMAL +# ifndef V_MEMRAM2 +# define V_MEMRAM2 /* fast data access in RAM */ +# endif +/* compatibility for modules which use old definition of memory qualifer */ +# define MEMORY_NORMAL V_MEMRAM2 +# else +# define V_MEMRAM2 MEMORY_NORMAL +# endif + +# ifndef MEMORY_FAR +# ifndef V_MEMRAM2_FAR +# define V_MEMRAM2_FAR /* slow addressing mode in RAM */ +# endif +/* compatibility for modules which use old definition of memory qualifer */ +# define MEMORY_FAR V_MEMRAM2_FAR +# else +# define V_MEMRAM2_FAR MEMORY_FAR +# endif + +# ifndef V_MEMRAM3_NEAR +# define V_MEMRAM3_NEAR /* fast data access in RAM */ +# endif + +# ifndef V_MEMRAM3 +# define V_MEMRAM3 /* fast data access in RAM */ +# endif + +# ifndef V_MEMRAM3_FAR +# define V_MEMRAM3_FAR /* slow addressing mode in RAM */ +# endif + + +/* *********************** default defines - to cast results **************************************************** */ +# if !defined(VUINT8_CAST) +# define VUINT8_CAST +# endif +# if !defined(VSINT8_CAST) +# define VSINT8_CAST +# endif +# if !defined(VUINT16_CAST) +# define VUINT16_CAST +# endif +# if !defined(VSINT16_CAST) +# define VSINT16_CAST +# endif +# if !defined(CANBITTYPE_CAST) +# define CANBITTYPE_CAST +# endif +# if !defined(CANSINTCPUTYPE_CAST) +# define CANSINTCPUTYPE_CAST +# endif +# if !defined(CANUINTCPUTYPE_CAST) +# define CANUINTCPUTYPE_CAST +# endif + + +/***************************************************************************/ +/* Local Inline */ +/***************************************************************************/ + + +# if defined( V_DEF_COMP_GHS_ARM ) || \ + defined( V_DEF_COMP_IAR_ARM ) +# if !defined(V_ENABLE_CAN_ASR_ABSTRACTION) && !defined(V_ENABLE_VSTDLIB_ASR_ABSTRACTION) +# if !defined(LOCAL_INLINE) +# define LOCAL_INLINE static inline +# endif +# endif +# endif +# if defined( V_DEF_COMP_GNU_ARM ) || \ + defined( V_DEF_COMP_MICROCHIP_ARM ) || \ + defined( V_DEF_COMP_LLVMDIAB_ARM ) || \ + defined( V_DEF_COMP_LLVMHIGHTEC_ARM ) || \ + defined( V_DEF_COMP_LLVMTI_ARM ) +# if !defined(V_ENABLE_CAN_ASR_ABSTRACTION) && !defined(V_ENABLE_VSTDLIB_ASR_ABSTRACTION) +# if !defined(LOCAL_INLINE) +# define LOCAL_INLINE static __inline__ +# endif +# endif +# endif + + + +/* ARM32 with TI compiler */ +# if defined( V_DEF_COMP_TI_ARM ) +# if !defined(V_ENABLE_CAN_ASR_ABSTRACTION) && !defined(V_ENABLE_VSTDLIB_ASR_ABSTRACTION) +# if !defined(LOCAL_INLINE) +# define LOCAL_INLINE static __inline +# endif +# endif +# endif + +/* ARM32 with ARM6 compiler */ +# if defined( V_DEF_COMP_ARM6_ARM ) +# if !defined(V_ENABLE_CAN_ASR_ABSTRACTION) && !defined(V_ENABLE_VSTDLIB_ASR_ABSTRACTION) +# if !defined(LOCAL_INLINE) +# define LOCAL_INLINE static __inline +# endif +# endif +# endif + + + + +/* ************************************************************************* */ +/* Common_VStdLib */ +/* ************************************************************************* */ +# if defined (VGEN_ENABLE_VSTDLIB) || defined (V_ENABLE_VSTDLIB) +# include "vstdlib.h" +# endif + +/* ************************************************************************* */ +/* V_NULL Definition */ +/* ************************************************************************* */ + + + +/* *********************** default definition of V_NULL **************************************** */ +# if !defined(V_NULL) +# define V_NULL ((void*)0) +# endif + + +# ifndef NULL +# define NULL V_NULL +# endif + +/* ************************************************************************* */ +/* defines regarding CAN and VStdLib MSR abstraction */ +/* ************************************************************************* */ +# if !defined(V_ENABLE_CAN_ASR_ABSTRACTION) && !defined(V_ENABLE_VSTDLIB_ASR_ABSTRACTION) +# define V_ENABLE_CBD_ABSTRACTION +# define STATIC static /* MSR3 */ +# define CAN_STATIC static /* MSR4 */ +# define AUTOMATIC +# if !defined(NULL_PTR) +# define NULL_PTR V_NULL +# endif +# if !defined(LOCAL_INLINE) +# define LOCAL_INLINE +# endif +# define CAN_LOCAL_INLINE LOCAL_INLINE + +# define V_NONE /* empty storage used instead of extern, static, volatile... */ +# define V_STORAGE_NONE /* empty storage used instead of extern, static, volatile... */ + +# if !defined( C_CALLBACK_1 ) +# define C_CALLBACK_1 +# endif +# if !defined( C_CALLBACK_2 ) +# define C_CALLBACK_2 +# endif +# if !defined( C_API_1 ) +# define C_API_1 +# endif +# if !defined( C_API_2 ) +# define C_API_2 +# endif +# if !defined( C_API_3 ) +# define C_API_3 +# endif +# define V_DEF_VAR(storage, vartype, memclass) V_MEMRAM0 storage V_MEMRAM1 vartype V_MEMRAM2 +# define V_DEF_VAR_NEAR(storage, vartype) V_MEMRAM0 storage V_MEMRAM1_NEAR vartype V_MEMRAM2_NEAR +# define V_DEF_VAR_FAR(storage, vartype) V_MEMRAM0 storage V_MEMRAM1_FAR vartype V_MEMRAM2_FAR +# define V_DEF_VAR_TYPE(storage, vartype) typedef storage V_MEMRAM1 vartype V_MEMRAM2 +# define V_DEF_P2VAR(storage, ptrtype, memclass, ptrclass) V_MEMRAM0 storage V_MEMRAM1 ptrtype V_MEMRAM2 * +# define V_DEF_P2VAR_PARA(storage, ptrtype, memclass, ptrclass) storage V_MEMRAM1 ptrtype V_MEMRAM2 * +# define V_DEF_P2VAR_TYPE(storage, ptrtype, ptrclass) typedef storage V_MEMRAM1 ptrtype V_MEMRAM2 * +/* platform specific order may be needed for MEMORY_CAN (position RAM1 or RAM2) */ +# define V_DEF_P2SFR_CAN(storage, ptrtype, memclass) V_MEMRAM0 storage V_MEMRAM1 ptrtype MEMORY_CAN * +# define V_DEF_P2SFR_CAN_TYPE(storage, ptrtype) typedef storage V_MEMRAM1 ptrtype MEMORY_CAN * +/* --- */ +# define V_DEF_CONSTP2VAR(storage, ptrtype, memclass, ptrclass) V_MEMROM0 storage V_MEMRAM1 ptrtype V_MEMRAM2 V_MEMRAM3 * V_MEMROM1 V_MEMROM2 +# define V_DEF_CONST(storage, type, memclass) V_MEMROM0 storage V_MEMROM1 type V_MEMROM2 +# define V_DEF_CONST_NEAR(storage, type) V_MEMROM0 storage V_MEMROM1_NEAR type V_MEMROM2_NEAR +# define V_DEF_CONST_FAR(storage, type) V_MEMROM0 storage V_MEMROM1_FAR type V_MEMROM2_FAR +# define V_DEF_CONST_TYPE(storage, type, memclass) typedef storage V_MEMROM1 type V_MEMROM2 +# define V_DEF_P2CONST(storage, ptrtype, memclass, ptrclass) V_MEMRAM0 storage V_MEMROM1 ptrtype V_MEMROM2 V_MEMROM3 * V_MEMRAM1 V_MEMRAM2 +# define V_DEF_P2CONST_PARA(storage, ptrtype, memclass, ptrclass) storage V_MEMROM1 ptrtype V_MEMROM2 V_MEMROM3 * V_MEMRAM1 V_MEMRAM2 +# define V_DEF_P2CONST_TYPE(storage, ptrtype, ptrclass) typedef storage V_MEMROM1 ptrtype V_MEMROM2 V_MEMROM3 * +# define V_DEF_CONSTP2CONST(storage, ptrtype, memclass, ptrclass) V_MEMROM0 storage V_MEMROM1 ptrtype V_MEMROM2 V_MEMROM3 * V_MEMROM1 V_MEMROM2 +# define V_DEF_FUNC(storage, rettype, memclass) storage rettype +# define V_DEF_FUNC_API(storage, rettype, memclass) storage C_API_1 rettype C_API_2 +# define V_DEF_FUNC_CBK(storage, rettype, memclass) storage C_CALLBACK_1 rettype C_CALLBACK_2 +# define V_DEF_P2FUNC(storage, rettype, ptrclass, fctname) storage C_CALLBACK_1 rettype (C_CALLBACK_2 *fctname) +# endif /* !defined(V_ENABLE_CAN_ASR_ABSTRACTION) && !defined(V_ENABLE_VSTDLIB_ASR_ABSTRACTION) */ +/*-----------------------------------------------------------------------------------------------*/ + +#endif /* V_DEF_H */ +/* STOPSINGLE_OF_MULTIPLE */ diff --git a/Source/bsw/CryIf/CryIf.c b/Source/bsw/CryIf/CryIf.c new file mode 100644 index 0000000..487c736 --- /dev/null +++ b/Source/bsw/CryIf/CryIf.c @@ -0,0 +1,2014 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file CryIf.c + * \brief MICROSAR Crypto Interface (CRYIF) + * \details The Crypto Interface module provides a unique interface to manage different Crypto HW and SW + * solutions. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + * + * FILE VERSION + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the VERSION CHECK below. + *********************************************************************************************************************/ +#define CRYIF_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +#include "CryIf.h" +#include "CryIf_Private.h" +#include "CryIf_Cfg.h" +#include "CryIf_Cbk.h" +#include "Csm_Cbk.h" + +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) +# include "Det.h" +#endif + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ + +/* Check the version of CryIf header file */ +#if ( (CRYIF_SW_MAJOR_VERSION != (9u)) \ + || (CRYIF_SW_MINOR_VERSION != (1u)) \ + || (CRYIF_SW_PATCH_VERSION != (0u))) +# error "Vendor specific version numbers of CryIf.c and CryIf.h are inconsistent" +#endif + +#if ( (CRYIF_SW_MAJOR_VERSION != CRYIF_CFG_MAJOR_VERSION) \ + || (CRYIF_SW_MINOR_VERSION != CRYIF_CFG_MINOR_VERSION) \ + || (CRYIF_SW_PATCH_VERSION != CRYIF_CFG_PATCH_VERSION)) +# error "Version numbers of CryIf.c and CryIf_Cfg.h are inconsistent" +#endif + +#if ( (CRYIF_GENERATOR_MAJOR_VERSION != (9u)) \ + || (CRYIF_GENERATOR_MINOR_VERSION != (1u))) +# error "Module version numbers of CryIf.c and generator are inconsistent" +#endif + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ +#define CRYIF_FIRST_KEY_PRIMITIVE CRYPTO_RANDOMSEED + +/********************************************************************************************************************** + * LOCAL FUNCTION MACROS + *********************************************************************************************************************/ +#define CryIf_Util_MemClr(dst, count) CryIf_Util_MemSet(dst, 0u, count) + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +#if !defined (CRYIF_LOCAL) /* COV_CRYIF_ALWAYS_ON */ +# define CRYIF_LOCAL static +#endif + +#if !defined (CRYIF_LOCAL_INLINE) /* COV_CRYIF_ALWAYS_ON */ +# define CRYIF_LOCAL_INLINE LOCAL_INLINE +#endif +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYIF_START_SEC_CODE +#include "CryIf_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * CryIf_KeyCopyForDifferentDrivers() + *********************************************************************************************************************/ +/*! \brief Copies two key between two drivers. + * \details Gets each key element of set source key and writes it to a matching key element of the target key. + * \param[in] cryIfKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] targetCryIfKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYIF_LOCAL FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyCopyForDifferentDrivers(uint32 cryIfKeyId, uint32 targetCryIfKeyId); + +/********************************************************************************************************************** + * CryIf_MapKeyIds() + *********************************************************************************************************************/ + /*! \brief Map the job's cryIfKeyIds to cryptoKeyIds. + * \details Check if each cryIfKeyId is in range before mapping it. + * \param[in,out] job Pointer to the configuration of the job. Contains structures with user and + * primitive relevant information. + * \return E_OK Request successful. + * \return CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \spec requires job->jobPrimitiveInfo != NULL_PTR; + * requires job->jobPrimitiveInfo->primitiveInfo != NULL_PTR; + * \endspec + *********************************************************************************************************************/ +CRYIF_LOCAL_INLINE FUNC(Std_ReturnType, CRYIF_CODE) CryIf_MapKeyIds(P2VAR(Crypto_JobType, AUTOMATIC, CRYIF_APPL_VAR) job); + +#if (CRYIF_REDIRECTION == STD_ON) +/********************************************************************************************************************** + * CryIf_TranslateRedirectionKeys() + *********************************************************************************************************************/ +/*! \brief Translates CryIf redirection keys to Crypto keys. + * \details If the keyId is valid, it is translated to a crypto Key Id + * \param[in,out] keyId Pointer to the cryIfKeyId. + * \return CRYIF_E_NO_ERROR Translation was successful. + * \return CRYIF_E_PARAM_HANDLE Translation was not successful. + * \pre Parameter keyId must point to an accessible memory location and must be valid. + * \context TASK + * \reentrant TRUE, for different keyIds + * \synchronous TRUE + * \spec requires keyId != NULL_PTR; + * \endspec + *********************************************************************************************************************/ +CRYIF_LOCAL FUNC(Std_ReturnType, CRYIF_CODE) CryIf_TranslateRedirectionKeys(P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) keyId); + +/********************************************************************************************************************** + * CryIf_UpdateRedirectionInfo() + *********************************************************************************************************************/ +/*! \brief Updates redirection info ob job objects. + * \details If a redirection for the corresponding job is available, this function translates the CryIf KeyIds to Crypto KeyIds. + * \param[in] job Pointer to the corresponding job object + * \return E_OK Redirection was successful. + * \return E_NOT_OK Redirection failed. + * \pre Parameter job must point to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYIF_LOCAL FUNC(Std_ReturnType, CRYIF_CODE) CryIf_UpdateRedirectionInfo(P2CONST(Crypto_JobType, AUTOMATIC, CRYIF_APPL_DATA) job); +#endif /* (CRYIF_REDIRECTION == STD_ON) */ + +/********************************************************************************************************************** + * CryIf_Util_Max() + *********************************************************************************************************************/ +/*! \brief Calculates the maximum value of the inputs. + * \details The function calculates for the two given values the maximum and returns its value. + * \param[in] a First Value + * \param[in] b Second value + * \return The maximum value + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYIF_LOCAL_INLINE FUNC(uint32, CRYIF_CODE) CryIf_Util_Max(uint32 a, uint32 b); + +/********************************************************************************************************************** + * CryIf_Util_MemSet() + *********************************************************************************************************************/ +/*! \brief Sets destination buffer to pattern. + * \details The function sets the destination bytewise to a specified pattern. + * \param[out] dst Pointer to the destination buffer + * \param[in] pattern Pattern which shall be written to the destination buffer. + * \param[in] count Number of bytes which shall be set + * \pre dst must point to a valid memory location. The buffer pointed to by dst has to have a capacity of at least count bytes. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \spec requires dst != NULL_PTR; + * requires $lengthOf(dst) >= count; + * \endspec + *********************************************************************************************************************/ +CRYIF_LOCAL_INLINE FUNC(void, CRYIF_CODE) CryIf_Util_MemSet(P2VAR(uint8, AUTOMATIC, AUTOMATIC) dst, uint8 pattern, uint32 count); + +/********************************************************************************************************************** + * CryIf_Util_MemCpy() + *********************************************************************************************************************/ +/*! \brief Copies values from one buffer to another. + * \details The function copies a specified amount of bytes from a source buffer to a destination buffer. + * \param[out] dst Pointer to the destination buffer + * \param[in] src Pointer to the source buffer + * \param[in] count Number of bytes which shall be copied + * \pre dst and src must point to valid memory locations. The buffer pointed to by dst has to have a capacity of at least count bytes. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \spec requires dst != NULL_PTR; + * requires $lengthOf(dst) >= count; + * requires src != NULL_PTR; + * \endspec + *********************************************************************************************************************/ +CRYIF_LOCAL_INLINE FUNC(void, CRYIF_CODE) CryIf_Util_MemCpy(P2VAR(uint8, AUTOMATIC, AUTOMATIC) dst, P2CONST(uint8, AUTOMATIC, AUTOMATIC) src, uint32 count); + +/********************************************************************************************************************** + * CryIf_KeyElementCopyPartial_Internal() + *********************************************************************************************************************/ +/*! \brief Copies key element partially without using the Crypto Service. + * \details This function copies key element partially without using the Crypto Service. This is necessary if either + * the keys are lying in different Crypto Drivers or if the underlying Crypto Driver do not support KeyElementCopyPartial Service. + * \param[in] cryptoFctIdxSrc Internal array index of the crypto function table for the source key + * \param[in] cryptoFctIdxDst Internal array index of the crypto function table for the target key + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for the + * copy operation. + * \param[in] keyElementSourceOffset This is the offset of the source key element indicating the start index + * of the copy operation. + * \param[in] keyElementTargetOffset This is the offset of the destination key element indicating the start index + * of the copy operation. + * \param[in] keyElementCopyLength Specifies the number of bytes that shall be copied. + * \param[in] targetCryptoKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination for + * the copy operation. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element size does not match size of provided data. + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element. + * \context TASK + * \reentrant TRUE, but not for the same cryIfKeyId + * \synchronous TRUE + * \pre cryptoFctIdxSrc and cryptoFctIdxDst must be valid indices of the crypto function table. + *********************************************************************************************************************/ +CRYIF_LOCAL_INLINE FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementCopyPartial_Internal(CryIf_CryptoFunctionsIdxOfKeyType cryptoFctIdxSrc, + CryIf_CryptoFunctionsIdxOfKeyType cryptoFctIdxDst, + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetCryptoKeyId, + uint32 targetKeyElementId); +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * CryIf_KeyCopyForDifferentDrivers() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +CRYIF_LOCAL FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyCopyForDifferentDrivers(uint32 cryIfKeyId, uint32 targetCryIfKeyId) +{ + uint32_least i, j; + Std_ReturnType retVal = E_NOT_OK; + Std_ReturnType retValSrc; + Std_ReturnType retValDst; + uint8 buffer[CryIf_GetMaxSizeOfKeyElementOfGeneral()]; + uint32 bufferSize = CryIf_GetMaxSizeOfKeyElementOfGeneral(); + uint32 elementIdsSrc[CryIf_GetMaxNumberOfKeyElementsOfGeneral()]; + uint32 elementIdsSrcSize = CryIf_GetMaxNumberOfKeyElementsOfGeneral(); + uint32 elementIdsDst[CryIf_GetMaxNumberOfKeyElementsOfGeneral()]; + uint32 elementIdsDstSize = CryIf_GetMaxNumberOfKeyElementsOfGeneral(); + + /* Get key element ids of both keys */ + retValSrc = CryIf_GetKeyElementIdsGetOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId), elementIdsSrc, &elementIdsSrcSize); + retValDst = CryIf_GetKeyElementIdsGetOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(targetCryIfKeyId))(CryIf_GetRefOfKey(targetCryIfKeyId), elementIdsDst, &elementIdsDstSize); + + if ((retValSrc == E_OK) && (retValDst == E_OK)) + { + /* Iterate through both key element lists and copy compatible elements from source to destination */ + for (i = 0; i < elementIdsSrcSize; i++) /* FETA_CRYIF_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND */ + { + for (j = 0; j < elementIdsDstSize; j++) /* FETA_CRYIF_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND */ + { + if (elementIdsSrc[i] == elementIdsDst[j]) + { + bufferSize = CryIf_GetMaxSizeOfKeyElementOfGeneral(); + + /* Copy compatible elements */ + if (E_OK == CryIf_GetKeyElementGetOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId), elementIdsSrc[i], buffer, &bufferSize)) + { + if (E_OK == CryIf_GetKeyElementSetOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(targetCryIfKeyId))(CryIf_GetRefOfKey(targetCryIfKeyId), elementIdsDst[j], buffer, bufferSize)) + { + retVal = E_OK; + } + } + break; + } + } + } + } + + return retVal; +} /* CryIf_KeyCopyForDifferentDrivers() */ + +/********************************************************************************************************************** + * CryIf_MapKeyIds() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +CRYIF_LOCAL_INLINE FUNC(Std_ReturnType, CRYIF_CODE) CryIf_MapKeyIds(P2VAR(Crypto_JobType, AUTOMATIC, CRYIF_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + + /* Use jobPrimitiveInputOutput keyIds if job is a key primitive job */ + if (job->jobPrimitiveInfo->primitiveInfo->service >= CRYIF_FIRST_KEY_PRIMITIVE) + { + /* Check cryIfKeyId before mapping it */ + if (job->jobPrimitiveInputOutput.cryIfKeyId >= CryIf_GetSizeOfKey()) + { + retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + } + else + { + Crypto_ServiceInfoType service = job->jobPrimitiveInfo->primitiveInfo->service; + + /* Map cryIfKeyId */ + job->cryptoKeyId = CryIf_GetRefOfKey(job->jobPrimitiveInputOutput.cryIfKeyId); + retVal = E_OK; + + /* Check if service contains targetCryIfKeyId */ + if ((service == CRYPTO_KEYDERIVE) + || (service == CRYPTO_CUSTOM_SERVICE) + || (service == CRYPTO_KEYWRAP) + || (service == CRYPTO_KEYUNWRAP)) + { + /* Check targetCryIfKeyId before mapping it */ + if (job->jobPrimitiveInputOutput.targetCryIfKeyId >= CryIf_GetSizeOfKey()) + { + retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + } + else + { + /* Map targetCryIfKeyId */ + job->targetCryptoKeyId = CryIf_GetRefOfKey(job->jobPrimitiveInputOutput.targetCryIfKeyId); + /* retVal already set to E_OK */ + } + } + } + } + /* For all other primitives, use jobPrimitiveInfo cryIfKeyId */ + else + { + /* Check cryIfKeyId before mapping it */ + if (job->jobPrimitiveInfo->cryIfKeyId >= CryIf_GetSizeOfKey()) + { + retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + } + else + { + job->cryptoKeyId = CryIf_GetRefOfKey(job->jobPrimitiveInfo->cryIfKeyId); + retVal = E_OK; + } + } + + return retVal; +} + +#if (CRYIF_REDIRECTION == STD_ON) +/********************************************************************************************************************** + * CryIf_TranslateRedirectionKeys() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +CRYIF_LOCAL FUNC(Std_ReturnType, CRYIF_CODE) CryIf_TranslateRedirectionKeys(P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) keyId) +{ + uint8 errorId = CRYIF_E_NO_ERROR; + +# if (CRYIF_DEV_ERROR_DETECT == STD_ON) + if (*keyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +# endif + { + /* Translate cryIfKeyId to CryptoKeyId */ + *keyId = CryIf_GetRefOfKey(*keyId); + } + + return errorId; +} /* CryIf_TranslateRedirectionKeys() */ + +/********************************************************************************************************************** + * CryIf_UpdateRedirectionInfo() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYIF_LOCAL FUNC(Std_ReturnType, CRYIF_CODE) CryIf_UpdateRedirectionInfo(P2CONST(Crypto_JobType, AUTOMATIC, CRYIF_APPL_DATA) job) +{ + Std_ReturnType retVal = E_OK; + uint8 errorId = CRYIF_E_NO_ERROR; + + /* Check if redirection shall be applied */ + if(job->jobRedirectionInfoRef != NULL_PTR) + { + uint8 redirectionConfigValue = job->jobRedirectionInfoRef->redirectionConfig; + + /* Update key ids depending on redirection mask */ + if((redirectionConfigValue & ((uint8)CRYPTO_REDIRECT_CONFIG_PRIMARY_INPUT)) == (uint8)CRYPTO_REDIRECT_CONFIG_PRIMARY_INPUT) + { + errorId = CryIf_TranslateRedirectionKeys(&job->jobRedirectionInfoRef->inputKeyId); + } + + if((redirectionConfigValue & ((uint8)CRYPTO_REDIRECT_CONFIG_SECONDARY_INPUT)) == (uint8)CRYPTO_REDIRECT_CONFIG_SECONDARY_INPUT) + { + errorId &= CryIf_TranslateRedirectionKeys(&job->jobRedirectionInfoRef->secondaryInputKeyId); /* VCA_CRYIF_FORWARDING_OF_REDIRECTION_POINTER_OF_JOB */ + } + + if((redirectionConfigValue & ((uint8)CRYPTO_REDIRECT_CONFIG_TERTIARY_INPUT)) == (uint8)CRYPTO_REDIRECT_CONFIG_TERTIARY_INPUT) + { + errorId &= CryIf_TranslateRedirectionKeys(&job->jobRedirectionInfoRef->tertiaryInputKeyId); /* VCA_CRYIF_FORWARDING_OF_REDIRECTION_POINTER_OF_JOB */ + } + + if((redirectionConfigValue & ((uint8)CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT)) == (uint8)CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT) + { + errorId &= CryIf_TranslateRedirectionKeys(&job->jobRedirectionInfoRef->outputKeyId); /* VCA_CRYIF_FORWARDING_OF_REDIRECTION_POINTER_OF_JOB */ + } + + if((redirectionConfigValue & ((uint8)CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT)) == (uint8)CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT) + { + errorId &= CryIf_TranslateRedirectionKeys(&job->jobRedirectionInfoRef->secondaryOutputKeyId); /* VCA_CRYIF_FORWARDING_OF_REDIRECTION_POINTER_OF_JOB */ + } + } + +# if (CRYIF_DEV_ERROR_DETECT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + retVal = E_NOT_OK; + + /* ----- Development Error Report --------------------------------------- */ +# if (CRYIF_DEV_ERROR_REPORT == STD_ON) + (void)Det_ReportError((uint16)CRYIF_MODULE_ID, + CRYIF_INSTANCE_ID_DET, + CRYIF_SID_PROCESS_JOB, + errorId); +# else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + } +# else /* !(CRYIF_DEV_ERROR_DETECT == STD_ON) */ + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + + return retVal; +} /* CryIf_UpdateRedirectionInfo() */ +#endif /* (CRYIF_REDIRECTION == STD_ON) */ + +/********************************************************************************************************************** + * CryIf_Util_Max() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYIF_LOCAL_INLINE FUNC(uint32, CRYIF_CODE) CryIf_Util_Max(uint32 a, uint32 b) +{ + return (a > b)?(a):(b); +} /* CryIf_Util_Max() */ + +/********************************************************************************************************************** + * CryIf_Util_MemSet() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYIF_LOCAL_INLINE FUNC(void, CRYIF_CODE) CryIf_Util_MemSet(P2VAR(uint8, AUTOMATIC, AUTOMATIC) dst, uint8 pattern, uint32 count) +{ + uint32_least i; + + for(i = 0; i < count; ++i) /* FETA_CRYIF_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND */ + { + dst[i] = pattern; /* VCA_CRYIF_API_CHECKED_SIZE_ACCESS */ + } +} /* CryIf_Util_MemSet() */ + +/********************************************************************************************************************** + * CryIf_Util_MemCpy() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYIF_LOCAL_INLINE FUNC(void, CRYIF_CODE) CryIf_Util_MemCpy(P2VAR(uint8, AUTOMATIC, AUTOMATIC) dst, P2CONST(uint8, AUTOMATIC, AUTOMATIC) src, uint32 count) +{ + uint32_least i; + + for(i = 0; i < count; ++i) /* FETA_CRYIF_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND */ + { + dst[i] = src[i]; /* VCA_CRYIF_API_CHECKED_SIZE_ACCESS */ + } +} /* CryIf_Util_MemCpy() */ + +/********************************************************************************************************************** + * CryIf_KeyElementCopyPartial_Internal() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6060, 6080 10 */ /* MD_CRYIF_STPAR, MD_MSR_STMIF */ +CRYIF_LOCAL_INLINE FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementCopyPartial_Internal( + CryIf_CryptoFunctionsIdxOfKeyType cryptoFctIdxSrc, + CryIf_CryptoFunctionsIdxOfKeyType cryptoFctIdxDst, + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetCryptoKeyId, + uint32 targetKeyElementId) +{ + Std_ReturnType retVal; + + uint8 bufferSrc[CryIf_GetMaxSizeOfKeyElementOfGeneral()]; + uint8 bufferDst[CryIf_GetMaxSizeOfKeyElementOfGeneral()]; + uint32 bufferSizeSrc = CryIf_GetMaxSizeOfKeyElementOfGeneral(); + uint32 bufferSizeDst = CryIf_GetMaxSizeOfKeyElementOfGeneral(); + + /* Check local buffer size vs copy length */ + if (((keyElementTargetOffset + keyElementCopyLength) <= CryIf_GetMaxSizeOfKeyElementOfGeneral()) && + /* Prevent integer overflow */ + (CryIf_NoUInt32Overflow(keyElementTargetOffset, keyElementCopyLength))) + { + /* Get Source key element */ + retVal = CryIf_GetKeyElementGetOfCryptoFunctions(cryptoFctIdxSrc)(cryptoKeyId, keyElementId, bufferSrc, &bufferSizeSrc); + + /* Check if required data is inside the queried key element */ + if (retVal == E_OK) + { + if (((keyElementSourceOffset + keyElementCopyLength) <= bufferSizeSrc) && + /* Prevent integer overflow */ + (CryIf_NoUInt32Overflow(keyElementSourceOffset, keyElementCopyLength))) + { + /* Get Destination key element */ + retVal = CryIf_GetKeyElementGetOfCryptoFunctions(cryptoFctIdxDst)(targetCryptoKeyId, targetKeyElementId, bufferDst, &bufferSizeDst); + switch (retVal) + { + case CRYPTO_E_KEY_EMPTY: + { + bufferSizeDst = 0u; + } + /* intentionally no break, since the processing of both cases is similar except of length assignment */ + /* fall through */ + case E_OK: /* PRQA S 2003 */ /* MD_CRYIF_NO_BREAK_IN_SWITCH */ + { + /* Fill destination keyElement with zeroes if there are holes in the destination element */ + if (bufferSizeDst < keyElementTargetOffset) + { + CryIf_Util_MemClr(&bufferDst[bufferSizeDst], keyElementTargetOffset - bufferSizeDst); /* VCA_CRYIF_STACK_ARRAY_VARIABLE_AS_PTR */ + } + + /* Copy source window to destination window */ + CryIf_Util_MemCpy(&bufferDst[keyElementTargetOffset], &bufferSrc[keyElementSourceOffset], keyElementCopyLength); /* VCA_CRYIF_STACK_ARRAY_VARIABLE_AS_PTR */ + + bufferSizeDst = CryIf_Util_Max(bufferSizeDst, keyElementTargetOffset + keyElementCopyLength); /* Potential overflow checked at the beginning. */ + + /* Set destination key element */ + retVal = CryIf_GetKeyElementSetOfCryptoFunctions(cryptoFctIdxDst)(targetCryptoKeyId, targetKeyElementId, bufferDst, bufferSizeDst); + } + break; + + default: + /* return retVal to caller */ + break; + } + + } + else + { + retVal = E_NOT_OK; + } + } + } + else + { + retVal = E_NOT_OK; + } + + return retVal; +} /* CryIf_KeyElementCopyPartial_Internal() */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * CryIf_InitMemory() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(void, CRYIF_CODE) CryIf_InitMemory(void) +{ + /* Nothing to do. */ +} /* CryIf_InitMemory() */ + +/********************************************************************************************************************** + * CryIf_Init() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(void, CRYIF_CODE) CryIf_Init(void) +{ + /* Nothing to do. */ +} /* CryIf_Init() */ + +#if (CRYIF_VERSION_INFO_API == STD_ON) +/********************************************************************************************************************** + * CryIf_GetVersionInfo() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, CRYIF_CODE) CryIf_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, CRYIF_APPL_VAR) versioninfo) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CRYIF_DEV_ERROR_DETECT == STD_ON) + if (versioninfo == NULL_PTR) + { + errorId = CRYIF_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + versioninfo->vendorID = (CRYIF_VENDOR_ID); + versioninfo->moduleID = (CRYIF_MODULE_ID); + versioninfo->sw_major_version = (CRYIF_SW_MAJOR_VERSION); + versioninfo->sw_minor_version = (CRYIF_SW_MINOR_VERSION); + versioninfo->sw_patch_version = (CRYIF_SW_PATCH_VERSION); + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_GET_VERSION_INFO, errorId); + } +# else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ +} /* CryIf_GetVersionInfo() */ +#endif /* (CRYIF_VERSION_INFO_API == STD_ON) */ + +/********************************************************************************************************************** + * CryIf_CallbackNotification() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(void, CRYIF_CODE) CryIf_CallbackNotification(P2VAR(Crypto_JobType, AUTOMATIC, CRYIF_APPL_VAR) job, + Std_ReturnType result) +{ + /* AUTOSAR 4.3.x standard deviation + * According to ASR 4.3.x, this function receives job as P2CONST. + * Also according to ASR 4.3.x, Csm_CallbackNotification expects job as a P2VAR. + * This inconsistency in the standard was fixed in ASR 4.4.0 and later versions. + * The MICROSAR CryIf does not offer support for the ASR 4.3.x CryIf_CallbackNotification interface, + * as the standard is broken and a workaround (e.g., by creating a local clone of the job struct) + * would involve heavy performance penalties. + */ + + Csm_CallbackNotification(job, result); +} /* CryIf_CallbackNotification() */ + +/********************************************************************************************************************** + * CryIf_ProcessJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6080 2 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_ProcessJob(uint32 channelId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYIF_APPL_VAR) job) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check for null pointer */ + if (job == NULL_PTR) + { + errorId = CRYIF_E_PARAM_POINTER; + } + /* Check parameter 'channelId' */ + else if (channelId >= CryIf_GetSizeOfChannel()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* Map CryIfKeyIds to CryptoKeyIds */ + retVal = CryIf_MapKeyIds(job); + + if (retVal == E_OK) + { +#if (CRYIF_REDIRECTION == STD_ON) +# if (CRYIF_DEV_ERROR_DETECT == STD_ON) + retVal = CryIf_UpdateRedirectionInfo(job); + if (retVal == E_OK) +# else + (void)CryIf_UpdateRedirectionInfo(job); +# endif +#endif /* (CRYIF_REDIRECTION == STD_ON) */ + { + retVal = CryIf_GetProcessJobOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfChannel(channelId))(CryIf_GetDriverObjectRefOfChannel(channelId), job); + } + } + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_PROCESS_JOB, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_ProcessJob() */ + +/********************************************************************************************************************** + * CryIf_CancelJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 2 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CancelJob(uint32 channelId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYIF_APPL_VAR) job) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check for null pointer */ + if (job == NULL_PTR) + { + errorId = CRYIF_E_PARAM_POINTER; + } + /* Check parameter 'channelId' */ + else if (channelId >= CryIf_GetSizeOfChannel()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + + /* Check if keyId is in range */ + if (job->jobPrimitiveInfo->cryIfKeyId < CryIf_GetSizeOfKey()) + { + /* Check if service is an key primitive job */ + if (job->jobPrimitiveInfo->primitiveInfo->service < CRYIF_FIRST_KEY_PRIMITIVE) + { + job->cryptoKeyId = CryIf_GetRefOfKey(job->jobPrimitiveInfo->cryIfKeyId); + } + else + { + job->cryptoKeyId = CryIf_GetRefOfKey(job->jobPrimitiveInputOutput.cryIfKeyId); + + /* Check if service contains targetCryIfKeyId */ + if (job->jobPrimitiveInfo->primitiveInfo->service == (Crypto_ServiceInfoType)CRYPTO_KEYDERIVE) + { + job->targetCryptoKeyId = CryIf_GetRefOfKey(job->jobPrimitiveInputOutput.targetCryIfKeyId); + } + } +#if (CRYIF_CANCELJOBWITHINFOTYPEOFCRYPTOFUNCTIONS == STD_ON) + /* Check if canceljob service with jobinfotype parameter is enabled */ + if (CryIf_GetCancelJobOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfChannel(channelId)) == NULL_PTR) + { + /* CancelJob expects a non-const Crypto_JobInfoType, therefore a local non-const Crypto_JobInfoType must be created. + * Since the call in synchronous, a pointer to a local struct is okay. */ + Crypto_JobInfoType jobInfo; + jobInfo.jobId = job->jobInfo->jobId; + jobInfo.jobPriority = job->jobInfo->jobPriority; + + retVal = CryIf_GetCancelJobWithInfoTypeOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfChannel(channelId))(CryIf_GetDriverObjectRefOfChannel(channelId), &jobInfo); + } + else +#endif /* (CRYIF_CANCELJOBWITHINFOTYPEOFCRYPTOFUNCTIONS == STD_ON) */ + { + retVal = CryIf_GetCancelJobOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfChannel(channelId))(CryIf_GetDriverObjectRefOfChannel(channelId), job); + } + } + else + { + retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_CANCEL_JOB, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_CancelJob() */ + +/********************************************************************************************************************** + * CryIf_KeyElementSet() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementSet(uint32 cryIfKeyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CRYIF_APPL_DATA) keyPtr, + uint32 keyLength) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check for null pointer */ + /* Removed to allow null ptr as value (e.g. start address for secure boot). + * CryIf is not accessing the pointer, check is up to crypto driver. SWS_CryIf_00052 deviation. */ + + /* Check parameter 'keyLength' */ + /* Removed to allow key deletion (keyLength must be 0 in this case). SWS_CryIf_00053 deviation. */ + + /* Check parameter 'cryIfKeyId' */ + if (cryIfKeyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetKeyElementSetOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId), + keyElementId, + keyPtr, + keyLength); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_ELEMENT_SET, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeyElementSet() */ + +/********************************************************************************************************************** + * CryIf_KeySetValid() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeySetValid(uint32 cryIfKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check parameter 'cryIfKeyId' */ + if (cryIfKeyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetKeyValidSetOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId)); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_SET_VALID, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeySetValid() */ + +/********************************************************************************************************************** + * CryIf_KeyElementGet() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementGet(uint32 cryIfKeyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) resultLengthPtr) +{ + + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check for null pointer */ + if ((resultPtr == NULL_PTR) || (resultLengthPtr == NULL_PTR)) + { + errorId = CRYIF_E_PARAM_POINTER; + } + /* Check parameter 'resultLengthPtr' */ + else if (*resultLengthPtr == 0u) + { + errorId = CRYIF_E_PARAM_VALUE; + } + /* Check parameter 'cryIfKeyId' */ + else if (cryIfKeyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetKeyElementGetOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId), /* VCA_CRYIF_API_CALL_FORWARDING_PTR_AND_LENGTH */ + keyElementId, + resultPtr, + resultLengthPtr); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_ELEMENT_GET, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeyElementGet() */ + +/********************************************************************************************************************** + * CryIf_KeyElementCopy() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementCopy(uint32 cryIfKeyId, + uint32 keyElementId, + uint32 targetCryIfKeyId, + uint32 targetKeyElementId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check parameter 'cryIfKeyId' and 'targetCryIfKeyId' */ + if ((cryIfKeyId >= CryIf_GetSizeOfKey()) + || (targetCryIfKeyId >= CryIf_GetSizeOfKey())) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + CryIf_CryptoFunctionsIdxOfKeyType cryptoFctIdxSrc = CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId); + CryIf_CryptoFunctionsIdxOfKeyType cryptoFctIdxDst = CryIf_GetCryptoFunctionsIdxOfKey(targetCryIfKeyId); + CryIf_RefOfKeyType cryptoKeyIdSrc = CryIf_GetRefOfKey(cryIfKeyId); + CryIf_RefOfKeyType cryptoKeyIdDst = CryIf_GetRefOfKey(targetCryIfKeyId); + + /* ----- Implementation ----------------------------------------------- */ + if (cryptoFctIdxSrc == cryptoFctIdxDst) + { + /* Keys are in same crypto driver */ + retVal = CryIf_GetKeyElementCopyOfCryptoFunctions(cryptoFctIdxSrc)(cryptoKeyIdSrc, keyElementId, cryptoKeyIdDst, targetKeyElementId); + } + else + { + uint8 buffer[CryIf_GetMaxSizeOfKeyElementOfGeneral()]; + uint32 bufferSize = CryIf_GetMaxSizeOfKeyElementOfGeneral(); + /* Copy key element by getting element from source driver and set it to given key element in destination driver. */ + if (CryIf_GetKeyElementGetOfCryptoFunctions(cryptoFctIdxSrc)(cryptoKeyIdSrc, keyElementId, buffer, &bufferSize) == E_OK) + { + retVal = CryIf_GetKeyElementSetOfCryptoFunctions(cryptoFctIdxDst)(cryptoKeyIdDst, targetKeyElementId, buffer, bufferSize); + } + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_ELEMENT_COPY, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeyElementCopy() */ + +/********************************************************************************************************************** + * CryIf_KeyElementCopyPartial_Stub() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYIF_STPAR */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementCopyPartial_Stub(uint32 cryIfKeyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetCryIfKeyId, + uint32 targetKeyElementId) +{ + CRYIF_DUMMY_STATEMENT(cryIfKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(keyElementId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(keyElementSourceOffset); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(keyElementTargetOffset); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(keyElementCopyLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(targetCryIfKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(targetKeyElementId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + return E_NOT_OK; +} /* CryIf_KeyElementCopyPartial_Stub() */ + +/********************************************************************************************************************** + * CryIf_KeyElementCopyPartial() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYIF_STPAR */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementCopyPartial(uint32 cryIfKeyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetCryIfKeyId, + uint32 targetKeyElementId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check parameter 'cryIfKeyId' and 'targetCryIfKeyId' */ + if ((cryIfKeyId >= CryIf_GetSizeOfKey()) + || (targetCryIfKeyId >= CryIf_GetSizeOfKey())) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + CryIf_CryptoFunctionsIdxOfKeyType cryptoFctIdxSrc = CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId); + CryIf_CryptoFunctionsIdxOfKeyType cryptoFctIdxDst = CryIf_GetCryptoFunctionsIdxOfKey(targetCryIfKeyId); + CryIf_RefOfKeyType cryptoKeyIdSrc = CryIf_GetRefOfKey(cryIfKeyId); + CryIf_RefOfKeyType cryptoKeyIdDst = CryIf_GetRefOfKey(targetCryIfKeyId); + + /* ----- Implementation ----------------------------------------------- */ + /* If KeyElementCopyPartial is supported by underlying driver and source- and target keys are in the same + driver, call the KeyElementCopyPartial Service of the underlying key, otherwise use internal function */ + if((cryptoFctIdxSrc == cryptoFctIdxDst) && (CryIf_IsSupportsKeyElementCopyPartialOfCryptoFunctions(cryptoFctIdxDst))) + { + retVal = CryIf_GetKeyElementCopyPartialOfCryptoFunctions(cryptoFctIdxSrc)(cryptoKeyIdSrc, keyElementId, keyElementSourceOffset, keyElementTargetOffset, keyElementCopyLength, cryptoKeyIdDst, targetKeyElementId); + } + else + { + retVal = CryIf_KeyElementCopyPartial_Internal(cryptoFctIdxSrc, cryptoFctIdxDst, cryptoKeyIdSrc, keyElementId, keyElementSourceOffset, keyElementTargetOffset, keyElementCopyLength, cryptoKeyIdDst, targetKeyElementId); + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_ELEMENT_COPY_PARTIAL, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeyElementCopyPartial() */ + +/********************************************************************************************************************** + * CryIf_KeyCopy() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyCopy(uint32 cryIfKeyId, + uint32 targetCryIfKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check parameter 'cryIfKeyId' and 'targetCryIfKeyId' */ + if ((cryIfKeyId >= CryIf_GetSizeOfKey()) + || (targetCryIfKeyId >= CryIf_GetSizeOfKey())) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + if (CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId) == CryIf_GetCryptoFunctionsIdxOfKey(targetCryIfKeyId)) + { + /* Keys are in same crypto driver */ + retVal = CryIf_GetKeyCopyOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId), CryIf_GetRefOfKey(targetCryIfKeyId)); + } + else + { + /* Keys are in different crypto drivers */ + retVal = CryIf_KeyCopyForDifferentDrivers(cryIfKeyId, targetCryIfKeyId); + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_COPY, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeyCopy() */ + +/********************************************************************************************************************** + * CryIf_RandomSeed() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_RandomSeed(uint32 cryIfKeyId, + P2CONST(uint8, AUTOMATIC, CRYIF_APPL_DATA) seedPtr, + uint32 seedLength) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check for null pointer */ + if (seedPtr == NULL_PTR) + { + errorId = CRYIF_E_PARAM_POINTER; + } + /* Check for value 'seedLength' */ + else if (seedLength == 0u) + { + errorId = CRYIF_E_PARAM_VALUE; + } + /* Check parameter 'cryIfKeyId' */ + else if (cryIfKeyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetRandomSeedOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId), + seedPtr, + seedLength); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_RANDOM_SEED, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_RandomSeed() */ + +/********************************************************************************************************************** + * CryIf_KeyGenerate() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyGenerate(uint32 cryIfKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check parameter 'cryIfKeyId' */ + if (cryIfKeyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetKeyGenerateOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId)); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_GENERATE, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeyGenerate() */ + +/********************************************************************************************************************** + * CryIf_KeyDerive() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyDerive(uint32 cryIfKeyId, + uint32 targetCryIfKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check parameter 'cryIfKeyId' and 'targetCryIfKeyId' */ + if ((cryIfKeyId >= CryIf_GetSizeOfKey()) + || (targetCryIfKeyId >= CryIf_GetSizeOfKey())) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetKeyDeriveOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId), CryIf_GetRefOfKey(targetCryIfKeyId)); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_DERIVE, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeyDerive() */ + +/********************************************************************************************************************** + * CryIf_KeyExchangeCalcPubVal() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyExchangeCalcPubVal(uint32 cryIfKeyId, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) publicValueLengthPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check for null pointer */ + if ((publicValuePtr == NULL_PTR) || (publicValueLengthPtr == NULL_PTR)) + { + errorId = CRYIF_E_PARAM_POINTER; + } + /* Check for value 'publicValueLengthPtr' */ + else if (*publicValueLengthPtr == 0u) + { + errorId = CRYIF_E_PARAM_VALUE; + } + /* Check parameter 'cryIfKeyId' */ + else if (cryIfKeyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetKeyExchangeCalcPubValOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId), /* VCA_CRYIF_API_CALL_FORWARDING_PTR_AND_LENGTH */ + publicValuePtr, + publicValueLengthPtr); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_EXCHANGE_CALC_PUB_VAL, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeyExchangeCalcPubVal() */ + +/********************************************************************************************************************** + * CryIf_KeyExchangeCalcSecret() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyExchangeCalcSecret(uint32 cryIfKeyId, + P2CONST(uint8, AUTOMATIC, CRYIF_APPL_DATA) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check for null pointer */ + if (partnerPublicValuePtr == NULL_PTR) + { + errorId = CRYIF_E_PARAM_POINTER; + } + /* Check for value 'partnerPublicValueLength' */ + else if (partnerPublicValueLength == 0u) + { + errorId = CRYIF_E_PARAM_VALUE; + } + /* Check parameter 'cryIfKeyId' */ + else if (cryIfKeyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetKeyExchangeCalcSecretOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId), + partnerPublicValuePtr, + partnerPublicValueLength); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_EXCHANGE_CALC_SECRET, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeyExchangeCalcSecret() */ + +/********************************************************************************************************************** + * CryIf_CertificateParse() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CertificateParse(uint32 cryIfKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check parameter 'cryIfKeyId' */ + if (cryIfKeyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetCertificateParseOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId)); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_CERTIFICATE_PARSE, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_CertificateParse() */ + +/********************************************************************************************************************** + * CryIf_CertificateParse_Stub() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CertificateParse_Stub(uint32 cryIfKeyId) +{ + CRYIF_DUMMY_STATEMENT(cryIfKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_CERTIFICATE_PARSE, CRYIF_E_REQUEST_NOT_SUPPORTED); +#endif + + return E_NOT_OK; +} /* CryIf_CertificateParse_Stub() */ + +/********************************************************************************************************************** + * CryIf_CertificateVerify() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CertificateVerify(uint32 cryIfKeyId, + uint32 verifyCryIfKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CRYIF_APPL_VAR) verifyPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check for null pointer */ + if (verifyPtr == NULL_PTR) + { + errorId = CRYIF_E_PARAM_POINTER; + } + /* Check parameter 'cryIfKeyId' */ + else if ((cryIfKeyId >= CryIf_GetSizeOfKey()) + || (verifyCryIfKeyId >= CryIf_GetSizeOfKey())) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetCertificateVerifyOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId), + CryIf_GetRefOfKey(verifyCryIfKeyId), + verifyPtr); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_CERTIFICATE_VERIFY, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_CertificateVerify() */ + +/********************************************************************************************************************** + * CryIf_CertificateVerify_Stub() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +/* PRQA S 3673 3 */ /* MD_CRYIF_POINTER_TO_CONST */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CertificateVerify_Stub(uint32 cryIfKeyId, + uint32 verifyCryIfKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CRYIF_APPL_VAR) verifyPtr) +{ + CRYIF_DUMMY_STATEMENT(cryIfKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(verifyCryIfKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(verifyPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_CERTIFICATE_VERIFY, CRYIF_E_REQUEST_NOT_SUPPORTED); +#endif + + return E_NOT_OK; +} /* CryIf_CertificateVerify_Stub() */ + +/********************************************************************************************************************** + * CryIf_KeyGetStatus() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyGetStatus(uint32 cryIfKeyId, + P2VAR(Crypto_KeyStatusType, AUTOMATIC, CRYIF_APPL_VAR) keyStatusPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check for null pointer */ + if (keyStatusPtr == NULL_PTR) + { + errorId = CRYIF_E_PARAM_POINTER; + } + /* Check parameter 'cryIfKeyId' */ + else if (cryIfKeyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetKeyGetStatusOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId), keyStatusPtr); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_GET_STATUS, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeyGetStatus() */ + +/********************************************************************************************************************** + * CryIf_KeyGetStatus_Stub() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +/* PRQA S 3673 2 */ /* MD_CRYIF_POINTER_TO_CONST */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyGetStatus_Stub(uint32 cryIfKeyId, + P2VAR(Crypto_KeyStatusType, AUTOMATIC, CRYIF_APPL_VAR) keyStatusPtr) +{ + CRYIF_DUMMY_STATEMENT(cryIfKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(keyStatusPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_GET_STATUS, CRYIF_E_REQUEST_NOT_SUPPORTED); +#endif + + return E_NOT_OK; +} /* CryIf_KeyGetStatus_Stub() */ + +/********************************************************************************************************************** + * CryIf_KeySetInvalid() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeySetInvalid(uint32 cryIfKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check parameter 'cryIfKeyId' */ + if (cryIfKeyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetKeySetInvalidOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(cryIfKeyId))(CryIf_GetRefOfKey(cryIfKeyId)); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_SET_INVALID, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_KeySetInvalid() */ + +/********************************************************************************************************************** + * CryIf_KeySetInvalid_Stub() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeySetInvalid_Stub(uint32 cryIfKeyId) +{ + CRYIF_DUMMY_STATEMENT(cryIfKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_KEY_SET_INVALID, CRYIF_E_REQUEST_NOT_SUPPORTED); +#endif + + return E_NOT_OK; +} /* CryIf_KeySetInvalid_Stub() */ + +/********************************************************************************************************************** + * CryIf_CustomSync() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CustomSync(uint32 dispatchId, + uint32 keyId, + uint32 keyElementId, + uint32 targetKeyId, + uint32 targetKeyElementId, + P2CONST(uint8, AUTOMATIC, CRYIF_APPL_DATA) inputPtr, + uint32 inputLength, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) outputPtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) outputLengthPtr, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) secondaryOutputPtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) secondaryOutputLengthPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId = CRYIF_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYIF_DEV_ERROR_DETECT == STD_ON) + /* Check for null pointer: + * No checks for null pointers, as SWS_CryIf_91002 does not list any. */ + + /* Check parameter 'keyId' and 'targetKeyId'. */ + if (keyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else if (targetKeyId >= CryIf_GetSizeOfKey()) + { + errorId = CRYIF_E_PARAM_HANDLE; + } + else +#endif /* (CRYIF_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + retVal = CryIf_GetCustomSyncOfCryptoFunctions(CryIf_GetCryptoFunctionsIdxOfKey(keyId))(dispatchId, /* SBSW_CRYIF_API_CALL_FORWARDING_ID_ONLY */ + CryIf_GetRefOfKey(keyId), + keyElementId, + CryIf_GetRefOfKey(targetKeyId), + targetKeyElementId, + inputPtr, + inputLength, + outputPtr, + outputLengthPtr, + secondaryOutputPtr, + secondaryOutputLengthPtr); + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYIF_E_NO_ERROR) + { + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_CUSTOM_SYNC, errorId); + } +#else + CRYIF_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYIF_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* CryIf_CustomSync() */ + +/********************************************************************************************************************** + * CryIf_CustomSync_Stub() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYIF_STPAR */ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CustomSync_Stub(uint32 dispatchId, + uint32 keyId, + uint32 keyElementId, + uint32 targetKeyId, + uint32 targetKeyElementId, + P2CONST(uint8, AUTOMATIC, CRYIF_APPL_DATA) inputPtr, + uint32 inputLength, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) outputPtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) outputLengthPtr, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) secondaryOutputPtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) secondaryOutputLengthPtr) +{ + CRYIF_DUMMY_STATEMENT(dispatchId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(keyElementId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(targetKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(targetKeyElementId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + CRYIF_DUMMY_STATEMENT_CONST(inputPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(inputLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(outputPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(outputLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(secondaryOutputPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYIF_DUMMY_STATEMENT(secondaryOutputLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYIF_DEV_ERROR_REPORT == STD_ON) + (void)Det_ReportError(CRYIF_MODULE_ID, CRYIF_INSTANCE_ID_DET, CRYIF_SID_CUSTOM_SYNC, CRYIF_E_REQUEST_NOT_SUPPORTED); +#endif + + return E_NOT_OK; +} /* CryIf_CustomSync_Stub() */ + +#define CRYIF_STOP_SEC_CODE +#include "CryIf_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* Justification for module-specific MISRA deviations: + MD_CRYIF_STPAR: + Reason: Number of parameters is too high. + Risk: None + Prevention: None + + MD_CRYIF_NO_BREAK_IN_SWITCH: + Reason: No break in a single case of a switch statement. Both cases only differ in one statement. Otherwise, the code must be duplicated or a function call must occur here. + Risk: If the code is refactored or adapted, this may lead to a problem if it is not considered. + Prevention: Code Review. + + MD_CRYIF_POINTER_TO_CONST: + Reason: A pointer parameter in a function prototype should be declared as pointer to const if the pointer is not used to modify the addressed object (MISRA2012-Rule8.13). + In this case the function is just an interface which hands the pointer forward to a function that will change the addressed object. + Risk: None + Prevention: None + + */ + +/* VCA_JUSTIFICATION_BEGIN + + \ID VCA_CRYIF_API_CALL_FORWARDING_PTR_AND_LENGTH + \DESCRIPTION The API call is forwarded using a function pointer which is read using ComStackLib macros. + The API is called with an id, a pointer and a corresponding pointer, referencing the former pointer's length. + \COUNTERMEASURE \R Validity of the function pointer and the ID: + The function pointer is read using the passed Id and ComStackLib macros (CSL03). + The Id is a SNV provided by the CryIf and is converted to the corresponding ID of lower layer using ComStackLib (CSL01). + It is checked when it was first passed to the CryIf module. + Validity of the passed pointer and its length: + The caller uses runtime checks to ensure that neither the (output) pointer itself nor the pointer referencing the output pointer's + length are null pointers. + The caller is required to provide an output buffer of at least as many bytes as referenced by the latter pointer per API contract. + + \ID VCA_CRYIF_API_CHECKED_SIZE_ACCESS + \DESCRIPTION Write access to array given by pointer through a parameter.The API requires the array to have a certain size and it is assumed that the size is available in the given pointer. + \COUNTERMEASURE \R The caller has to assure that the API requirements are matched and the size of the buffer is according to these requirements. + + \ID VCA_CRYIF_FORWARDING_OF_REDIRECTION_POINTER_OF_JOB + \DESCRIPTION A member of the redirection info of a job pointer is provided to the callee as a pointer. + \COUNTERMEASURE \R The job pointer is assumed to be valid by API requirements, the redirection info pointer is checked locally. + + \ID VCA_CRYIF_STACK_ARRAY_VARIABLE_AS_PTR + \DESCRIPTION A pointer to an array located on the stack is given as parameter to a function including its size. + \COUNTERMEASURE \R The function call is synchronous and the size of the array is given, therefore the stack array is valid throughout the function call. + Runtime checks ensure that the passed sizes are valid and not corrupted by overflown values. + +VCA_JUSTIFICATION_END */ + +/* COV_JUSTIFICATION_BEGIN + + \ID COV_CRYIF_ALWAYS_ON + \ACCEPT TX + \REASON CRYIF_LOCAL is always defined externally. + + COV_JUSTIFICATION_END */ + +/* FETA_JUSTIFICATION_BEGIN + +\ID FETA_CRYIF_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND + \DESCRIPTION According to FETA loop may not terminate + in function + - CryIf_KeyCopyForDifferentDrivers + - CryIf_Util_MemCpy + - CryIf_Util_MemSet + + \COUNTERMEASURE \N The here applied loop uses as upper bound a constant value or a variable that remains unchanged during loop + execution. The loop's type of the counter variable is appropriate for the loop's type of upper + bound value / variable and is increased once within each single loop (strictly monotonically increasing) + until it reaches a value that makes the loop stop without any occurrences of overflows. This + is done by a comparison used as loop termination condition that considers the amount of the + increment that is applied within each single loop. + +FETA_JUSTIFICATION_END */ + +/********************************************************************************************************************** + * END OF FILE: CryIf.c + *********************************************************************************************************************/ diff --git a/Source/bsw/CryIf/CryIf.h b/Source/bsw/CryIf/CryIf.h new file mode 100644 index 0000000..4d6c51a --- /dev/null +++ b/Source/bsw/CryIf/CryIf.h @@ -0,0 +1,649 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file CryIf.h + * \brief MICROSAR Crypto Interface (CRYIF) + * \details The Crypto Interface module provides a unique interface to manage different Crypto HW and SW + * solutions. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2016-12-01 vismss - Initial creation of Crypto Interface + * 01.00.01 2016-12-06 visrpp ESCAN00093184 Renamed CryIf_KeyValidSet to CryIf_KeySetValid + * 01.00.02 2016-12-16 vismss ESCAN00093334 Adapted CryIf_CallbackNotification + * 01.00.03 2017-01-24 vismss ESCAN00093699 Correction of error and service id codes + * 01.01.00 2017-02-14 visgut FEATC-815 Support CRYIF + * Support CryIf_CancelJob + * Fix Reference of Driver Object + * 01.02.00 2017-05-05 visrpp FEATC-1228 FEAT-2902 Release of AR4.3 CryIf + * 02.00.00 2017-05-12 vismaw ESCAN00095159 Validity of cryIfKeyId is not checked + * Silent BSW + * 04.00.00 2018-11-07 vismaw STORYC-6541 Support redirection of input/output buffers from/to key elements + * STORYC-6546 Support partial key element copy + * 04.01.00 2019-03-15 vismaw STORYC-7654 Release of CryIf 4.x + * STORYC-5723 MISRA-C:2012 Compliance + * 05.00.00 2019-12-04 visenc SEC-19 Asynchronous Key Handling + * ESCAN00105151 Compiler error due to incompatible function pointer declaration and + * function definition + * 05.01.00 2020-08-18 vismxe SEC-1838 Migration to QAC Helix + * vismxe ESCAN00105785 Fix comment before case label not recognized by compiler + * 06.00.00 2023-02-28 rstemmler SEC-5474 Introduce APIs KeyGetStatus and KeySetInvalid + * SEC-3020 Add stub functions for non-autosar services CertificateVerify and + * CertificateParse + * SEC-5682 Improve parameter checks in CryIf_KeyElementSet + * SEC-3644 _MemMap migration + * ESCAN00114084 Avoid possible endless loop when copying keys between crypto drivers + * 07.00.00 2023-04-26 kwiedom HSM-3726 Multi Core support: remove CryIf_ModuleInitialized variable and checks + * 07.01.00 2023-11-07 coechsler ESCAN00116074 CryIf_KeyCopy may not copy key elements as expected when copying from one driver to another + * main-1 2024-04-23 viseag CRY-717 Change history is maintained in the global ChangeHistory.txt file starting with this release. + *********************************************************************************************************************/ + +#if !defined (CRYIF_H) +# define CRYIF_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Std_Types.h" +# include "Crypto_GeneralTypes.h" +# include "CryIf_Cfg.h" +# include "CryIf_Cbk.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* Vendor and module identification */ +# define CRYIF_VENDOR_ID (30u) +# define CRYIF_MODULE_ID (112u) + +/* AUTOSAR Software specification version information */ +# define CRYIF_AR_RELEASE_MAJOR_VERSION (4u) +# define CRYIF_AR_RELEASE_MINOR_VERSION (4u) +# define CRYIF_AR_RELEASE_REVISION_VERSION (0u) + +/* ----- Component version information (decimal version of ALM implementation package) ----- */ +# define CRYIF_SW_MAJOR_VERSION (9u) +# define CRYIF_SW_MINOR_VERSION (1u) +# define CRYIF_SW_PATCH_VERSION (0u) + +# define CRYIF_INSTANCE_ID_DET (0x00u) + +/* ----- API service IDs ----- */ +# define CRYIF_SID_INIT (0x00u) /*!< Service ID: CryIf_Init() */ +# define CRYIF_SID_GET_VERSION_INFO (0x01u) /*!< Service ID: CryIf_GetVersionInfo() */ +# define CRYIF_SID_PROCESS_JOB (0x02u) /*!< Service ID: CryIf_ProcessJob() */ +# define CRYIF_SID_CANCEL_JOB (0x03u) /*!< Service ID: CryIf_CancelJob() */ +# define CRYIF_SID_KEY_ELEMENT_SET (0x04u) /*!< Service ID: CryIf_KeyElementSet() */ +# define CRYIF_SID_KEY_SET_VALID (0x05u) /*!< Service ID: CryIf_KeySetValid() */ +# define CRYIF_SID_KEY_ELEMENT_GET (0x06u) /*!< Service ID: CryIf_KeyElementGet() */ +# define CRYIF_SID_KEY_ELEMENT_COPY (0x0fu) /*!< Service ID: CryIf_KeyElementCopy() */ +# define CRYIF_SID_KEY_ELEMENT_COPY_PARTIAL (0x12u) /*!< Service ID: CryIf_KeyElementCopyPartial() */ +# define CRYIF_SID_KEY_COPY (0x10u) /*!< Service ID: CryIf_KeyCopy() */ +# define CRYIF_SID_RANDOM_SEED (0x07u) /*!< Service ID: CryIf_RandomSeed() */ +# define CRYIF_SID_KEY_GENERATE (0x08u) /*!< Service ID: CryIf_KeyGenerate() */ +# define CRYIF_SID_KEY_DERIVE (0x09u) /*!< Service ID: CryIf_KeyDerive() */ +# define CRYIF_SID_KEY_EXCHANGE_CALC_PUB_VAL (0x0au) /*!< Service ID: CryIf_KeyExchangeCalcPubVal() */ +# define CRYIF_SID_KEY_EXCHANGE_CALC_SECRET (0x0bu) /*!< Service ID: CryIf_KeyExchangeCalcSecret() */ +# define CRYIF_SID_CERTIFICATE_PARSE (0x0cu) /*!< Service ID: CryIf_CertificateParse() */ +# define CRYIF_SID_CERTIFICATE_VERIFY (0x11u) /*!< Service ID: CryIf_CertificateVerify() */ +# define CRYIF_SID_KEY_GET_STATUS (0x13u) /*!< Service ID: CryIf_KeyGetStatus() */ +# define CRYIF_SID_KEY_SET_INVALID (0x14u) /*!< Service ID: CryIf_KeySetInvalid() */ +# define CRYIF_SID_CUSTOM_SYNC (0x15u) /*!< Service ID: CryIf_CustomSync()*/ + +/* ----- Error codes ----- */ +# define CRYIF_E_NO_ERROR (0xFFu) /*!< used to check if no error occurred - use a value unequal to any error code */ +# define CRYIF_E_UNINIT (0x00u) /*!< Error code: API service used without module initialization */ +# define CRYIF_E_INIT_FAILED (0x01u) /*!< Error code: Initialisation of CRYIF module failed */ +# define CRYIF_E_PARAM_POINTER (0x02u) /*!< Error code: API request called with invalid parameter (null pointer) */ +# define CRYIF_E_PARAM_HANDLE (0x03u) /*!< Error code: API request called with invalid parameter (out of range) */ +# define CRYIF_E_PARAM_VALUE (0x04u) /*!< Error code: API request called with invalid parameter (invalid value) */ +# define CRYIF_E_ALREADY_INITIALIZED (0x11u) /*!< Error code: The service CryIf_Init() is called while the module is already initialized */ +# define CRYIF_E_REQUEST_NOT_SUPPORTED (0x12u) /*!< Error code: API request called but request is not supported by Crypto */ + +/* ----- Modes ----- */ +# define CRYIF_UNINIT (0x00u) /*!< State: Module was not initialized */ +# define CRYIF_INIT (0x01u) /*!< State: Module is initialized */ + +/* ----- Other constants ----- */ +# define CRYIF_UINT32_MAX (0xFFFFFFFFuL) + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + +# define CryIf_NoUInt32Overflow(Value1, Value2) (((Value2) <= (uint32)(CRYIF_UINT32_MAX - Value1)) ? TRUE:FALSE ) + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +# define CRYIF_START_SEC_CODE +# include "CryIf_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * CryIf_InitMemory() + *********************************************************************************************************************/ +/*! \brief Power-up memory initialization. + * \details Initialize component variables at power up. No action is performed, CryIf is stateless. + * \pre Module is uninitialized. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYIF_CODE) CryIf_InitMemory(void); + +/********************************************************************************************************************** + * CryIf_Init() + *********************************************************************************************************************/ +/*! \brief Initialization function. + * \details This function initializes the module CryIf. No action is performed, CryIf is stateless. + * \pre Interrupts are disabled. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYIF_CODE) CryIf_Init(void); + +# if (CRYIF_VERSION_INFO_API == STD_ON) +/********************************************************************************************************************** + * CryIf_GetVersionInfo() + *********************************************************************************************************************/ +/*! \brief Returns the version information. + * \details CryIf_GetVersionInfo() returns version information, vendor ID and AUTOSAR module ID of the component. + * \param[out] versioninfo Pointer to where to store the version information. Parameter must not be NULL. + * \pre - + * \context TASK|ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYIF_CODE) CryIf_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, CRYIF_APPL_VAR) versioninfo); +# endif /* (CRYIF_VERSION_INFO_API == STD_ON) */ + +/********************************************************************************************************************** + * CryIf_ProcessJob() + *********************************************************************************************************************/ +/*! \brief Process the received job. + * \details This interface dispatches the received jobs to the configured crypto driver object. + * \param[in] channelId Holds the identifier of the crypto channel. + * \param[in,out] job Pointer to the configuration of the job. Contains structures with user and + * primitive relevant information. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \return CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \return CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * \return CRYPTO_E_QUEUE_FULL Request failed, the queue is full. + * \return CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \return CRYPTO_E_CUSTOM_ERROR Remote processing failed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \spec requires job->jobPrimitiveInfo != NULL_PTR; + * requires job->jobPrimitiveInfo->primitiveInfo != NULL_PTR; + * \endspec + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_ProcessJob(uint32 channelId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYIF_APPL_VAR) job); + +/********************************************************************************************************************** + * CryIf_CancelJob() + *********************************************************************************************************************/ +/*! \brief Cancels the received job. + * \details This interface removes the provided job from the underlying Crypto Driver Object queue. + * \param[in] channelId Holds the identifier of the crypto channel. + * \param[in,out] job Pointer to the configuration of the job. Contains structures with user and + * primitive relevant information. + * \return E_OK Request successful, job has been removed. + * \return E_NOT_OK Request failed, job could not be removed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-127561 + * \spec requires job->jobPrimitiveInfo != NULL_PTR; + * requires job->jobPrimitiveInfo->primitiveInfo != NULL_PTR; + * requires job->jobInfo != NULL_PTR; + * \endspec + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CancelJob(uint32 channelId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYIF_APPL_VAR) job); + +/********************************************************************************************************************** + * CryIf_KeyElementSet() + *********************************************************************************************************************/ +/*! \brief Sets a key element. + * \details This function shall dispatch the set key element function to the configured crypto driver object. + * \param[in] cryIfKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] keyElementId Holds the identifier of the key element which shall be set. + * \param[in] keyPtr Holds the pointer to the key data which shall be set as key element. + * \param[in] keyLength Contains the length of the key element in bytes. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \return CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * \return CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * \return CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre - + * \note NULL_PTR check for P2CONST keyPtr is not executed to save runtime. + * Zero value check for keyLength is not executed to be able to support key deletion. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-127562 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementSet(uint32 cryIfKeyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CRYIF_APPL_DATA) keyPtr, + uint32 keyLength); + +/********************************************************************************************************************** + * CryIf_KeySetValid() + *********************************************************************************************************************/ +/*! \brief Sets the key to valid. + * \details This function shall dispatch the set key valid function to the configured crypto driver object. + * \param[in] cryIfKeyId Holds the identifier of the key whose key elements shall be set to valid. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-127563 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeySetValid(uint32 cryIfKeyId); + +/********************************************************************************************************************** + * CryIf_KeyElementGet() + *********************************************************************************************************************/ +/*! \brief Exports the key element. + * \details This function shall dispatch the get key element function to the configured crypto driver object. + * \param[in] cryIfKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] keyElementId Holds the identifier of the key element which shall be set. + * \param[in,out] resultPtr Holds the pointer to the key data which shall be set as key element. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \return CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * \return CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * \return CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-127564 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementGet(uint32 cryIfKeyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * CryIf_KeyElementCopy() + *********************************************************************************************************************/ +/*! \brief Copy key element. + * \details This function shall copy a key element from one key to a target key. + * \param[in] cryIfKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for the + * copy operation. + * \param[in] targetCryIfKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination for + * the copy operation. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \return CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * \return CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * \return CRYPTO_E_KEY_EXTRACT_DENIED Request failed, not allowed to extract key material. + * \return CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * \return CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-127565 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementCopy(uint32 cryIfKeyId, + uint32 keyElementId, + uint32 targetCryIfKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * CryIf_KeyElementCopyPartial() + *********************************************************************************************************************/ +/*! \brief Copies a key element partially. + * \details This function copies a key element partially from one key to a target key. + * \param[in] cryIfKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for the + * copy operation. + * \param[in] keyElementSourceOffset This is the offset of the source key element indicating the start index + * of the copy operation. + * \param[in] keyElementTargetOffset This is the offset of the destination key element indicating the start index + * of the copy operation. + * \param[in] keyElementCopyLength Specifies the number of bytes that shall be copied. + * \param[in] targetCryIfKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination for + * the copy operation. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element size does not match size of provided data. + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element. + * \context TASK + * \reentrant TRUE, but not for the same cryIfKeyId + * \synchronous TRUE + * \pre - + * \trace CREQ-188329 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementCopyPartial(uint32 cryIfKeyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetCryIfKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * CryIf_KeyCopy() + *********************************************************************************************************************/ +/*! \brief Copy the key + * \details This function shall copy all key elements from the source key to a target key. + * \param[in] cryIfKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] targetCryIfKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \return CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * \return CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * \return CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * \return CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-127566 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyCopy(uint32 cryIfKeyId, + uint32 targetCryIfKeyId); + +/********************************************************************************************************************** + * CryIf_RandomSeed() + *********************************************************************************************************************/ +/*! \brief Initialize the seed + * \details This function shall dispatch the random seed function to the configured crypto driver object. + * \param[in] cryIfKeyId Holds the identifier of the key for which a new material shall be generated. + * \param[in] seedPtr Holds a pointer to the memory location which contains the data to feed the + * seed. + * \param[in] seedLength Contains the length of the seed in bytes. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-127567 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_RandomSeed(uint32 cryIfKeyId, + P2CONST(uint8, AUTOMATIC, CRYIF_APPL_DATA) seedPtr, + uint32 seedLength); + +/********************************************************************************************************************** + * CryIf_KeyGenerate() + *********************************************************************************************************************/ +/*! \brief Generates a key. + * \details This function shall dispatch the key generate function to the configured crypto driver object. + * \param[in] cryIfKeyId Holds the identifier of the key which is to be updated with the generated + * value. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-127568 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyGenerate(uint32 cryIfKeyId); + +/********************************************************************************************************************** + * CryIf_KeyDerive() + *********************************************************************************************************************/ +/*! \brief Derives a key. + * \details This function shall dispatch the key derive function to the configured crypto driver object. + * \param[in] cryIfKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryIfKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-127569 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyDerive(uint32 cryIfKeyId, + uint32 targetCryIfKeyId); + +/********************************************************************************************************************** + * CryIf_KeyExchangeCalcPubVal() + *********************************************************************************************************************/ +/*! \brief Calculation of the public value. + * \details This function shall dispatch the key exchange public value calculation function to the configured + * crypto driver object. + * \param[in] cryIfKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \return CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-127570 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyExchangeCalcPubVal(uint32 cryIfKeyId, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) publicValueLengthPtr); + +/********************************************************************************************************************** + * CryIf_KeyExchangeCalcSecret() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret. + * \details This function shall dispatch the key exchange common shared secret calculation function to the + * configured crypto driver object. + * \param[in] cryIfKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \param[in] partnerPublicValueLength Contains the length of the partners public value in bytes. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \return CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-127571 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyExchangeCalcSecret(uint32 cryIfKeyId, + P2CONST(uint8, AUTOMATIC, CRYIF_APPL_DATA) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * CryIf_CertificateParse() + *********************************************************************************************************************/ +/*! \brief Parse stored certificate. + * \details This function shall dispatch the certificate parse function to the configured crypto driver object. + * \param[in] cryIfKeyId Holds the identifier of the key slot in which the certificate has been + * stored. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \note If API support is disabled (/MICROSAR/CryIf/CryIfCryptoModule/CryIfSupportsCertificateAPI) + * for a specific driver, the service will always return E_NOT_OK for this driver. + * \trace CREQ-127572 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CertificateParse(uint32 cryIfKeyId); + +/********************************************************************************************************************** + * CryIf_CertificateVerify() + *********************************************************************************************************************/ +/*! \brief Certificate verification. + * \details Verifies the certificate stored in the key referenced by verifyCryptoKeyId with the certificate + * stored in the key referenced by cryIfKeyId. + * \param[in] cryIfKeyId Holds the identifier of the key which shall be used to validate the + * certificate. + * \param[in] verifyCryIfKeyId Holds the identifier of the key containing the certificate, which shall be + * verified. + * \param[out] verifyPtr Holds a pointer to the memory location which will contain the result of the + * certificate verification. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \note If API support is disabled (/MICROSAR/CryIf/CryIfCryptoModule/CryIfSupportsCertificateAPI) + * for a specific driver, the service will always return E_NOT_OK for this driver. + * \trace CREQ-127573 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CertificateVerify(uint32 cryIfKeyId, + uint32 verifyCryIfKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CRYIF_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * CryIf_KeySetInvalid() + *********************************************************************************************************************/ +/*! \brief Set crypto key to invalid. + * \details If no errors are detected by CryIf, the service calls Crypto_KeySetInvalid() of the configured + * crypto driver for the crypto key which is mapped to cryIfKeyId and returns the service result. + * \param[in] cryIfKeyId Holds the identifier of the key which shall be set to invalid. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \note If API support is disabled (/MICROSAR/CryIf/CryIfCryptoModule/CryIfSupportsKeyStatusAPI) + * for a specific driver, the service will always return E_NOT_OK for this driver. + * \trace CREQ-324923 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeySetInvalid(uint32 cryIfKeyId); + +/********************************************************************************************************************** + * CryIf_KeyGetStatus() + *********************************************************************************************************************/ +/*! \brief Get status of a key. + * \details If no errors are detected by CryIf, the service calls Crypto_KeyGetStatus() of the configured + * crypto driver for the crypto key which is mapped to cryIfKeyId. The driver writes the key status to + * keyStatusPtr and returns the service result. + * \param[in] cryIfKeyId Holds the identifier of the key of which the status shall be read. + * \param[out] keyStatusPtr Holds a pointer to the memory where the key status shall be written to. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \return CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \note If API support is disabled (/MICROSAR/CryIf/CryIfCryptoModule/CryIfSupportsKeyStatusAPI) + * for a specific driver, the service will always return E_NOT_OK for this driver. + * \trace CREQ-324922 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyGetStatus(uint32 cryIfKeyId, + P2VAR(Crypto_KeyStatusType, AUTOMATIC, CRYIF_APPL_VAR) keyStatusPtr); + +/********************************************************************************************************************** + * CryIf_CustomSync() + *********************************************************************************************************************/ +/*! \brief Requests the execution of a function that is specified by the given dispatch id. + * \details If no errors are detected by CryIf, the service calls Crypto_CustomSync() of the configured + * crypto driver and passes on the return value. + * The driver executes the custom cryptographic operation and returns the service result. + * \param[in] dispatchId Unique id to identify the request. + * \param[in] keyId Key Id (e.g. of the key in which the certificate is stored). + * \param[in] keyElementId Key element id. + * \param[in] targetKeyId Holds the target key id. + * If the service does not require a target key, the targetKeyId still + * must reference a valid key + * \param[in] targetKeyElementId Key element id of target key. + * \param[in] inputPtr Pointer to the input data. + * \param[in] inputLength Contains the input length in bytes. + * \param[out] outputPtr Pointer to the output data. + * \param[out] outputLengthPtr Contains the output length in bytes. + * \param[out] secondaryOutputPtr Pointer to the secondary output data. + * \param[out] secondaryOutputLengthPtr Contains the secondary output length in bytes. + * \return E_OK: Request successful. + * \return E_NOT_OK: Request failed. + * \return CRYPTO_E_BUSY: Request failed, Crypto Driver Object is busy. + * \return CRYPTO_E_CUSTOM_ERROR: Custom processing failed. + * \pre - + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + * \note If API support is disabled (/MICROSAR/CryIf/CryIfCryptoModule/CryIfSupportsCustomSyncService) + * for a specific driver, the service will always return E_NOT_OK for this driver. + * If the service does not require a target key, the key referenced by targetKeyId will not be used. + * However, its id must be valid. + * \trace CREQ-CryIf-CustomSyncService + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CustomSync(uint32 dispatchId, + uint32 keyId, + uint32 keyElementId, + uint32 targetKeyId, + uint32 targetKeyElementId, + P2CONST(uint8, AUTOMATIC, CRYIF_APPL_DATA) inputPtr, + uint32 inputLength, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) outputPtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) outputLengthPtr, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) secondaryOutputPtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) secondaryOutputLengthPtr); + +# define CRYIF_STOP_SEC_CODE +# include "CryIf_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CRYIF_H) */ + +/********************************************************************************************************************** + * END OF FILE: CryIf.h + *********************************************************************************************************************/ diff --git a/Source/bsw/CryIf/CryIf_Cbk.h b/Source/bsw/CryIf/CryIf_Cbk.h new file mode 100644 index 0000000..7c21155 --- /dev/null +++ b/Source/bsw/CryIf/CryIf_Cbk.h @@ -0,0 +1,63 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file CryIf_Cbk.h + * \brief MICROSAR Crypto Interface (CRYIF) + * \details The Crypto Interface module provides a unique interface to manage different Crypto HW and SW + * solutions. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYIF_CBK_H) +# define CRYIF_CBK_H + +# include "Std_Types.h" +# include "Crypto_GeneralTypes.h" + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +# define CRYIF_START_SEC_CODE +# include "CryIf_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * CryIf_CallbackNotification() + *********************************************************************************************************************/ +/*! \brief CryIf Callback Notification + * \details Notifies the CRYIF about the completion of the request with the result of the cryptographic operation. + * \param[in,out] job Points to the completed job's information structure. It contains a + * callbackID to identify which job is finished. + * \param[in] result Contains the result of the cryptographic operation. + * \pre - + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + * \trace CREQ-127574 + *********************************************************************************************************************/ +FUNC(void, CRYIF_CODE) CryIf_CallbackNotification(P2VAR(Crypto_JobType, AUTOMATIC, CRYIF_APPL_VAR) job, + Std_ReturnType result); + +# define CRYIF_STOP_SEC_CODE +# include "CryIf_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CRYIF_CBK_H) */ + +/********************************************************************************************************************** + * END OF FILE: CryIf_Cbk.h + *********************************************************************************************************************/ diff --git a/Source/bsw/CryIf/CryIf_Private.h b/Source/bsw/CryIf/CryIf_Private.h new file mode 100644 index 0000000..d7087ad --- /dev/null +++ b/Source/bsw/CryIf/CryIf_Private.h @@ -0,0 +1,202 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file CryIf_Private.h + * \brief MICROSAR Crypto Interface (CRYIF) + * \details The Crypto Interface module provides a unique interface to manage different Crypto HW and SW + * solutions. This header file contains stub function declarations for services that are not supported + * by the underlying Crypto. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYIF_PRIVATE_H) +# define CRYIF_PRIVATE_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Std_Types.h" +# include "Crypto_GeneralTypes.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +# define CRYIF_START_SEC_CODE +# include "CryIf_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * CryIf_KeyElementCopyPartial_Stub() + *********************************************************************************************************************/ +/*! \brief Returns E_NOT_OK. + * \details This function is referenced in the crypto functions array if the underyling Crypto Driver does not + * support KeyElementCopyPartial Service. This function should never be called and is only existent to + * overcome Compiler / Linker errors. + * \param[in] cryIfKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for the + * copy operation. + * \param[in] keyElementSourceOffset This is the offset of the source key element indicating the start index + * of the copy operation. + * \param[in] keyElementTargetOffset This is the offset of the destination key element indicating the start index + * of the copy operation. + * \param[in] keyElementCopyLength Specifies the number of bytes that shall be copied. + * \param[in] targetCryIfKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination for + * the copy operation. + * \return E_NOT_OK As this should never be called directly, E_NOT_OK is always returned. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyElementCopyPartial_Stub(uint32 cryIfKeyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetCryIfKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * CryIf_CertificateParse_Stub() + *********************************************************************************************************************/ +/*! \brief Returns E_NOT_OK. + * \details This function is referenced in the crypto functions array if the underlying Crypto Driver does not + * support CertificateParse Service. This function should never be called and is only existent to + * overcome Compiler / Linker errors. + * \param[in] cryIfKeyId Holds the identifier of the key slot in which the certificate has been + * stored. + * \return E_NOT_OK As this should never be called directly, E_NOT_OK is always returned. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CertificateParse_Stub(uint32 cryIfKeyId); + +/********************************************************************************************************************** + * CryIf_CertificateVerify_Stub() + *********************************************************************************************************************/ +/*! \brief Returns E_NOT_OK. + * \details This function is referenced in the crypto functions array if the underlying Crypto Driver does not + * support CertificateVerify Service. This function should never be called and is only existent to + * overcome Compiler / Linker errors. + * \param[in] cryIfKeyId Holds the identifier of the key which shall be used to validate the + * certificate. + * \param[in] verifyCryIfKeyId Holds the identifier of the key containing the certificate, which shall be + * verified. + * \param[out] verifyPtr Holds a pointer to the memory location which will contain the result of the + * certificate verification. + * \return E_NOT_OK As this should never be called directly, E_NOT_OK is always returned. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \endspec + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CertificateVerify_Stub(uint32 cryIfKeyId, + uint32 verifyCryIfKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CRYIF_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * CryIf_KeySetInvalid_Stub() + *********************************************************************************************************************/ +/*! \brief Returns E_NOT_OK. + * \details This function is referenced in the crypto functions array if the underlying Crypto Driver does not + * support KeySetInvalid Service. This function should never be called and is only existent to overcome + * Compiler / Linker errors. + * \param[in] cryIfKeyId Holds the identifier of the key that shall be invalidated. + * \return E_NOT_OK As this should never be called directly, E_NOT_OK is always returned. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \pre - + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeySetInvalid_Stub(uint32 cryIfKeyId); + +/********************************************************************************************************************** + * CryIf_KeyGetStatus_Stub() + *********************************************************************************************************************/ +/*! \brief Returns E_NOT_OK. + * \details This function is referenced in the crypto functions array if the underlying Crypto Driver does not + * support KeyGetStatus Service. This function should never be called and is only existent to overcome + * Compiler / Linker errors. + * \param[in] cryIfKeyId Holds the identifier of the key whose status shall be returned. + * \param[out] keyStatusPtr Holds a pointer to the memory where the key status shall be written to. + * \return E_NOT_OK As this should never be called directly, E_NOT_OK is always returned. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \endspec + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_KeyGetStatus_Stub(uint32 cryIfKeyId, + P2VAR(Crypto_KeyStatusType, AUTOMATIC, CRYIF_APPL_VAR) keyStatusPtr); + +/********************************************************************************************************************** + * CryIf_CustomSync_Stub() + *********************************************************************************************************************/ +/*! \brief Returns E_NOT_OK. + * \details This function is referenced in the crypto functions array if the underlying Crypto Driver does not + * support CustomSync Service. This function should never be called and is only existent to overcome + * Compiler / Linker errors. + * \param[in] dispatchId Unique id to identify the request. + * \param[in] keyId Key Id (e.g. of the key in which the certificate is stored). + * \param[in] keyElementId Key element id. + * \param[in] targetKeyId Holds the target key id. + * If the service does not require a target key Id, pass on + * CRYIF_EMPTY_KEY_ID. + * \param[in] targetKeyElementId Key element id of target key. + * \param[in] inputPtr Pointer to the input data. + * \param[in] inputLength Contains the input length in bytes. + * \param[out] outputPtr Pointer to the output data. + * \param[out] outputLengthPtr Contains the output length in bytes. + * \param[out] secondaryOutputPtr Pointer to the secondary output data. + * \param[out] secondaryOutputLengthPtr Contains the secondary output length in bytes. + * \return E_NOT_OK As this should never be called directly, E_NOT_OK is always returned. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYIF_CODE) CryIf_CustomSync_Stub(uint32 dispatchId, + uint32 keyId, + uint32 keyElementId, + uint32 targetKeyId, + uint32 targetKeyElementId, + P2CONST(uint8, AUTOMATIC, CRYIF_APPL_DATA) inputPtr, + uint32 inputLength, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) outputPtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) outputLengthPtr, + P2VAR(uint8, AUTOMATIC, CRYIF_APPL_VAR) secondaryOutputPtr, + P2VAR(uint32, AUTOMATIC, CRYIF_APPL_VAR) secondaryOutputLengthPtr); + +# define CRYIF_STOP_SEC_CODE +# include "CryIf_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CRYIF_PRIVATE_H) */ + +/********************************************************************************************************************** + * END OF FILE: CryIf_Private.h + *********************************************************************************************************************/ diff --git a/Source/bsw/CryIf/Make/CryIf_cfg.mak b/Source/bsw/CryIf/Make/CryIf_cfg.mak new file mode 100644 index 0000000..6e53173 --- /dev/null +++ b/Source/bsw/CryIf/Make/CryIf_cfg.mak @@ -0,0 +1,81 @@ +############################################################################### +# File Name : CryIf_cfg.mak +# Description: Configuration makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the CryIf_rules.mak file. +############################################################################### + +############################################################## +# CAN_CONFIG_PATH: (not used for Vector) +# The Variable CAN_CONFIG_PATH is optional. It allows the +# configuration of the directory, where you can also find the +# generated source files. Generally they should be in the +# directory $(PROJECT_ROOT)\source\networks. +# But if the application should run on several hardware +# targets, then different CAN configurations of different +# directories will be necessary. Therefore the variable +# CAN_CONFIG_PATH should be used. +# +# For example: +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\st10 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# + +#CRYIF_CONFIG_PATH = + + +############################################################## +# CAN_DRIVER_MODE: (not used for Vector) +# This Variable contains the name of the can driver module. At +# the moment the Standard Software Core Supports the two driver +# can_drv.c (single CAN) and can_drvm.c (multi CAN). Other +# values are not allowed. +# +# For example: +# CAN_DRIVER_MODE = singlechannel/multichannel +# + +#CRYIF_DRIVER_MODE = singlechannel + + +############################################################### +# REQUIRED +# +# No Other resources are required to write a Configuration +# Makefile. +# +############################################################### + + +############################################################### +# PROVIDE +# +# A Configuration Makefile does not provide resources for other +# basic software bundles or the base_make package +# +############################################################### + + +############################################################### +# REGISTRY +# +# Like the Provide-Section this block is empty. +# +############################################################### + + +############################################################### +# SPECIFIC +# +# All variables in the _cfg makefile are "Specific" variables, +# because they should only be used in the *_check.mak, +# *_defs.mak and *_rules.mak Makefiles of the same basic +# software bundle. +############################################################### diff --git a/Source/bsw/CryIf/Make/CryIf_check.mak b/Source/bsw/CryIf/Make/CryIf_check.mak new file mode 100644 index 0000000..907183c --- /dev/null +++ b/Source/bsw/CryIf/Make/CryIf_check.mak @@ -0,0 +1,79 @@ +############################################################################### +# File Name : CryIf_check.mak +# Description: Configuration check makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the CryIf_rules.mak file. +############################################################################### + +############################################################### +# REGISTRY +# + +#e.g.: PREPARE_CONFIGURATION_INTERFACE += CAN_MODULES +PREPARE_CONFIGURATION_INTERFACE += + +CHECK_VARS_WHICH_ARE_REQUIRED += + +CHECK_VARS_WHICH_ARE_OPTIONAL += + +CHECK_VARS_WHICH_ARE_OBSOLETE += + +CHECK_VARS_WITH_ONE_CC_FILE += +CHECK_VARS_WITH_MORE_CC_FILES += + +CHECK_VARS_WITH_ONE_CPP_FILE += +CHECK_VARS_WITH_MORE_CPP_FILES += + +CHECK_VARS_WITH_ONE_ASM_FILE += +CHECK_VARS_WITH_MORE_ASM_FILES += + +CHECK_VARS_WITH_ONE_LIB_FILE += +CHECK_VARS_WITH_MORE_LIB_FILES += + +CHECK_VARS_WITH_ONE_OBJ_FILE += +CHECK_VARS_WITH_MORE_OBJ_FILES += + +#e.g: CHECK_VARS_WITH_ONE_DIRECTORY += $(DIRECTORIES_TO_CREATE) +# $(DIRECTORIES_TO_CREATE) = C:\demo\drv (this var is defined in _rules.mak) +CHECK_VARS_WITH_ONE_DIRECTORY += +CHECK_VARS_WITH_MORE_DIRECTORIES += + +CHECK_VARS_WITH_ONE_FILE += +CHECK_VARS_WITH_MORE_FILES += + +CHECK_VARS_WITH_MAX_LENGTH_ONE += + +############################################################### +# SPECIFIC +# +#ifneq ($(CAN_DRIVER_MODE),singlechannel) +#ifneq ($(CAN_DRIVER_MODE),multichannel) +#$(error The value of the variable CAN_DRIVER_MODE is not valid. \ +# Please use singlechannel or multichannel) +#endif +#endif + + +############################################################### +# REQUIRED +# +# No other resources are required for a Configuration Check +# Makefile +# +############################################################### + + +############################################################### +# PROVIDE +# +# A configuration Makefile does not provide resources for other +# basic software bundles or the base-make package. +# +############################################################### + diff --git a/Source/bsw/CryIf/Make/CryIf_defs.mak b/Source/bsw/CryIf/Make/CryIf_defs.mak new file mode 100644 index 0000000..9615cfa --- /dev/null +++ b/Source/bsw/CryIf/Make/CryIf_defs.mak @@ -0,0 +1,82 @@ +############################################################################### +# File Name : CryIf_defs.mak +# Description: Public makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the CryIf_rules.mak file. +############################################################################### + + +############################################################### +# INTERNAL REQUIRED CONFIGURATION (in can_cfg.mak) +# +# CAN_MODULES (required) (not necessary for Vector) +# CAN_DRIVER_MODE (required) (not necessary for Vector) +# CAN_PROJECT_PATH (optional) +# CAN_BUILD_LIBRARY (required) + + +############################################################### +# REQUIRED (defined in base_make) +# +# PROJECT_ROOT +# SSC_ROOT +############################################################### + + +############################################################### +# SPECIFIC +# Specific variables which were defined here are only for local use in this Makefile +# if for example additional includes are necessary, these vars can be defined and used in the REGISTRY-Part. +# e.g.: $(CAN_CORE_PATH) = $(SSC_ROOT)\Can could be used for CPP_INCLUDE_PATH += $(CAN_CORE_PATH)\CPP_FILES\... +CRYIF_CORE_PATH = +# e.g.: CAN_OUTPUT_PATH = $(GENDATA_DIR) +CRYIF_OUTPUT_PATH = $(GENDATA_DIR) + +#CAN_TOOL_PATH = $(PROJECT_ROOT)\core\com\can\gentool + +# it is also possible to generate own configurations with some checks like the following example +# ifneq ( $(CAN_CONFIG_PATH),) +# CAN_PROJECT_PATH = $(CAN_CONFIG_PATH) +# else +# CAN_PROJECT_PATH = $(PROJECT_ROOT)\source\network\can +# endif + + +############################################################### +# REGISTRY +# +# $(SSC_PLUGINS) is a list of the components. Here can is added (not necessary for Vector, whole component-list also exists in Global.makefile.target.make...) +# e.g.: SSC_PLUGINS += can +SSC_PLUGINS += +#e.g.: can_DEPENDENT_PLUGINS = +CRYIF_DEPENDENT_PLUGINS = + +#----------------------------------------------------------------------------------------- +# MakeSupport usually includes all header-files which were in the same +# directory as the source-files automatically, but to ensure that the +# Asr-Makefiles will also work with other Basic-Make-Packages, +# it is necessary to define all include directories for this Module +# e.g.: CC_INCLUDE_PATH += $(CAN_CORE_PATH) +#------------------------------------------------------------------------------------------ +CC_INCLUDE_PATH += CryIf$(BSW_SRC_DIR) +CPP_INCLUDE_PATH += +ASM_INCLUDE_PATH += + +#PREPROCESSOR_DEFINES+= drivermode + +#drivermode_KEY = CAN_MODE +#drivermode_VALUE = $(CAN_DRIVER_MODE) + + +############################################################### +# PROVIDE +# +# A Public Makefile does not provide resources for other basic +# software bundles or the base_make package. +############################################################### diff --git a/Source/bsw/CryIf/Make/CryIf_rules.mak b/Source/bsw/CryIf/Make/CryIf_rules.mak new file mode 100644 index 0000000..feb925e --- /dev/null +++ b/Source/bsw/CryIf/Make/CryIf_rules.mak @@ -0,0 +1,101 @@ +############################################################################### +# File Name : CryIf_rules.mak +# Description: Rules makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Version Date Author Description +#------------------------------------------------------------------------------ +# 1.00.00 2016-11-22 visrpp Initial creation +# 1.01.00 2019-02-06 vircbl Added support of component-based SIP structure +#------------------------------------------------------------------------------ +# TemplateVersion = 1.02 +############################################################################### + + + +############################################################### +# REGISTRY +# + +#e.g.: LIBRARIES_TO_BUILD += $(LIB_OUPUT_PATH)\vendorx_canlib1.$(LIB_FILE_SUFFIX) +LIBRARIES_TO_BUILD += CryIf +CryIf_FILES = CryIf$(BSW_SRC_DIR)\CryIf.c + +# e.g.: CC_FILES_TO_BUILD += drv\can_drv.c +CC_FILES_TO_BUILD += CryIf$(BSW_SRC_DIR)\CryIf.c +CPP_FILES_TO_BUILD += +ASM_FILES_TO_BUILD += + +#LIBRARIES_LINK_ONLY += (not yet supported) +#OBJECTS_LINK_ONLY += (not yet supported) + +#------------------------------------------------------------------------------------------------- +#only define new dirs, OBJ, LIB, LOG were created automaticly +#------------------------------------------------------------------------------------------------- +DIRECTORIES_TO_CREATE += + +#DEPEND_GCC_OPTS += (not yet supported) + +# e.g.: GENERATED_SOURCE_FILES += $(GENDATA_DIR)\drv_par.c +GENERATED_SOURCE_FILES += $(GENDATA_DIR)\CryIf_Cfg.c + +#e.g.: COMMON_SOURCE_FILES += $(GENDATA_DIR)\v_par.c +COMMON_SOURCE_FILES += + +#------------------------------------------------------------------------------------------------- +# .dep & .lnk & .bin and..... +# all in err\ & obj\ & lst\ & lib\ & log\ will be deleted by clean-rule automaticly +# so in this clean-rule it is only necessary to define additional files which +# were not delete automaticly. +# e.g.: $()\can_test.c +#------------------------------------------------------------------------------------------------- +MAKE_CLEAN_RULES += +#MAKE_GENERATE_RULES += +#MAKE_COMPILER_RULES += +#MAKE_DEBUG_RULES += +#MAKE_CONFIG_RULES += +#MAKE_ADD_RULES += + + +############################################################### +# REQUIRED (defined in BaseMake (global.Makefile.target.make...)) +# +# SSC_ROOT (required) +# PROJECT_ROOT (required) +# +# LIB_OUTPUT_PATH (optional) +# OBJ_OUTPUT_PATH (optional) +# +# OBJ_FILE_SUFFIX +# LIB_FILE_SUFFIX +# +############################################################### + + +############################################################### +# PROVIDE this Section can be used to define own additional rules +# +# In vendorx_can_cfg.mak: +# Please configure the project file: +#CAN_CONFIG_FILE = $(PROJECT_ROOT)\source\network\can\my_can_config.cfg + +#In vendorx_can_config : +#generate_can_config: + #$(SSC_ROOT)\core\com\can\tools\canconfiggen.exe -o $(CAN_CONFIG_FILE) + + +############################################################### +# SPECIFIC +# +# There are no rules defined for the Specific part of the +# Rules-Makefile. Each author is free to create temporary +# variables or to use other resources of GNU-MAKE +# +############################################################### + + diff --git a/Source/bsw/Crypto_30_LibCv/BSWMD/Crypto_30_LibCv_MemMap.arxml b/Source/bsw/Crypto_30_LibCv/BSWMD/Crypto_30_LibCv_MemMap.arxml new file mode 100644 index 0000000..6ea7617 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/BSWMD/Crypto_30_LibCv_MemMap.arxml @@ -0,0 +1,117 @@ + + + + + + MICROSAR + + + Crypto_30_LibCv + + + Crypto_Impl + + ResourceConsumption + + + + CRYPTO_30_LIBCV_CODE + /MICROSAR_MemMap/SwAddrMethods/CODE + CODE + + + + CRYPTO_30_LIBCV_CONST_8 + 8 + /MICROSAR_MemMap/SwAddrMethods/CONST + CONST_8BIT + + + CRYPTO_30_LIBCV_CONST_32 + 32 + /MICROSAR_MemMap/SwAddrMethods/CONST + CONST_32BIT + + + CRYPTO_30_LIBCV_CONST_UNSPECIFIED + UNSPECIFIED + /MICROSAR_MemMap/SwAddrMethods/CONST + CONST_UNSPECIFIED + + + + CRYPTO_30_LIBCV_VAR_NO_INIT_8 + 8 + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + VAR_NOINIT_8BIT + + + CRYPTO_30_LIBCV_VAR_NO_INIT_16 + 16 + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + VAR_NOINIT_16BIT + + + CRYPTO_30_LIBCV_VAR_NO_INIT_32 + 32 + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + VAR_NOINIT_32BIT + + + CRYPTO_30_LIBCV_VAR_NO_INIT_UNSPECIFIED + UNSPECIFIED + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + VAR_NOINIT_UNSPECIFIED + + + CRYPTO_30_LIBCV_CRYPTO_SINGLE_PARTITION_VAR_NOINIT_8 + 8 + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + CRYPTO_SINGLE_PARTITION_VAR_NOINIT_8BIT + + + CRYPTO_30_LIBCV_CRYPTO_SINGLE_PARTITION_VAR_NOINIT_16 + 16 + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + CRYPTO_SINGLE_PARTITION_VAR_NOINIT_16BIT + + + CRYPTO_30_LIBCV_CRYPTO_SINGLE_PARTITION_VAR_NOINIT_32 + 32 + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + CRYPTO_SINGLE_PARTITION_VAR_NOINIT_32BIT + + + + CRYPTO_30_LIBCV_VAR_CLEARED_8 + 8 + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + VAR_ZERO_INIT_8BIT + + + + + + + + + + \ No newline at end of file diff --git a/Source/bsw/Crypto_30_LibCv/BSWMD/Crypto_30_LibCv_bswmd.arxml b/Source/bsw/Crypto_30_LibCv/BSWMD/Crypto_30_LibCv_bswmd.arxml new file mode 100644 index 0000000..d478cb8 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/BSWMD/Crypto_30_LibCv_bswmd.arxml @@ -0,0 +1,15429 @@ + + + + + + MICROSAR + + + Crypto_30_LibCv + + + Crypto_Impl + C + 14.09.04 + DaVinci Configurator + 30 + 4.03.00 + /MICROSAR/Crypto_30_LibCv_ib_bswmd/BswModuleDescriptions/Crypto/Crypto_30_LibCv + + /MICROSAR/Crypto_30_LibCv/Crypto_Pre + + + /MICROSAR/Crypto_30_LibCv/Crypto_Rec + + LibCv + + /MICROSAR/Crypto_30_LibCv/Crypto + + + + Crypto + + The Crypto Driver (CRYPTO) is called by the Crypto Interface (CRYIF) and performs the specific cryptographic functionality. The Crypto Driver specification by AUTOSAR offers a key storage and a superset of algorithms which can be extended by custom algorithms. This software-based Crypto Driver offers a subset of algorithms and features. + +#Security #Crypto #Cryptography #Key #SHE +#AUTOSAR + + + VENDOR_SPECIFIC_MODULE_DEFINITION + + + + 1.00.00 + beta + visrpp + 2016-07-13T09:39:25+02:00 + + + + Initial creation + + + + + + 1.00.01 + beta + visrpp + 2016-12-06T05:24:34+01:00 + + + + Added CryptoNvMBlockDescriptor + + + + + + 1.00.02 + beta + vismss + 2016-12-07T02:24:39+01:00 + + + + SW Version update + + + + + + 1.00.03 + beta + vismss + 2016-12-14T05:13:35+01:00 + + + + SW Version update + + + + + + 1.00.04 + beta + vismss + 2017-01-24T09:44:19+01:00 + + + + Adaptions to Specification + + + + + + 1.01.00 + beta + visgut + 2017-02-23T09:24:55+01:00 + + + + Change multiplicity of Mainfunction Cycle Time and add default value + + + + + + 1.01.00 + beta + visgut + 2017-03-03T01:15:32+01:00 + + + + Set min. and max. Queue Size to 1. + + + + + + 1.01.00 + beta + visrpp + 2017-03-07T09:23:34+01:00 + + + + Removed non ASR 4.3 parameter, added CryptoKeyDeriveIterations + + + + + + 1.01.01 + beta + vismaw + 2017-04-19T03:18:30+02:00 + + + + SW Version Update + + + + + + 1.02.00 + released + vismaw + 2017-05-05T05:26:41+02:00 + + + + Release of component + + + FEATC-1229 + + + + + + 2.01.00 + released + vismaw + 2017-09-01T05:07:30+02:00 + + + + Added CryptoSupportSheKeyUpdate, CryptoSupportKeyDerive and CryptoSupportPublicKeyExchange + + + STORYC-281 + + + + + + 3.00.00 + released + vismwe + 2017-09-12T15:28:40+02:00 + + + + Adaption of Preconfiguration for RSA Support, Added CryptoSheMasterKeyRef reference, Added missing default values + + + STORYC-1851, STORYC-2438 + + + + + + 3.01.00 + released + vismwe + 2017-10-06T16:37:50+02:00 + + + + Adaption of Preconfiguration for ECC and References; Adapt Rsa Key Type Names + + + STORYC-2159, STORYC-2600, ESCAN00096938 + + + + + + 3.02.00 + released + vismwe + 2017-11-10T10:54:51+01:00 + + + + Key Primitive Configuration, Add ECDHE with ANSIp256r1, Add HMAC with SHA1 and SHA256 pre-defines + + + STORYC-2604, STORYC-2606 + + + + + + 3.03.00 + released + vismwe + 2017-12-01T14:25:27+01:00 + + + + Use VStdLib switch, Adapt enum for CryptoKeyDeriveAlgorithm + + + STORYC-2601, STORYC-2603 + + + + + + 3.04.00 + released + vismwe + 2018-01-10T13:17:55+01:00 + + + + Add ANSI/NIST/SECp256r1 with SHA-1, expand pre-configured key types + + + STORYC-2605 + + + + + + 3.05.00 + released + vismwe + 2018-01-31T13:12:26+01:00 + + + + Add NIST DRBG, add RSA PKCS1 CRT, add ECDHE SECp256r1, add dele key elements, rework AES CMAC key reuse + + + STORYC-3392, STORYC-2607, STORYC-2602, STORYC-4075 + + + + + + 3.06.00 + released + vismwe + 2018-02-20T12:45:23+01:00 + + + + Support AES 128 encryption and decryption without padding + + + STORYC-4373 + + + + + + 4.00.00 + released + vismwe + 2018-05-18T14:20:06+02:00 + + + + Support for ECDSA 384, Support AES256, fix she pre config + + + STORYC-5043, STORYC-5044, ESCAN00099048 + + + + + + 4.01.00 + released + vismwe + 2018-06-12T09:49:35+02:00 + + + + She Key Update Protocol - Support UID, Fid and counter + + + STORYC-5529 + + + + + + 4.02.00 + released + vismwe + 2018-08-20T11:10:41+02:00 + + + + Fix KeyExchange SECP256P KeyType + + + ESCAN00100349 + + + + + + 5.00.00 + released + vismwe + 2018-09-12T11:00:30+02:00 + + + + Support RSAES-OAEP with SHA-1 and SHA-256 + + + STORYC-6301 + + + + + + 5.01.00 + released + vismwe + 2018-11-07T13:15:54+01:00 + + + + Support redirection of input/output buffers from/to key elements + + + STORYC-6543 + + + + + + 5.02.00 + released + visivg + 2018-11-26T13:10:28+01:00 + + + + Support of SHA512 pre-hashing for ECDSA , SHA384 Hash and ECDHE for SECp384r1 + + + STORYC-7065, STORYC-5518, STORYC-5520 + + + + + + 5.03.00 + released + visivg + 2019-01-07T15:03:34+01:00 + + + + Support GMAC AES-256 + + + STORYC-5807 + + + + + + 5.04.00 + released + visivg + 2019-01-25T10:21:01+01:00 + + + + Support of HMAC SHA-384 + + + STORYC-7447 + + + + + + 5.05.00 + released + visivg + 2019-02-26T15:18:30+01:00 + + + + Prepare Release of Crypto 5.x + + + STORYC-7655 + + + + + + 5.06.00 + released + vismwe + 2019-03-26T11:34:26+01:00 + + + + Support RSAES PKCS#1 v1.5 public key decryption, Support KDF X9.63 with Sha256 in Crypto Driver + + + STORYC-7979, STORYC-7161 + + + + + + 6.00.00 + released + vismwe + 2019-07-10T12:56:35+02:00 + + + + Support Multiple Nv Blocks and Export of She RAM Keys, General Improvements, Support of She DEBUG_CMD + + + SEC-61, SEC-62, SEC-652, SEC-27 + + + + + + 6.01.00 + released + vismwe + 2019-08-05T14:03:37+02:00 + + + + Introduce Immediate write of NvM Blocks + + + SEC-667 + + + + + + 6.01.01 + released + vismaw + 2019-08-20T11:42:56+02:00 + + + + LibCv causes endless loop in NvM_Readall + + + ESCAN00104069 + + + + + + 7.00.00 + released + vismwe + 2019-12-15T19:44:34+01:00 + + + + Support Asynchronous Key Services + + + SEC-54 + + + + + + 7.00.01 + released + vismwe + 2020-01-20T12:13:08+01:00 + + + + Update Version + + + ESCAN00105402 + + + + + + 7.01.00 + released + vismwe + 2020-01-20T12:16:31+01:00 + + + + Add callout implementation for esl_getrandom bytes + + + SEC-10 + + + + + + 7.02.00 + released + vismwe + 2020-02-28T14:56:26+01:00 + + + + Support AES Padding One with Zeros + + + SEC-885 + + + + + + 7.03.00 + released + visenc + 2020-03-23T16:29:15+01:00 + + + + Support CryptoStack KeyGenerate Interfaces + + + SEC-902 + + + + + + 8.00.00 + released + visenc + 2020-04-14T12:15:45+02:00 + + + + Support HMAC with RIPEMD160 + + + SEC-1280 + + + + + + 8.00.01 + released + vismwe + 2020-04-23T11:51:57+02:00 + + + + Update Version + + + ESCAN00106180 + + + + + + 8.01.00 + released + visenc + 2020-04-26T15:30:25+02:00 + + + + Support of ECDSA with SECP160R1, Support User Config File + + + SEC-1276, SEC-1408 + + + + + + 8.02.00 + released + visenc + 2020-05-25T11:17:29+02:00 + + + + Support of HASH with RIPEMD-160, AES CTR mode and KDF2 + + + SEC-1278, SEC-796, SEC-954 + + + + + + 8.03.00 + released + visenc + 2020-06-10T16:13:56+02:00 + + + + Support KDF963 in combination with SHA512 + + + SEC-1534 + + + + + + 8.04.00 + released + visenc + 2020-06-19T17:22:51+02:00 + + + + Support ChaCha20 with Poly1305 as authenticator for AEAD + + + SEC-1250 + + + + + + 8.05.00 + released + visenc + 2020-07-06T12:13:03+02:00 + + + + Support CTR_DRBG based on AES-128 from vSecPrim, Support Write OnceKeys,Support PRNG based on SHA512 according to SP800-90A, Support of HASH SHA3-256 + + + SEC-1164, SEC-1687, SEC-1215, SEC-1472 + + + + + + 9.00.00 + released + visenc + 2020-08-27T10:28:08+02:00 + + + + Support DRBG CTR AES256, Support SHE command: CMD_GET_ID + + + SEC-1691, SEC-1665 + + + + + + 9.01.00 + released + vismwe + 2020-08-27T17:15:40+02:00 + + + + Support AES-CMAC 256, HKDF HMAC SHA256, AES-CCM 128 and SPAKE2+ + + + SEC-1801, SEC-1805, SEC-1809, SEC-1812 + + + + + + 9.02.00 + released + visenc + 2020-11-18T16:14:22+01:00 + + + + Support MD5 and Key Generation for Ed25519 Keys + + + SEC-2080, SEC-1677 + + + + + + 9.03.00 + released + vismxe + 2020-12-17T14:21:22+01:00 + + + + Support AUTOSAR 20-11 custom mode configuration + + + SEC-1887 + + + + + + 10.00.00 + released + visenc + 2021-05-05T17:25:50+02:00 + + + + Save and restore context for running crypto operations + + + SEC-2476 + + + + + + 10.01.00 + released + vismwe + 2021-08-25T13:29:39+02:00 + + + + Support Elliptic Curve Burmester Desmedt + + + SEC-2122 + + + + + + 11.00.00 + released + visenc + 2021-11-29T18:34:14+01:00 + + + + Support Key Derivation NIST SP 800-56C Option 1 + + + SEC-3388 + + + + + + 11.01.00 + released + visenc + 2021-12-20T17:18:40+01:00 + + + + Support key value changed callouts + + + SEC-3570 + + + + + + 12.00.00 + released + visenc + 2022-05-16T15:37:45+02:00 + + + + Support of ECDSA secp521r1 with SHA2-512, Support AES-192, Fix ESCAN00111597 + + + SEC-4482, SEC-4863 + + + + + + 12.01.00 + released + viskju + 2022-11-11T10:01:11+01:00 + + + + Support of ECDHE secp521r1, Support SHA-3 and SHAKE + + + HSM-3249, HSM-3096 + + + + + + 12.02.00 + released + viskju + 2023-01-23T15:13:12+01:00 + + + + Support of HKDF HMAC SHA384 + + + HSM-3086 + + + + + + 12.03.00 + released + viskju + 2023-03-15T10:31:55+01:00 + + + + Support of HKDF HASH Sha-512 + + + HSM-3819 + + + + + + 12.04.00 + released + viskju + 2023-03-23T15:50:06+01:00 + + + + Support of ISO-15118-20 KDF for P521 + + + HSM-3826 + + + + + + 13.00.00 + released + viskju + 2023-04-13T15:10:26+02:00 + + + + Support multicore with shared memory + + + HSM-3728 + + + + + + 13.01.00 + released + viskju, vikrio + 2023-06-06T09:05:40+02:00 + + + + Support X448/ECDH based on curve Edwards448, Make LibCv more compatible with Hwa with regard to primitives and custom refs, Support ISO-15118-20 Key Derivation for ED448, Support EdDSA ED448 + + + HSM-4098, HSM-3811, HSM-4090, SEC-6446 + + + + + + 13.02.00 + released + coechsler + 2023-08-02T15:52:43+02:00 + + + + Support HMAC SHA2-512, support HKDF Expand SHA256, SHA384, Support IsKeyOnCurve + + + SEC-6306, SEC-6310, SEC-6685 + + + + + + 13.03.00 + released + coechsler + 2023-08-21T13:51:35+02:00 + + + + Support IsKeyOnCurve Ed, Support ECBD P256R1 + + + SEC-6734, SEC-6768 + + + + + + 13.04.00 + released + viskju + 2023-10-04T10:01:53+02:00 + + + + Support for secp521r1 Key Generation + + + HSM-4583 + + + + + + 13.04.01 + released + viskju + 2023-10-16T16:05:32+02:00 + + + + Update Version + + + ESCAN00115928 + + + + + + 13.05.00 + released + coechsler + 2023-11-10T11:48:25+01:00 + + + + Update Version + + + CRY-418 + + + + + + 13.05.01 + released + coechsler + 2024-01-05T10:58:36+01:00 + + + + Update Version + + + ESCAN00116209 + + + + + + 13.06.00 + released + coechsler + 2024-01-16T15:36:41+01:00 + + + + Support SLH-DSA SHA2-128s Verify, SM4 Cipher, SM3 Hash, SM2 Signature, SM2 Key Generation + + + CRY-58, CRY-391, CRY-389, CRY-395, CRY-393 + + + + + + 14.00.00 + released + coechsler + 2024-03-15T09:24:46+01:00 + + + + Support AES GCM variable tag length + + + CRY-759 + + + + + + 14.01.00 + released + coechsler + 2024-03-20T07:45:18+01:00 + + + + Change history is maintained in the global ChangeHistory.txt file starting with this release. + + + CRY-462 + + + + + + + 0 + 1 + /AUTOSAR/EcucDefs/Crypto + + VARIANT-PRE-COMPILE + + + + CryptoDriverObjects + + Container for Crypto Driver Objects + + + + + false + false + + + + 1 + 1 + false + + + CryptoDriverObject + + Container for configuration of Crypto Driver Object. The container name serves as a symbolic name for the identifier of a Crypto Driver Object. + + + + + false + false + + + + 1 + true + false + + + CryptoDriverObjectId + + Identifier of the Crypto Driver Object. The Crypto Driver Object offers different crypto primitives. + + + + + DEC + + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + true + 0 + 4294967295 + 0 + + + CryptoDriverObjectQueueSize + + Size of the queue in the Crypto Driver. Defines the maximum number of jobs in the Crypto Driver Object queue. If it is set to 0, queueing is disabled in the Crypto Driver Object. This Crypto Driver does not support queuing but uses the buffer for asynchronous processing therefore the value need to be set to 1. + + + + + DEC + + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + 1 + 1 + 1 + + + + + CryptoPrimitiveRef + + Refers to primitive in the CRYPTO. +The CryptoPrimitive is a pre-configured container of the crypto service that shall be used. + + 1 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + CryptoDefaultRandomKeyRef + + This is a reference to the CryptoKey that is used by the +CryptoDefaultRandomPrimitiveRef. The key contains key elements that +are necessary to seed the random number generator. +This element shall only be set if the primitive referenced by +CryptoDefaultRandomPrimitiveRef requires a seed value. +The reference has to be different for each partition. + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + CryptoDefaultRandomPrimitiveRef + + This is a reference to a primitive that configures a default random number +generator. If a crypto driver object needs to perform a crypto primitive that +requires a random number generator, but the configuration of this primitive +does not provide parameter for a random number generator, then this +default random number generator shall be used (i.e. the elements of +algorithm family, secondary algorithm family and algorithm mode do not +provide this information). +Example: The crypto driver shall generate a signature based on elliptic +curve but the primitive for signature generation lacks information about a +random number generator. + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + CryptoDriverObjectEcucPartitionRef + + Maps a crypto driver object to zero or one ECUC partition. The ECUC +partition referenced is a subset of the ECUC partitions where the Crypto +driver is mapped to. + + + + + false + + + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + /AUTOSAR/EcucDefs/EcuC/EcucPartitionCollection/EcucPartition + + + + + + + CryptoGeneral + + Container for common configuration options. + + + + + false + false + + + + 1 + 1 + false + false + + + + + + + + + CryptoVersionInfoApi + + Pre-processor switch to enable and disable availability of the API Crypto_GetVersionInfo(). +- True: API Crypto_GetVersionInfo() is available +- False: API Crypto_GetVersionInfo() is not available. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + false + + + CryptoMainFunctionPeriod + + Specifies the period of main function Crypto_MainFunction in seconds. + + + + + SEC + + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + 0.01 + 3600 + 0 + + + CryptoDevErrorDetect + + Switches the development error detection and notification on or off. +- True: detection and notification is enabled. +- False: detection and notification is disabled. + + + +

+ True: Development error detection enabled. + False: Development error detection disabled +

+
+ 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + true +
+ + CryptoSafeBswChecks + + Selects if safety checks are used. These checks improve robustness as e.g. invalid parameters are checked before function is executed. This attribute has to be enabled for safety projects where this component is mapped to an ASIL partition. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + true + + + CryptoUseVStdLib + + Use VStdLib + + + If enabled the VStdLib is used for copy and clear data operations. If there is no VStdLib, disable the switch to use the implementation of the Crypto. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + true + + + CryptoKeyElementDelete + + If Crypto_KeyElementSet is called with the length 0 the key will be overwritten with 0 and the length is set to 0. If KeyElementDelete is enabled the standard AUTOSAR DET check for the given key element length in Crypto_KeyElementSet will be disabled. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + false + + + CryptoAlignKeyStorage + + Enable, to align each key inside the KeyStorage. The KeyStorage size will increase but the access will be faster. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + false + + + CryptoNvMEnableSetRamBlockStatus + + NvM Enable SetRamBlockStatus + + + Select if SetRamBlockStatus shall be called in KeyValidSet. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + true + + + CryptoRedirection + + Enable job input/output redirection to key elements. This is a Autosar 4.4 feature. Therefore a Csm and CryIf is required which also supports this feature + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + false + + + CryptoWatchdogTriggerFunction + + This function is called by the vSecPrim to trigger the watchdog. The vSecPrim watchdog level need to be set additional. +void "WatchdogTriggerFunction"(void) + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + + + Appl_WatchdogTriggerFunction + 1 + + + + + CryptoDefaultRandomMaxRetries + + Number of max retries for default random number generation. The calculation is reexecuted if the default random source is used from two driver objects at the same time. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + 10 + 65535 + 1 + + + CryptoUserConfigFile + + Reference to an external user configuration file that will be included during generation. +The content of the user configuration file will be added at the end of the generated module configuration file and allows altering or extending the generated code. + +Caution: User configuration files can cause the software module to malfunction and must only be used with great care! + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + + + 1 + + + + + CryptoNumberOfLongTermPrimitiveWorkspace + + Determines the number of workspaces used for long term primitive execution. +See Technical Reference for more information including which primitives use this workspace, (for example Spake2+ and ECBD Key Exchange). + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + 0 + 255 + 0 + + + CryptoStrictLengthCheckForKeyElementGet + + This option only affects key elements which have partial access enabled. + +Enabled: KeyElementGet does not allow partially reading key elements, only complete reads of key elements are allowed. +Disabled: KeyElementGet allows partially reading key elements depending on the available buffer size. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + true + + + CryptoEnableKeyLocking + + true: Enables the protection of keys while they are used. It is recommended for single-partition usecases. +If this should be used for multi-partition usecases, please check the technical references for the necessary adaptions. + +false: Disables the protection of keys while they are used. This is recommended to be set for multi-partition usecases. The user must ensure that key elements are only changed when they are not accessed (read or write) by any other user (different contexts or cores). +Please see the individual API definitions to check when a key element is changed. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + true + + + CryptoMultiPartitionRuntimeChecks + + If enabled, additional checks are performed to +- prevent the usage of driver objects by wrong partitions +- prevent the usage of SHE functionality by other partitions than the main partition +- prevent the initialization of the module by unknown partitions +- prevent the usage of default random source by unknown partitions. + +All partitions referenced in CryptoEcucPartitionRef are known to the module. + + + + + false + + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + false + +
+ + + CryptoEcucPartitionRef + + Maps the Crypto driver to zero or multiple ECUC partitions to make the +modules API available in this partition. It must contain all partitions which will use the Crypto driver. + + + + + false + + + + 0 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + /AUTOSAR/EcucDefs/EcuC/EcucPartitionCollection/EcucPartition + + + CryptoMainEcucPartitionRef + + Defines the main partition is responsible for the initialization of the shared data of the Crypto driver. +The main partition also is the only partition which can use SHE functionality and persist key elements. NvM has to be located on this partition if key element persisting should be used. + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + /AUTOSAR/EcucDefs/EcuC/EcucPartitionCollection/EcucPartition + + + + + CryptoKeyExchangePrimitives + + Configuration of a Crypto Key Exchange Primitive. If there is an algorithm configured, key exchange is usable via Crypto_KeyExchangeCalcPubVal and Crypto_KeyExchangeCalcSecret API. + + + + + false + false + + + + 1 + 1 + false + + + CryptoKeyExchangeAlgorithm + + Determines the algorithm used for the crypto key exchange. +The exact algorithm specification can be found in the technical reference of this component. +Disable to save ROM. + +Equivalent algorithms: +- SECp384r1 = NIST P-384 +- SECp521r1 = NIST P-521 + + 0 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + CRYPTO_KEY_EXCHANGE_ALGORITHM_X25519 + + + CRYPTO_KEY_EXCHANGE_ALGORITHM_X25519 + Vector Informatik + + + CRYPTO_KEY_EXCHANGE_ALGORITHM_ANSIP256R1 + Vector Informatik + + + CRYPTO_KEY_EXCHANGE_ALGORITHM_SECP256R1 + Vector Informatik + + + CRYPTO_KEY_EXCHANGE_ALGORITHM_SECP384R1 + Vector Informatik + + + CRYPTO_KEY_EXCHANGE_ALGORITHM_SPAKE2_PLUS_CIPHERSUITE_8 + Vector Informatik + + + CRYPTO_KEY_EXCHANGE_ALGORITHM_NISTP224R1_BD + Vector Informatik + + + CRYPTO_KEY_EXCHANGE_ALGORITHM_SECP521R1 + Vector Informatik + + + CRYPTO_KEY_EXCHANGE_ALGORITHM_X448 + Vector Informatik + + + CRYPTO_KEY_EXCHANGE_ALGORITHM_P256R1_BD + Vector Informatik + + + CRYPTO_KEY_EXCHANGE_ALGORITHM_P224R1 + Vector Informatik + + + + + + + CryptoKeyDerivePrimitives + + If enabled, key derivation is usable via Crypto_KeyDerive API. + + + + + false + false + + + + 1 + 1 + false + + + CryptoKeyDeriveAlgorithm + + Determines the algorithm used for the crypto key derive. +The exact algorithm specification can be found in the technical reference of this component. +Disable to save ROM. + + 0 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + CRYPTO_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256 + + + CRYPTO_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB + Vector Informatik + + + CRYPTO_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256 + Vector Informatik + + + CRYPTO_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING + Vector Informatik + + + CRYPTO_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256 + Vector Informatik + + + CRYPTO_KDF_ALGO_X963_SHA256 + Vector Informatik + + + CRYPTO_KDF_ALGO_PBKDF2_HMAC_SHA1 + Vector Informatik + + + CRYPTO_KDF_ALGO_PBKDF2_HMAC_SHA256 + Vector Informatik + + + CRYPTO_KDF_ALGO_X963_SHA512 + Vector Informatik + + + CRYPTO_KDF_ALGO_HKDF_HMAC_SHA256 + Vector Informatik + + + CRYPTO_KDF_ALGO_SPAKE2_PLUS_P256R1 + Vector Informatik + + + CRYPTO_KDF_ALGO_HKDF_OPTION1_SHA256 + Vector Informatik + + + CRYPTO_KDF_ALGO_HKDF_HMAC_SHA384 + Vector Informatik + + + CRYPTO_KDF_ALGO_HKDF_OPTION1_SHA512 + Vector Informatik + + + CRYPTO_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING + Vector Informatik + + + CRYPTO_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256 + Vector Informatik + + + CRYPTO_KDF_ALGO_HKDF_EXPAND_HMAC_SHA384 + Vector Informatik + + + CRYPTO_KDF_ALGO_NIST_800_108_CTR_CMAC_AES + Vector Informatik + + + + + + + CryptoMacPrimitives + + Determines the algorithm used for the crypto mac jobs. + + + + + false + false + + + + 1 + 1 + false + + + CryptoCmacAesRoundkeyReuse + + The AES CMAC supports the reuse of calculated AES round keys. If this feature is enabled +the round keys are hold in the driver object. The round keys are hold until a different job type +is processed (not CMAC AES128 and CMAC AES256) or the corresponding key has changed. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + false + + + + + CryptoCipherPrimitives + + Determines the algorithm used for the crypto cipher jobs. + + + + + false + false + + + + 1 + 1 + false + + + CryptoEnableAES192 + + Enable AES 192 for driver objects with AES. Otherwise only AES 128 is available. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + false + + + CryptoEnableAES256 + + Enable AES 256 for driver objects with AES. Otherwise only AES 128 is available. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + false + + + + + CryptoKeyGeneratePrimitives + + If enabled, key generate is usable via Crypto_KeyGenerate API. + + + + + false + false + + + + 1 + 1 + false + + + CryptoKeyGenerateAlgorithm + + Determines the algorithm used for the crypto key generation. +Disable to save ROM. + + 0 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + CRYPTO_KEY_GENERATE_ALGORITHM_SYMMETRIC_GENERIC + + + CRYPTO_KEY_GENERATE_ALGORITHM_SYMMETRIC_GENERIC + Vector Informatik + + + CRYPTO_KEY_GENERATE_ALGORITHM_ANSI_NIST_SEC_P256R1 + Vector Informatik + + + CRYPTO_KEY_GENERATE_ALGORITHM_NIST_SEC_P384R1 + Vector Informatik + + + CRYPTO_KEY_GENERATE_ALGORITHM_ED25519 + Vector Informatik + + + CRYPTO_KEY_GENERATE_ALGORITHM_NIST_SEC_P521R1 + Vector Informatik + + + CRYPTO_KEY_GENERATE_ALGORITHM_SM2P256V1 + Vector Informatik + + + + + CryptoKeyGenerateMaxLength + + Select the max key length in bytes.This parameter is only used for CRYPTO_KEY_GENERATE_ALGORITHM_SYMMETRIC_GENERIC. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + 32 + 65535 + 1 + + + + + CryptoConfigurableCallouts + + This container is used for the callouts to notify the application. +Activating the callouts costs runtime, so it is recommended to activate them only when needed. + + + + + false + false + + + + 1 + 1 + false + + + CryptoKeyValueChangedCalloutFctName + + This function is called by the LibCv to notify the application when a key value was changed. +This function is only available if the callout name is set, otherwise it is disabled. +It notifies which key element of the key was changed. +If the keys are set to their initial value, the callout will not occur. +The limitations are documented in the technical reference. + + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + + + Appl_KeyValueChangedCallout + 1 + + + + + CryptoKeyValiditySetCalloutFctName + + This function is called by the LibCv to notify the application when the validity of the key has changed. +This function is only available if the callout name is set, otherwise it is disabled. +The limitations are documented in the technical reference. + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + + + Appl_KeyValiditySetCallout + 1 + + + + + + +
+ + CryptoKeyElements + + Container for CRYPTO key elements. + + + + + false + false + + + + 0 + 1 + false + + + CryptoKeyElement + + Configuration of a CryptoKeyElement + + + + + false + false + + + + 1 + true + false + + + CryptoKeyElementId + + Identifier of the CRYPTO key element + + + + + DEC + + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + true + 1 + 4294967295 + 0 + + + CryptoKeyElementSize + + Maximum size of a CRYPTO key element in bytes + + + + + DEC + + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + 16 + 4294967295 + 1 + + + CryptoKeyElementInitValue + + Value which will be used to fill the element during initialization, when the element is not already initialized. + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + + + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + + + + CryptoKeyElementReadAccess + + Define the reading access rights of the key element. +CRYPTO_RA_DENIED = key element cannot be read from outside the Crypto Driver +CRYPTO_RA INTERNAL_COPY = key element can be copied to another key element in the same crypto driver. +CRYPTO_RA_ALLOWED = key element can be read as plaintext +CRYPTO_RA_ENCRYPTED = key element can be read encrypted. E.g. SHE Ram-Key export. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + RA_ALLOWED + + + RA_ALLOWED + + + RA_DENIED + + + RA_ENCRYPTED + + + RA_INTERNAL_COPY + + + + + CryptoKeyElementAllowPartialAccess + + Enable or disable writing and reading the key element with data smaller than the size of the element. + +- True: enable partial access of the key element + +- False: disable partial access of the key element + + + +The partial access setting for writing applies to all APIs, while the partial access setting for reading is specifically used for the KeyElementGet() API. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + false + + + CryptoKeyElementPersist + + Enable or disable persisting of the key element in non-volatile storage. +- True: enable persisting of the key element. +- False: disable persisting of the key element. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + false + + + CryptoKeyElementWriteAccess + + Define the writing access rights of the key element +CRYPTO_WA_DENIED = key element cannot be written from outside the Crypto Driver +CRYPTO_WA INTERNAL_COPY = key element can be filled with another key element in the same crypto driver. +CRYPTO_WA_ALLOWED = key element can be rewritten as plaintext +CRYPTO_WA_ENCRYPTED = key element can be written encrypted. E.g. SHE load key. + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + WA_ALLOWED + + + WA_ALLOWED + + + WA_DENIED + + + WA_ENCRYPTED + + + WA_INTERNAL_COPY + + + + + CryptoKeyElementFormat + + Defines the format for the key element. This is the format used to provide or extract the key data from the driver. + +Parameter not used. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + CRYPTO_KE_FORMAT_BIN_OCTET + + + CRYPTO_KE_FORMAT_BIN_OCTET + AUTOSAR_ECUC + + + CRYPTO_KE_FORMAT_BIN_SHEKEYS + AUTOSAR_ECUC + + + CRYPTO_KE_FORMAT_BIN_IDENT_PRIVATEKEY_PKCS8 + AUTOSAR_ECUC + + + CRYPTO_KE_FORMAT_BIN_IDENT_PUBLICKEY + AUTOSAR_ECUC + + + CRYPTO_KE_FORMAT_BIN_RSA_PRIVATEKEY + AUTOSAR_ECUC + + + CRYPTO_KE_FORMAT_BIN_RSA_PUBLICKEY + AUTOSAR_ECUC + + + + + CryptoKeyElementWriteOnce + + Determine if a key shall only be writeable once. +- non-persist keys: Only once after start-up. +- persist keys: Only once for all time. +A init value does not affects this behavior. +If a init value shall not be overwritable use CRYPTO_WA_DENIED. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + false + + + + + + + CryptoKeyTypes + + Container for CRYPTO key types + + + + + false + false + + + + 0 + 1 + false + + + CryptoKeyType + + Configuration of a CryptoKeyType + + + + + false + false + + + + 1 + true + false + + + CryptoKeyElementRef + + Refers to a pointer in the CRYPTO Key Element, which holds the data of the crypto key element. + + 1 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + + + + + CryptoKeys + + Container for CRYPTO keys + + + + + false + false + + + + 0 + 1 + false + + + CryptoKey + + Configuration of a CryptoKey + + + + + false + false + + + + 1 + true + false + + + CryptoKeyId + + Identifier of the CRYPTO key + + + + + DEC + + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + true + 0 + 4294967295 + 0 + + + CryptoKeyDeriveIterations + + Holds the number of iterations to be performed by the key derivation primitive. + +Parameter not used. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + 1 + 4294967295 + 1 + + + CryptoKeyNvId + + The CRYPTO_KEY_NV_ID is used to give a key a unique id for the complete lifecycle even if the CRYPTO_KEY_ID changed. The CRYPTO_KEY_NV_ID is used to identify a key within the Nv Block over several different configurations. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + 0 + 65535 + 0 + + + + + CryptoKeyTypeRef + + Refers to a pointer in the CRYPTO to a CryptoKeyType. The CryptoKeyType provides the information which key elements are contained in a CryptoKey. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + + + + + CryptoPrimitives + + Container for CRYPTO primitives + + + + + false + false + + + + 0 + 1 + false + + + CryptoPrimitive + + Configuration of a CryptoPrimitive + + + + + false + false + + + + 0 + true + false + + + CryptoPrimitiveAlgorithmFamily + + Determines the algorithm family used for the crypto service. + + 1 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + CRYPTO_ALGOFAM_NOT_SET + + + CRYPTO_ALGOFAM_3DES + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_AES + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_BLAKE_1_256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_BLAKE_1_512 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_BLAKE_2s_256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_BLAKE_2s_512 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_BRAINPOOL + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_CHACHA + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_CUSTOM + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_CUSTOM_DRBG + Vector Informatik + + + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + Vector Informatik + + + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + Vector Informatik + + + CRYPTO_ALGOFAM_CUSTOM_FIPS186 + Vector Informatik + + + CRYPTO_ALGOFAM_CUSTOM_HKDF + Vector Informatik + + + CRYPTO_ALGOFAM_CUSTOM_ISO15118 + Vector Informatik + + + CRYPTO_ALGOFAM_CUSTOM_MD5 + Vector Informatik + + + CRYPTO_ALGOFAM_CUSTOM_SPAKE2_PLUS + Vector Informatik + + + CRYPTO_ALGOFAM_CUSTOM_X25519 + Vector Informatik + + + CRYPTO_ALGOFAM_DH + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_DRBG + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ECCANSI + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ECCNIST + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ECCSEC + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ECDH + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ECDSA + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ECIES + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ED25519 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_EEA3 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_EIA3 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_FIPS186 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_HKDF + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_KDFX963 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_NOT_SET + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_PADDING_ONEWITHZEROS + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_PADDING_PKCS7 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_PBKDF2 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_POLY1305 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_RIPEMD160 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_RNG + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_RSA + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SECURECOUNTER + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA1 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_224 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_384 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_512 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_512_224 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_512_256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA3_224 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA3_256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA3_384 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA3_512 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHAKE128 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHAKE256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SIPHASH + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SM2 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SM3 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_X25519 + AUTOSAR_ECUC + + + + + CryptoPrimitiveAlgorithmMode + + Determines the algorithm mode used for the crypto service + + 1 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + CRYPTO_ALGOMODE_NOT_SET + + + CRYPTO_ALGOMODE_12ROUNDS + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_20ROUNDS + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_8ROUNDS + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_CBC + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_CFB + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_CMAC + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_CTR + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_CTRDRBG + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_CUSTOM + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_CUSTOM_CCM + Vector Informatik + + + CRYPTO_ALGOMODE_CUSTOM_MODE_1 + Vector Informatik + + + CRYPTO_ALGOMODE_CUSTOM_P160R1 + Vector Informatik + + + CRYPTO_ALGOMODE_CUSTOM_P256R1 + Vector Informatik + + + CRYPTO_ALGOMODE_CUSTOM_P384R1 + Vector Informatik + + + CRYPTO_ALGOMODE_CUSTOM_RSAES_OAEP_CRT + Vector Informatik + + + CRYPTO_ALGOMODE_CUSTOM_RSASSA_PKCS1_v1_5_CRT + Vector Informatik + + + CRYPTO_ALGOMODE_CUSTOM_USE_DF + Vector Informatik + + + CRYPTO_ALGOMODE_ECB + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_GCM + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_GMAC + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_HMAC + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_NOT_SET + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_OFB + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_PXXXR + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_RSAES_OAEP + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_RSAES_PKCS1_v1_5 + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_RSASSA_PSS + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_SIPHASH_2_4 + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_SIPHASH_4_8 + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_XTS + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_CUSTOM_P224R1 + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_CUSTOM_P521R1 + AUTOSAR_ECUC + + + CRYPTO_ALGOMODE_AESKEYWRAP + AUTOSAR_ECUC + + + + + CryptoPrimitiveService + + Determines the crypto service used for defining the capabilities + + 1 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + CRYPTO_MAC_VERIFY + + + CRYPTO_AEADDECRYPT + AUTOSAR_ECUC + + + CRYPTO_AEADENCRYPT + AUTOSAR_ECUC + + + CRYPTO_CERTIFICATE_PARSE + AUTOSAR_ECUC + + + CRYPTO_CERTIFICATE_VERIFY + AUTOSAR_ECUC + + + CRYPTO_DECRYPT + AUTOSAR_ECUC + + + CRYPTO_ENCRYPT + AUTOSAR_ECUC + + + CRYPTO_HASH + AUTOSAR_ECUC + + + CRYPTO_KEY_DERIVE + AUTOSAR_ECUC + + + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + AUTOSAR_ECUC + + + CRYPTO_KEY_EXCHANGE_CALC_SECRET + AUTOSAR_ECUC + + + CRYPTO_KEY_GENERATE + AUTOSAR_ECUC + + + CRYPTO_KEY_SET_VALID + AUTOSAR_ECUC + + + CRYPTO_MAC_GENERATE + AUTOSAR_ECUC + + + CRYPTO_MAC_VERIFY + AUTOSAR_ECUC + + + CRYPTO_RANDOM + AUTOSAR_ECUC + + + CRYPTO_RANDOM_SEED + AUTOSAR_ECUC + + + CRYPTO_SIGNATURE_GENERATE + AUTOSAR_ECUC + + + CRYPTO_SIGNATURE_VERIFY + AUTOSAR_ECUC + + + CRYPTO_KEYSETINVALID + AUTOSAR_ECUC + + + CRYPTO_KEYWRAP + AUTOSAR_ECUC + + + CRYPTO_KEYUNWRAP + AUTOSAR_ECUC + + + + + CryptoPrimitiveAlgorithmSecondaryFamily + + Determines the algorithm secondary family used for the crypto service. +See Technical Reference for cipher suites. + + 1 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + CRYPTO_ALGOFAM_NOT_SET + + + CRYPTO_ALGOFAM_3DES + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_AES + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_BLAKE_1_256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_BLAKE_1_512 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_BLAKE_2s_256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_BLAKE_2s_512 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_BRAINPOOL + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_CHACHA + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_CUSTOM + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_CUSTOM_CIPHER_SUITE_8 + Vector Informatik + + + CRYPTO_ALGOFAM_CUSTOM_CMD_GET_ID + Vector Informatik + + + CRYPTO_ALGOFAM_CUSTOM_PADDING_PKCS7 + Vector Informatik + + + CRYPTO_ALGOFAM_CUSTOM_POLY_1305 + Vector Informatik + + + CRYPTO_ALGOFAM_DRBG + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ECCANSI + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ECCNIST + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ECCSEC + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ECIES + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_ED25519 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_FIPS186 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_NOT_SET + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_PADDING_ONEWITHZEROS + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_PADDING_PKCS7 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_POLY1305 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_RIPEMD160 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_RNG + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_RSA + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SECURECOUNTER + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA1 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_224 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_384 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_512 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_512_224 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA2_512_256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA3_224 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA3_256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA3_384 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHA3_512 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHAKE128 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SHAKE256 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_SIPHASH + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_X25519 + AUTOSAR_ECUC + + + CRYPTO_ALGOFAM_CUSTOM_BD + AUTOSAR_ECUC + + + + + CryptoPrimitiveSupportContext + + Configures if the crypto primitive supports to store or restore context data of the workspace. Since this option is vulnerable to security, it shall only set to TRUE if absolutely needed. + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + false + false + + + + + CryptoPrimitiveAlgorithmFamilyCustomRef + + Reference to a customer specific algorithm family custom container + + + + + false + + + + 0 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + CryptoPrimitiveAlgorithmModeCustomRef + + Reference to a customer specific algorithm mode custom container + + + + + false + + + + 0 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + + Reference to a customer specific algorithm family custom container + + + + + false + + + + 0 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + + + CryptoPrimitiveAlgorithmFamilyCustom + + Container of custom algorithm family values. +The container name serves as a symbolic name for the identifier of the custom algorithm family type. + + + + + false + false + + + + 0 + true + false + + + CryptoPrimitiveAlgorithmFamilyCustomId + + The custom value of this algorithm family + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + true + 254 + 128 + + + + + CryptoPrimitiveAlgorithmModeCustom + + Container of custom algorithm mode values. +The container name serves as a symbolic name for the identifier of the custom algorithm mode type. + + + + + false + false + + + + 0 + true + false + + + CryptoPrimitiveAlgorithmModeCustomId + + The custom value of this algorithm mode + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + AUTOSAR_ECUC + false + true + 254 + 128 + + + + + + + CryptoSheKeyUpdate + + Container for She key update, +Present Container, the She key update with M1,M2 and M3 can be used for setting/updating a She key. +Remove Container to save ROM and Runtime. + + + + + false + false + + + + 0 + 1 + false + + + CryptoSheEnableFid + + Enable check of FID. +If the check is disabled all flags will be interpreted as 0 and the keys can be used for each service. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + true + + + CryptoSheEnableCounter + + Enable check of Counter. +If the feature is enabled ech she key requires a key element with the Id CRYPTO_KE_CUSTOM_SHE_COUNTER. Otherwise the key element can be exclude to reduce KeyStorage size. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + true + + + CryptoSheDebugCmd + + Enable She DEBUG_CMD. +If the check is enabled the DEBUG_CMD requires the CryptoSheInfoKeyRef. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + false + + + + + CryptoSheInfoKeyRef + + Reference to a key which holds information's for the she key update. +Information's are: +UID key element +Boot Protection control key element (Only required if CryptoSheEnableFid is enabled.) +Debugger Protection control key element (Only required if CryptoSheEnableFid is enabled.) + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + CryptoSheKeyRefSecretKey + + SECRET_KEY + + + Reference to a key which shall be used as SECRET_KEY She key. +The SECRET_KEY is mapped to She page 1 and She Id 0, + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + CryptoSheKeyRefMasterKey + + MASTER_ECU_KEY + + + Reference to a key which shall be used as MASTER_ECU_KEY She key. +The MASTER_ECU_KEY is mapped to She page 1 and She Id 1, + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + CryptoSheKeyRefBootMacKey + + BOOT_MAC_KEY + + + Reference to a key which shall be used as BOOT_MAC_KEY She key. +The BOOT_MAC_KEY is mapped to She page 1 and She Id 2, + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + CryptoSheKeyRefBootMac + + BOOT_MAC + + + Reference to a key which shall be used as BOOT_MAC She key. +The BOOT_MAC is mapped to She page 1 and She Id 3, + + 0 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + CryptoSheDebugCmdAdditionalKeys + + Reference a non-She key which shall be additionally be cleared by the She DEBUG_CMD. This key will be cleared additional to the She keys. + + 0 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + + + CryptoShePage + + Container for a She page. +A she page includes up to 11 She keys. +Key_1 - Key_10 and one RAM_Key. +The Encryption and Mac constants are defined for each page. +The SECRET_KEY, MASTER_ECU_KEY, BOOT_MAC_KEY and BOOT_MAC are mapped to page 1, + + + + + false + false + + + + 1 + 255 + false + + + CryptoShePageEncryptionConstant + + KEY_UPDATE_ENC_C + + + KEY_UPDATE_ENC_C +Page_1: 010153484500800000000000000000B0 h +Page_2: 018153484500800000000000000000B0 h +Page_N: Not Specified + +String may only consist concatenated hex values without leading 0x and any spaces. 32 Bytes are needed. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + + + 010153484500800000000000000000B0 + 32 + 32 + + + + + CryptoShePageMacConstant + + KEY_UPDATE_MAC_C + + + KEY_UPDATE_MAC_C +Page_1: 010253484500800000000000000000B0 h +Page_2: 018253484500800000000000000000B0 h +Page_N: Not Specified + +String may only consist concatenated hex values without leading 0x and any spaces. 32 Bytes are needed. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + + + 010253484500800000000000000000B0 + 32 + 32 + + + + + CryptoShePageId + + Id of the She Page. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + true + 1 + 255 + 1 + + + + + CryptoSheKey + + Container for a She key. +It is possible to configure Key_1 - Key_10 and Ram_Key for each page. +Key_1 = She Id 4 +... +Key_10 = She Id 13 +RAM_Key = She Id 14 + + + + + false + false + + + + 1 + 11 + false + + + CryptoSheKeyId + + Set the She key Id. +Key_1 = She Id 4 +... +Key_10 = She Id 13 +RAM_Key = She Id 14 + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + 4 + 14 + 4 + + + + + CryptoSheKeyRef + + Reference a key which shall be used as She key. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + + + + + + + CryptoNvStorage + + Nv Storage + + + This container is used for the non-volatile storage of the key information + + + + + false + false + + + + 1 + 1 + false + + + CryptoNvManagementDataPerKey + + This parameter is for information purposes only and can not be changed. + +This Parameter shows how many additional bytes are needed per key element when it is stored in the NVRAM. + +e.g. 16 bytes AES key needs 20 bytes of data flash inside the NvRam if the management data is 4 bytes long. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + 4 + 4 + 4 + + + CryptoNvWriteBlockFctName + + This function is called by the LibCv to write a Nv Block. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + + + NvM_WriteBlock + 1 + + + + + + + CryptoNvBlock + + A NvBlock describes the mapping of to be persisted keys and a NvM Decsriptor. + + + + + false + false + + + + 0 + true + false + + + CryptoNvBlockId + + Id of the NvBlock. This value has to be unique. + + + + + DEC + + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + true + 0 + 4294967294 + 0 + + + CryptoNvBlockLength + + Size of the NvBlock that is actually used by CRYPTO. The referenced NvBlock shall have at least this size. + + + + + BYTE + + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + 0 + 4294967295 + 0 + + + CryptoNvBlockFillLevel + + Number of used bytes inside the Nv Block. +This value is for information only. + + + + + BYTE + + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + 0 + 4294967295 + 0 + + + CryptoNvBlockProcessing + + Set the block processing type. +DEFERRED: write block will not be triggered by the crypto.The block can be written manually and is written on shutdown. +IMMEDIATE: write block will be triggered by the crypto with validation of the key.This cannot be used if key locking is disabled. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + NV_PROCESSING_DEFERRED + + + NV_PROCESSING_IMMEDIATE + Vector Informatik + + + NV_PROCESSING_DEFERRED + Vector Informatik + + + + + CryptoNvBlockConsistencyLevel + + Select the storage kind. +NONE: none (deprecated) +DETECT: CRC layout checksum, checks if the key storage layout has changed. If the layout has change the initial data is restored. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + NV_CONSISTENCY_LEVEL_DETECT + + + NV_CONSISTENCY_LEVEL_NONE + Vector Informatik + + + NV_CONSISTENCY_LEVEL_DETECT + Vector Informatik + + + + + CryptoNvBlockRevision + + Revision of the NvBlock. + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + 0 + 4294967295 + 0 + + + CryptoNvBlockCrcLayoutChecksum + + CRC checksum over the NvBlock layout. + +CRC Calculation is influenced by: +- CRYPTO_ALIGN_KEY_STORAGE +- CRYPTO_NV_MANAGEMENT_DATA_PER_KEY + - For each Block + - CRYPTO_NV_BLOCK_REVISION + - For each Key within the Block + - CRYPTO_KEY_NV_ID + - For each KeyElement within the Key + - CRYPTO_KEY_ELEMENT_ID + - CRYPTO_KEY_ELEMENT_SIZE + + + + + HEX + + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + false + 0 + 4294967294 + 0 + + + + + CryptoNvBlockDescriptor + + NvM Block which will be used for this CryptoNvBlock. + + + 1 + 1 + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + /AUTOSAR/EcucDefs/NvM/NvMBlockDescriptor + + + CryptoNvBlockKeyRef + + Reference to the key which will be stored inside this NvBlock + + 1 + true + + + PRE-COMPILE + VARIANT-PRE-COMPILE + + + Vector Informatik + false + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + + + +
+
+ + Crypto_Pre + + Software Crypto Driver pre-configuration + + /MICROSAR/Crypto_30_LibCv/Crypto + + + CryptoPrimitives + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives + + + AesGCMEncrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_GCM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + AesGCMDecrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_GCM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADDECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + AesEncrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_ECB + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_ENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CBC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_PADDING_PKCS7 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_PADDING_ONEWITHZEROS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CTR + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_PADDING_PKCS7 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_PaddingPKCS7 + + + + + AesDecrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_ECB + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CBC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_PADDING_PKCS7 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_PADDING_ONEWITHZEROS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CTR + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_PADDING_PKCS7 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_PaddingPKCS7 + + + + + SHA1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA1 + + + + + SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + AesCmacGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + AesCmacVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + RngFips186Sha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_FIPS186 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_FIPS186 + + + + + EcDsaEd25519Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + EcDsaEd25519Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + SipHashGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SIPHASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_SIPHASH_2_4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + SipHashVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SIPHASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_SIPHASH_2_4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + RsaPkcs1Sha1Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + RsaPkcs1Sha1Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + RsaPkcs1Sha256Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + RsaPkcs1Sha256Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + RsaPssSha1Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + RsaPssSha1Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + RsaPssSha256Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + RsaPssSha256Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + RsaPkcs1Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + RsaPkcs1Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_ENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + EccNistP256R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + HmacSha1Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + + + HmacSha1Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + + + HmacSha256Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + + + HmacSha256Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + + + EccNistP256R1GenerateSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1GenerateSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1VerifySha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1VerifySha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1GenerateSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1GenerateSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1VerifySha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1VerifySha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1GenerateSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1GenerateSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1VerifySha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1VerifySha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + RngFips186 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RNG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + RngDrbgAes128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_DRBG + + + + + RngDrbgAes128Df + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_USE_DF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_UseDF + + + + + RsaPkcs1CrtSha1Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_RSASSA_PKCS1_v1_5_CRT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_RSASSA_PKCS1_v1_5_CRT + + + + + RsaPkcs1CrtSha256Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_RSASSA_PKCS1_v1_5_CRT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_RSASSA_PKCS1_v1_5_CRT + + + + + EccNistP384R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + + + EccSecP384R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + + + EccNistP384R1GenerateSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1GenerateSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1VerifySha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1VerifySha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1GenerateSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1GenerateSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1VerifySha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1VerifySha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + RsaOaepSha1Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_OAEP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_ENCRYPT + + + + + RsaOaepSha1Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_OAEP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + + + RsaOaepSha256Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_OAEP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_ENCRYPT + + + + + RsaOaepSha256Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_OAEP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + + + RsaOaepCrtSha1Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_RSAES_OAEP_CRT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_RSAES_OAEP_CRT + + + + + RsaOaepCrtSha256Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_RSAES_OAEP_CRT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_RSAES_OAEP_CRT + + + + + EccNistP256R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP384R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + SHA384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_384 + + + + + EccNistP256R1GenerateSha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1VerifySha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1GenerateSha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1VerifySha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1GenerateSha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1VerifySha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP384R1GenerateSha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1VerifySha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1GenerateSha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1VerifySha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + GmacAesGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_GMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + GmacAesVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_GMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + HmacSha384Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + + + HmacSha384Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + + + KeySetValid + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_SET_VALID + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + KeyDeriveX963SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_KDFX963 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + KeyExchangeCalcPubValX25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_X25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_X25519 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_X25519 + + + + + KeyExchangeCalcSecretX25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_X25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_X25519 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_X25519 + + + + + KeyExchangeCalcPubValSecP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcPubValSecP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + KeyExchangeCalcSecretSecP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcSecretSecP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + KeyExchangeCalcPubValAnsiP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcSecretAnsiP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcPubValNistP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcSecretNistP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcPubValNistP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + KeyExchangeCalcSecretNistP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + RandomSeedRngFips186Sha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_FIPS186 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + RandomSeedRngDrbgAes128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + + + RandomSeedRngDrbgAes128Df + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_USE_DF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_UseDF + + + + + KeyDeriveIso15118 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ISO15118 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ISO15118 + + + + + KeyDeriveSymNist800108CntModeSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CTR + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + KeyDeriveAsymNistFips1864Erb + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_FIPS186 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + KeyDeriveNist80056AOnePassSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyGenerateSymmetricGeneric + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + KeyGenerateSecP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyGenerateSecP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + KeyGenerateNistP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyGenerateNistP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + KeyGenerateAnsiP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + HmacRipemd160Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RIPEMD160 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + HmacRipemd160Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RIPEMD160 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + EccSecP160R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P160R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P160r1 + + + + + EccSecP160R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P160R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P160r1 + + + + + HashRipemd160 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RIPEMD160 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + KeyDerivePbkdf2HmacSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_PBKDF2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + KeyDerivePbkdf2HmacSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_PBKDF2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + KeyDeriveX963SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_KDFX963 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + AeadChaCha20Poly1305Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_20ROUNDS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CHACHA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_POLY_1305 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_POLY1305 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_POLY1305 + + + + + AeadChaCha20Poly1305Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADDECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_20ROUNDS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CHACHA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_POLY_1305 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_POLY1305 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_POLY1305 + + + + + RngHashDrbgSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + RandomSeedRngHashDrbgSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + SHA3_256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA3_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + RngDrbgAes256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + + + RngDrbgAes256Df + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_USE_DF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_UseDF + + + + + RandomSeedRngDrbgAes256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + + + RandomSeedRngDrbgAes256Df + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_USE_DF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_UseDF + + + + + SheCmdGetId + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_CMD_GET_ID + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_CmdGetId + + + + + AesCCMEncrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_CCM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_CCM + + + + + AesCCMDecrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_CCM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADDECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_CCM + + + + + KeyDeriveHkdfHmacSHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_HKDF + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_HKDF + + + + + KeyExchangeCalcPubValSpake2PlusCipherSuite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_SPAKE2_PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_MODE_1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_CIPHER_SUITE_8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_CipherSuite8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SPAKE2PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_Mode1 + + + + + KeyExchangeCalcSecretSpake2PlusCipherSuite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_SPAKE2_PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_MODE_1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_CIPHER_SUITE_8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_CipherSuite8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SPAKE2PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_Mode1 + + + + + KeyDeriveSpake2PlusP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_SPAKE2_PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SPAKE2PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + HashMD5 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_MD5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_MD5 + + + + + KeyGenerateEd25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + Crypto_30_LibCv_PaddingPKCS7 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_FIPS186 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_ECCANSI + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_ECCSEC + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_DRBG + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_X25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_ISO15118 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_POLY1305 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_CmdGetId + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_HKDF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_SPAKE2PLUS + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_CipherSuite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_MD5 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_CCM + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_Mode1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_P160r1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_P256r1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_P384r1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_RSAES_OAEP_CRT + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_RSASSA_PKCS1_v1_5_CRT + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_UseDF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + KeyExchangeCalcPubValNistP224R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P224R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_BD + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P224r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_BD + + + + + KeyExchangeCalcSecretNistP224R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P224R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_BD + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P224r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_BD + + + + + Crypto_30_LibCv_P224r1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + KeyDeriveHkdfOption1SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_HKDF + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_HKDF + + + + + EccSecP521R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + Crypto_30_LibCv_P521r1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + EccSecP521R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyExchangeCalcSecretSecP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyExchangeCalcPubValSecP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + SHA3_224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA3_224 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + SHA3_384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA3_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + SHA3_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA3_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + SHAKE128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHAKE128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + SHAKE256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHAKE256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + EccNistP521R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + EccNistP521R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyExchangeCalcSecretNistP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyExchangeCalcPubValNistP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyDeriveHkdfHmacSHA384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_HKDF + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_HKDF + + + + + KeyDeriveHkdfOption1SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + KeyDeriveIso15118_20 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ISO15118_20 + + + + + Crypto_30_LibCv_ISO15118_20 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + KeyExchangeCalcPubValX448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_X448 + + + + + KeyExchangeCalcSecretX448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_X448 + + + + + Crypto_30_LibCv_X448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_ED448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_EdDsaEd448Pure + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_EdDsaEd448Ph + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_EdDsaEd25519Pure + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_EdDsaEd25519Ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_EdDsaEd25519Ph + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + EdDsaEd448PhGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHAKE256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ED448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd448Ph + + + + + EdDsaEd448PhVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHAKE256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ED448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd448Ph + + + + + EdDsaEd25519PureVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Pure + + + + + EdDsaEd25519PhVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Ph + + + + + EdDsaEd25519CtxVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Ctx + + + + + EdDsaEd25519PhGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Ph + + + + + EdDsaEd25519CtxGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Ctx + + + + + EdDsaEd25519PureGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Pure + + + + + EdDsaEd448PureGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ED448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd448Pure + + + + + EdDsaEd448PureVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ED448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd448Pure + + + + + HmacSha512Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + + + HmacSha512Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + + + Crypto_30_LibCv_HKDF_Expand + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + KeyDeriveHkdfExpandHmacSHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_HKDF_Expand + + + + + KeyDeriveHkdfExpandHmacSHA384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_HKDF_Expand + + + + + Crypto_30_LibCv_IsPrivateKeyOnCurve + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_IsPublicKeyOnCurve + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + IsKeyOnCurveP160R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P160r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + IsKeyOnCurveP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + IsKeyOnCurveP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + IsKeyOnCurveP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + IsKeyOnCurveEd25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + IsKeyOnCurveEd448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_ED448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + KeyExchangeCalcPubValP256R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_BD + + + + + KeyExchangeCalcSecretP256R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_BD + + + + + KeyGenerateSecP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyGenerateNistP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + SlhDsaSha2_128sVerifyPure + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + Crypto_30_LibCv_SLH_DSA + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Crypto_30_LibCv_SHA2_128S + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + Crypto_30_LibCv_SM4 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + Sm4Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_ENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CBC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_ECB + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SM4 + + + + + Sm4Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CBC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_ECB + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SM4 + + + + + Sm3 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SM3 + + + + + Sm2Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SM2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_Sm2P256v1 + + + + + Sm2Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SM2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_Sm2P256v1 + + + + + Crypto_30_LibCv_Sm2P256v1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + KeyGenerate_SM2_Sm2P256V1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SM2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_Sm2P256v1 + + + + + RsaPssSha384Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + + + RsaPssSha384Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + + + KeySetInvalid + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEYSETINVALID + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + KeyDeriveNist800108CtrModeCmacAes + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CTR + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_NIST800108 + + + + + Crypto_30_LibCv_NIST800108 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + SHA512_224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_512_224 + + + + + SHA512_256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_512_256 + + + + + SHA224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_224 + + + + + SlhDsaSha2_128sVerifyPhSha2_256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha2_384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha2_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha2_224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_224 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha2_512_224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512_224 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha2_512_256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512_256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha3_224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA3_224 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha3_384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA3_384 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha3_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA3_512 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhShake128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHAKE128 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhShake256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHAKE256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha3_256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA3_256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + KeyWrapAes + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_AESKEYWRAP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEYWRAP + + + + + KeyUnwrapAes + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_AESKEYWRAP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEYUNWRAP + + + + + KeyExchangeCalcPubValP224R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P224r1 + + + + + KeyExchangeCalcSecretValP224R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoPrimitives/Crypto_30_LibCv_P224r1 + + + + + + + CryptoKeyTypes + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes + + + Cipher + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Cipher_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Cipher_IV + + + + + KeyExchange_X25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_X25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + KeyGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Seed + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + + + Signature + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_Key + + + + + Mac + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Mac_Key + + + + + KeyDerive + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerive_Algorithm + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Label + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Iterations_PBKDF2 + + + + + Random_Fips186_Sha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Fips186_Sha1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Seed + + + + + Hash + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Hash_Result + + + + + Signature_Rsa_Pkcs1_Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + + + Signature_Rsa_Pkcs1_Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Priv_Exponent + + + + + Signature_Rsa_Pss_Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_SaltLength + + + + + Signature_Rsa_Pss_Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Priv_Exponent + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Salt + + + + + Signature_Rsa_Pss_Verify_AutoSalt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + + + KeyExchange_ANSIP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_ANSIP256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + KeyDerive_NIST80056A + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_NIST80056A + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_AdditionalInfo + + + + + KeyDerive_ISO15118_ProvCert + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + + + KeyDerive_SYM_NIST800108 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_SYM_NIST800108 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Label + + + + + KeyDerive_ASM_NISTFIPS1864 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_ASM_NISTFIPS1864 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Label + + + + + KeyDerive_ISO15118_ContrCert + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_SCC_Contract_PubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_SCC_IV_And_Encrypted_PrivKey + + + + + CipherWithoutIv + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Cipher_Key + + + + + CipherShe + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Cipher_Key_She + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Cipher_IV + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Cipher_Proof + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_She_Counter + + + + + MacShe + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Mac_Key_She + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Mac_Proof + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_She_Counter + + + + + Random_Nist_800_90A_DRBG_AES_DF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES128_DF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_PrivateString + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_AdditionalInput + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Reseed_Counter + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Nonce + + + + + Random_Nist_800_90A_DRBG_AES_NoDF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_PrivateString + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_AdditionalInput + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Reseed_Counter + + + + + Signature_RsaCrt_Pkcs1_Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeQ + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDp + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDq + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_InverseQi + + + + + KeyExchange_SECP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_SECP256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + SheInfoKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_She_UId + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_She_BootProtection + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_She_DebuggerProtection + + + + + Cipher_Rsa_Oaep_Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + + + Cipher_Rsa_Oaep_Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Priv_Exponent + + + + + Cipher_RsaCrt_Oaep_Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeQ + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDp + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDq + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_InverseQi + + + + + Cipher_Rsa_Pkcs1_Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + + + Cipher_Rsa_Pkcs1_Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Priv_Exponent + + + + + Cipher_Rsa_Oaep_Encrypt_With_Label + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Label + + + + + Cipher_Rsa_Oaep_Decrypt_With_Label + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Priv_Exponent + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Label + + + + + Cipher_RsaCrt_Oaep_Decrypt_With_Label + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeQ + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDp + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDq + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_InverseQi + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Label + + + + + KeyExchange_SECP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_SECP384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + Cipher_Rsa_Pkcs1_Decrypt_Pub + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + + + KeyDerive_KDF_X963_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_KDF_X963_SHA256 + + + + + CipherSheRam + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Cipher_Key_She_Ram + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Cipher_IV + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Cipher_Proof + + + + + MacSheRam + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Mac_Key_She_Ram + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Mac_Proof + + + + + MacGmac + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Mac_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Cipher_IV + + + + + KeyGenerate_Symmetric_Generic + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Symmetric_Generic + + + + + KeyGenerate_Ansi_Nist_Sec_P256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Ansi_Nist_Sec_P256R1 + + + + + KeyGenerate_Nist_Sec_P384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Nist_Sec_P384R1 + + + + + KeyDerive_PBKDF2_HMAC_SHA1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Iterations_PBKDF2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_PBKDF2_HMAC_SHA1 + + + + + KeyDerive_PBKDF2_HMAC_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Iterations_PBKDF2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_PBKDF2_HMAC_SHA256 + + + + + KeyDerive_KDF_X963_SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_KDF_X963_SHA512 + + + + + AEAD_ChaCha20_Poly1305 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Aead_ChaCha_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Aead_ChaCha_Nonce + + + + + Random_Nist_800_90A_DRBG_HASH_SHA2_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_HASH_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_HASH_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_PrivateString + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_AdditionalInput + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Reseed_Counter + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Nonce + + + + + Random_Nist_800_90A_DRBG_AES256_NoDF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_PrivateString + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_AdditionalInput + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Reseed_Counter + + + + + Random_Nist_800_90A_DRBG_AES256_DF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES256Df + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_PrivateString + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_AdditionalInput + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Reseed_Counter + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Random_Nonce + + + + + KeyDerive_HKDF_HMAC_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Iterations_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_HMAC_SHA256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_AdditionalInfo + + + + + KeyDerive_Spake2Plus_P256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_Spake2Plus_P256R1 + + + + + KeyExchange_Spake2Plus_A_Suite8_1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8_1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_W0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_W1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Verification_Result + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Verification + + + + + KeyExchange_Spake2Plus_B_Suite8_1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8_1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_W0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_L + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Verification_Result + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Verification + + + + + KeyExchange_Spake2Plus_A_Suite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_W0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_W1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Verification_Result + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Verification + + + + + KeyExchange_Spake2Plus_B_Suite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_W0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_L + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Verification_Result + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Verification + + + + + KeyGenerate_ED25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Ed25519 + + + + + KeyExchange_NISTP224R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_NISTP224R1_BD + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_NumEcu + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_EcuId + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Intermediate + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey_2 + + + + + KeyDerive_Hkdf_Option1_Sha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_Option1_SHA256 + + + + + KeyExchange_SECP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_SECP521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + KeyDerive_HKDF_HMAC_SHA384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Iterations_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_HMAC_SHA384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_AdditionalInfo + + + + + KeyDerive_Hkdf_Option1_Sha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_Option1_SHA512 + + + + + KeyDerive_ISO15118_20_ProvCert + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118_20 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + + + KeyDerive_ISO15118_20_ContrCert + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118_20 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_SCC_Contract_PubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_SCC_IV_And_Encrypted_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_SCC_Contract_AAD + + + + + KeyExchange_X448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_X448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + Signature_EcDsa_SECp160r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp160r1_public + + + + + Signature_EcDsa_SECp256r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp256r1_public + + + + + Signature_EcDsa_SECp384r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp384r1_public + + + + + Signature_EcDsa_SECp521r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp521r1_public + + + + + Signature_EdDsa_Ed25519_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed25519_public + + + + + Signature_EcDsa_SECp160r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp160r1_private + + + + + Signature_EcDsa_SECp256r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp256r1_private + + + + + Signature_EcDsa_SECp384r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp384r1_private + + + + + Signature_EcDsa_SECp521r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp521r1_private + + + + + Signature_EdDsa_Ed25519_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed25519_private + + + + + Signature_EdDsa_Ed448_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed448_public + + + + + Signature_EdDsa_Ed448_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed448_private + + + + + Signature_EdDsa_Ed448_public_ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed448_public + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_EdDsa_Context + + + + + Signature_EdDsa_Ed448_private_ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed448_private + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_EdDsa_Context + + + + + Signature_EdDsa_Ed25519_public_ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed25519_public + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_EdDsa_Context + + + + + Signature_EdDsa_Ed25519_private_ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed25519_private + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_EdDsa_Context + + + + + KeyExchange_P256R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_P256R1_BD + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_NumEcu + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_EcuId + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Intermediate + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey_2 + + + + + KeyGenerate_Nist_Sec_P521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Nist_Sec_P521R1 + + + + + Signature_SlhDsaSha2_128s_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_SlhDsaSha2_128s_public + + + + + Signature_Sm2_P256Sm2_Generate_withoutID + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2_P256Sm2_private + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2Generate_P256Sm2_public + + + + + Signature_Sm2_P256Sm2_Verify_withoutID + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2Verify_P256Sm2_public + + + + + Signature_Sm2_P256Sm2_Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2_P256Sm2_private + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2Generate_P256Sm2_public + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2_ID + + + + + Signature_Sm2_P256Sm2_Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2Verify_P256Sm2_public + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2_ID + + + + + KeyGenerate_Sm2P256V1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Sm2P256v1 + + + + + KeyDerive_NIST800108_CTR_CMAC_AES + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_NIST800108_CTR_CMAC_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Label + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Context + + + + + KeyDerive_NIST800108_CTR + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Label + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Context + + + + + Signature_SlhDsaSha2_128s_public_ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_Signature_SlhDsaSha2_128s_public + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_SlhDsa_Context + + + + + KeyWrap_Aes_PlaintextKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyWrap_Aes_PlaintextKey + + + + + KeyWrap_Aes_Kek + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyWrap_Aes_Kek + + + + + KeyExchange_P224R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_P224R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /MICROSAR/Crypto_30_LibCv/Crypto_Pre/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + + + CryptoGeneral + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral + + + CryptoKeyElements + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements + + + Crypto_30_LibCv_Signature_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + + + Crypto_30_LibCv_Random_Seed + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3 + + + + + Crypto_30_LibCv_KeyGenerate_Seed + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 16 + + + + + Crypto_30_LibCv_KeyGenerate_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + + + Crypto_30_LibCv_KeyExchange_SharedValue + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + + + Crypto_30_LibCv_KeyExchange_PrivKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 9 + + + + + Crypto_30_LibCv_Mac_Proof + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 48 + + + + + Crypto_30_LibCv_KeyDerivation_Salt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 13 + + + + + Crypto_30_LibCv_KeyExchange_OwnPubKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 10 + + + + + Crypto_30_LibCv_KeyExchange_Base + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 8 + + + + + Crypto_30_LibCv_KeyDerivation_Password + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + + + Crypto_30_LibCv_Cipher_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + + + Crypto_30_LibCv_Cipher_IV + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 5 + + + + + Crypto_30_LibCv_Cipher_Proof + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 6 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 48 + + + + + Crypto_30_LibCv_Mac_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + + + Crypto_30_LibCv_Hash_Result + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + + + Crypto_30_LibCv_KeyDerive_Algorithm + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x00 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x00 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_X25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x00 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_Random_Algorithm_Fips186_Sha1 + + 4 + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x00 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Label + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 130 + + + + + Crypto_30_LibCv_Rsa_Modulus + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 160 + + + + + Crypto_30_LibCv_Rsa_Pub_Exponent + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 161 + + + + + Crypto_30_LibCv_Rsa_Priv_Exponent + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 162 + + + + + Crypto_30_LibCv_Rsa_Salt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 163 + + + + + Crypto_30_LibCv_Rsa_SaltLength + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 164 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 2 + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_ANSIP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x01 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyExchange_PartnerPubKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3003 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_NIST80056A + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x03 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x04 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_SYM_NIST800108 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x01 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_ASM_NISTFIPS1864 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x02 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_AdditionalInfo + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 131 + + + + + Crypto_30_LibCv_SCC_Contract_PubKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3013 + + + + + Crypto_30_LibCv_SCC_IV_And_Encrypted_PrivKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3014 + + + + + Crypto_30_LibCv_Random_Algorithm + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x01 + + + + + Crypto_30_LibCv_Random_AdditionalInput + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3016 + + + + + Crypto_30_LibCv_Random_PrivateString + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3015 + + + + + Crypto_30_LibCv_Random_Nonce + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3017 + + + + + Crypto_30_LibCv_Random_Reseed_Counter + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3018 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_DENIED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0 0 0 1 + + + + + Crypto_30_LibCv_Rsa_PrimeP + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3051 + + + + + Crypto_30_LibCv_Rsa_PrimeQ + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3052 + + + + + Crypto_30_LibCv_Rsa_ExponentDp + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3053 + + + + + Crypto_30_LibCv_Rsa_ExponentDq + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3054 + + + + + Crypto_30_LibCv_Rsa_InverseQi + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3055 + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_SECP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x02 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_DENIED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_Mac_Key_She + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ENCRYPTED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + + + Crypto_30_LibCv_Cipher_Key_She + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ENCRYPTED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + + + Crypto_30_LibCv_She_UId + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3021 + + + + + Crypto_30_LibCv_She_Counter + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3019 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_DENIED + + + + + Crypto_30_LibCv_She_BootProtection + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3056 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_She_DebuggerProtection + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3057 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_Label + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3058 + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_SECP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x04 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_KDF_X963_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x06 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_Mac_Key_She_Ram + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ENCRYPTED + + + + + Crypto_30_LibCv_Cipher_Key_She_Ram + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ENCRYPTED + + + + + Crypto_30_LibCv_Cipher_2NDKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 7 + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Symmetric_Generic + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Ansi_Nist_Sec_P256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Nist_Sec_P384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Iterations_PBKDF2 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 14 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 4 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_PBKDF2_HMAC_SHA1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x09 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_PBKDF2_HMAC_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0A + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_KDF_X963_SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x07 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_Aead_ChaCha_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_Aead_ChaCha_Nonce + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 12 + + + + + Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES128_DF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 2 + + + + + Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_HASH_SHA2_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 3 + + + + + Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_HASH_SHA2_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_DENIED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 222 + + + + + Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 4 + + + + + Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES256Df + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 5 + + + + + Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_DENIED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 48 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_HMAC_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0B + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Iterations_HKDF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 14 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_Spake2Plus_P256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0C + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 5 + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8_1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 6 + + + + + Crypto_30_LibCv_W0 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3084 + + + + + Crypto_30_LibCv_W1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3085 + + + + + Crypto_30_LibCv_L + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3086 + + + + + Crypto_30_LibCv_Verification_Result + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3088 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_AdditionalInfo + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 131 + + + + + Crypto_30_LibCv_Verification + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3087 + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Ed25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 3 + + + + + Crypto_30_LibCv_KeyExchange_PartnerPubKey_2 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3004 + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_NISTP224R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyExchange_EcuId + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3007 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyExchange_NumEcu + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3006 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyExchange_Intermediate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3005 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_Option1_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0D + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_SECP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x07 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_HMAC_SHA384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0E + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_Option1_SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0F + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118_20 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x10 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_SCC_Contract_AAD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3060 + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_X448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x08 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp160r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 40 + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp256r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 64 + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp384r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 96 + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp521r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 132 + + + + + Crypto_30_LibCv_Signature_EdDsa_Ed25519_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp160r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 20 + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp256r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp384r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 48 + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp521r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 66 + + + + + Crypto_30_LibCv_Signature_EdDsa_Ed25519_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_Signature_EdDsa_Ed448_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 57 + + + + + Crypto_30_LibCv_Signature_EdDsa_Ed448_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 57 + + + + + Crypto_30_LibCv_EdDsa_Context + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3061 + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_P256R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 9 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Nist_Sec_P521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_Signature_SlhDsaSha2_128s_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_Signature_Sm2_P256Sm2_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_Signature_Sm2Verify_P256Sm2_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 64 + + + + + Crypto_30_LibCv_Signature_Sm2_ID + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3092 + + + + + Crypto_30_LibCv_Signature_Sm2Generate_P256Sm2_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3093 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 64 + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Sm2P256v1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_NIST800108_CTR_CMAC_AES + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 8 + + + + + Crypto_30_LibCv_KeyDerivation_Context + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3061 + + + + + Crypto_30_LibCv_SlhDsa_Context + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3062 + + + + + Crypto_30_LibCv_KeyWrap_Aes_PlaintextKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + + + Crypto_30_LibCv_KeyWrap_Aes_Kek + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_P224R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 10 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + + + + + CryptoNvStorage + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoNvStorage + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoNvStorage/CryptoNvManagementDataPerKey + 4 + + + + + + + Crypto_Rec + + Software Crypto Driver rec-configuration + + /MICROSAR/Crypto_30_LibCv/Crypto + + + CryptoKeyElements + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements + + + Crypto_30_LibCv_Signature_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_Random_Seed + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 20 + + + + + Crypto_30_LibCv_KeyGenerate_Seed + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + + + Crypto_30_LibCv_KeyGenerate_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + + + Crypto_30_LibCv_KeyExchange_SharedValue + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_KeyExchange_PrivKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_Mac_Proof + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 48 + + + + + Crypto_30_LibCv_KeyDerivation_Salt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + + + Crypto_30_LibCv_KeyExchange_OwnPubKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + + + Crypto_30_LibCv_KeyExchange_Base + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + + + Crypto_30_LibCv_KeyDerivation_Password + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 64 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + 1 + + + + + Crypto_30_LibCv_Cipher_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + + + Crypto_30_LibCv_Cipher_IV + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + + + Crypto_30_LibCv_Cipher_Proof + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 48 + + + + + Crypto_30_LibCv_Mac_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + + + Crypto_30_LibCv_Hash_Result + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 20 + + + + + Crypto_30_LibCv_KeyDerive_Algorithm + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_KeyGenerate_Algorithm + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_KeyExchange_Algorithm_X25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Random_Algorithm_Fips186_Sha1 + + 4 + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Rsa_Modulus + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 256 + + + + + Crypto_30_LibCv_Rsa_Pub_Exponent + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 3 + + + + + Crypto_30_LibCv_Rsa_Priv_Exponent + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 256 + + + + + Crypto_30_LibCv_Rsa_Salt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_Rsa_SaltLength + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_KeyExchange_Algorithm_ANSIP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_KeyExchange_PartnerPubKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 132 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_NIST80056A + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_KeyDerivation_Algorithm_SYM_NIST800108 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_KeyDerivation_Algorithm_ASM_NISTFIPS1864 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_KeyDerivation_AdditionalInfo + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 5 + + + + + Crypto_30_LibCv_SCC_Contract_PubKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 132 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + 1 + + + + + Crypto_30_LibCv_SCC_IV_And_Encrypted_PrivKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + 1 + + + + + Crypto_30_LibCv_Random_Algorithm + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Random_AdditionalInput + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + + + Crypto_30_LibCv_Random_Nonce + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Random_PrivateString + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Random_Reseed_Counter + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Rsa_PrimeP + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Rsa_PrimeQ + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Rsa_ExponentDp + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Rsa_ExponentDq + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Rsa_InverseQi + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_KeyExchange_Algorithm_SECP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_Mac_Key_She + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ENCRYPTED + + + + + Crypto_30_LibCv_Cipher_Key_She + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ENCRYPTED + + + + + Crypto_30_LibCv_She_UId + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + Crypto_30_LibCv_She_Counter + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0 0 0 0 + + + + + Crypto_30_LibCv_She_BootProtection + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0 + + + + + Crypto_30_LibCv_She_DebuggerProtection + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0 + + + + + Crypto_30_LibCv_SCC_Contract_AAD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 34 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + 1 + + + + + Crypto_30_LibCv_KeyDerivation_Label + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 4 + + + + + + + CryptoKeyTypes + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes + + + CryptoDriverObjects + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects + + + Crypto_30_LibCv + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects/CryptoDriverObject + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoDriverObjectId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoDriverObjectQueueSize + 1 + + + + + + + CryptoGeneral + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoUseVStdLib + 1 + + + + + +
+
+
+
+
+
\ No newline at end of file diff --git a/Source/bsw/Crypto_30_LibCv/ChangeHistory.txt b/Source/bsw/Crypto_30_LibCv/ChangeHistory.txt new file mode 100644 index 0000000..eeeed02 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/ChangeHistory.txt @@ -0,0 +1,77 @@ +/********************************************************************************************************************** + * REVISION HISTORY + * + * This file contains the revision history of the component implementation and all related artifacts. + * The revision history covers all released version of the component. If you have received a development version of + * this component, the changes made in the development version are not referenced herein. + * + * Legend of Columns: + * + * I - Implementation + * G - Generator + * D - Documentation & Technical Reference + * T - Test Implementation + * S - Specification + * B - Build-Artifacts + * + * Legend of Cells: + * + * X - Artifact is affected by the change. + * - - Artifact is not affected by the change. + * + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author I G D T S B Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * main-1 2024-04-24 c6oechsler X X X X X X CRY-462 Component Migration + * main-2 2024-05-06 group_433_bot_8918be7e278d67622ccce09cfb7f4951 - - - - - - CIA-488 Renovate Update config/common digest to fdda146 + * main-2 2024-05-15 c6oechsler X - - X X - ESCAN00117308 Fix ESCAN00117308 + * main-3 2024-05-16 c6oechsler - - - X - - ESCAN00117308 Fix merge pipeline subsequently + * 14.01.00 - - - - - - - - - SemVer release 14.01.00 based on main-3 + * main-4 2024-05-21 c6oechsler X X X X - - ESCAN00117308 Fix implementation descriptor + * 14.01.01 - - - - - - - - - SemVer release 14.01.01 based on main-4 + * main-5 2024-05-22 c6oechsler X X X X - - CRY-900 Correct implementation descriptor + * main-6 2024-05-23 c6oechsler - - - X - - CRY-902 Change memmap descriptor + * 14.01.02 - - - - - - - - - SemVer release 14.01.02 based on main-6 + * main-7 2024-07-04 c6oechsler X X X X - - ESCAN00117427 Add maximum size of 'Other information' to TechRef + * main-8 2024-07-04 c6oechsler X X X X X - CRY-827 SafetyAnalysis AES CMAC Generation + * main-9 2024-07-09 c6oechsler X - X X X - CRY-829 SafetyAnalysis AES CMAC Verification + * 14.02.00 - - - - - - - - - SemVer release 14.02.00 based on main-9 + * main-10 2024-07-26 coechsler X X X X X - CRY-953 Unify usage of NvMBlockLength + * main-10 2024-08-15 lmangold X X X X X - CRY-892 Support RSA PSS SHA384 Signature Generation and Verification + * main-11 2024-08-21 vismwe X X X X X - CRY-957 Support KeyGetStatus + * main-12 2024-08-29 coechsler X X X X X - CRY-955 Support KeySetInvalid + * 14.03.00 - - - - - - - - - SemVer release 14.03.00 based on main-12 + * main-13 2024-09-11 coechsler X - - X - - ESCAN00118169 Compiler warning due to conversion from uint8_least to uint32 + * main-14 2024-09-16 coechsler X X X X - - CRY-825 Key Id equality check in KeyCopy() + * main-14 2024-09-24 lmangold - - - - X - CRY-823 Analyze R22-11 documents for LibCv + * main-14 2024-09-26 lmangold - - - - X - CRY-850 Analyze R23-11 documents for LibCv + * main-14 2024-10-21 coechsler - - X X X - CRY-1145 Improve internal Safety Analysis Documentation + * main-14 2024-10-30 coechsler X X X X X - CRY-1090 Support NIST SP 800-108 CTR Mode with CMAC AES + * 14.04.00 - - - - - - - - - SemVer release 14.04.00 based on main-14 + * main-15 2024-11-08 viskju X X X X X - CRY-1231 Support SHA512-224 and SHA512-256 + * 14.05.00 - - - - - - - - - SemVer release 14.05.00 based on main-15 + * main-16 2024-11-15 lmangold X X X X X - CRY-1109 Support AES256 CCM + * 14.06.00 - - - - - - - - - SemVer release 14.06.00 based on main-16 + * main-17 2024-11-29 coechsler X - - - - - ESCAN00118414 Compiler Error: Syntax error in Crypto_30_LibCv_KeyDerive.c + * main-17 2024-11-29 coechsler X X X X - - ESCAN00118765 Incorrect parameter description in KeyElementGet()-API + * main-18 2024-12-06 coechsler - - X - X - ESCAN00118833 Add CMI for AEAD decrypted data + * main-19 2024-12-13 lmangold X X X X X - CRY-1101 Support SLHDSA with pure and prehash + * 14.07.00 - - - - - - - - - SemVer release 14.07.00 based on main-19 + * main-20 2025-01-08 coechsler X X X X X - CRY-1360 Update internal infrastructure: Switch to esf-config + * main-21 2025-03-04 lmangold X X X X X - CRY-1184 AES Key Wrap + * main-22 2025-03-06 coechsler X - X X X - CRY-430 Support Process Signature Input in Finish Mode + * 14.08.00 - - - - - - - - - SemVer release 14.08.00 based on main-22 + * main-23 2025-04-08 lmangold X X - X - X ESCAN00119740 KeyUnwrapAes.c and KeyWrapAes.c are missing in Crypto_30_LibCv_rules.mak + * 14.08.01 - - - - - - - - - SemVer release 14.08.01 based on main-23 + * 14.xx.xx-0 2025-05-26 vismwe X X - X - - ESCAN00118376 Add validation and configuration hint + * 14.xx.xx-0 2025-05-26 vismwe X X - X - - ESCAN00117783 Compiler error: unresolved external symbol for RandomSeed functions + * 14.08.02 - - - - - - - - - SemVer release 14.08.02 based on 14.xx.xx-0 + * 14.xx.xx-1 2025-06-16 coechsler X X X X X - CRY-1599 Support ECDH P-224 (CFG5) + * 14.09.00 - - - - - - - - - SemVer release 14.09.00 based on 14.xx.xx-1 + * 14.xx.xx-2 2025-08-13 coechsler X X - X X - ESCAN00120258 Compiler error: vSecPrim_initVerifySLHDSA function declared implicitly (branch-14.xx.xx) + * 14.xx.xx-2 2025-08-14 coechsler X X - X X - ESCAN00120735 Out-of-bound access when using KeyGenerate P256R1 (branch-14.xx.xx) + * 14.09.02 - - - - - - - - - SemVer release 14.09.02 based on 14.xx.xx-2 + * 14.xx.xx-3 2025-08-15 coechsler X X - X X - ESCAN00120484 Out-of-bound memory access if configuration parameter CryptoKeyElementVirtualTargetRef is set (fix on branch-14.xx.xx) + * 14.xx.xx-4 2025-08-18 lmangold X X - - - - ESCAN00120928 Diffie-Hellman key exchange P224R1 is missing in pre-configured primitives + * 14.09.04 - - - - - - - - - SemVer release 14.09.04 based on 14.xx.xx-4 + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Documentation/TechnicalReference_Crypto_30_LibCv.pdf b/Source/bsw/Crypto_30_LibCv/Documentation/TechnicalReference_Crypto_30_LibCv.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b1d8e59eb68ccc4997367a868a981c270536255d GIT binary patch literal 387770 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

XNVT=G_or| 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

!**_SmH?t@iahOcLrYKw$ z-zHs5@2bn|uHQktqRM1uRr(5KlJp?bLQS2Lg7a4M%;E!S|2Vr>p7Qp6BC7lfOv(!x zK3q&GcMRG^k}_{0ZPQ%9mn|{{$bG>rkW;eT^a`#!w$}@7yX&S3Y>EMY6Y0OSN5eJ9 zpuHM=9F;Wn9^&QS7*vsG!OVM1tg{=eZ@R%00oWRR@hU9*M$zgNu@C&tgg4o7@bgR~ zkCn2<@;g%tRj?TwtI4ba;RjB#`oqTnxuFm4<@fL;)B?xV z>W021-7l9TtjPAyTf5xu#p>eg+>@x|71E-m&D&ou4@6^R^gemJ=u@lhy_@mkzf4DG zX&IT=2NW$}-WRfgw#U`cL0lcAN?4cW$ZaF~zfk^kKt;4Q*=6~WY4foFPYfr^d1^%B zI}KeTuD`5uF0|gW{R%z_v|SIQdm1sgI!OLCoYXLtO_dZ|TNPNDpJ#nM@W@1TtHElt z_!aS*is@I1)2WBYM{h)4H`X`m(YjX$a(L2qbRfw*rAyi**`@b3wE#=uDT@SivJ`|LBgqH|$4j1~ z+`}ja8YLAO;N%OA4X65;3>kb2r{-;?K zoTjpOMMM{@k**+VE0WUlN15(uuhXCd`>uTS3G4kL+WbXp< zO{YQnz(7qPtlrfEh(cc08Z>u~0Kc||dqN;AQd(N~@ELE!sc%y>mMC7Q^Bf5$empsI zXdf%(e&?-1hJzy53zlp*)q>LYF_G46yu$F(Ai!HEQhS3D%tEySY2W|a^O}}o^mCHY zb#Ae{BdI_$ffmE{`pGRR(Y{y0EM`Y;EX7f2xK75m0UbC8i|}g_ZiB)X$x%7t75UJt z<*8pWW`0QdExJo4ycWNjQ0X&>?m=K4^9cVWmyhyN$w7*ZV&*4;^v~bYlr+Fstvkx8 zVC|)Dg~)+er@c0jaRXpiqAu+8FxKunTkNvU3RK;a;p`WpsnSMoMWV2+$HobrQA$8m z3YJFRW^o?C#S8-=w%WbH?wZgfnn1f^Xx3t05Ozg8lg{)POS_zK2*wc+MhHU|9T>W| zm?Z_WKh{*$Uf{ztC~qV^fX9#%BtgWFfC-0U_okqw`Lq_N!ci4F6lVJf{P=F=9yC+a z{s|}1W22t;r?R2G65;65E|Y%(3&Y9)gj~4+x6q(ZLQPmrnah)O;e?j2b?2(s(&A(m zn*E1mc+S*f3azEEc~!KtXR$l-Kh5hD=G@EEb~^Yh{n&Jo12CLi8%#qBTuGMyaj4gp zD1h+}S5_8Twg?&`WcLQ-CcYqbs8JZ9MBad13Bg0)NeU;Hb@iuBI3qq^W^mcUvijZh%+LWEdg~(fxK|==<5Z@!O8!yOCTPKpVW3-+QxK{sm(;6K4c&a zcoIJ>a7m5e*tPd9Bayz|Ul1j_B;1lK&heGtVa7_PojrV3qbftb7>4x{pD|O|iIOuh zo>B1P%*votvFJBzy)tmi)QLHO^HO^uPre~M@a40rwRdyW~){HNeY(^5Ad;BFydxX1y57Y6_^gR=Jn+apmg zdm2PupiE7@phAF{Q>Y6xUx@RB;Uc;xia}`_CZK202i8bbPKd%VY@fHxEz_dX{-+FVh599pfv8?Fr=Nn=a1<47LE&uL9=<#LAUKr)-#qIU znj!_A*%_o%{OHjP2UGuE7_K^-lYw3)xp#KQXx3xJ_oaTd#0#2u8zdb@OJO*&ff{}n z9Qp~ERRSyoJ+J62!ApPmRpK`O3 z+K?*b-v_80TCDnTpo6vUEG**B?(%`m!5PN6YDKVDg#Q+tAOZMd;LDw?X?GE0WiYdk z1I`wb?9M}CUnvjp2tGp_iGo11Xz_?#*jl`UD3aFrpvr@N#CN$26O^Cjl_Q#L_$Q6^ zLLdZCzK({ac6e!$Qr+?6;o_DTp}E3KqJJ!*Fluy}lI;-tZ};}Qq;FaBww*pyxy%5PltS4aDquo^;I9piE*rX`e)gO*JQ0&Fplig@X^bXTK@sxcfSD=yD(Lq4}bHlnGfqi`G@A_S;;j7S&hOThh42a@<#g zhY)}g!{nQ?nFZ9&n$(bvZj}!`g`k4B z6~$*$VD=MR)8gkc>`VMM7RkDxGvVOGho@n+PMzV8Jh$boZRuDuCk_{9_DJqB)_`4z z*`lAH7+4T} zcltH&hw|WF6hAIm)^kl(AJluoK9-7ip#GgQh9*3K0_+jZY;$S0#vaeaW~y<|L(RqlgD8@ zUBBIM!R0@2ET?z6Xs-OFXpU5y>?4peZ%4Wzf6YxF){1wyJw>iY3kX)#p{@9?!@TFI zS5nzB2g(7C=d-v^h`KI@T&+1#00pm*A~=B&If(WjB%~3(^#?QM4tXr>>gNJ(aHw|F z$C`M55Az<9pS`&g{{|$8ui1J6T%p1b;_~D1Zp-7kTy2<}M5Y1d~mh2Sa8@SNjGxK67#VY!LDRczgsU>u~mwSP1u9 znxYV{MAzRbtlBRD_L|EH&EcEX@ZS<>8Hlr$e#I;APS)yUSN?V}yrMGLn*>&(rs`jo z#iohhgTu$x=o19pLkGTqz7a9BvCtfA4+eO>H6xxmVO$8YjeVxnv&9W)5K!5Em0O?9 zXkdx80)drKszU$oL_+SBv}Alf;C}@;{Es~N|A~z9|B|)vzvEQ>KcOxBkK_|xcJBX% zI2fEd8O*1OEVf450jNIrP<2mbpx8JQm1sa?pY#;NT7@NG4qy-T+gKB^6W}vA3yx@T zG-r{cO?Q)toA-wmII1DZQ)H5<4QLjsNQwQVFxT-D)$*%9kf0KN9D72TSZi7csCwf& z6!s(Tx(C+pxm|dlH3a(BcHXb}et2TT!TuLf6iGv)m76ikwI`v=Rg5N9_xJKmihjsu z_!DS%+*?b^rR>mw^xcVjV*MuE&32=A2ydGEeJO=hSOdK9Q&943pgo?M!w^fbaYE1Q z(Kg_hvb$1dZONg$7Ri=X*2Yjf>&6HWI`S}0S*XrzL-z7(P@mQ;DVao#lVWF)@?|+#+-y-+X?%0V{Fmhb$a4wmT z*7(qDH`u12QW{M1$RM}l>5qcr=(qYuN2mvmT{d^}_cgmw21%Rk-swH3r9lY%`C5e= zjYvBqckK<7rLZ!Q0rxe|UD}0@Z=HbtheLUZ?GfkM=1vRq3tz3to>_nqihFhT#lyFs zKW7Zmb>~dbIOc60@xB{!IUKygPY%5@(!1|p_#QVzQ4tXNIYt4Rjy#4wd+-w%r98-T zHJ+1#`iEE)6i6OJH*3;mR8r;B(3NdJh)>q=9whfp(OBbkH$k$4%8iEuyl+=6r17bS zLXejC$Qx-}`KZYzViKjKovpN1GbJ72gNNd&c^}=@?c~n!9V&OVp~d=2vi6;EoDP}% z?Zdw3IvKs!7L!1`NB}hO_ufXIoYKx08;-L1L$f}X;>vMw;dU$1h6|yN#IJNz9avGe-m{_SP0Fb`yqh7z)vYeH=ibQT z^H7c%M&(f}W&s+s1lG(Yh41MTjXCUs{t$47^7sqmhM5SlL-Qs;u;7}#Wfq8+%SsR@ zzCD?Nx0AH?kD7~CU%RF*@NQsRJAV*kYAENDKNXm0xD~GnEj4<77oGMQ;B_1xG$xyh z`q-w!M13{f12mIG>ZAnwbg1wNN7uG57pQYS!e@*;e3q%%1%|h(_L&P~GA}L&-~phh z){pvYZC2nAB+T2%X2DO1Z8hG%Q;6eJ{NuX|{k6*lrbL@Mf~73tE``~Gjf6x$Lchl| zYm8AtfJkTo%t$5L8n3H^GaujAF%rKgb$Ig{JiL7b7h%N-aL=^yzTOh9EgG;?TEa;R zAGFbK!vyTl#kUJH<_ZVa0@e`2AyOTm5#{g8kOObya0ITwGCSmC@3Hocu1iN9^GB^{ zogUjAp#uZ9aI_@~e>4abcPfGNSdB|E^Cpz|$~_zqZb;+fn(w3nvcRd>QwCP`ZNJ3* zr9oQa8fGQysu_NNC%iBHWunZHfuU*%*=XmHf2*G(>sz~qP@zn2KRRXjRU)hAZqFzE zE+Y}7uW}fJv|!KjnPqqwD1+njJfZHCOCQ}f>_e>#5i@EZcB|a{*WjI+dW0;DG_Cgs zIxw64*bTyI2(Kk_tMVKC6;qfVq7E>Xz`od7{a?ESq({UZJ}GysY)I$No8;>;+OVpB z_%SGZQUamf4ZIe)Xc4#iuU6_h)LAPbl7%qH3DvZI@Nr!-koj^YEZ?f{im+{c?#K1W zCzy1^DNH}uKL1Rpl{j|s$!2v#Jy1k(efnLY!#L4C&SHKBSH!zo!0B1ZGI_*oNr0Wq zN;kpu7h5$Vu6^T6lLnVxNDp11gkF!b1509UEPC`n`bCe_UQd6#WpQA$=rtUR)Jxdz zv_xIkf|fB~c_sX#<4$D{$RZ6G%IZ$x6SwK2(oduj(rnxEDieV!Xu*6r4??(3<*7+> zdfWe1*Rx2yA;mg$R~5X4EY!VLd3AYAeRlZXkD!V%Wk(kJI6NM!o#GS!7ae%veaTV%x!K=<1Tj(kTd8%xp)2?@WR1sxf}w zm&Rz?ayb+3C50qL?UH^dy(LJZ0gi^iHh z|NAK^ca$o#!`07f)pTr=?XefvW1`VWpa9#INTt)*c@G|(?!)WlQR0ZgWlm5>cPK;> z2!o;*9SV=}3q}B6>eH#0BfU!TNz*uyC|L-Sivu zr=L+Y&G7|>`_-PnFKU)dqyE5Jbrg~~kDMuJ_h#WgsE8H@pYmTT5rVk)548OXc)zU` z+jS14Z%_1wIx6@5_F3Ot%Uim*T`< zya#vfPYMnv4ofl1A^Hbj zLour$?mie{SM{|TUsE|-VhPEjYw=_|BzvED`Ig4e&d!=>HUV3AuVfU{d<>L%S+=i8VOm*a1Fmq$CyhE;g95%g1 zbqMrnfEVVv9XPrpBK{`xBEOUJ47O>R!DRKry#)^-DXlt*U((;r7GkN~sMbz*6%=i; zTQPR=p1JMd zqBLrJE*%YI|IO}DcE184sJ3JDFBWoAZP0(0@Sg`zUt>??)Yv%{5O0VKU$7<5r4b&gTxqn| zDMU+ASX-25B*(tn#soK`Sd7cne9DJ{3svPD)!J>iuWxBbyXNli6R8z6W3GM1`$=#G zk#e7B8gHhyWF)c^UFCzzwMwXs2z+1DY`DyAoVnT_P09Xe&999~4O34{szrE-@dD$9fYM^qglGcYOKTaK(G0IT*IvuN_ zvj6FHIwvZK^Dkbt`%{@lo=#LH_C)FDd(AlACtY5THkFSM8ZRw0ZKPxQ$8jbjCE9gB zLAWIAg2SLsoL|#?D2u+5hS_pxc)~?}Xy(2h5!2C=6C=>s;G}86r?ZX+d?JB&!Zwmx zHV;*iZZ-Z8dmSD#&&sz!)+XVR-D`klWao0c7|dZ;!}y75r>Z<87&gLcyd|=BZS*3z z@;CM&gVE3~j+4`p*B^K49L&c1l06La^H#{B*wQx2Yw9=ZVlGBlX+V!y+ z>ht5aveuVmB<+t`hI7Q~I;yhTzal8*%F+nU&WrIk;iswo?%WOn?9r$33+2ibM{8LM znfdq(Tt=U%{c*zd+O>EQ(~HiuDo>*U2jNbtkZL3_k()h-L*>T?P)&Szk-1SYoxmx`v-EEcQF{k&sTX`m~x!@p+ zy$svZshUUKL~*>_cvjNHmS}~GF2^hY+o8RbGC}TfESks`zY`=pk`gV^#qpi@(G_AV z)8UWmr81D~T;+ZYYgC?eTiOL>!%#FLnV7-3mBiI#DZ3K$1C^kh`i29}&!H0oQaY zQL#srGi}re5(NF#r5;rKo9mfI$Ay$~I=2R;UG|WYfz`S>XD!s+PLii#u788B7y!+bbv0l*yI~!x#Tr7^50~{dpWO_`dVaXd>yLQcdshr_=Y>7SE zY-5ZjOT$5ZY-intLZV%MkaRB}YFKC>lnn`gvi<2OAtBcF8Qfh$#yWF#H0_tOM>_vq zNz21hv@M5X+Hm7cuagkMh=jx$=aBOqK+e?^nO(a zj7%{oGW$MFmo#^&)(I)*!uLM)9`xghbQ~tX-XWxHZ~~m*3$5aVsizegtN=x|CSFU|_njq)|%@A%`HLk;F^5w>Feff+{57 z9{deV_9oq4!7DnPQp`KZ*kg8OpB0qLbb{#ncrCwj`gRL@FAp>D)XSBn`c0OJ-wD@< zD!ZbQ&Nw-(>Wx_7*dINxt}meJG1AeE()cReGTBKa%pZl-Xo+-t*QTv2hhEOEUaz>HuDlmAn;?gXF@!>h`u@i4_;8gm zg+da^qiIqb7wWNlrEmjbRJs8vsgbap?+Jk3>Fc1}w6B~a;Sm4P=?ge&QxC~o~ zhZwbD_(=;7%w=anUHB$-nFx#1ZhY}-0}+ZCPFz`yNaTDma=c)K7SedJEGF}@C$2A1*v=FImdN#&42Ss54MqsW4WRhaBim0~-Tv(;WyV5Zy!G%<1Y2VxM|7a= zr2U3i@s=q5Vbtu1gMZui3%cYoB1pQ`gG4e?zL`d*uF>#^TezD`I?9*vqF!I`|K~k5 zb_<$eMBCv>S!s{}LRlVuAb;h*ftnM|jbzPQbiR=jpt#>!cprP*9JUQ$=RyaINjnq& ztyX7*y4rE$t9o~h1bu=feTpIVqi)w>F)|%<>+NR++JHHzj`hMz+wW&I(Wr4F+=acK zu4Vr{X_2ituLSG7Yc$Hq1ddNrUWN#&A2i#52H%J^uA(6GX4zR)GJi}ED{^cxv~F;7S>6<^J^;{>5N4z{&&acHMD4Vy33JGjCB3d21|}pshvo?oDWxaTSfz$1&A3 zpV3By=rP1Gf)frk>7>~v^^@+iz-Nt*!_?sP)|0ox+;rry-XJUGALuI-vd2I{6k zIOD19$|Cd*ZngOJ!}@ILc?1%<7oBcAY;CJfT&g?w)^Q`XPq~%P%%P!Pl^}^Qq13De zletgv#czLa;A*-AfdQXS86ib$#$MIkavi1<9*wYzkBc2@EvCitE0c6a5APClzu}=t zCa7lVtBnTvyx$m>c$!LsJ%2T{z08JulY1f9w`-A2X*V-1_ffJS8kjl1)3eIjG^+s+ zR(SsOLY4hDUR7|jTHzWomPv*&0}iY-;+MH`TH|e0xBb;ya*de)=_gy-Hba-RMu4}v z;t5Z)*%dM_VkQM#kNcSx?0$ODHEQ6zN z{|qQ2;}6##t7_2iQ=QB69%j<9YrkPXNjN|98ewXJN=~C{gi@YO)eX|edNMeK)6vCi z|K$0aHejpBm4yV8cO|XS2bXTAy!hxFatlE$i-h*vc#9U{lnk7%9B@jw~LT79wyUr#blhY*R39Y19Fc|Y(J-0k>`cl%7~ z^DUci{+~A&nib!vaCnIuQ{=J^kr1}meu|A_$2Zy(8D+^jn<#(4_bWMb5T9Xo2i`d~;@C?n;x#t(Pt|cr?SFGbcIkb1m@Z(hJwbl9Rthm%lso+XxDQj1y z;EHgRw&dJFTwYBa0!tl!6?pg#_nFlwJJpqF7dibU&Z$7(VeLz^Voe0^6SUfQ@?>T@ zLyGhq!guMD4I1(M@Wv5UXC+L2jX(>-?x97FrGzleXpVmlaN1C(ej|FLXR|Uhz*os; zVpDdh`YyJ&L}_aw`WEMZN>NKi^OG_J>#FRc z?|KJVojG74VKgKwohKw2LV~g?n2Ir$(<2`3^apt~n;2RhpgWk{L z(g9OWM~37G(U067Jjn8OrFZa*7>rwMy}9v`dB*qhWV-n4O2hIp91$;oHVsj7i&6eK z&?dug{cdz~90eo{&e{mY0^T&jf(t7iZ7(cNisc}qjo0CA$EC;wkI@y|l~MyQgTn7` zrTeY!fkhl(j*?f&7YqFUZmn-{Mt{hyukYSv(vcTk82nO~SHoWWKC-#)hG2|Tar_E0 zZrc@IUH=uVuEKsdU4o_#D`$rT7cxAq*m2XgN~mvD{@tL#hn$ZUsm^`24X!P71uyY% z!p44D7}dJ}S0WNt4;5_Wfbp-jeLs^pW6mM#%A~BP(X~~{>9Ay&6e$!xDUBtG46)LA zIU>(OCm@mBx1MzDy2+JQ*jB3X;bw^Bn9TJH9uva>@(`Phb(U0L+w7iW%#I;}(Ql|m z!fW}>RoLo+A4D_u*^ZNM$T&DRO<{C|LWXqtX@RZ~qNXlW3%^A7{iR_z`xdnao}MQn zS8TXV2G2#dOQZa+z7^1k-ZGk3* z(Oz@@zcda8Y4w)x({ZkG)?K16a80}}H)xJb*}|2-n&JMZo>*a)ms4L`z>>JX;$NI| zHJk!*aN*!NU!8oMmCrrTahe-1m2(;s zas3G15dIZ#TVC_-QFmDjz7q<1@znD8?yvDnIk)C{v>xTZ3NGru_*Ei~>VXP(c)3O~ zLs@tk57By_=$5>LW2U=RZZ0b?cB@0ez;*nq?U>oS)$kdMM+O*ouo?n#j70i&CCb#J z{P`p+ra?q4NB5YPE$@tn7sk=&PM{(_7;u$hW^3hr#No$`3E2Nrr07ln#znH_Pm5#e zTci-9A3ApvT|8CV2Lt{7RnFgkyjlL#CUCFc>a_aAx_Pb~mG?z3eZw!-@b zC)5r(!|vvzDK~+ii3z^@J=D{E@yt`&-TC|I7JR9z{Ad4>X=c6_XRTCDz8@WaiNBCXMSXs6^-`%E$!fCFs3VZso-((QW_Vu>fjSonhBAqjwmd7V7r`JyT@F1 zTdvqXDqE2iB7zEXLk9QL3#=0WR7dfJy}I$h<@-fDip#!f?{WT|w^qKjPj_3Zj(O%T zPlTAvL^4#?4{81v_u2}XsaS8zS+%(=4eI9Rc_~WmH*IcwOlW$OE7#Ra{xl19oJ=)a z;DCYdQI~&yGdCd3wRfBqiTb`W%?xZoHDYIRUVf>pvU+R#p!L`8%L7e&aE(W_`cf?@ zBxeeW(7a3d4Q=(k(#`@AN~wkNI3Zd`ZrO(xO9Lq zM8wLdl~(X~te5uRA1LCW3H??f$b$e7Ep?%FCd>TB~9q|5b&zt8UrXbv8Kk2-UZQh5qBFb>L zKs{E*bh)v}WFMYQRFy)?yW&7XGIJ$A@`sVypsdR8fxKy>wo>z+5D2=#LO|2?)27Vz z9p@0qx}FSB!fIDbZxXZ<$J-39<22)dr0&P7F04t`;sO)37SnF*p0!>9>Wvx zB}i1r^XNX1*nxr|jLF&@!H%zYwW)r4RMVv}Cw$=C*deDquCH=1#vnysrO44{^@;;9 zp;G*z?x~~u7cOxz=p5B^>q+Jy=0NIaLG#;wB<=#*FY|5m4wNII)?YycHp{=#?mBKy z6Kx>PEJl$>8pgh5AV*jak~-X4S5>_kPKndH}KqgnG1FG3!nDUl~5 z*B3b|-9j`N=&S?6(Tv8AyAI}CJf75;XzNmOU{llsc%2T3@x#X|#3qcvQ{UnHplgXu z2zRbLG)d9OjIw%qO($C8@w@SSZaZUnf0+c2hyM!e`4{mu5fg5mLwTdYOVB9BueEkH z6vOAcF)W(5os_ZZKX_+1A_5mPX66EGlO)8qNDy{P?f)R|ETiIRo<@&DAh;~<7HkP_ z!95UM0)a(>1OfyC1XvxDU*VvlH$A5nFeGND*R0ZU>YE?&C#3FrFpt~8{tie?cE zM-bnUT@+o};$>ASQ3`|t72mbsXA->f$A6mFG~w(9UY`fOZD<1hHqH(KTKt|Z)oE7l zSQ>Ze_|}SnZF;5Kr*qVvDROh9vx)I~EQnJ{;>L+Iis`MBboed>05u=wQjP7abMx8;y2gl zs4M)p%{ABL#%)Hswo5+i!n_JK7aPXyj%;Z&eOsDk5-sP9;*1pOF}uv-96|lL;L~oX zp5^?_kk|KyvqC%BC8pNy70~0rmswTzDJ!ux*X~>8T4DOuEUD+v#qYSF`DBPfO5-dH zEvuTF_OiYgCGk2hrt)GVSNdhous{JTwnC?f1%GGu3|2LUYm-G&^{sW8Ylz=W?jp0+ zOLns94im>T5pIBU(CM0iPq)dx-Hm;`0pdDOwS)`2jT_^_)-fTUq0i`+50+e_!Gtl( zrfR4g0Q4?l1Rk#Z5evtn1I>z{94Bp#p)>JfuS0MeL+5wxB%l5KqZYt&1L+vRL*TTE zM1uNBNs!#;H%;owgv0J)HcCgHa5_8t$iji6zKF6Gq!}EXf7?`$!743qWXZKt53@4FIR~dJgp8S)K zb=9eJoz8c#GH5)#3x!U>CqsNA*B>MXr|Ep<=IY_+}4DdL+E!c z^{~@5p{LfnNN#`NYsn!~0#}nBxBDJXQR9H7>LA0f6|5@zCQ%&YjgRZ~{^s2G0RhhZ zIP2{6BncR9M{*fRW`8xRi)3l(UQ8$&L0^m#6nNnN2>lP2v)C7?w__Lxr$QgK?TKiJFdEuC`%Ia-z>*+K^#z{tu+?c?L|+Dvy7x@DthAQX3 zFp+EHi1#UTg#sn(+7V|%AlMo{GI1$MdT^UVMnJ`{w;_E=%h9OBlx`m{E(m!z zgvNHvPf=mBkL9*!&d^pw88-DbT7*$kIZv6bqt;L1Q3ekxFWJMrS&O@mXQbgCmE}mo0l@W42Uz+MEGVvkZeS>BAfZG`--wytc*bnDd1{G#H>rLI;!(tl3w$0dBc133$!i#CG78yG1yp+BU+#KA4`ftaA?5wTAM zxvptqvX=>$>ECZtHKF2u<+AR_3cI#7^Su-8I(` zH9gb0#ds+7>l>nHC#I*!rB8~HdG$pPD!1gnn&eg?iJ(AD? z_!_|@NUwd8{~)$^A&@1*eZi7MvhQ%*l`;4ULOcqvpEY00N}s3f0erR8y2TDIfgnbA zYaoFtW4#atY6#vRuSEWC72BKgUr8Tr|11aV<%527x!5ZmkE)JV?5gsXFVAB-PcRnY zK-uq4urM?_gRGfmQf#o-r>Q!2*}n+~+TL0u4w@ieR+FZ>s_DX#@y_7SV46(qSBcGc=#(5?V)qg+M)OP?d_5?SPxb?FM%%6!+`Tsed zj-;kQuY%U}XjoyN&sH6=SD%NxH?#$LLCM`7d3rv-|7tS3H~huexqUhqX=e74>B>ZB z56hp1X)zEb$9yJpjoK>(QgS)V%f4qPNdM`v$gM~KRK7=HATiYOUrTni-(ocKr}M7M z$rAIqg<`QXDWOJ%$ETf)r6b6qVHR-pEkM})w=4dD-gKhI+exZKj!%codu+pcbD~&= zK^)U8DV3)hhC!v{h99AeYsrS{T#Q~$x5{li{a;cu)6;i-o*LuJN@+nEAPx>ds(3Xx z$Dqj0=Xp%zli^g&Euk0*TWi9$ZBEm~U!`@dKde~LU%F>F`o&sehg|(i`BG^`byS2l z(Ur)7l^!~~2(#4c`igNs<`E$Jmo3Cj9_x)inWO$tgVY739+3}sWixE1yQNLs(DlEK zujO2c)m3<9Hq>E}o4p}au#E=l|H6^>Q5P(BHh+hhsNN;o;dF<^37@{K(*3lQH3pg$ zLaFZu%&5l5qNZtHu=N;p(t3u_M1=nEEjJ@-`i!G*J7^K?%qfu7rYWmbz8?})de=N( zK&=n3Rf|5Rr{_B~W*r}C-U@S8Y-Z|T4>zxP={ex*r9A&TYv}-g%$ZT~(hrlvIwrwA zqU&6eR#zGLBK`7rf2w$HE_Pb5VQU zPc$W|4Ppb^Lzl0VSo$N&TCZQc0BdcUq#(^@tRGq1cdpij;shI2H{Cg|>9F`_|vDtw{TY0H515V}Lb};iafpxgJA*KK=eUmOT<(qB8ZOk1lyNJQBKy zMmP>w2;|4BzE*}=w-YqksXu9NNrlK}6@NjS{+HS%Ms_JX;ke$xqh5#c8)IQ-_lWY% zQjXrWK;juV%MMi{&SYnM^-oEKi(Bcil~8NzvNp|DCZ^lmGzdZVd0N9uNj`$as2ueE z{yeIugSb~^y-bnqNY|@HNFder5Spl857R6}6Ozi|4l_8Qea9lu!O!tIU3mH?KmvT* zXM%gQWPXxBFsA2=PClrYyvKG|sgYHQGKhNo`V^4Wf5uU^(Ywgb6a$1i6Y_OoZLxDu zt&%@GD(hQi@67_nROpI_7ObX0J5UixhQ8>wiu;xN`GLORQ}_bKC2R`CC6og-{u#sw;KP2bpXZaX z#B=(;sRlA%9|>grRYJWV(H{6cTJU9@QeOsE{pOGHn@(_bO$J_;o0e#AVGIKF*DsH6 zB9_=G@=V?gcuon*cfb67`iL(*lTIwZGk+%Kf4PGWTz&ht*0ZW;$uSt+LEvRe1na}g zD#TC6`Nyul`IUk?UUQ0tq`d!@FYM({YEW35yNww&;-5F`N}3h-Pui6jwd_A{@qSw4 zcyamzPB+ZPRX;r0T8pH&(?N4h(9_lKf2nc&Mr35&{d7rcTN%#{ExR^lx_t0n{dl+- z=IK64_WFIuW!@*Lug7vta@x}@04fD&;a9IIndNAG&-}m(3;s6n+^AQb;X~Qw>@~V8 zHcjV!fsCk9EA>O)2xl&fm;dBHhR!pR?m4~SS&0R{Q&A8&qE?BL2f|BX_p3A_YI3O&U7kB9$x`~R=c zfq=!1XJqGhl-B>1dH(;JkNW?!d0tR}_dh~KCk{IODH3z~zoW1Q=+J(C_3utZV#_7| zTwC`;Mql5Pm=1q~ud9=9p(3H#z1Tl4h+V&8C>T)Bmyfp{$}}XR{^o1wXUX44ShDo8 zpNZrWd(l5%#nsbrTm`hJ`>Y?kXIdF&rtt3FEgu~L&L70}p?fZ450;tkyD2GaD1IUT zP84=nf1JqvdZ?6vt-}p>^GkV3`~d?@bxjqaY~MMstSgF}3^{8az1#lxj~)H9{A9PS~; zp)r&!67)Dr;8^3h1bZ>|g>|l8GaVvcyu&^LMaXZAdW{}_lzL2IZH5YAWUl_;jgW7T zc{8E^yZi@hxP0ZYsUV$`TARCz82MvaJ{JY3{_NKTvBdt6H4*j|G}rhEj(zXvQn<;$ z8KtL<|MB*2a8}Xe;Y36X`tIrZ0m;3;WCOmJ1lb;U@yYL}2dVBId=Oayi$oB0t?>^U zp1*6#@?uxZ@KnyEgC4F@C%xGhAXuJwSCRRnA|>m~T?Tk|cJ?E@^fuk2+wBK3 z)i70EEzZSy-_}1JlHJ-+%(_!%e2pm%V3VDXG9tMmv_B-ky>p5FUCApR!<$L8HOA)p z-WyA_R77%Mj_`g#b&q&hs>;Jx!oE&bulnl8Us#JR%WkQq;8cAdGLQ#X9g)D7^D$zfCQ2)TT?TD2 z{KyK!ZS~C(ciNEL=m5lHU7Va}3g#rPa*&LfN5%@HgID0u7&Ka~VS-nD1HUSoAo))= z)!)DvPgp;8MtEWG=FF(?B+^1Fm$?LuoW;lwIEln5EDmgr2`$vKa|FZtGKYU2#7PQ3 zJHDC9Ro*jge+Dr;to4Qy3V<}~K+Ek96sC_C+Vpz;&wm8QvHY3zvN!AgZ0fj(`g-4n z{mtAz^l;nmqTkk_(P3C;|JlIXNKo@;Q8fD0z=KTapieh{_hXSw9{mbdXK;|5*d?5X z-e`hD5gM8(T1o&g!M|@no&MDBsa;qq`qZdLoW8DbV=<;e$8$k^T9E^S>(FH`au*nK zSXa`oWY+gQw3f9k0YXl7<1)Lh2V z;Q9lt_3;VMSm4*kd80Y%fM*dGFZvEY!b{{5nAm-XsN$aO4P+|+ck7H;U}pBBYR7$+ed7VW+|0qBU=&*9xB*YN;7i1obTuyr^dEznE6>+hP@vFT7NZ z#P_O@fuRoOn^Es+COb6K0gpAA@TgIYR`~S6ROY`>DtpmApa2YAH;KQoYOT z?6+|PWf2l|e~9-zX@WIIrT3V=3Vx8$T6S>5PorP3H;*MyC8;A^MpJp2p`Znl{k0yz zHUr6bq3h9$v#Sn}Bjs}rI!x2vMC0i^ba2krl|IJSE%T!igdSTxt%OG7An6o=V;_E)))eCo1B(a>mOKg{C>8h@;rp4qYkYiO_3@FkKWS~=mKg?O3XEQgp~pk=9Jia0gMDTk|Pw_9M-Cvp8}&}GC%qQ zsgEJKv4*vQl}|gHb0SrRdB9|{_#uFS6z1zdEgA@tWL~B-hO6ZkRx)C)ao#m1c~!Ew zi3SN`+Dm!w$lM&PGY8}J+6QcgfSl`+>tPl1Mn#!sQ7vZBp{%_i<7wg{b!ovA_Bqc) z+pP(?nFhl7pd2tMCv8XO6?Edls2>W%F+OE_zh{Q_XbVtfp)~$%F(jca+^i7g`>aL%@|L^7?nkuVWq&u` z!%#DOQ#`5y6xFFIs<;mL(OyAm{RzG5I>4k`!{0hOizTDq-{&B)%{&C0Q5GxE<_G&7 z4)p)?kx zcGx>?TabQqXY9^recDfrUr8+mG@nQG1f$wf>B2McX`;XD2>JCq6uE|eD)~)BWIa7q zk8Q-(FbJna+YyvRus<}{Ksdfw`63Xtvl^;j&Djeen3!T}G2C~PkQl*i7zDVQxwD`K z#6|$0MnzJ?KaLh3$G1;H1TYa8sR)tNqwIKSk|HacaXaaUeiJdnSRwA&Sj7@Z3U}Fq znRog`NH#pYa|m@9L*z-@Sjua$62)TZT5tt2N7Q7n>4r%p;%)`L#EhfG2>)R(9cbhI zVS^=U$ghd<+KDjs{pC-ul%C&xX2uyi%GBl@LmU+V5&8EW7SA(n;V@{oe@nZ2)v!Nu zX+Dh)k>)cF?D1MH!pe7mm??IJ;>6Vw)Bvh+y=kkb@4;Fn;`c1=Zxq!i-;YBM4We~Hk|RHki~jm zC)lWu>U)lG-?z!u58K}%W(>N|BS7oi;0i~k+b*Toi*9DN1LZ-z0NoehCib<>pKvAo zF8qY8T+#vSE<}0L;2yV~0j?surYmk%vW9RLv!L(~Vv%7VeG+tDlV6C;y?&lPx3Yxx z{1VWpDtdSSV(AzKve}psRzTXln{t_nlYP$i)@N19)XOd_J@O+<)Y2D|1 z1HGla^$^Er9KOW;msPq+NbNH)O*DV#^~KeYTq5*`{{6ES?^W5a4eQ#TjIt*&e`UYW z_mdogH%oFVHU?%In2f&?5O_Z$bf+h-_K0!#D4EImA{}s1-xJ?MKHI zdOp^8-%;J7D$H*4F?dN$YuM4w8~N24hpHu6KpZeemaqhsT9ORc3cvSzw7_={Lgn6$ ztevM}1*mU2T-5=2K}M-STR0g7_a8@_<0p<`bz`)y)f`u!L11*v5%g+R4CG*EJTyxADc)2pH>?V%eCDhxBOpyQEF@ z$R~@n)a|AFf;S}mEhb4=*qw7q=iTXbaE+4taw<#xu`0&5PHd3G;eeZ){N2g5Cn|8kY4n*QM*pU0j{4-))P%mKk!>o@f$a|*eokv$Pq$W zc!#czS?9#q0Vg@tJ=lIS4%0$CpCJmE(8*I_3EUSCc0Xm2(TjilZqR(1bacoE& z;-W?e$R_*-gBo(W%8;#WtT8-a-z63c|fOj7gpK-i&fagy!_%!~m~9^X@xA2M(8wPGP?E>-ej{o4#m4C#8OZ)$ z9c@{$>M$duz=teg;pNs6?hXi=(FB|WNiyBygL8TB@DK79h~6jkxW~VG>q-a_-0(|j0ysoTVX)w3fgbPkh{(7 z!k-w#dM?vSp7g8!fc2Gvh$8xTV4HmUXevV&5jCNSr`zw zuM}!I8eRrmJ1p8uA zAEUNNK=AMDA9=>G+k=6CN|MFRcE6G~l)8Qmbtz>|jBZxAGO@kjBer539q!Ht*H052 zOvMfbVH0IlHaXt-)sEKlX-{Y_w0D1UZ|T!GE91bi0>`T;M)Tu%HV;k26V@1rANh_{ zEJzJ3ED<|Jn1h&E5X7hR#Y`?N24AeGuV?KV8iWq}So!g*>9dj*0rrBo{?F|i*8{J% zr95K_VuX0fdy?LFuWn2R*)J* zj#4Q_Q~yep+yk`lAB9w)>hchGrlJt}#pVG3`_ewiK_;rwEgs=P*NGBT`3n!a(wy-t zMY_7;YBvk=Yc$Y+pq5v!G)uEbPtwenhY45ws*}(11jKUtJ0=MAQh~ZD{Y>1r!z(nT zGixeLpAh3JQ7dWM9V1`Zuf;iuSz+w{ns~7)RUx6WcJyK+=1ZM?gn9l z^`!rafmxw~)-_`QU)=s$i+{L`7I9Pf2LoFqkfWEVUQo*xgC0Jg-Wn-X44Z=blAzzT z=qp7T37LZOg+b>D_V~tIIr7bu_qm^t*cqDwkCw@=(<^_G@ba!wg>%v6TfKfsAtV@} zNFfCJE5JRUXkG~UV7cFB^ObQ+V-!8))0Y~!GHD4W9H~1c=h>pbkpJ>GU`p3D!;tVD zGRV0|W?GKR&iO~aixC@WG0*>qqf>+FCW9(@Aq74qDuHzBEt&w{ST!Z=7aVbZPv@wu zre~V11e3c$yw_9aC)80|_?$8Y&LNg<%xBISmpP%3V%qW12J z;zcIT6NirJBJBE?&!d8ZD_IT6m3h2Dgu7J2tU-tIllR|SR@=@Nu$sWqR zTI$KFO%5A=kJ;F=tB``+#3ykmLuFOdPCT-6F5&%!=my6a@EZF*Y^$wHLh)RV{+8!k zq!G_9_a^#tr8m+1bpTKpMS(q>#{bsE)#Wvm+c+<8+2wwsv2Z?V6yQ~|+}VbhLaY)` zV2=(>?qg7u5t%ECE|c7}nCmajN0Mt3`kHKhDAvSx91EPC+H@OI`Yt9H%FeQP^YeyD z^Mhz}@hdHtb^P-bHC6$SAvz(sav*Kza&*>7Drrof2cA`k7H-epMP zGljQeQrBCbOy#)H_pzwAU~Gy*J`!GM4U**QB407y!Y}Nv+VV?Z#R18C{plPQ`NUg! zm>W$MZIIh!1D>43JJ$F>Oo2;{TVaOCayd0wOB{t&uW??#4);+Ixb)WX2NDnnilbM2 zx1EnGM5w)dCiZ69MK1CaK?m_wntsK4{09%)RDEzTL2W0!`QrGR$NxzEDHEv!GQ3fB zH=Ontg%&=L^?WY6FsgiEaV*Gv2dPc1Be&51Qx!B*r~J-GWcphx0=(97ghqVJ)&>5Yx(x~+-tNh^HVXJe zFl%jo(ujC6dA~lR3;|LHx~p@#gk2WD3?`)Wn9LQ~vS`(}OtGxe`7)@OXEzb@&+aBB z9`FqpPbdFKu$v{gF`BI8>H}1EM;r2++`y6T!~~e8#EzJe#mI}tsQMdDhCn4^g^xWYi*xHuKQf`KfK|HX+gtK+lwy;+MpqeqLbZ&qWND|FDGT&fF#CD% z>krU8z14&Gn5n*CV?gy`?)X&gRY$SZ{M$#eog@C(qWiFU`A=;>(Q6r?Z5~G|wxXj6 z3SK*7_>~BxSP}YFN@nu6iyy+2RbKU(`VVU3klN5WB1c}Mgz z_dQsue_0GCFJsn9V>}kwfKoQb z&5i$qyshu(>^_2gAr|B`8&qJHclhgCF-7P~b<{?cd|l1aA0iep&;i)IZddFp8PU6Z z8XWx*f8z<|Q0(k1xu|zLb89L+)jGWaFW|jjEg76!!%eLG8RPU!xd#EJdPV%f3=@u< z-7ZC%O|HA&!vOtW{OHa6>eoCN)hws-#T6J?`L&216ou=~il_pr~JNwV1$a- zG*7B*hspvnC|=ktbzE{>)^w<9^a>L%dBm=^dS6xb*rfeFi?#+0fI8rJ@FvnJ6W=_*}^BVx<3X*ccZj-V{gkp816fMbDMI1Uuz#p^Af#A6Xx$8+L`X zS&yY|f7P|ADk>?nW@i7wd&>Il6V)|1r<=dr2k+YP?k;f3A7e z`+obUR`;6X%91QbU5tP*W`zxnp- zep>F!mY!ASF8V$>^VQYR%DgKu>MN)dM1ZK;jsR<#ALL@EaEE@Ytijy%1=i~vqMocO zmbv#MtW6b(&djx09QVzF9R{l>l%8c=w5@1695jm7X3$2JWn?6H5lBz{t>70c+G%YE30{WokZVf96! zCQ58#<5qeejD1C8V_|;%3c3p%J!3VFrLqzP9p4c_ndd#}I)c_>nUFSaF*WZ%&088Pv%1B^lFejc2-DbuzkS?^2p_vST1$J6=%A4ASq!mf3e%zM9_^Oa4i3x zVgb(fW`|`F*iGvJ_2+?iVN3nX@<~#$^%FD zKe@{Mn^1;59!^-gHs4|=NyV>n#oIDK2CDE^6cGP%$m#Ih7>vzlqyZA z@|m4KOoo*L4?asWc}e_v56c!MO<3MAL3>1RuuYXnRY+L!qwKhzdhokIvd;z?b(Vm; z>$+H3GO!ZI8ZCZ@STjFF%$g^kP#ggJdVyVbX~84|%pXvrpj*aQcIx96#^>M2%(T4XlEUU0BRW zeJHMPh-6}4G$}}x25;iqRKI!0lN9xlA%4a$zu#jX3RQUL^1;I1tvSWcCndIWeX`cM z5u;o5MnDP>@Wy$Qw6-er&*OK3ot}TJPNrB_bZ_w-^>!o$DNPurnvU( z71ssYa)oQpZqEPT#0~HKx%>)aQ?lxbls7y-3XG0WVR4fUW7!LzweU?AtCSXq`;P?1br72nzW<(^u!OI z9_7D;nYr{%&q>RE4N|-8PdYc(f5lvm6=?vcZ)VmTABM~lLnN@pKX1QvW%NY3ZMLnG zTR;Ev{qn(nM*|r&%rYgd$IOcd9&9X~_hW%dLm!O2XLHs&tT-fljs#a@eP@ zI&Q4~7@~8bktD&O%-&U_pv|Fz0#L?J7 zrEHMYIYI9~6oyrd?Tp#VPy+=`IX&iS3h7*^Vf+UWc9a_?95QEBnP@ADIRUklRW0GFq zO7BDif8ycTJW|~)2XMh>BNJvGmX5p+F0vBCrr$Sa{MNwyuuOddDmX=^^tse#zKjc) zd)Mv;ZC90m6+2YD{VXc+`{X`olG^ZWM7(8BbMmH8;YVH2_$RL0-de-7(yh`f{ntiK zV*zU@m0(X<3Ghz5SNCq5{3s)e(3%M2vmY~Q(T$sW+u?8~QOW?|p#MU>|IN7Gc~m2W zr$_H{^{0>)xhB61m{XW}nAm%+2UKLPvQoh}Gc;aDlO)I0u8s}jJd>MFF#7TFU2auv z%51<}s}~@rysQ9ckC+?q^xz0XUxiKgI-e`*Qc`OB_*OoX;%7CB3dNkT-=X~)MZYz0 z3C$o&(xwLutJP}t^Kmv&^fT7{>1CHf8D-iyNNt+P>CfZz2j&hJgVVN9nb2$Upa_BTL??)I;lXN`y^}_R#^b% zGjd+eq8_BlWUYRmXpCp4p6$X%N^YELk^cvu7O5@iK+yU|Nb}uO6J-t3TfTgZlLC3% zLnSSRY;LX=qKCF6nfjI1w)IjqSt>cqfn%E@tY?JcDFg_jn1eDzCsjkk_3WT*7I2X|F zM+*!0UGd)hDuO~J0!u7c(BjAoZfH5Y}W;~c5x|UlFUC#a$h|~}iEt_6=EQlF_=6eu}OTUuE z6OCv?LF{8QZ6noYAl^U!jE+VimP5+`GU&BCy+0p1;c_iSjK=M0w;-Vy^5voJ z7@6qIYyinF781gUxJVf#@;QPYL3KXc^JA~`{q+!UH{l8m(QD{PCI(@FDI5{3T3^dM zw2GSGeyNzb5wDhESj!2MM} zSr_x3F5uV$HyW5zCGox6Dy~I^2};s-hES~VWfDD`NOxFa?A%Jf3B6P!B_ptg5Fnu14Nw;EcO$=fg`NNm8BOAQynFiF z^!(6RSW^Hsz2M)jg$=J`^}D-Ok#9;D#R6R{2t9Bk-^lm`<r&57R_OWGyi2^N%=wQ2PJZ})r9iT&5`hlTe_UpK);<4=R4!B$pw|}oGAU@; zR-MYcl>{*x4jp`Y@oYQ9i}oJf#=OQvv&YAsF?k{)_47w;R4dbG^o%rI=i+c zlY>gN|LCsmB;vlw5Ets^O0u5C&6@ZRw_3{VN!E7iKxG~~4Wx-Oj}5Kgm{_CUZh7NW zo~lrF+`TxWPd`n-j-F%oS2X?fmUoinub<7`E4=eGsIw6GM!0d!j~8`rYdPf{G`=Kx zWTwR67fBzIgk`d4Q!!7!tO1}KJd~+GQrWvCEs3jqzTN9au)g-q@MMf>8?%NIAa+-G_wXYK8ZFpu=*KK4UN7P zApOuv6B$4P;^w%IJF42*{SyUiib&p%@sxF?`bIyxY1Vde&zY^g+aUc|!p~PnOZ*&K zQ{-;t=OSouL4M@BX4n1MyK>4WGkr18D7>$>WhsU}Rs4dOvU-J~x`7puv_o3F^|yPk zkTq;po@hlpc05{oU>O-a?iQoULNl&@GCu}YEp$87{u!G*0EIsCir0RH%_^NQ`y&5I2lc1isd!xQYNs{ zl#5%6^DIb5spf(nB+C3(>CCQJ0Ri-*vG!-L_`9d!pg#3C2N=L_wFX|)lHv$cTynCHjwgAMi( z?r8f-IatHJ?ksKz!45j`I33!lx9k3rq9a+EZNh!7uAmkk__G>dj+Hjh=Hy=CsBHMG zuI@lM2#D^~yLPYguVO#2bI=RcXwN_hNnU@rPj*xm4f;}P1-<;vaHU+cl~m|EW3 zbDqy&AMdjoOpj}nNb=VcjAhY4(})rOv=~&er25RK(n5fvEvNq}V(`$kEQ1d8)yLyH ztez(CSK?;N!=(xCLh)xNsh3i<_jF5tlwofqEL#w*9imrFHE~>a*%@xWD_s?JT{fQ< zj_D!0iq*7{6UBZBsYZd&p+p+RRu@Tt%-F-{E7UjK*U3|PK&(9IZ@Q4Z zM8yS95PML|%?>_Y0+_Dr{NjZ#yIi^2G^ov4WnCGH7+@Rquq*#?lyPRq?|bY*RD*hH z^KEZ#;9XQ&+Z?!SBfCR*(hMF)XuImaV#xVn_1972MK}3l8I|k#d2o?S7SrU|PX6^= zB0G6MocsX%4NE<0bNPUb@GV=|*~M*X=Na(wR!nvV0s4d_m3#(fZAfG%=8dW(_8FtW zUbWu!@i+9vX7~wQUbsIgnYdiv?20%8(NIGxEc#5+d#n{DjgHp!li4_!RVTB7o@SIF z1o0;=R!{udoSkS=J=1z9M|hCoKR!Nlj$g z{!_7KRtxP&@L&fM-#D>U_-mf{PnZZVsetg+hYjeUT_YVG zo_tKDZ0fTd4~yMM*a|j&?Y(M$8s!awr0U*+zjov(pKn(pSOPw~e{+psFpss_|h8 zC+O=9%#EhO8SX4_zV$=bd26f4w?{}nFsTD?#>}*AZu3Z;3>x7E!3)*dGy6Q=OZt4Z z&CYq3v!cUVyb>G3PSo2=A|P6Xkm!ZME*b^2rtLT_nerM`;&#wP{<_#Yz5(J9j`OG;p>GTJ#f2 z!12tQEPQmHF2?8;_^2+bmThG8o5=U`46NtP3^)U>obZT;5=+cu2&drz73r#&mIc5~ z)a|}>=2;K~0GnuKj^6NOi|r@@Tp)zs-DU7?GGX~;L^?430WO?NRL25~i-TZv0da;` zIU^FFyUP0QwWYVRrwbwRgeY?M%<@aJuH1tF44M?9k7asME*&qSzXcB2%Xnw>d+gEE z1kh~MEw|wioo$E&Fcqjj%`2zKkT-|RDfPJ}pRo7u_V$l1s;=`a79eCwDBtrYxPT8t zI@9EA?&S6sc9j=`xFbjD*4AdlAiv6%Suk_i+xCN)Q|RptR$N^Bn06f z)r$o_wOT_7((8Ya_`XWw_eC9W_3k8VIS(hMV{iE&Tm7A(Pkmbab;h z^t0NIy-|)DT|#h7Z`jkBwAo7z3csYkMS`WCtGwaQnTx)jw?4YHF2Ts%?P(}#vedd6 zT*8Zk7WR&L&%+RprH~?}0&5&jaDQ3C9zHDfOib}&`W>mc3R=8|@-(R?-^sY9U=IEE zHf986k3eZoq-J7#l{D(mm(uYw$lWsECO6C=v>aVay})(X@{A%t!%<)S7I7qoSKzk8 zd^=>)WU516S{7fRdZF_W)EVJgPo67hg!t7ud(b`mB%HiHkjIKc3{rCB*YHE7e(d(X&pNMF`F z)91tTDF08wu|5`yNL(~6S!RAFDW|ujLcj|gb_mQ+81$$;#2?nPr&3Gb%s4dJ+f4#y z$XG<}OpoZXIx2su#PJf%0>dcTzH?+5L!CF{mqZ-Hamx9l!DPbPyZYkwV2xFj=T&jc ziMrpAYog)_m&<{Emq&3s-s9tG#k>?VGq7b?L24dhMO-g6m)l8&gqs~ubuOVzu_81@UcL@BBZcqGn|KDhP%cw}Urd<%Had&s8 zaBHk_cXxMpcXy|8x5gW2XryrW1{!yFcbhur&Yktm{oYx3=EwYq67+gca&A3-By9jzt_@TEsux!n9;BFjAeEEwx{6HA;F zHc;4}ROKDUCUKZ|wcPS9dSB(JIGL12@}|VRy8G$eRVaFVPK;fnYC6nHLE+Tm%j? z8*2wf-n-MyCv2zYsHVuNI}2h@o7Zo4wfoOl5xQXln?RJ(9qup4fK^_tKVRk<=)>Sx zp5eEMA|vwkkxZl$D9D9>qUsQR!Ul@rg3@OUH-bQ0c>6J;yWHG_E{SNH&PL zD&x{pp&=`-H0CN@cYg#e=#kkZPG-XI{Mu`-Pm|h_wMWqYXsLgwEX?I&n$*QT5<62b zdu839ue^M6`QDIuK=6H7*<#LH?CFP*-OuMg_Z<*@@+vz>owE}b>RLfuKpFHi5`;B7vcioErIIJokRaDoyZzm25xEDW@Y8g8rg)lw%t5^U^}XL=3yGF$J%e>G6utOeMzC za#bB7=sL^a0@xwCWAK1re)}H~un%S>;}w`Q-)w$5Qbq#ic_!4`?{34%RU$_ z(k2vEfw-TvkYQTZ(f2N(9JUiYz<#pZYsx9_h$SEJ1=Ef(%HrR(_HD5oG;l0!{7dX* zmIh`FU-|$=4-PX)xC!)4CmpsS|JaGcy-+^jtcw2yyAFU{^*VU1UY={ESZGtYttmYq z83foSY2iI1p_;73He6|!vBjH*+kF;^B*vbG%e(~zDgHfyup~OcA&Ry@V}=a_1-)QZ z1I(HhC&%vfjfgj-CGk`NcN%A*c0vJgQ#`2s$&g=Bkeb=_hbqW|zqjdA=s-CDq6t#gS6W*pT}0y%xj z<%pz=0%ez$p0Ze5u*+)IHL>YloJLiM5!jwdm}(%)NT8q%dftJSnjMMmBmKreFXZ$# z7h0OEzoE7hBIG*zs&VB7U9QL}Qt7LPbSK=a&%Mp(7&`g&TMym1KzymjzCnTMlXBF9 z*h8gghQ&!t6tPo0LnKR&XGwgt`_m*N9w0tKLj6$4Zgu01#3QGYPK z`*Jzv6d2Et$_GUrWBhF^yqI2EcgvoLt5>^7YLttSoIuh|7hz4Uw&yIOHTq4>3TT%T zU#zl6n`2{cS1OK62gOUfGM?nEUK9J(27EYqO(q zGyL`Wc>VQYgO|M^i`{Z+B9{OPkIif(iA*#C@&7!40dVQT^*hb9YvaZ`M8v*Jn<*iC zGxBE)tfuxDQOff+wtn-TcF%rvfwh@kU)g>*Fr2=oI@0kfe{O}X9oL*bO&l@w%mYX- z0x$|=cdM^np^j~of$&25^AKzHK$q9*=-I(5b)IBO{n}B@M{)8V{R4*9`V>NaW>AnS zVkLJqdt?>TprD?&aK3s#^8&immKLv_5XhH6DXR(pB!jKt?fMnHZ2X|QD~(0p&=dHJ zMmBR$^Ty48@>wREIko$^_AH+Be>x!r!@?t>l>qbt(3~XL`ipK+Y7qiJ_@fwFVQYlyX$NrVMt4M=&wYPy{FU;LJE>)b zmtTa1@-hv&TPJ~jT*|;EaN^i*GSex$%`N(Md&jHlPB25CdbA7goft3xS0vhf{H2u; zSS}cZI3%+_{(Yf>U_Y=AfIU?}PxOiLcO#$^=^kNa&+gc6U!>I#S<3TE+iwkKc@5K9 z?k;7YR}b8cXZ!GiMHAv)*pvWMrfQ919|uJ4rMu#>-T1$)q7{-cJ0T z+w+vEFFl;@q5a@=EY?|ZWu0unay$;dwYANJ2HM5XpPtjWwfA|cK?_w<2%$_ET3)fZ zWjGZ)RiCry$vHy$r+lJSwk#X82}LQ&IY0#aoQ{zF37^v~6l@=B(Q>==dseR5_2lZg ze7mibMrmcDqA@fmEo+r(Ru9AWyFxJK{|4DR`R#_vPj9>XYyIYv zwcG2Cg?lvp^FrBS0z>hPGNDZb+64}ZZd32 zx*~Gyq6cm_!0irf+B7B#epF=~kGNcY?y#*`|w&HiSiAc3(W8IjBrA31GIO?e^8!Dm@_7%a4{W)a6%LCvp9OdI%t5xaYjfpu(Q+*1OWpK~5> zFI7dbkjt}Da}T3MUn#3XoWu@KZdwBVq=6Q-Iu(Wr<(-SY{69KXS+StNs0j{SzMul` zi0LsogTrShtoYDf2*dNk`LtJz;Aa>Bc!~Fto`N6PA8QyVWC*u63Ei^S;*7g()P@Nk zPrKY%+{h7sXSS0~S(*&3W-fW`;ts6gUpSF<0uK%UYzJwpXWZ-&)y*GmD@B*<)K zX{$TEg)9+WRZ;9ayP=i8e!WsUVKBxzcQZK_lCn^j;V)%Lzt!Ye5MFk^NxbbZ5j2B2 z3-p9KvZHtKd+i0e)z84j&c-tkOz1)M;ml{MM;TLf{bNxP3!P6-3x_m%|rIT>u323M34&0U8Q*onsJdFhpBics8sEFe;+R#~EKN;4JNPJZy0I@{v=0 z>c??(I4TKxJ^SJlzU}(`&Nk@PH{9D#`sl~KHtHk?Ui}?=N`djcP;YA!9$I{Q=`%m)`krkN1b z2^w1Qo+pPNE}~4_*ROr^dTGxmHof?0aUopq-3fu2`uE>k@(?qtQ3PCg{Cc0%9N%Q* zNQU;$MN!_F-vO!6&{}v#Yod~-wf4UL+HGe;cV`$DyM3i5;GC%1c`QLrKw8ZJu0SC1 z$qIo6fysW58(>bY(YnLV*HkRM`y0@%{%me`zktM;7z2!f_<)5asqycxrojFil@R4~ zWjC+}D{^rtRc#M9w>`_-!&C4Y$Nqf4RG`Yn`q0hb7%T3Ny3j@&6NvONVmBEUAZ>a*tK3;6Oc4=aW^W?D3Gk!Ezr7mSIIl+s_bXrf zjqCI6J(&Eg)wxai)VbvjXh_UED@qIu9gN3cQR$7W0H7~$T=%?=ZmTN-in?S9XQpdH zgEOwhtNf6FGly00DsAmi?P1_-a_Z(}K|O4)I+~|K_l@E|k_$htnt?+Rw4Vmi-H+?Yhj0fg zh8qtU&5&DZakz0y?*SF7LRZ?L>K~6FjhULfhlz0e9%5n*v~Z%h<+ihrF}-oLIQF48 zk48o>4=$@o`WY=J_t(X>9YpJfnvd4EI?zZeW|UE9+pB$`y}09T2hb*V$`W(>{Edz08KM{nlZ zJheR!YkuA{a)#45$0$UjfgP`rzcRg{uTD(D=2fTFa!6MLpL?^L24e)r zSd521ottn&fipAw%_`>X&s-4={(h9s?G4leL6Q$coc-Ha*eGdA1$U?0(0q(*i>6~s zH{+Zg*&08qF3BdAQjt-kzuTMRV>eiCioG4p&KZGE@ruPJnu5O7)5~&^*gqWI5VQ9f zPSyugxowQkb$B-lM{oDX$mZ<5&Rv-F2siavQVv@aA(IO|&mQg90Nk#B`nZNOabqse zlorIg^kF?2Y=3=M2MynEtSzVg+P>+${> z#hIWK09J}MG$jCRIJd`=6@Wb(S5L($U>vaR3>LLLBgrzri-#+S@=tv`QHYF!(d=A%H*kh(CZt_c2_Qs63p!uzj<;N`%;@70 zU?fx6`w4tiM>_ln{VJOLUx4}lMCkpRNdB%v!1FK9!x2KAcoExgk=-wmEjl5+T80na z#Ek+;(Syx|ZoosBWhpXv(>pEWusTu0lu5f*13AB8jp10|421y@WVi9k+pb!*1(we9 zZy7PIhtqg$s6Oq$az(ufDcn}%$+P&ae_dGni7FO`ufIyQdNA8+#5ldlPObezFYhax*NP<m%Y0`x}C!=<(Y?Jp8IY!CugY=?z^%}e`?wH zJiL0jX7LCV?V!R(QEd0D5vIYYmLD{Td~MyPDTu+}XH;;#kokJ^oRF^5 zQT1^JMxx!m6AM4aJo1~&WI$Wap%6+cI8|6v_(h|z>aXcNM(=|mBb2v=_G&ylg+UVw zyP^NaDr(-=$cne-iuBSOPaWS(p%dDSL-bK7T!=}&KlJ$!ky_a)) z8}m}j(+C%I$ekuARrwpOxcCAVjx8A-{Dt3djTvbR92mr^&DVnKE(cOb>d_FD(DGY#k?S--ZrBIFD*b3EKNdOtE-t^TL7#4i;hbnP#Ix#&#L0uXhkx*1E9}BpS zLBxyHb7?%F{GBC4&wo1q3mZ2i@{flNE|Bx^;x4cQs7h`vmGWH20N>7$ScAWx4`0_F zwsNK@TvJ(Pxg4Qi{}!8gEj$(47J+etZc#u^0Ck_`C_LQ7wgyw<<|X~&(@!8T0_GjX zB=wKyGTFKZGiTKJ#&8r!?;3s4s`VonlK;7+?+Xh?Pu&ULiJL>I4z}o%UySI{)&{!8 z=yb8(54^AkNmmANqSkk?LOJRCBd)^zQgP*Ri=`Frp$zH8!c9YWi`q|8*x%-IoW_2&r7X|RF3eWeS(ej3;UfT3?v+nOn`L@u;N-$1d70NE7D-FO=Ckg)Fp%5N#pmsKz}|9%2c5mq>%j#q}{@GvS1r zNQ(zSs-b0xHBK}T*sny3NC_eF_|A`7b@fU%4XR2z1kT|IMZfh)D zgQswh_0Gm$Kt(`)r*+%RA!e&rto@6c1q`7o+&sY$1|?tkOkDRcsa|owFL|1W)`+E{ z*oQog8d`#lozdq^zF_v~stmy z@!V)6gbDC_&q||Q3ZNNG+)SZeLYQU)>gQ&U7PX6LxPXz_c0d~?Rn+QFFsNh0p||n9 zSd;;S=4euTQ)}Q=#+EGp8E!&KKu{?N?0K3DLx)C99YL~Al&1iE#ZjMiSGtXF24PJc z6Y9a4@(f~D&HYsx1Pv>pXYIh7%s39sK)33%kMMrDLm|D-ZW>Sf9+3{e>)<6Kpj3%L zwBY=oZJOQ@Z@*7&c+`_7D7_~Sr;aj^DN#-(dq;1b9Y9TkEfWeK!8iyKjp z>AGEpc8s&v0=rlH{5^l;?bLBc>>T}UhU+h6u?>w_qk1}EoF=d_j3WSCsJ^VtHEa#$ zd#$xm0`;bEwgbv9_V%EvK)dlml6um#MvMtJke}lX_nJ26qLLL`EdHyQT$)%7j8uN zFp}BE&|gthD9ZhWhI*tACRTN9MUPSjs~@y0CNqxWZ_3S&u_L)-fP1AkUUhH|vfV#H z4kR$Mxu}Z1Cyx`@FkVn`SL4M<1)Orozw^;vv(A3H1TV$zWeLNas|5n~FVi1_I}9;( zQ{fHbRoP5fijUGSk8QVZ*Ag#Sz^PPEg$8;>km=D))GCq#eH%RKEK!GXaH8~UD&BO; zF;6LfkboQ7$o1Z1cKxFIGpf#*3AmP~Zc#-bSs*AMNRfXV1<$qgyGF+Nh8mxn8Oi~H z=wrKwRdA>A>bv?0WGs%Tu0Lt;V+~%~_t_T%=wUjsDpzZ>u+1AF&K3>+v}o8S;u|%2 zm`0dnd{^0-4PTd1HZH~2xz2?N`%(^|N7cZ#gsK2rnwPVbzZ$5awd4_EcNJx}P(!JF zmuEDT1Ksps!S~7d`QLl^jZlC$FLHP`f0j`SnS?L=VyxtEK+V#cZvvz(l%H|39|X}5 zr|9#)Yk!xa5^w_UV$woOv3AHa@Z|%zLD%i85auvMMFpmhc`WK1b^>0Gg@g4c)o|t# zWZ|2N#f0xoi)+{uWAJ_~yqIeh24!a%c<9f$zc;$nR#*Yg7$!#7e!qj4SoOEHu~LA1 zA{)u61#cMSeDx>WTDT9L#JN*Zuk`*L$UgPvK`L=86F~~r;iTJ0;9-Yu-j5fm z>`w3#yoMmi1Y?qU4F6j3!+5_0@~>URBQD{_JYH*HHzSw-ML9cM24Is-`L(qX|M|<#+ zZZP1x#S)MfbAf2?PiR*Ql*hl{1_2tl*A(GGDy;>yrN^?)g9A z)&CUsiW(-I)onZSg*86S*UXvu9qT?)}x#@&}jQg>k>lF45d@d^b5TzM$PZ-a(cqR z3*%TeaUC0`xqsiq^I-M&d5!huFG*h#WZbtu#HYVgMuhM9H_7q=zPIOkZkxNn%G=98YljoTBTDz> z_VlzssofzKQQdTam%PvOuQ?XWr5?vSdzo zd}{X%(Z~eCnL-7hYqPm;J`L$^9EayOmVKh(I=GF}nPVdx&5qjBUmGO5@s*0uxd*v7fmyZ zmV>;4O;I*OvDB`v@QPG)_$5*e0p*8Hsn>RHe%H?Y;3t~z>X71+sFE(Pc(V+0na+R7 zZs}zlZp+GXl!?KAt)18J4$vz&m@~~kzJf`Fv7ln|AgAWiDo5si9oP@h-(mgD`JIkI zp>+sih~{-%7t36wbung=5H~nHpt*c^{`u49K`twi8o>ka5vfliLm!(7^K0?v2i;k- z9hs*=%Cf5NponQ4L0q$Qq(f18u%!9(!$Ga+EZUh_db z-{!P|f8qVxV5T+>IyGI59av|4dZRd#1M+&Zu@6=bPWJBs)Y$oztMxxq4dd{e*!aRb zNX&=DuD)5QEF5)yBXrJfxA@;k4I{iobr3|NeJ3kOE@YT+E}96RfqjBI?OzwL@9t0c zj*3+s^<~WHfY;S>A%^z^toQb2h)BS>xx?Rt#vj|N5$T?5a9$Hb6B}W=s-b$yJlHB{oW#0mT|S1j1I@Y= zW${Z#d0FOV6^+`E0`~s1{k2iKO`PM(EVYsE^Z_tEQ` zZ(F9bd@n~mN;k&mezUWGqmFna+fJz|LW@wVIQ)i8afkz@wN+U#r1R7f`jKk>2l=gO zm1gpNGcTX5Ec6O0XIRd`4LW3>z1FYok9{jR$qbOZ%zd=Ud1ZDZ2n0u0Q_JR&4+ zyy8H&V+_8)hcL-9hHyk$vkr7dIhY#>P;M=KbvpV7bN?(U?MP)sf0L1yt;Gj6_A@!zH; zn9j_GWh5|*$P;U=lG$r?i&M-|+HL#m&LlAN1+2nO-pE{3_3y8wzuzHQH|<+b5DPW* zP-=;{q$`rc9q*jU#IU#gj=$7#8Y-cnyY5f)td>y zq9mv)f3U=4GGqQjI$cl8{GYLBewedm86rVCqrx&xNHE-8g%-J?(z-9C{$0j=R3sCN6}f6>V>L?qDDLR)Czp$g!a($BSczTT@-9 z3sYrQ1hw9$b?|)s?+2BlB*Mz%mXRW9WpP`%I$7&IlGbAZ^lBeX)MAq8cjJ+eb_Z7| zw7yGFf-WI$tMcUmFXB1t)4ZF}C0~6=IdH1lvS^+v_hl=GFzTIJ7x!Ck&)676rcTSx z=CKuMJ7=n~>Oa^I;qBIRVerNjRGqNhrV`mV&?(kG+ZQpvE5IxV{Ycw#UFZhG+B|v? z$s7|bTYSMA4`BNHGyWzI$R%Bao@jYUGlXbE`rMFiz79*I7+bp~5ThA3+6UFVLh!Zi zclSu^J%=Sn?;V(&%06t<_1U-=gk93#u-a7%2$B?m%le$STa+wBioQen9A|+YmuHj} zx#$B(>d+P(izdcS1Mh^cPI=ZpZOD$-$#_7c7Z+SfD+J*mam{3A%GdO2qtjz?{cpId z5i)s(aWs-AF#$e)0T1KP9oJ{K*UOP}*A0`55|R}aLZAv>GHfHT{A2Up{lQ&kNou^v z*NB8dk-Y?E>$xtPr_Y(eiJufntGLd&X=MH3r4)&uGXTMwdLamMMx)?os~jxup&q)@ z5=_V2T;Uktm+Z#9zm%r9(fDox3nNe=FPCa zG);U!E?|9<_pPbmm<>NN|4pe~=i78@S&)xr(4e;hk>2WoW0~t@E;Jre*|7UO%Xvz~ znEwtXRCG{O@1s@q8adi@2q-%iwNuVNpwaFeEuogjKql9Nk#LTItT-Sf8}~=yzcWqxkUb(0QXjs;@t= zd@X<_p%xM>5rjI`ylr}0a&;Vv94a|um4Gj6W98jrq|q_&Dl!Yh8e85AL%SZp_r0t& z-;L%~oZ3r_Wq&+4|C2jrqR|Jp=C@Y4AW^du5kfNacVlSpr<=MSVCu5|?X}}|brm{F zdc|=4w|uqIg$JJb+2LTgZ(c3r0oR+S^Fd->`{HHue2j~}P1*jV$MoA!`Vs-{iclV6 z>2&1RU?CVToCVcnHPmd&hPnJP--n`yi7ZNTY--)2%`7p{&MA3xXsX;B8FaYUc8-K` z#m8H7Z(w?VNzUr)!Y%hBgO{@|a(VT!=AjA;k*oCvAa5n_wHaRAE>KHPp9x0pzI(|o zd(zd`WLy3_)8X7g(0#>4Kj2+b1><%7ZlYNXHLxbP7B&L>MJn2<4!C!B&fhn{s&z6;cC z2fNJDNFT8AH~mKJIPo$^xorwJZVY#)yL2pZRgG&ik_0B&$yJmYFZ-I3e0 zE9&p7$1X;{^fIemteb!NqRrv4knzPpX2%{W(aWU$$qCkHLYBb*PM4Gs>}S9#y-)n$ zi=J%SVi}Qu#xPO7`p~z|b|sS&Be|k74m#NWzHkHdtF$<>frmJgeTR&Yobu}c3tu|i zde3}bNKef%SZ7-MwQSDI{t)O&^6uQ%g3$yjgx{Oty7@^)3{3;ktZ(G!SukZ0yYEdH z)!&A|x%u4agVi4H7|8W1)`%#9=#?IGZ`b2$zB=3QTWB0l4R*We#(*v?@2cK_YY<3?Lt=cZxL7UEnQZG zX$yU>6qXCT&R&t1Ze94+Td+x>W0*~%dCOwNG|MU6Aal{uVcupziR%S^8hlzW;B@Gx zHCUbAuO`|;r0O>m>9zLu!*FtRj~uN7de_CPhn-ySqn-?}USb&(hCz}xlg%G<@qf6l zvk%Y5%E0=xOm{0X>~nHD$2XKPvgpEUdT5bF7j-_4dC~B4Gmd77Mo}S{u0@{8rQbpDT z9SVl+h-uSL)B30QCh;#7`r! zn7)>)OkWzn+!_`fyFiv~itRFK7|KLC>1uJ(-=AMH6d&hsv1`Cq%%zbK>I(IM=1-4m z36n%{LpnSTi}IvcGZQPNZFxY<+^b^wA)OQ3BYm%mdMk^|;Bvc$7`Wo}CA$Wi3IKYG zR$B-;G;LA%#5z6a4ZW#Vs}1Y@WUWpWCz?v2Yt8f5O04H~CEr|KyvSbzZ(U;ox0P0( zPM|v0m&>q5smdk^oC(@U!&{g)PVl3=88c3MOA*_9gtoJcsZNN}LN181o34n`f-a24 zq49*(TuaD25m;=~Xh{`6JbeBz4Wr&O4V%F%*XEIWj5W6S5hTz_Q(_Si`f}rwbUpF1 z_Ta--!x(MpLtT!7gJeVfBO6TicxerMWVw77C;AO$i|USnjv{Sb;Y~vL*U=>%STrRG zcovI3TGE1>JD5~WlDBYhCwj}HQU^3;F%X&(5LKCH=`l83xdD?X5*%i@&B?bxl9L`N z)SX8eVLB(g(0~?a+3V%PRenn_yA-`CJamA>Iy!+YDd>VAys zJyNTH2|=UUoSfPD!$y-q0oCrM_wld({V@RRKFPUfffHQw%K1q%GVv zo6NVPF4PnULU)NJi(cL;20lvo!sbnOWJjJlhu}SGOWxL{1wi(2y_Ey0vgRAQskAxY zn9qqu(>(f#Mkk-jyC{~+J7~5jGW@no$K0R=HRjTZ6Rpr(z0jc{<+f`1d*@rdCZH&B z?DwU`fk?!zGGRux{2pArw#0S#{2{)~UXp%tRy;S({Z1~zQ~I?f8WKS!QxCjgKsxi5Pqd{2NYhrt8--uMn;s)d#@OR3C^m*A^w<16;klNX3G>)3{R!EToIKg# z2QRi$DJfDut`23!sYwKePG^*_Sjfz~5rQx0KQ5WE3OE{o*wXP>7Qe(1Vr|u!oQVghfp8qm(m!#~%=e{k!b5 zENjwdBtC(1U2Zc_;p24!!_pa~%pj?ItCH*piTeX?an%nG1aJNnm&rG%6hg~ymi$Yy zLjN2WLCXpjmi-Pu(kVP;TSwELfjEfppa7g?x_ZQ5gVfB({pK)>9jCUZ+Yo+;H(DB4 z$hYxT(CfCnze3GkBqNMP>m~SKl6px7@q8Akn`D;wdlH(s;~pK4U*r%>W&v^2lS*2# zZ4P*$m5z8NykEGFyb~3`)Kra24KrRLGd^V6v+2ZeQ zX(8*c1GlLo5jA?=Xcaj}Pc!@6W%0!PL-8!=r)M-kis~9gV8yTulI%^4S_SgUbZ-6j zo*@owFr5ni(H!_d{5|cDqgTURwBd9ES3DbZf5RPQ|I8gxf5RSRzY5o4Pec4cHlYb< zHlwoMbOtQwSD^OKx1x?$zN38CLe(8_4c3C`#bgsXGvm0%C@mQ{MPCVH7{r8=7utfB z1(CGS4z%p%E~u>DPFZ6Bl0o4u{p>(9SOCdkeeiPeo)j<`S)uAW=qzuYaaK>|mKp0)k+@4Z4}@ zbbClobbG#hqm|Un()eeXE2FB{WTL+Lc0O{kYUqT~!D)c3`WfbE#d8zSMoEDE;WR&}bCHT$c=;p`%da=Zc;LG=y zeIE~QgQ^356Cy&N2j*v%&*QY(I&T|jW`0zfKOYAG8K>7Pju(cZ35V1If$g0hs|g94 z`3h^RAOPAU{MfGd?floi*Xp$4(t!-TdA^9jT|~&2jK>JV7v+P`uS26k`b>-a_gSou zlF!faz5?38GfICx#z-1@0I)_ecGe=fg-qsYc+&92xl$)U-un*g>n;R@{jmiTN7#&} zg+5!7bv;B<;fInFLq*No&9#L7)22*RD2;|blIG4FKqt2pE7OJEoAQ?Mu zJA1$^%WInJZ9sqqFu(S<&uq;dT|2Y=A|Y-U;Muu+eLnO278oetE%dbZett3xY16TF z#e)N9D#kEat>lxtPpPi`CpC_x_Qa^JySloA;c_Dr<-VI_OsIewWncc?nyt2V@sYd4 z+gf(oVT@UoNChnz#yyo|!9CrvBgKPD?Q2JYqJ`?>&S%HUuBD_8f0hCZDJyEZ+64kx(=Fqp>PF@;*Z6$h3=Sfne^}Y{ls0*f0%2Xwm!1?~fY*!EvTx z2ZL$DGWy_8%mWN%l}4MAKYCOsBq>b35j3!aSaKsR-k?l%4m;zz_ZtFv2cylz1<*<) zP=2&S?0{F9<=N_n?swSp2}Ymh;9?<(ij{~leCt(_8|QS{6ReP?is&|f$(WrhGh^Ux z{x)#ftA(9{B`IT7+kg6ZSl>_UWznoP4SC-xYR>W-a1s7SHbADCAeIq95^bkK_T) z;R78sIMtdHSt_yf@gb*E^r0jI439Ej*+K5ME1kUZQ%l9$R~m*S#{+ldLK5Abr)5_s z1R2V`?o9NoGC%=#k0lEu_R}E^w9Nhmp|veDRB6uTL^wkWCr| zc_y-ST4k8+c)7BPEx zw0CtAZ7S0f69?W+2GW&#QI6cacvL=~E_PMvd!6S83!H>Yz!N!#&y5qNQ`kTXY3WA= zc=NAw#aqpzOPaPidR6JodW^qi>ACkz-z)1yK`Gq=RW4UwG@z4u@3&(O8~l*K%_uQ= zb17unEKn6z{5!80CIkpruJ`!g>7S*i69Q)KyGUA49-UX*7-@OXpl5l| zfTJ9E>?MdC#qrw7c6syZNN*TaD=%#6R@#>^<}fp^h|5Vis5r(o<+klv`2_-S{vthG z)|@+#x;!zv+O`-^lA3i+Ar=qVc7d*L#1#Yw@IEBzIfaG$2S!=CA5r9J<}Gr~hs#Fr zP<=~BU+Y&*wNv2%fEjKEUzzcDh)Bz;J0px-;u-How zIWFK{G1}_K$DhJP`R&3GwrgCp&S3N*ft2J%b;4~OpL{P4#Jqely1cM)hKe$9!5T*c z$>R|L$)gC1;|Vp;O5~ZTO&|IOF~op(7p$;5a7s9AItJ@Z$Ov==k-A?`#d%`yusfj` z(3$W@G^Um9s;n2uurXZ`hc1sor)^SKNA;jHZe?+-VCODWT$^()58Bt^YuuD?b>AAE zrqCcPYP2V`rnHU*5lcU82%%yfu?Vkf-nVPokV8i53BznRG^^b#HVmNt{oo_Qs>k+d&nX_v}9;H6>nDQL?IZ6$J%jk66cji zS=nAY}wKILcXaLh0fAEgFONgiJhWC zp03~A#RwA`dwR=om2lhJz{4;FxmkL1%vKP`nE;XopE%%%NgR8LNgTaN%Z0s32O@gv zEe7mt6N;O7lh_l@^BL?$kgymgyfn?z7y-r?$>712lGczYPVCKSPV{axTSg#;EoA`3 zU*B8qH_(26u4A8@J@PXjZ;A`8ck@B4tLAs`sHSl@!_L`yHyz#5PysfRL%U zY2(kgqaDTr{g1AWn*9jmX5j{@KzJgyt%C#w&`gT-LL4I{4jJ?$4jFLdhl;)A2hAi- zysIDYXytABK_m72!Pcl$A2;1aW&*}=m%DIkDSD^oifxQBJv6U^0$4j{B=L^n__3E^ z`2Us18zPv8SDY)ti(}cy0ntw6Qgbg}dV9S@x_W%SaE_~zyL9}$Q@v*1$?8xHgiZz- znEH=_i&}m(i&AeAb&XF7Aktt4uU{eA0OgWJ`B5y=Q8@J`QZFKOChAq-jjGO$+$*#4 z`xEF?2=LKIDVSd8DNtM!#FFaAIir&LZO=Px2YyGfdXEx@1f7fFCV8pKe`-S?Yo%_I77!95ESD_A`uqXF%!}2 zZo}ST%~55A`@Tx{^m0c8g?R=9g|)gMx-BOp+QLTpnZlCx>a~27Dya!+ZTTa90}Hhz zK-&I^ix}H8&G_P`lcehPKa4E-$H*m+k&PfDe}ar;|4rKdUX|UJ4bm}N9%~e81N{Kv zvSc|9~3h z@@|z=LbcQ)CR64kVx3y(Q4ZaV6Hu_qngWA9aS}+zWEI^1PSmGd#Nfs<}>Vnr;0!wKyCd8!s)wS%fYqofnf}#?TlX^ocUR^W^@Y z04e)_2c)dLY@GjlKzfdE>$u8ww2n! zNQ_gu4bqBZ9hC}Gd3)oxL@}|~n~7YpVQik~RW++8UsL_US< z$~qa^fKE9+{qNWJKj{V8-mcX>fUm!Ax1aWrk;$Xl(K8Co=J#>YigO0$Tw}e>=-}}B zv!g{{#KtR-z3WG+881-@73DYQ2;^cK9rYFB_U~Oae}kp_I}0BA{>v1jFRS zIPfH7C6FII^GQOtR$ol;=|pPe6os}bQA`2ngx{|Rza>!QQ%VITIdjA$2m|haUiSBS ziW`RJNyQ|q>`=de$)i*9c1Q@J=|MUbH#kj){S*$|9@+LktZ7jQ?{UgLZGKO40Xt|) zmzU#ckoB#knhY66)mlTjm>{@d#0!J1CWbbU@029MyAm^bFFMR6C66H;wG!hYkMS;C zwD3cAlK<3O)wB{pD|#!6H_r!GP}7Yi3=wgSzIiH^Pk14-qEh5;<;Fu{{oYq>Lf9M4fV1DfW|_5#En*7rfI=T!#i z!W2Fn<^|}`Eh){D;s~7|v6|E*8aVdu%@yyYC#a9Au#(?v|4R0umN49-6&~CvV;NeAuOzG%nR- zpb?&=JM^b%^mUhdC7*&Z%sj|=*dr06yV;QGH7nDBvdi&%X_sc=oX^!k#$Oh{fqt=? zei0;J;@j)cqfDZRG8Z1*+eTshWCuf}E!Bd^QA=n(V2BeYo8&r8O#q)VPYwP(mqzn@ zfXVUL>3$TJhSqpn>Gt(j=#$6q!GoRVbJ-eZl>yfsg^rmAC8#e8l+dj1+SQ5|fQN;; zIwA23=pBseQ{3d}IO29_HXyi5d6-%xs z^p_M#0)tP^-TQhT6swi@uKNgg*Vi>_e_v19t?%XE1FkqQ>+bOPG--;;yd|vSaL?#Y z`CV@;ZnG?izSXvvBW9V}-icB#VZZY=IK~G=%{^9hlQsse!=ImL{PpN4>QouNw;!!e zIMpq=-2Fi{{Ty$-pEGptegr`A#5FcCrHMRDLC+JInv!w5?ma}ty140G*oq5(*@=t^ z4%EOg{yX58ZIRj@l9>=8-quvfEW&iTwfA&B>a0JQvlL^<$E9AacI^c)cJdR~`C{|? zg6+#xbQhciIz$y9^lh&(&cDnQ{GIV}x@642)|oJ}2iYlH?;fh3HG-5bltsZI z{$cNDfyMzg?WSkY14Q$nc{-N2esUN4N|&x{d*;5jw=>4rK*^eZ^dI&3Se9npy>y1j z4XZs;zA)7I z-*+v0gvzyZeb2Y~duXj+U?_3Bf?=&d%hQm7`-|y*ZZIsI;+7YaP=CpmM2aeVg1L`} z2S%1Wgp2^Jq;`EOuR!W~3yL4rNW}MIB`JG3ug0#k&RDfh)!B2`+H+2o zp8KIB=}KpfsA(Yw!WHn{t11GbmbJH@zA?*`;>86u^u*hl0~n-xe6y|RNHyr+dtnPH z;v`{v^5cF?GB_XuHJA#@!K;2#g{MYSV0srovQc%OCm~=`-gO%~U_i*Ow(N{|M?l)V z0|ycBp=MZ-LbgMDW@h3%F>k|%1CF$FcR-@t{8plP# zN)M81>M~FBX!LBITk$uuH8IKwSClH|DPQ@@4CAPkGo#Bt1~=Oz>oBj{ zm73JrubciTVi#b_+dQhbmmriRvi$MRHS#-K;nwuZ%mZ!$6?rvKMVtd=tU^Xth$T_s z^s1owVwzLV(p=|j5oa${Pu9$WJ7MYr-F`w@P9Li5n19gT_Dp`I+dr9acM_=cwm;W# zeXE)Rdmp=tbSWPTPj!HHr#YRz91CSdOtbfZ8$fzuN-C3`0~Ip=&}KG;3TDo+U@I$~ z*+OgI&C4r3RMp&Ef{)yIW8YNJ{O9GCo~x6El2k}`*nr_C+rQqcXG^e#j6HEu)nA@W z9xuFe)}PeXHCBn^rO&Bpw1Mc~3oakticC=PKBh=7gV5=#PZBi{O?Yjc#K*RgH%fPXDC? zC+x@6gSF9=Ky_drrWDNi1|a5~^7^Owoaw*M=M0SWKQ#RRX@lh=hK0>W%Wb<)5VyIX zMyBW)1PGw!x|3(){(^HgSzJKxqW!XX!`znmSbldGV@531<=7N)3n4Z1&+40v5qm2B zoWo++Whxrv;~8f+Fcz(FEG)j~Z~Vw8i%2(~8v}}%E&`ZBJ5kVsp=o!(0#tiYHZ4ov zpUS8&SRb6jKk->`rr(EGC&%4jx$*91M8A)%4@cM@6j$!MHP~%7+f!q@Eb2lSrXA_i z$Jy*`Cd`WfS{RLtjqhikH_QLVr(@u2Z{u#m&xz%pvroSmu%`D%(XJP@seFAJb+Ns& zy|ISvLi8OKfwFX~`_TnE!#mV!ezv&{#maEPO=E3K8mmrRv%TF5>RL?kdrXk1kx10&JUA|U?F9FT+Cxz<#&r?-puf2*1C$x1&>Pc^RbD`Gg`4voUem1 zQ*sxY=;J3LZZ=MKT*RnVVjcyO_R4LU!e?CEpJ*3NLCHu@*iCS0f8 z&M5C^&j^R?F=H%iL?K!ry;{$C8T~e*GkxtBq@L`Mb&*7dpcWnIjI)YSQPt^h+GZ;S zq;Q&KkczdUfWF~yl~ad&o?|Sg5@!M5zJ&85ztjrwr6Z%?dEWhsE1zuf1Owkoy23Zc z_heE8S_dOck-QZZrpdwGO&5h&lb|3s&8T<)(`$w(;4~ZF2u}l^=qnrO(%7%?1bOj{ zpO6R497jcNAA!Y8LcI@Xr3%>M#+efg!w?Xx+C-Og9mkf5HyJu_OHngp7u$+G5Ir|S zrXr3KlsON9#hkAor(SVW8X7~HS9j4R%n3K{w_Ap$Q27p@^3-S5Y6T!$a%^NEhH?7- z)=(M6Uu5OW9hTJPrgv7oSVWR>I* z7qmH4i1E%UrzU(S?da76E|lmQfa*PKoS>z#ESA{Pb6{>(D$8LNST`eBmtVVMd3szG03)_3t+Uweb{dL$IbTA|qJ!ON$-lSS(5RGrn|x>221#f*3l_%RwN%A3Xi zJKdB$zBVL|5UHlNs9{e$Zi)#RTO@e+f~d%C*QPX%W=Kx%b0+@b2fGW9&;Zav$7IZr zf9mg*{kuK-jUWbnBlo(#eHU5?Y^ns6V59}0jh@&UnyWR)$p;b4CDfp#6}X06^i^@eXTWuk>Y>MhSq5H&W7}+P!P@x0+S@#=8BRlP?NC$lMAI z$m+83dYrNg|MWf8(iY9DKU5s1#zp!W#>>kW@vlQaE_GU=#w-;l3(ZQ7&1*v~pRx|X zZtc<3q)+aEFjdbQ5*#JJH`McAZLu3;VtWVZHE^mf*oWRt2VP|9!!X0~m2`EgTLiqZ zzMd)ulT@2;t|9{a*+v|h)5Nznqhj=z7k*#@?g4jb8#k&zz12JUj-cS z<6_0NI_oY)kfAA2)XUJftdraH91{TaN)SZrRiW-7kL)#PEh1mh_=1Gja+z%rMiQ)n zREp%Gt%u_G*&ThCuBj1t3*O<7*+W|FXiA zK?sf&>Tk?2vw_-_;&2F(Cy3MXv$1pAPJfJ`|H84nTTr}uU$4!zcB)uL-k~c z9yQ$)dw5~UMQk=6s7fBLB0?=)JAmK0nXPcOozcw>LNw?VFPP{i* z0S02%}CnX^#~&7b03 zp2zoL;TIp4j*a1-c0$8k>zknN?y=kG=5J~9&f0p%o0xmX*7GVYh{%SYPWLw0onP&DEde|AhW$ayfJlk6X+J4-Og1+LW0RO=@b7)XzL-nzD z*^n3dMFLvKx49&kx#Zm&AubCFZ}v7aJS>%w`nFM?nZ8%!TS)#IQK2=i{^h5I7I6R9 z(&Jw@CVAGAHNi`;eGxISTX+>V5R70`y*o{qi?R@XoXMvA3PTNKTNFu46|sZ z@#*RQt;c8Y;E4Z+jqU$owiK$*M&U3+dmU5W0h`9JL?M;(^NV))0uXG;;!)J{CsOcU z`tMxZF^oRE6*TwHg>>$>y6o-0ys&YkinS)e3ydiVgfB#5+EZlV&Yb5z=CniN-x2+q=_fto8v>nJpLkmLB((DYk4>ymL#oM( zNLVUkEsKp5P6xz9QTLmgX_}x{KAqb`2hY#iLq4%~jT@Uq|53n?i!$Ct zRCw0ciz&zo&;&|k6E0EXQc1ADr|!>2kZTF1uh#d@TT^y&MWU>)SMwos%77Z#OJ?flIv><8-k*E+C z5REdXHqmLK5i(YVn;j)w?05Gtm@V#U(z z0$o&uMqfizg_@li)`f=Jg254(w!)bKWl);KaAi@Cw!3kdTBG;Vo{;Oy*)xxi2P844 z=lxr<%kHsk*nmW$2yAmiTYTv&YW zsTY9Q2kcNo4KTYLWWyiMaCL5E zE=M8?dJf*lr#dj4!ej$pB>dwn6B(C+BvmkD3%{nqeg$k99- z>QN_863FKyZVa~ zt(Wjl*f3xfiB0oV6?bh&^L~Q3YhN!offvonpi0XP|E7k1hL;YDfLmf6o7H=*6D2Ip z-J2#bhF1*+Vir6wM?iIeiI4!ZHnniiK=#HL+Vo*<_j!I&o5R6Mrx%hX4)T!9H)6u< zfs1~djNlz5{1dZBW0t9hU!M7mCWYSWkAFxcr6~@^U_Ix=sfmtB8p~PSviy)(Za*|E zD@m@7;RV`BOwX<`e1#B3VGt|^wlx)zE}#TB4nIU;WCCF=w~gF;d@_&`cY;lK<60yFgry9fUc^rqVU6 z*xDO%l#MqhN%|RA+~D>YI1oX37K)_~$fkrW<=&v*W_XSoL>2ztHT!@Cs0RvPIpP9j z+wW^wGhg9GVyI0w2um;Xay9Jh_{o$DC8c+mvX)4CimXKcxgZXpZ=JXBGcYt!{>o6a z5PZr#HFC13`zWKL-oFAdiJ4&NaPxea2UlL+w|lZO-P#+fdYCcXE6bLwE#4+lpD>$E zw8|YNwi@>tLu0JrWv(c@xW|8VBSla$+lz)f{;D8YyUO31QHkQU-Ba{QNl|zckdHvN z-RJee$jHw?nj>$%I)S>-%hV-t{A7I39KexLkOe7pn!`bhvvIXSfr$m&b}!z?B{}!k zu=HC8#D%VO%gPio93JmknZGNR-)~=-w3nOoiZGj~>UKmNR9O}u((DGPcT#-qiNdZ! z1>{Ooe$({kwC5BbW^z8p#`NYq{7r-lr5pj1@PT}zk!YnsaUtB@Zij@}$|KG(y)qpt`VcX31?Y4#{;z)z3aK<8ui%In(f@Uqm(i7 zF~-iGb8EqkTeZWjg-s31=0(zgt0&_X&*p^_tDqa*A&)973$A>6IG&bgFE1--%=WsD z;vW6&Gh4<+``bC<3k~i$81uiQ07f>J|AGSkFMpMu@t@~?Zf-~iM|&eZD@fOjMYT&=|ZPuZTxDJOu z+i1(_Y+v=J^SV{gx_fkDI&SjNxK@4IyIVSvD8}|A9dI^n2(1;V7VJLXogUUNyr*0l z>dURvD(*Htd!^Xh8`E0>^sUAdGiep$CcYkb&zxZ+@UFME5$6|aY|``(dCp#ej5+bv z&iIJncu>a6r|-YFzFlKok=Ufr|1uV`mDTM~MK&_b^4Fypg(tL*+eJ=0R2kP)?bs(J zTbwO4nU$}}Em|riRtlkXH!!u0Nt`JjUZuKA#N8-Ebh)>qX}Ev$TC+qiW)dZ1ku$VNLw90$`9}t#3Izr;g1WaSI?eE3iL-fr-MY#iwTcK zhBdPu%Q@ANfF@qFGe{^-#4`a&gR2OHd^mu@zNrI%6yId|bW`_uG31)0S7|m1DIK-v zd6C53UrCZ3&x?+zY#H1wRfRPSjNE=SO>7=lk>SaOja!61ZLJaN)h=M1>@0N+>tp>y}C$ATc*?R+EV}tbGmHq$}V1_fITKV>o#URg0bj`+M*Zb z2!;G1fdfyP<_^tZB8nM+xOYIcSjkF%$DLP!40hIo?QH5>nn=?V?u)IwhK`4azX7S` zQj9@A1)vfeWv!Gz`8<_M2Nok?SW4mPk|PVB@x+GODmSt^{g_BL^nI$WPHJw%2rshHr9 zG{HW7uh_6&W)TLr!h6RUsq6pzI`!JE!JI|wNN9ZB`RPlIcQGU~Jp!Z-0%eN3fW*gz zuz;jU=sTEXVIqN_>%GuUGnRMziDyPZ+6>UQbF;%yygQeND^vXF+mCT&N_>k-5xba* z!0yF5w~(2b-zod2DZnZ(IiGul=F?@qQn|^DW%CLKAtPWeVon9k{7o8U8@SOnW1$bX zjoBVuFJY;N)Dg^R0dw@SeYrdaqyX^3rgJj=3p75%G<~IxLzZ= z9JuTGtonLm)9iui)i<$Qnw=)lRmV+=&a1MFnOjc=th?ucMuzRUd6GX%Vn-bsgF8C=B(Hzx0doEM2OGqcu_G=WEQB>s51j$NtP}tp59i0n z?bq%;PcdYtw0`DDkC+HBRLrTa-+XZWR&XZ?+Z8V;;0(4an4Q0pnq}Q}*uBS*Cvi6d&~an&Oul z^5?(b@-l)GV#)Q0o;$c&%#E#To3l3HjZ}KAEO>8IWMnuob<3R4-1Nylpy9@u!8LLr zvv2V96p$!R2J{Z-Y|anFF>FZ-w25VA)Y|L~*PCqB$9$g-C5%w*%8g?#LPyQOFGo0e z?O>trW@fk)sSeFR{kM96OA+vUoeOx`^1>JxIO$5#r;0VBx76n9HH0aE!({}Z0Z&~k zAsId{foz{2XE*gOs$8jdrxZMvur$^bjD*Gp%3;(bfR@=*f$&cuq*{2CqC;Y8T*g?b zy{Ne~tk9}p^}mth#9HPgA@VFN;0gHMsB7RQTKK?h0FpXLUtCiUI&J-;&)`|$$oD6A zfW|j-r7s>ElD`HEuCa$1OjZ66Wy+OifM}*j+Aln$a!=XtOJLEknV@K7Qan)>CIHIo z623plk9EtCGpkXpylMrNs+L{5shqCfC#r{w(sV!`W|m9pc&O2nr#oU6z|H+aq>I$^ zC>fQ4bh#H1#}#(=9S@18E7QbE>MsKfYE1RilmJX0`_1Cz!*K>-5yde zxH7H=1C(t${qBn{&Ev$Grz##3Lj8qI*pjT)G$3hogivpj^f3Q;DvV?kvC`Q0X`9=0)D1`)q1H9iBnN?Biq`K#^i2(RO(aQKQ*UgZnf&@C?TdK zyr@T^U~ZP*WeDJi;{rx0pvJ610aNNJ}`u zhe~f}jK~6(hK@gFbsw?S>Dq@f`t6jp2WMc#+k`h}fG{)+QxcYKx?|k^@v8-OT=j@_ z5hfKBOpikhl@zhduxLwm{P^nZR-JpSi)lA2ZYIt$`gS2sT% zvF1c5vXEE^e$UYPh1EO>*RU8uLr4&ngO!%m=%U2j*L(V|Y@MY={VEBsEnQ7QaKGDe zf9{gYQq;Akj_u1i#|8w7g4m8=t)W~+hNa8xFenm4bfF$PXBv4gC{nIlG6Yn6STQTd zm1ZK^cd!nro4$|?Se*_PO;%SzZhVa(#39ucHbM{;xX0(;#QXC0o0c1`OsjBCiRLXq z!CH=G7j1w6akSJYlHBWdo=wSPT)Hkdk3XbEr!1A{ob|MctbQmym+5ybH#R;K$@9@$ zKBzpJFDxLNY#JFt0i=>|8Jb5E(I0`DINa%@ys5|dy0diXc~C>8RURTqqBPj(33!8_ zs+E}@#z)JhY0Mmyy+mLzMy;;f{2JpX2)0bPZ_Idx1tzm7{8zp87>pp zx^cz62~rZgPi?0Vnb7a1KVu;9BA}7~CguR86j{Y556U%3ZbGBJO$ADj7^yH~l|W($ zU6Dq=TSK%S=e~P%$}kEF^Aqj5mBc8TLYR@{VSD12dUvgdH$_#Hh z9$d-lXs`-ut5ZHHt)5gIvot~x_T(z`*Gs8aI9>X+PNb6|#8L7MY$~l4ybx_*Tk7N! z-cj0o5k^r_hw7D@EeLJ;H=2nU#>mLx&@T=tM=2;E4oSSF-G0&f(qZ%JUA`==K`1j4 zjIcmgq~V_8k^;b)O1$dvGs2j#l1ilT+teZ6*7KYq(zWTlt~_P33Rj{)>JOMd(Gy2s zkJZu>2F+|wH13P8CZM<#ItSv)s-IIOga^;jY7XX^5AN~VUxGtuM)YFKH;uAe2cX!1fq$rg3Z^+i!9Yoq+LdG|8ARC%eTEV zC`qs&zzp15yAp71LtEu!KWs|Yz0U-j=7HJ^6_b)A!WKgHHF%l%(vtLrE6_Bu>(DJm zY!x#4McEn0F{~(kBdK~4kY`@`!e;i$QDh^jFm@@(7&{^4IzA`HSw1|g9$AtrDLzi8 z)_O^d&?*_!s9zF~Ny03uXCo|ZZWW+r^hY68Wpmaw4C8C&AbistsHH@PZ{JmVVYxJ; z7kd4DZXk=eKEqju@Ke(bR1Bz+-dg>H{BGWy09F-sFn|D`tX`9b2iuqOJAFutBxPhu%hD2UbY3s2V?XKXKKzs}WLeV5@=Ssv8f+ zi&2jNEHWU=oZXie2tqS=j*QX=K)(`V{)ZaA*$3(MKkPCf(oxoSIe5r3L*78uVvaFN z#qDx2m{L^iHuwT7u!tg}kKvJFE#`6};FZc@20-GG%mh`N1?X4Nf697VJ91M6lEpol z+N;4x*&gkMZ-#P;5h^LmsV{MBwtZ`s24>OFsT=&S9lq}$1JtA4MSlm2zDo0Kh-K~T z_ZX0L?Gci8Bhds;LC)I`(VXv+ zr|;WzMZ-)Aq!rcWbk3pp9ttM!{L=_o*AtP8vP{q`Xqp-*Yyx*`A(J(widg@Ag-=@E zZU{;8X%G3jgTGMlC|)&(n&i5}aX&v{Lvy7IBkC0bcl>f|>^pF6+@o*+4EWU{xqsFq zy__WI1OZ1Hf@8Z{4}3(i*-%hcQt}1zq=dIn*nz>h%+gdLK-PB@cnK)u*#W$G*+g*V6{gcr zp?P8;EUpM<%i7~`S0Y%-+ur(n+PHaV`SP6g?>cMs5G1p*?U9H`5acgvglXClLR7ey zKi!unusOV)@B7bccWuo99h*k{XP=FO(0LQXA%aElUb*-=kd zzM@;%@W8>_-Sb{9KuC~#rDzD(>mprB-PlpPU(!oGS|5JsqdC(Y+|O=kacPc3&QJR; zesb@C@F{oGvyk^(SCAnndU>#;EOWHY%2Huo)EKde?MB)u^=oMcnPX@Rkfxf7ba*;T-RZYKTMIl*E=hA<+M*;!l9n_<9R za)|;YQxq+vABBp;EhBM7Q&$&m<5@eW8<`h0;j8!D_sUuxSlF#hag;)$MNN@_^-wIK zK=TJU;n`)^8H0?W*Bftn==!?lW0El1`}Hi}F*R zDUlwDe^V)$l8{D>P>V!#vB%4d)uk*&20_uq&b|<2S3~b>F38LD0>~D1ZuN4p@fL78 z7;XncX^w>8LW5@k85JxqhpDscYk@#FOB=+A zo*JCpcA;+5r0E!2p2OxRDaVJRN`+Qh=(h z-Zo|OZ_2jBJGng}8jh7jM=%3AWM~6QVX1usL;4DN!0H2yZV(UKr7bP)VG=AVvbYQ% zPjXg)vB4~vI8Q&EwUQtRAPpd8$hD-;Mcv^~37-`N50Gm&1dphgW~oy~KfVToHvwC` z8V*qI1mwRQ3d(@ek5GNwHH%F~JxCj#SKEy#RlC6d%%7^wogj62>~;^-<++3SotW`)M%{0e-_ru>fviY zF!sS3*?M?~5d?bg(|Z(pW&{PkWqy>2Ztxp10unL83sE5zQ7Af%aH_v#t=P<6g>h@T zJVHizn$@pFn#Vdin|TQ4RhBfNp4U2MH)dBvbpo(A0r0*LY~zD3@sWGAzHKMH#O++F zjOg^^%oeHkrKQQDnjLQye5kUa&z`OZLs#tXGfBHZ-@%!x0Ce>*=Um0;;b7_ne6g0Y z$@wszZwEvwIi_00OL;EB+pUNoyh;72dk4ivUwBHVZv-sRuvK=4Vx#O7JLo?ycc9hh znO20>LBW5Uxjot{#KOF2{=|Q&s@X0)g?VzZaPRqAm%0Y=Q09`*F38H%_wjk-dfFA> z72Q1K(=-FePIJGAesx4sy_~u5T|{Yj30;Jhf>YhBJ%v%;wsdDz1$jF=^CwDS`k-zBVni*nw^8D4-Rw7FQCKKxct~nRPrU@6A z&#)U#m9n>475`QYIbaKFFdc?>9zjIOa-pc^VZTsI&UeCYWwZpHY1O67SH=D4#t}*f ziy6N>PIUQf-oxR$WmFJ*gE6a++5(TKRnYXHW5OaI0A9C7yS)p95v62C@(=rPVa0u( ziTAiwYQpr<%f^zTXGE53f&372YAmGc^=y8WksR$>8fi8w9T|~uA~-XBefePhZZ*B!u z?WpuL3SBH|xn8OOOGsYW^pWpV4Zn6SiW`}5iTHp~Vq{HaCm1y0F`g_nGoTqmy9~bTtWggf1|lq5Yz)r)g%CjZO`Jz(Q|`~QvNK_v-wW?46trR0lAX0w^_%nw3i0Zi-MINHuKGOVm zbjEoq22G1Zidvbt$dhpHzDpnz^MR!Ikr-qHJnU?BI_;nemCXy{pGlkB!jaW6RdbbO#OMfa!r? zCLWc}I#9kr4+5_nOEar_$mXpv&cpcAX>;E*@8yFh`tfvV04~M#uJXOj|?N*^!ur4Z(5) zROKyV`g%Tm?Qz(zPVupvo|PTk%kOPajq`k}L!9(`yci%} zPA4tD{cb?!E`MipnP_imhr(+w!GT?J%7nSTpS9-KvEIGOmiY=G`E-8l#VwnbZgaeT z+VY%AY`)CgIoS*F;<_v5M7MoX4di@55qk+f`4xweTP^Z>R}b_AbC>W0BL-u1A_Dm9 z2?W;0-}bw_@11JU&2|hW>a$u~|GQrlry+}HHQReQxc+vMRF@~IZowsOGQATjLtKHM zxMNiDuj<(&T>3YV5)t`7>}+9V`>)Pl{|W9`{`_w!Kw1_y`z)xR{{naRwMREn2z!D>O!-ofT<)rdkt&=?PfW&+EuA;p61R^dJzS0{Uky!_WK z+M8qXtF^rLpt^17C+*Hd!Z}e1iu_(9!9-rkgRfuvCjy)&@ZtNTC+;jbFgEO3WpOP$ ztrv7Jch(G8QvV_YdAi%LT>I{}*9UkTJGwGzQWgDv->sStV(ju#pPI(t{x);Bdnvqs z-wENeBpA_&B@{1m;uDmp$md|Qy&nIn4a*b>#HR*f?sXxT6YX))lI{^V+`X=TMD#kb zkKEUh@n&b|Ji)_AM-Jz=^R)s}b%YSf(4dm0sb8b2COu7GP7xzq^nN>ZjP(+s!5~O} zC+>eae=z36+={H1$=|hP(J{WJtr$EWG`z4(UY=Kb`bsdYCf~Ymzvy3m=DHUi^g$mW zJ=$i~7%9HB{c{SBkZ<4VBC@#4OTU+319-N3$`{fvfjawM9}v}ZYiIL&D5<8m5!fE4 z<<`^Lpq#xeD?)OT5t_S{ymGp02eZ z{}cJc3R9pXg-S))7XU!XT<#e?ut=`*^b=Ly90trLY5%iO0Mv0pIyrP%-hhIDY_KpX z*`A;DU2DkggPt2bx_JE5^N9VyUc2hAg}$ucVU57vD*D>ha8%*uN9t4j7hk#`1$}{= zej9$AJle0Q-JsHq$%9-4o&s%MYy&t|WcB1)?5UwgA+9;cWd{>Wk|_vw0_EW zXKgds=aR-tf!a@{XF}v)8NEI16=!RMae_&Z5n^gdt?3T|*yNNb zFqjNuHw@|+cnZ|vi ziN58yu(7#4PbVPoHj!!N@B;?A zTW2VRrL$f$FfQyn^U)$(6@~7D zER`7o3r&>?&ZaH$1;w11(FWd32HMKHb()DfC>ynsSM*CTDMsid82$B*r5ji+${klr zG$pGh!n?vwbkI>GT9VQWE$cs%V^ZRD5m!jyQ5wpt=H|+U*%EaqQY3<_;{c*}Q&5B6^ zTEZqrh|-%P%WH$^hxwFw7(>u$XnLwNuy z%+f5rc%1QnpQL!KfiDHooU`;~=VHTpcsuUwf2J;(oieR#wfxo4hn@mf4N@OaUR=9a znmp|4@M!*9n^c>7-)V1AxI?-f^8uH3?GS-h6`nA*3FF)KPbCzHN|h7tE+WX1jDI7L zN>ya;P2E}nxT)YJW|5W^^a;83IUhRwR6%Q5^Ip<45Ht!JEE8^6PT@IF+f%9VQO5SbQUvvtockW!@sb!QBP z7Fk=_u7@kR(SN;a5A-3M0v9RN9#QgE`6`_Zmz0daymQY@xjpl?OpXIwr}f6GTnpH{ zvm{fb!@ki1n6}v2?`CXq>bG|5TBC2WLOZYRq4_aFmFA_oFQrPmtgBk19y}Oajl>i5 zN3ppGk-XzPb>L;`=9m{!WByH<%JX2xx6M1 z4V??tM!IH_xkn@$_|sVxa~%+#F=~_MSq)eSEts^36V6Fnj4&@7w6q>IAym(AfCY5H zO#(k>EQ))#r(w->&uSJS3Eo<-cj7WN?{tM7>BnoEU5A|DWn>k%z1ORm!d8=H9X3Pg zb6@#F9Bq#o(0wak@xQvRo?3DJG8x=u17Yh@oTlxZ{Fe&5iABd~B` zNgqJyq+7O$Q%G&6GSyvV9lgJ%1$i=E-7%vT7SyZQ$}?gU}5~B0!>VIJTnL`8;TgD%UB>CZykwsLsSwa_o1ngP$1m$Oqf{D%kK7! zY;k9Ji_XXGGLLh!ij1o*l*|YDF-lkk=erT0xKPoONwMN?Ne-_LN2~GUwbg+dole{C z4o`L*m@D=_%Id|h7(G&Y6-u6%Vbe6 z)HAtx9F5is5{p`_zfI3gcw_sdMv*+n8>@|r)yr(iUy)8KlX+^+RRA)~+OHR^`oH#z z)lZo|{~TdupJJsOV^fpPh7QX;tQ4%O|J%QdR=ly-{O|9nhn9j>clQdVuq+a>dRpYm z7$yyg*m?@N2CumbC;|?m$t5KH$}#(T0<$L}HD}SZ%Hm%2L{nG8pR<(zI$O6_F;=la zI>}9on$|*lTtSi>Z`=1IB)obKe1R&8*!Hu`S-=tU`#~ZLLC>@@=U?nBdV&i7?TZPGZDfRr1z-?>I&;Z4@o*E-Qv->a#R+$q+?`e>dV4#WJ8B$U5+4o zmmS5NK$Dc;Z)H-5EWwA8-*4lX5P7T{DOdKZ64KYBqMxgcpx|3EI5aQ{=VBHH^jXRf zTzNaAU4#|-vi~TWlu`8!2|L{+_Z_7GEXNI@AoFt>98q@!JGcvF)TBc?b}e*SOdj9c zLF_IxxqY<-rXwQ|)Soh$F50%WJ!IXNGP&dDVH*W}<`4296cGIuzHJ6_$9;7a^@*w80O1ac;@@(p&a!M%xa6MU-lY9~@j56lSApML4<% zvl!K{60hZB{DK0Vvj+W#*Oh<%$z_0z?SCVy`-5oL+5R2TKIu;0k;nDu`Z2{jvuEaH z5@}uJp@UTAlMJyr4>_+(h&Pw#eeda894tx5^kCyPLT z%|{qfkhY?vvc#Fjo8-6W^F)I;PmC}KJT!F-V32AiW)~8db=_Pn;*5Kz;e3MmIE@19 zJm6EjzaGxkqsbd3tz;ap9u7xX2n9mEBrmVNZy9CVtx*a$&)=G|ox-)Sbl&e7=WGG#JIqCR!XqJE5 zvy)$ipWfxE?lq`cv*~H#>NZe+g1M@wsuVe!DdBvD^{dcH+-c_Dp=k1P&%@{}Q}9BU zc;-fm_P6a?dTZU@(;xP!yrx1$QT7-IraSQ&WAmE7_+_Cfm zBY?XiD}KuS1$>thBG!U?&rYBT=N`t14c4jn;tekWf(KTs`0|*O0J#kZ36On0L|?nk zcM9;a>BUTp+y+F3w{+_M&ahS4*U!-9qAgiQ?4Dh|RkI;yJ6a#Tc>Y&~=QYTq^^`7M z1uv~tFInyW(fVaGWk^r3<$zR50s=!%e9<$$sg#?soq=g@LS*G z{q*%hAD#@4j#(>udz9Dy&+=!iVD4p;W+*vH5(`dKGs)xhyXy`509NZH z2ZHdMNCxM`#7RtfvLYm&%<9~XdVfz zDGF$Hm-kE=gn-TeO}fBheavSK3TkKR3c6_zqEkef0^JWe1Z-V_g5FU_2Rr)69FSMV z;Pz*pa^y1N&mA}iH6m2UC?W@wRZwn zcn+P#Bjdo|`S|si!Qc0fEUf{ z*SsnTwVyAlD@a1ml{12R%wh-zff z#Fj_q(unmQXf2cq-Hlk-FoV55q3CQbuPzYyw2j2+b3a7wOj|t_wYhK(qLUtqQc~Ee z3>-x%E!ft`vV1~VUeBzBY{%v}Iwxf~zw2SgpD$N*>oHDRKHpNg?b*&An;162Ey`F# z8&eoI!fMKR^tWg#Mo(niui-@i@q2( z$rT;{GiD?fC47XHjOi!QnV&?F`(VWWj7ouCKaPUrw%v~3ke<(biBL?4XV)2c5h@d$ zFjfT!FOd>%=S-*2HgRj*4QWmL{uV|wJDJqqxkdh zv!iPU>EFRXM!phKHgM@62eG|$xFKwm^8ZvY2vZzdBy%4!Ka|P7aHhi`h)_9K`9vLu z>R*??1gW+EA9(@Yl>LNM^8XYt=qT<0)hUV6ULtUgGUzM{C0sQqXQl-f`gN5+vX3v1 zUe7YD>FDoo1mEPz@*Qj9H0W&!#Wu#l_bEs&sXTGs*&mk6zk&jCW=bHTU&#q2yZCYt zbS%A^ivH%q`5yl(=rI*~`&_}6koe3&kl(b=lt^~HmKUKM9t3mQkAO!!P>hX?i6nx0 z_NQb-KsS;_9w}rvUCCtQVY($UgHY08i*64cK$oidp-$kKk(9kL+2nmh*i4v6Lreeq zWiSC<$L75@<6yTf66E`!&wk(ei|c==I2;d~Tmf!GF^8*$7gcO(D~c(LT2vo?l`6+OgcocYw7CK%^s*lVEyL~PlV4^ z`(*_Z;5T_C>_lS>OiP;hlbnrw}2p z7O&3_u7gT`Sj*{-P=1*OInaU|Kx80edYs6=lVpg0*UuV08u&3}=%*%ZRsb+1x}Id2Gse;j=)uct{}fA@Mx zf>Apk31@pEnQpVdZcsU{6I(O=1`Xauh?WzAE+xS|5WDhTCTIM5`1bG>Vo03j zw?XO`Ic}YXcdlmVwB~lfZ8N%0xgJD!x6)8--o}KhU;f6=v?T5(@vaTyzq)@0b- zuHqqEo*}+=l*+D{CC;2$={)6~m9#Ra>M|fyR!Msp^S-)iTiV!t68OsaI*!NWxZ86R zjwni)>FgrwE=Y9%29}ZJ^vIuTIs)&3ebm5*xQrL%xbDA$S;vb^cR_}2Bm2=H!9~{88MKZL`51iCXZ%U#mN!{qk4B;%fm))4 zqh4g*OSiZLT_pSy9p%2`=8H9yzK+sOH4!(90gw!B5;t*dwl1d|0XsXI7t03dnPiz~ zN5&;^IeE;cR{oD>!U#W>wy`K!%;V?&eFIeO%22s%^Hwj}hBr-;&#{gqqq*@zDly8vZeA*EX$q-%5IJ?$5i&0#4s4 zTE6pM$S#3~PI)Pcm@3#Qp#_waIGiWF->?}7XO{o19RDvW7c5-N|D$sJ|DXq+j3)20 zNfgnfP;EIn;M+4>TU@DJKu466jZsUjIxf*e->*5nnl1+K77PA~+Cw2}p$(a{v1Wx9 zNT4y;!0KkUFnhjzQaz1;-^W#%gF$yySX#CT{UJB3m0JaO1XwT(i9ji_(-RFp9 zG@i$ca=F60of&fFUqXf(yuAE8*P=tqn4!njbF-Unb!qY+Q=Ni-tO7j-0=g_-ua+Lp z4|U(~C#9elYKm}Vx&aA8e#T;9)q$}!vg580(xU{r4UN$P%Xh&5uRA6kd2{aoPr`Dm zP*+ypR@a`bX(yoPCZhbuzkXkpRmK59!$hyFjOQ#X^0L)a+W_sE9-FO_jFniUNY! zjAM6x_5H9cp<}q{C?DDcbWJp9N+{m1D>8emW9tQhhClxr}slmSWwgYzqS-0-vC+&v6N)uUTXaIjk z_sZOf`E56l9;v`+&~xRufvcB;pAkQ%1WDW-Je3gi(shd~!dDjOxFr{+K+PDH?<{#I zAv0>SEd`x^LrQ+okC+q(yB%ucms%bl-(DOP^%8CoqiGYWoPP%BJX5Ff;2 z>Yw$J0#4?{DA6$63)2mcNEHFbpl9v(?l6$GPddPIS8lDcf9R}%4f*RMGK4lUoKZ1q;eb1gh zQ#aKwZML84#BLeK%5wS4|y-=It{e&VG#;Huf)lMP3m}izGb% z-d-%}`k={17R-t1hm)wPg8~=b+jLnA(+{=jj|u_}>0Z1vXZ=ta29s32dP4weDymsx zmo9uJ90m=d$fa=A8>(@8G)FdZ$dAaOl9wzrjWyElaI9&cx26m1VOnJJ|eUj}UnuD#1Vf{K5ITD{~N7SxW6}IuY z=tsLWhrFyQ%G=}B!F`a+zdZVAJ|LMX7u*#lbUy0twe35voLFTG&y zJEX`a0f>CHj9#Gde#zx@U-$N930d~P4|Fz;$Q`t2DV<-4N95K4p;!)zfBTk-y&oa6b<5~E#J-pq<`F}7lEQm zQjGn$9|P9k^|ER@803`gXA|vw-JE4eFM`+(k!F(645G}gARE}#b2gYv!BpFWF6EH< zB~1FhZ|fTx`iBaY%~=y>B2m?3nh!r5Zg=$!jrw)W1eK0`H}q z!NIco-{LdB0hXKck&X`qW%nU1xS55|c#}%Ec3;a5tvU)>ny;n#e4zl{Hn5T$<^CZX zS;cbV;e7q_7R|=jRD2uB6iN*Q>Iy@CXZ&S*9H*k5j63L}Gm-5<8-^aukes@VxA@$d zkU@MM%PB33B7@g75D=qj_wgO~Ej?&oig~7oPJYWS;ffJS^Cn}q>bTf7u*APr4RiP? zQtCOf%Dn`sEh+BPgXpOF@J@dRlz+HbrLgX#hee5;TUyQ}ws~bicMu_GB3n{QKSs~0 z=XYQ6FV&Xcc^Lu9hQHjp=>mVglXF;Q&9D5s^4tLM?U04mG3BRN-q@)a#@J9sIgh@~ z#6jI95iMzo@BhS^at42XlWr&RmqEOh!!G32Xb@o=5vC8+<Wd>y?K34Zx@)+*_u`=zYx2$=xH1tF~oEHKDhg(?`@Ww0S&c&x68ws5J*xaPU#~ zg}M5;AJLxw=X+QIq`=~1QVjo9-Q3d^f8s$h0uRZ-U9#H{^#xCK@w|?vhK+Q@y3pa1Qtd@(JWr zz@c*!e~(xO65xq$SFh|(4Nv3e&;u3k-oi;WK={|vwr2%4kcSptIM}?}T2EB*iXE(2 zT~x6?pBQur=&mTjvfAP+>Uh299<@bVc9L8O9S$VsZWUdKR*I;3cC>joqUFh0wT2+z zTFmux2&=)J8+)B|i98>O@w4-gI%{gDU}Sk&<#}P^f}U^!E<2rWefWZnoy=L@gC_xmh;a=;nD^n}cjRw2%+ z0WyOocGHT8>M~l0_o~nY@t)=^!$VJ0CD$wDcagt_&0vhHE)6V5l6xhu2FC; zdCm|);3}MFmzaO#kr&dJYB0I;s@c&i!;JoTusJrz6|*Xs?M~>Y2OQIr^>u3S)!Orh zTq(;oOT6!joa+_nB;=Qt2~{ z9M@Zszpf1WV&`OskcglXve{T;3hrMWVmwne#__p5l z!kP$)@&rxZI@HRj3?U_u2&8r9eeiEpb1x4m?7fG;Jl?M$hU?7A(Vxw`rJ)|DV~@VH z17juNP-A}XdW~J3eDQht^E41{E?eunx9xH|GroxZj|y*igA0lahI^0B!4!#yv`-fU zl8nMN9k+E)qx#fqMnu793ylaXOfNod{+d!^U>?@Po!6vKXm?uF3IJ#eQ6(4!XOSYE zx@EVMT1Z|5)4T@XD z-RX33<&*6ua$uK`FM=M7Sn}WPcCRz2LUxA4iqmHEs z*WLzflX7ysrZqF~CV;r%57H4}baAst!LM6Kedx*XO`j&sNALj2lGcwTa+zhzJhYJm zafwu zr48ee+)?SGSt?P!cu!W*MTVh<~~J5t`SVVQKM0`CTh5jR!+iH4Ko!D z;_%JRvd(#}(Z0k#O+gc^dnh!25EKyWL*3dtWUD%|3J^NZs+kzRrol*G{&cf`_B`W9 zcgtj+6-NOt2h8{`ZoS)Ls~Y1~ZSWImj+FQ5Bd(X`jgUL0T}s#`x?2Pn1a<|7^ zvCN4&yS|2tNhaka}CYU@DLLFSJ)ipoGe=D zlpvX%ofFp5|Hd?4722eoDFWiSMUqyD(T-Fd@@DANiK8t;VR#uy<2sfg+)$)8*H1n= zYQaNgvA7}b9Rx^5`RFYh$npXb9l^SWX$d1KGM%~�DYHdgpXbY-KJeker%eX=mGn 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 K`if45^m3}8rcH+|Q-HE}C%EZQG>6QAC4=<0$ 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∈x)mB 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


77BeaJ%=1+O;fPDMN=yxjuPY+e zu_n-FFI+f}l_GT8~dsqGXxjOJL~1bu6^Eo>BO&HJCt-1^w-J1htx{zQBAZS| zhkt^%)M9s*#gl!g60l}bU|QomF z`*8;pdp<9TQBcU~=iiVNB`uSI$P0%{dfsh*zr5xXJhXNBd=PDoh;0Y=84`0d;2jBV5{INP|yF#5V*P#tF|B zFf#=~gEiNVelc@TD&5WAictGH#B-Im_i)H5a2?*(=IE{m_-76yp!~GXd)?%@yW~tM z8LD5_R_A3dCnIeU%E0!upsG^e0=Trja2Z_eNbbDIlXd`RGGjZ}vHR@)ky}kDy=xLj z9Ozw;=A5d;F^+}bV;K&Wvepjc{wQaGcvHE06>at|wBDBPa)v1kKJ-dE=O?L3J;3Y$ zJAc;)nFHDA`bEy>P?qYUUP@bKH3w(%-aB#bTJ)}%QFeJ0_+TA`b1hG^&d)&Q=D+zl zM?t>Tyolz33<-1{0d2Gmf7HFBS?VXoI!>3tgWVivzADCI9w2t_ca(A9X?>~we)_Jr z${lR=O4#S}0c+SM^`kH%_@2b!d_Fdfane$A)D6zFnV03yvBp3!J?xk`dJZvlQ+jzM zd)i;D{c%0JJ*k2KX&K};$5Y@(kdt1vWw6>xYKi2X|F@Vw;VD_*NY{FvU(6LkJFM|N6$#hq`8I z?^)ZSFZA88Z?2zw9_DGWEq~?w%l`}&WFwkXXj3DtQLsX7{^Tqo5rQu;NWTHx^iIEl z&DknDNU0fF`~i;_QdcyAGMDZJ6~(c_IU`L36jsx6&;N1|s;77|Zr*}Wk3TJhW4wKv z*qk*ld{cF?n6jVbg*;#xDlHr=!eH(@%7q#K6BMia=lHQVb$0n}W@HER^W|V{4a3CB z@*fhdOe|dg3wq~es=<%K1yaxUC)EQba5A+t89BO8;KbxwrA#x|Rzw~?jF_=;-oFFs z-#pjz*D<`GG8@%8^I;$&0Vf{31hK>K@eK}}nq7}By*u3wOfr%R6nW@_8ZrNiYvDA~%*!5%d$TbS9+fpDA|3*3z*M+kKXY<;^2O(Mq>Le&qJ>k& z3EvIZs#;;H&7!ASP7Uy)UEmA%ZavEr88Uev3idneI-1sSU=d|p;dHXvfr&^~1oijc zyP7P!Fhl6TyzYbSZKI{R;HmV}_m#9zl{e5*70P80YUN~ME{nvw6hqC?s@T~aY|TS} zfbIs)>T^6UNoq(BhwOC?(iS}Aov@3~jRWn99>s~%qvj~TAl`e_=ijs8Pez*sC)11Y z(}`%RLOo(K)l;4_#cuz;Wztxpfgift+W==JitqmJaN|VU<9B!Y+TGq2+x(0ee@BBs z5<&8ijo26bjlDA7pKPt2d}-CX*?XdKw%KLrGTIQED~MIUJf7_B)T-T9!YzZ!$S@~A z`_kYOpgCOdSVu>J$ocpESNv*-B6FN58hQ@}3^hN>DWi8ChKh8ZiGc?6p*AvMFy0s$mpOrKf6;U&=c=7`Q12X{}a_Xb?} zOy~wtr-$Nll6t+#MlfG8hKugI$eNQ?+(B#yAI?Uu#ig^wHFATId3)q)9W5%i#@e?D z)cWT-i`aoL@$6ff;)~1BV?*@~3^`fYgLMDI6x?hs;-D8mP={x@y_swWeMyBNXJuNX z&iIUJc9g6B5!da2T$7xlA{qNJSc|D^WVJ2?2Ml#hM1Ms@arfVW5LC);9Ft|unIjX1C772~cGR|R1VAqR${TtWC9=Z4hb3H959$VEco!0261q9IH3S*lFqu)4HxcQR(Y zR-mJiI;}bIfkyv>`0y25O8C}#H(nB7$oKA=(PtMc=@Obb0Lmc3JHVeAKx5_lL*X@J zikML=@F0}-WiuAqEE7%=3 zixZ2>4g7YO^AN+Z$4?AO`29q->#l&(NgAIj%3lBrL#j=&Tn>{aZRej3R-$EV03NPtjFFKtutu1lN9 zWOK;uQ;*NDNY(crcLj4DZUuI;lz~>Jx*)}z+vHuKx+Al`=x__Ix5potCeS|N{e8M| z#*x#!DKxyb2?&jwj?yOQ(&Y8(Z!e3F`j^WA64VQwk3}0fSM$`;f(j;c@obBN1XMss z@iq9`fEh(3Z&9%WGmB5Y=w+m;r@g=jKge$UKX}^gwm}_A+~gXRpj`2Sk5MbywOH#q#~C%kONm4l9VK zwixh|MAS;i=Us8T64G^h0PUOs{f>w8tFL*C+W`y5TV z4Kp=*y2{cMYukF|8@33n0i1vC_oMvzf8oFOE+LGKJlMzHjImq{fBkZNq*<9o5aE-b zhkJ&E1R^?Jm5whWt)0gOhIEHGK{}?x5vH#u*C^ahNe14#PR6q7<}KSHi^H-eBgI}( z%LUo(p-Et7#6u9Ow!JUc?Z*~JXf8x@U_=V`48{@YBSbpVG;avYIvK2G86+)W>k5xe zeu2w-MLBTt^+xlI^9$w$Hc=4ERvCD8oaQsvObCe7J(t^gi#L0Zna({1pISv~?*n#g zRTo_e;d|h03R?+DB4~FMTp@4QEuH!`*AxJh6e!VmeCehmb<6EU9of&-jSQR!rvr}d zDMG`dY)()>Es~zrOiBU7h^!_D>{bhl!gyOpM>8wp_O@+U-cMjyE}|9cY*H-z*1?v> z-++MvdCaM{tj2H*!0ty({js}1nw(>_V8ME*xWiS`Y%0qRnpIPp_@ zCS90Xt?I?#4+0doTJ}kiPx;}Zb83-K?QMUQWz;az_^q!n?QjVV24&dap8?m!MI*tU zb_DYhb5SSzT*Fg#-f>YPM!e%8?y(5m7WBa9vp~ovp(}8@%|F)%R-Zw~;WiUtgD?q& zBDYIbwR_|8OakpIi%Ew9g$A=?Fj)zWuZL2X1QrJGNg=4)r5o0Apy>}IbK}&vAfXgrEdx?=slF;`eyd|Q5?%?uksE5gY)i?P z)s92ufEB2w5g(t$HEw`x#)y0Gh7>uHQ4N(uw>1caV8A3bIgdwkBd{uPLXSh!0vTQ3 z$97j0CE)~C^q5=$YYYP&H`r8;GJ>&F>=u-NvC+2C9gB<7tRhy}w2t3vP%B>rEn(QAM zByukIN%B@U#T8f`*x;6s+k;-VufW}}$Frt_?09JEjoyfh*X2crsSkz+s!2Q;T%)#~ z@hdeNuM_Zf6^Vedz|bzevM~26a(&C;WtFA0Y3HAbc@$9)9{|0SeE!%T-MZhyezY;=y?7#A|bQZWl|fhhc1_;Ke8XGv@_NS?F27=zJcE1KHWKAs!~ zOqinZT9ti(Sq~3SJ_7ifGixB{>&UXp z)BCaOTH3WeKO$F4+{{PND~qN`WENvoI`E1l;S*O}xR)RfesyM*cF<{u+tXx`XhK<*x18%^G%c zoB5=vkrKA#mIY-cuUs;}iAp2{k`7%LUyA5}wK?b>OBR`Fq^%XoyZ7*zfcr;6f^Fn{^7qKD!(1va`mKVRHF;M{smis#|I zYO7S^#C1zW3P7k7N2$S0=zfVo&mug5@u1X=!!WuUpRV^pD)orczXWEmJ-CKhsMB)4 zr6!Ro@ks|0A_d1rAza5~B7$ei=xu2fdX{4LU|*HfPfw)&B?3R9cNHqA)V2;Vtq_Y( zrmOM_7-a>*MQ3B{6{T@pv?GAfp8r!<@3rP(Z|T_`g_9eAGu=>ZY3EEi&Sgg=T8YYS zKeHi#7uZlD;V>8TS}FnR{Ev{3*yI+XwiX{~AHK&S9vaI6)ztxjzAdwy;W4*`)Q2!*pLlgH|F zK}fJ|*&gC>O)q;YX~)%Xz5gRh#u{>hsSd+ATs|k$K(b&Y6e1181~L`e)ws_&^|xUU zzV=O4kP2_E2)78aSzuU;in~T`DQD3Je1UrtSX%C!?QC=d>mCY_PgWkj17~dnGzJdr z`$j8v8K;ZN5{p3v%A^%EF5_dx|Q zK`6GzQ68ULFn8A(F(X$-Kys^?kbyjw*zbb~e_hv>(@hLe(3)R0EaGwoth|f)rVT?` zopJ_S@IEM?+Fp8l*pFbLX!s&~6cJIJUWI9U4RYUDfn*ryjHzJZ5BWBPJL93(G&on# z)x%BJ>p>OiF&iez*zqqI@-gj?#(1nFfWN$7GEq>CN?+Dwt}x1` zv4*)rtWesg{s;dY(%*((l(n8rSHh33y6&AD`P-mR_)l=5dQ(n6M0LJ|S{*8#A6JQJ z7fwW-FS<>OE9LzpwK^4Zq`Mm2TmN$s=`WUKpq-b){PYCuTK_uHH{}jJltqta)a|^d zlId*z)H2O~qQwAR@oRGfKhpPI#g40*qPurAnE*MaT$9JO*ZtYw2gvAic5!GqrffX<@V?}Y(? z>is4Rk9>;_JQtg1tIPeL552K?Xw)5@VOcJv0b|GY&4%0K?bldcZMbHCyM|ab! zcm(Nj0;%!#K?47ih4biBbm1L?@Jnc22Ii|g!mayuiGT&(=wATd?Pdh0d{p03I5R^k z=@-bi1%BTpd^tLFq{lPbiQm$An+D}EOeplX&GEkJ^>C+=9p=?zG{K3C*T09sZo2zE zc1WM|p3e>wb7-FZZVFw;hzt zNG>fCYkTfE9^IKAV0(X63;mQf(bS}Z97*>aH6n5`i^M~$+CY(XAG^JEg#XJ^f%U%x z^4K~57ai0|JsXF0ag5LZxr8r4${l|K{Q>eDDT{0y9g@e4%%!vpZwi+#)F@1x?B3?- z4-;D-7rr=@H|oi!jX&1C!<*V@WnsmFeKBry6PEV#RL1_<&;vOiI@b-of3WY9PqX`F6OvYBn;{c$09m>La+SY-0Qve zRmOvmOH_A+0>g`DX`Yi-reGOwBb^+_@4N;nq0Kh8x-~AfK7oJ|8nR0e|-7H{_m!^^t zr(Jkp&&&R>ZW$rkM!FsPtj#N8W)HI)ZCu4GY(-c`RxnTqH1S4=g)M6x-C4&mpgwUP z2Lc1!r;h>Xyzrf)9n|46V(qrCbRL=UMSAZWHwm}QT1SSMlGY(7AO^_UUyt6b4~FiJ z5yRXc3*EMl+VfT|rE~0aQht+nY8Y!V&B`Y_S<2PXN}=6BJRZvE?b^zg{GxEBEd73> z*Ymualc4U`VKbEKVzUh=d3<4MeE#Em^hOhDE33rbmsRZ6unfNP^Dp>L15K@r< z3vCH!A>NlA5a2x&xJ7VbC;u1jxA{61c@-`HWy&f;$o^tCVDq@An@1Q!P(buQ;8RDCW=fTnTE#e(m)m)|{ zP}L=9<@n5dVer_WqjBhSwa9;=^eyzy?c$GDo^J>%-dSt@sVNu95g*c)p)71oz4SP`j8HP! z&V(ec5fOAW2f8F^vS>DPEkMk1ocpEMwBhCA3Vx=jJxA+| z{nIoNVLmn3A|>y7ew27Q3iY8G@=*} zvmg9lcWuLI{Y00tUc4I&kiX69hUgHYVnHN4fTpc@H;01|`!JKB_%s2WnlHl0)N2TX z3>ugt`4XlZ;aw7*0QL+6aykFwR8xUKdv5_V9d??EO0UW|Jtl5hJS`Ajwpr;RV*tp{GL0bE4-1Q)&S*#5*{^Q7ua7w^lUTP)*_P82BOoM; zp-3m9*XAQ9XyXWWOkoTKP^!pB)m^T@J(LP8qniqF!7t*a9q>3mtcJxG8SALZZMHP^ zg@rZ9rFEyOt-0jJxL3SaN^30cBP^yT{38T2$N7SOgFWXP}xel~gHmLPUN^eHvr7vjJ`+ zL;o##MIJ7(6kd{D`8&R$)qdYK*(Ux~G#UZ$!&vj;N8g0QuEb#K?^)p86U3cG#~9|a zkNsZAR~d;Y!75f*a_9z==rnqfZjg1*zm+_Q50;RKv_E;4j##(YEPbP>Mm?w9XAjL= z)5<58a}Ue|+W}oc^koO0_{ZJ;&|;Ut#sdD}13S^-IKsDY+hI;Gy_#TscHw%{7&J#f zph-jqGmdh|xA(B2yILNx-%AFNGPv+0x(mav->x4Wy`$%OU}$_h89 z&wpJ-$BQl%QN!ZFr2KZ__){zti$9w=*LN_SrS$%|1w^gUW@0L3B+Ey(FYC)YN+l;_ zA%7bUab5m(e6!k@K&(@_rkbdxc9M}>5RVU}BWCG1HjH3`h_w#Il^H)ZigJy=AKbHu zk79cYmap&Bui4LG=Kh1pfR9e3U-|3A(Xj#YMp}#pR3aF0?bvS>@yv&N3LUxWR6UoW zy_akwynEQgJF$A%jxLwuHBa7ip1FOz?)s~spbwe2M~0w^9uJw{BS1PI@9ct09>0TK zFY@pd`X3|`v^&8G(^kNqyVw>V+dO9b8MTwrM_|RrY~79|;!f-T;p`oQYzelg!M1JN zwr$(Cb=$UW>$Yv%w{6?D-P3RQ&CHvaiTQW(L{(H(#>UFrE7y)vLyCpCNtvl4RVtKA zGL}Oau`TsJ+~6lWPem_qm z*i=HXu<$|&|I$H^@uJXhaC{iRTJP640B~#}Wuq7y*gwz2_m0dm<2j_B+4`*_4|Qtg zIm^k`M@>yyXQ-c5tP5w{D$3DtNa86{i0s*IGFFl9xBV!INL-&R{z0;Yq>S^tz$F}96W0wD+G$`O&iBb0{Mua+R*7?h2W2W8MxjpGlCntfeCfd-DFS81 zCa2X&Ee_2*U(uHcB0V|6&yc+mHBRmu?)y%;gyx8ah5d7QeHVKqW=dzjace$o!d|h` zCi)N22KXTD%Ig#`-hteQ&-heFrpsHa6~RboOres1`dzL+I^uTL5Tj8jK7~V>WHwoW zPv+(u=sg4q(bh5{Z;xz5^XQA=0j-#7tr_%Qzg1*WTg6EUf>w(e~d20Xf;2{@*v+j&ybZ z17rVZLgHgS|qPMtm3a8ATo6Vog``2*OQkyhj7v#p}tE~vj9>5 z(L~A|r!yyx7e}+2z%e@{neA+aSN`Gr#RmZ=_XafJq>sjPyxRp7}P|o}Q(=t`!L-S>b_6^Pcb} z>4&u}p2~R}v7j@?wPgo4QQtB@PYNX2C*@3h>5p;Gw8dGGd4+yUVkL5lNK6xQ{WYZz{S|LYVKg zU1J2vQI3d#I(WR;)LTIqbUbGSFOg%_&b-6zlIq0ztbPBWZR@xQ*#E`3E%oC%<-8a)prWWP{&>Il3}F^y z;rmCt>0Uj!3NyMz^&D{<0-p*Sky>R>T%k-tyG%!iC=NY6 z7<!!%WmYwn9B=vPpwP{>!^XPNT0L*RK}_taqs;+Ez%mD?kjT`!(- zk4o$*5Q$`WlIr4I#T*yfM3|t#4rZ?8%ax2EXx?%L{Y$?gN55*qiyK3rrpO*Uot&)0 z*d@;-Wg_nKHh|X%1`boa1OWeWMZK_N2*2x31c2pW#ISP&ge1;;{4|6Df>ayNKIugwYbCiVuXCe+CX_tuAoZV8XqznVlj0Y(pP>9Q`vf z)$fA}`{r=^qQ2jaRmMJo*b~*G%ktfr4%QOYJ+*cyzfm;re{UIUh2&TK>}7wssA{)w z+BtIND7%JlW5dAt50J@yS-~${@5Aq^4^RN%!(ReRM51bY=+`#E|D7Z6S;NmEh_w<; zfaODht3rh-1`Zw^Rv@03t|6KWfR)5J3Mv<`Qw6~x= z!#xVbUEm|zk>6fgj6kTt^@NoRJ@z12mL1In(4j3!f*c|8WI7M|Dm0_0}lk zCeAbbjYIfpX;wLy$Qm(>1gc9`=J%6o0%u}{7g@cD0!Q1XRJV0&?Bc(IM^`y3q}!SC zeKJy1wQ#Ak?2g=aboQa-&++lt+YUdx!?Yt|;&8;v0cyKciN0rJWRpn}1a$Anh1~rN z9x^V}Palxeldbd!R`Iftc@wO1m+wm;y=^j3j)m7ul*SKUBJJH=jU7L*DYB+#E z+!pkzVX6Ln@5X#{k~4|rOrgEcP+gt3U%-#DS2IAekKZt`3DH-+g&lBJ#)gq|d$@T* zl(XaTZd%(DlgkGI56uzxd1)^k!ft8=go20>t57qDQ8Ypy)ugRPAQSD4K;e#;dvz)oO?>b@RIydec(Gauw17i3a*}9rbzz(fEjr#5{5*$2?xG zFQvZj;KH}s-OOf@G-Auwqrbw!!;8oMdbv7DVMjlHmn(1_iQ!icY3>CW-Y^N&m1FzS z(bL-!W(__ACpW*dQQYl_2o;%NaHh;%e3HVdsQ4){6xrU0AnpjiHwq>mQY?_F z$iTOdnF{c)i-W~`W+7S04U>+JZ|7;oI_X0uxf}$tT^-&SYeoA?Te@R#%>T!=C!;HV zU0du;C!wtOq`xtRo&vExM?$YA9(~jZ$xdX)@G|kQRZoXL{=AWI#};`Qs~sdS4-C!{ zVAo}>rWoq)WD$F!#n<(=_cw~pknD|5KP{ts9Zn&n7yX7?4g5wbUJ^Ujs$8RwWHgV^ z9zr8`5{`Xf_q|&50&(}kF98J3GUBb5X8fVxKiqzuS_CtM21s_!JBHpGolPaVylwjE zHS@ZMVL@l>88LHaHtrT2QXuZfwY+)a?zSLkq9XarT{OqRN?AO$(+NKQqbqCq(rum3 zWn1_MA@Ne6GJ-J`MN&d{_u%r4u(7zJWmq{<_DR!tdol7tVjOn-d}zz~x);|#?LvJd zn;gZ19BVkbnxCtFmP6G}gTw=f1byJ!B^#fAv7ZKshi%9IsR$6Q?Ay5n=#c%s<>HRv zrlMcHZRX9|Rgr39%4)>?ZN38u1!)8?*MB0A|7=#Wg8CLCp~PwCdi6ZG6Y6j?AkoP zY=9{uZC}riFaID`y6r+X+p&}E58~krx3mtZs#$;jbhODg7B!)*KB~ZNA^Y3$&(rTA=(iz>lJP*XE=;QyQR~|X$)(P`>89PDZEx4uBu`cb zxD&9{J%fVMjz3fDUkeJAs%w>dqy@A=V9~ka(35Yjr{7H40-7(Xo(o{MCH;+mp|P-k9ip1D{9xxx={Y!lCsY z*Na7fWOKA<@YQ;&xF#jqlelKm(CuH;UuVTW-~q*r5-vvD3Y=k((g> z4xnk#_3e@h7TNVXC)zgJktztm{{3g|0{{7R@%t2*zn#Sg&liO_rybXB?5ENVjF{}H zrwVMjb=?=bIk$spmhkY%;;9{RUA-edzh*;CK?-Phzy}o;Rs*_Sn>Nbr^BasxP8p`> zd#f?^1e8e5k1!9&q=JkG5(r==PHT;K`2Byb^_P8`*2Gua*Li&_n|dnR?Nf4dx6iFN zsz25(8X2lDef_F^SR}Y=XSGRhc8lAiC5FziU+I_sbjOE*%J99x1>bmcpY&d$K09~; zrWs)^toD>sWK9{Vls=Fk+{%O#WDA+#x)N0W07;3QF8()g&qBaJ@E^i24-WyojH#Wu zvjqVw)Bgu-Kc%AmpTkD~5&JHDB2X1)*H(bi?Qp^DWM%cCEaZq?$XHS{R!Ee}EW$!{dE_qG6rlPFFqek^vztt9 zFD<-;$C0_>KW*c@m&?lxxp;{A()n8rBtT_aw5U;R5#v!*Df{Q%v2U)7 z`i4u!BY7a&J~Ck2Vyc{+PBF4i|F8zs8MH$ukACoXO?TTx6)_qO`Q)zd>?+29J+JcU z67Oe}Pn4#};KwDB1V}Pu(K}v*qe!I^1QAk&YcfiTyyr9%zzNH&Nlu@U}bl2$%|QN`ZDV%i@d7tcrD+Ipt(C)y%di;|bAGa+HkN zdd9et|B#y-sf)&>*)mQ!gc$Q&ip-L#V`5Q~rCJo16X>+WNz2&2V5bP@Pb_0yDe>Xn z)$+&#j4mHCV>1aa@{(7#!xp?2i?2AeiSVMmQY)cbZ#3Ay@ zJ+@dpX;y%LNSsHsVxgxL#mx{(Rw^4qDJU|{s>YEVE+@ryB%(bskx^bscx2~Lq4Od6 z+cLO%(a@&OSPq!|j!i}L;>pJ0j@F2&NgBp3P+? zSkVlaLL9Dcy6E52A!T~)<}uC^}hrs4DQ{<*_jDX@IpFwR=Je%64;XFV`HmRW+w z7vp+WK_cqi+1`rWbp>k;J$49VeK^n3lVm2roW{`*=$E3i++Z?Acj0iagJYIciEG*S zavo))GI#IlXdmR){MK53e7xZ_>;Y=*5Yb=!4p7Cxz!38g)T;Zy5I&>#S&S_PDt}j5 zIiXbFFs+2GnUe{l$KXDP5WTgr3+hEr)_8R#IqVYckKRBFvh9jXOwhBrwO?_Q{&sTM zl>v6o2?!#CT-9?J&{$HOJV|=2BNdh(TQehApJnAR4*zA2#&f! z1gm4U7PL1KU{GU>6%OyEp8{@htzlsx`w*j0kBBgtA__dbQP`?WJOoS%*5}=he zu~u-zRiF>X-xT=KWptGgLIa@A&fkKV2!X(cu8&mwW@!cLz7*01?y6rd2-JTCFUDVg z6>8GI4pXIDFfe&F51Iy`?LWUa1cUrx0oa3f!HBi9+yw;Z*m@0m)2gij5IVqWS+VZu zMweLuAasM&v19xxwO0TLoME?JS%6AxbbJG>ajSyu5Nrw0+YLL(Ooyp6S&UO-M_M06^6|OvuDK$ zsD>W4@LjQ)WpSUIgRp}M2ha^{{e7s^MjUc2QVpU#2iDy;&C2?p0M4&9-wpw)Q~a(U z3lQuQ!LVIgapLdvzacr?rl$^Rb{~O<%6l^^_NrTS5>L0)O}cGZz(886ahH^PlndU} ztbhVd6?lh$twun7VEz^oysN-=xcdMzsM-D&>b%$GEQkWnZDV+arNNy5ui3XkVvG;VosRdvh{X6OKT0PZzcBCDSfyYM@L>B$fP?0!ZM{`Ua0_#CXZ zuB3I9yZ|7b^JePzvdD4Z{aq`u4!lu zYe}@ZG~M!O%qLT$FqQP9ynqA8I@4}?894cd_hzcTO;Cq*lDS_eaV@7Oe8S3(-5D*7 zuvxfTtoGBUJDP~x)I!uLQvpD52Glv&^9aCNI10>?6g5j;{pD) z97*#>MTkQc@t?=#{{kOqrPtTn_J!REgZF!X`&aw@{rvd;%;^0(vGI^5&*%rkPcc_Y zKf^&7YwITSiQ$fN1A&7@$Ub}=Ee}SV$in2iq5p9AYWp)deZy2L<2shaop=A*%ui&J z&?QzOI*w%+HH(E9wMc4YA|A9=m`cvv-anbDriL}rR7DeQp(%+m)8NRE*)+|NI{4*P zl$rQ`r!U{z#oOyU&hE|{)P^#Y{o?h&9J|~B_H^|d#Y7e(NQGolGE3(&Iq}YF8l5sd zK4#MLe7$_WQDD7HJ0~N=!MvB~MksG!mhm2~nPG{8Rfg+p+YTR|y@PJjQ*GA6^mBbZ zuR(hobj^$A_E++yl1JDaV9lVRKwO$F)s9IMX!BP5%}PF0{$(GKK#4l|@Eu_zDhucg zMax=?luk}Og`XySMCvXq?e*)r9+9lrB`o}N(#Jz=?(|e$ycmy-#L^w^F6LV~KGwL4 z3;M!qXK62X4AO28(^Qpexr^ys4qqKXS8o`5PW+>dfw+NdQEay6?%mTN9YfZtox84_ zx>Rd|9og2^Qph2hXiIrO$3jGvh;tEHm2vbHIAPvx+R;CSH&JgkR*}e&(!eUI^=5t% zf0?e~g~A?2bMLQ{b2$DdN~c*&M|8|4q4})g3e$A#P zYFvHt?sp)nar?lxmRXtKD5~Gl6o+opcdnBO_cYI~8S^5k+pfypsABQGXQwdh%gv`S zm-^Q0YUh1S9rfG&I{_SNg=4r5Y`0DAG{`mTt--Ow+!U@1wFwk;>(iLVIQTFh*7SG0 zz(D3+Q}=aro@@pfevE9Aq9{>!4wbt8+Z;ht7>XA61D^$Xi2i?vc&xwefc}qV!+(W% zjO;9&|Gh%+e}#CA|0jqyr8yP5$p+JNLg{QnAK@zr3E@aJ3vQur;AUQWMG86p{3Sh~ zOlv(7$wL_k(2230I2Cs&9+{{cX;Jlu(hT{i6~jCsSVUbB#Jnqt#{D1(q8}tT?Uc#{ zF)@O(5rE7Can>J}#spX~*oeUssSj)N6VHK+m>+H%g&at>DIhOwltV;n1eCf^AdvzL zEESV}7Uh;`4gf4OJDv_v)Nv#Qf+pcOQ54DqzMPB_>!w;_?6r>yIq+^SGI%5?X--B7 zsT?D37((gV$*i-1*-$XE8&d8vKL8=slL1DuTH&Q%P#FN!gvXt+v94wgrY zMv?;Qj3R-Ss;JN;Aus~YgeCKo)|wgxoF0+Vzz8C`JwF1`B-toC)nj;;))QJo8YvEl zlZXgYHnG&A0T-uVW0j2{ZMHDA*d)=|-oMy@J5UfQ6Qyf%g5>Wcb*RQLS2n8%o-cEI zk`a#PJ;@*UK2TvjbC4mXdxi^_qQW}(zJ%C7rt#>=d$fY&DW+PC4tQwLK5oJwW(1x% zPx-{t+W?95H(EX{iCo0^x4uXTphTqJ3;`gr3~{cya1pNH5&{2wcVB!?wCYuC9!a4A z1Q;$eF6?l+sAL$=JAHs4!B6z~dx1-W0^>s&e}VRdp;8fOnf(O`E&&>HB0@(fMei5{PqmL1kF9#8$34xdZN|p=KNhz8`Y(GLDSk33J1Pm($0{NJR6tc# zt3=iAWT-4*&ba0uZaXxhyyM7-ZeIb!ykW$23`q28m#h;5@&V`+C?aS^V5bqJJYl5P zRsNyB&p7*JzyR@-AYrAX(SDOx{e0}0e|!17oz%+XqfSdQKoyw!>xg$hLt_~F10gyL zBns#CtvLtLZRw#qHqa+FkOXckb)*HEu$1^zm8*^0KLVP)vxDO?>pXdAA%5%QOpc3%(rv@MKRlPgZD1Pl}loK|%s zwgthx#clZ5cdNJC26~uon)RDKtFokP3ACI}N>bWHO@G-%uS`oJ#&V zQPuPnzw0DRcV2W%0ordve#EwF`oLzG!{lg8l>xsF>1r8LtjVC`M+rOqp2uOqJWeS?#EH zv5=uty4t@|T#wDP3+aA7alPif;b;}=QL|tDU_jkUHGQj8&Ee^_8uDdtq{{vwPI!|b z(^<_a^l_BRxyo-Ie~R%?>SnQCR6C=?C-Exz;y2xsR+p%Z{__TC!#% z;GeF)9{SbdMf3kGFpjlI&OlG zSn?@+_g04W;ZFE)yy9^~L7mUUkvHac%L;(o^a|^hSv(V~rweKZyd3P}--d6{mb*#Z zMO~^M4UwC_eIiwsLt!&R?djOb+@Mh<_y82pF?vbwYD_KUspz%EX(au6H*6H-N~ZhS z3shPaw06R9`<(+H^#k8Uk4&}aOcWCye*W%DN^lMpY$-^xxnU^km;A}b z@;_?){P+CH%EA8sCw~rWPB|WuA@tlRJIK(n@x#KZ(&Z_ofJ^8Zxbh@Tk-Bnby~w*k zlLUu^N*)$j@mfjtz07^h!D=BBP*uzL7xm3AEyO(8V7v>mRXJ+uaUKDz0)WQqd({Hq zVhg@e)GB~tuZBap7!gx~_#!n$rsjbZ5;?vYsNQck|C8fqT0#) zD}X^v0VG5{MGHo~XJKJZ?Z<5uwhAO`5Dh9gxr@glAB^#MB_TFeP_y=kGU2Qz(j15+ zs7}xnt*!#auS z9#f29Fp4+F0UkUcg$g_-04+F{Np{uar2bS=m?nJ&{NhL#i!gz#Oiq3XUH`jmGIwi& zc@!99g9wJ@A%+2QAI(7I1w6({2UZV39AFm3kl3an4w^YQ$OtaHHF}kaGOV~O*iUqT zB|RRo8A}FiP>fqXCav!X8C-5pVECtLmOzs-3^6gqH8??o%A)x`vpZ^;!XBr!QO$$e zruAu zq~3Y}6u~!f7-+gDh-gQeYZF6YlB;4uOFBMh*y3Q-XpV@#xyXJ&I)gb9nMd$H;(dw) zF(fX+acy}t>0HsE+~z2MlYo!=$09sGCH~L174>g7PQRb8r#SEr1H6HtA4T5p0z5z8 zuP0Srem{>6y&Cmu+=v~$Q>%N{!^+aiWvm`6*$hGB@fY)sQs4eL{NBQofOT;1ZD9D9 zfH25t2Ubumh*fkTH_U86VK8#hLj85nRkCZthVr+^%`2pl4+vxMWJ#qBhiMbTj)M3# zQiK~~1n#|i%hr2WAsDmU)`gF=)|Z8iR-jM$d~2u^ z$$<2)s2(W38Gf@6y^>;-Pb~}x;XhVirZ>d4R=Qj$5M*U5;ET z@xTsTakR#6O5^dV7C>n_r`hf;p_+vT`EZoo%V~uk7x7wuF|iGr+9IA;3kV}Sq}^HF zbPNxM9Ju~HmFaH8r$za^qTztjl;7IP?7*KH@Oqs`Ph&`FsMmT)>w57wonkL8+V?Rg zd^HpF2C~<`LQlPNjk}3SIb>H`obv`Be?R9TcHEA)I(bwoL8_=r&339e6)*>Nc5O2K zmCU6D9i?sdrE@L08}BfxBAVYCT6S-~j}j-0%cD-QS-kh*)R5%f8tneNX@(5(bexZ4 zKHh1)?fsuXroO8wJ?-Op!p1~&Bw4HCj+0~-@5R29Dit%0= zoH-~a^v^SLar>l=gLiELjOPXN%|qF)Roy<$S{$BM{R30SE1PSr;^+`=fAJFk`C$8? zi})^+8E1$y53W7WdxZkqY{g`8-<~t>vCXZ*Z(<97(8q;CBj>$*i;{nb$AoD`?%lpU zH0V=jeAIMr{OFKvMvm9gV_%S`QeM_nocO?b#pk4M`#vhK&;EpY72{=Ey*AbBoxk1w z#(iB^R+;_LVb9^6KUaq?zCq&Ta3N>Z9h9dE3Qn%*Qr~S9K2^lYK(lJp-lqhQfLDWg zD!`?Yj2C$`Qy}fpV2%YGZ5r4aW6D@>V?SHp0MTvfAd zw4{ro)8xuvsVPsLHGzLf1>fZSr%%%-!olO?qLeXBVR zoJ}2nQ<06Kv#E%wvAxOfe*XVbDPkmGWMllT75y(GrvHpM|M%g4SY!WNMTwD}ftme( zT;{D;wHiB{=`PS=ZMa^qy3W@x)L(J88yKC0j&E&Zb#+N?Y)vv%0L$zI`o`ki zrJxYW@fV{@eReexqZ82c2b)D90Am5HYXH)4cX!{V04R8d%auz#Mxz6;Vl{=u;^KP$ zY4}72VtD?{%kAaPp`E${NcPj;^k;j9YZ2g1>qYok!B+Jb@Q(sTFfg+O1_`I4u#%jR z1}Y;xS^`KE;LcAMbXyeje&-g(H_Vh=d z-5ecT1UtR_L_el~=HGg&2s;nONbLIrh^;Idj_%jJJrH>?5^6bi%3!t2jiIddTJ+YGv zaQ?%cg8B0y@@*gg+AF&IgXZz`6Y-IU^<^LS`g7y)EpGv-j*aa>ywMAMdjk!2`x06Y zJ__{RZfp~s{jI+z){^@BMq#i&m}P*U>|;OhIF{&zy;BG+%sR#xo@?pJ0-{O>x&m}+BckrR%;oabUS$j8-CI+Sl zKn~xsqf-O>AAY0H^cbl>S`(P<9Gad0&flq%llQd)KmQ)|sk?vt5nGw-*}u%yRCJ;* zWqx8;ewaQF*#5XUzE__2%6;wx{+zt)2f=}O0?6*FrCrLt23F5AE$CX+JB5)AIlp^q z^o0rGNMWf&K><}{tt7V3)e{YxAPZ*Ctv9}g9pgGlZKy}W6f==LpNw6tY=T2gL5NGjlU1yCz@B{Yl5Ah#|0O4k*rK9^d`(>dg744#it+)t6shGEtWY zHs=~!hL2Ext8LTmH91g$svmPEQMS9?#PXol+T1g0&y z{LrXA_In(jKrhjvAmiNHq$dLeLx;DIZ9vIk)`p#(!|>D=Q+VFIpC#+T>6cl<8N0Y|rg1(CU0*J56tPe% znrU-$RE{{W&8&e# zAxEa*4Ma-wlTw+ZBsArxdb73l3eEZNv_#Cek!<_eN2;dyC)VW-2IyZ!;*6l0;vVv< zcI>if9rcMR)=5)oKjH~3#l{=ofqpU05U6=@ih8--ihD8@`Ti0Sty=vEUYi&H(TL~Q z-i`+E(*>3YR)xk=no=S|5i+s9EquM)R7lsfUW*w;EDUUu7-q5uA5CDE(Tc@dTI%ss z*xPQddgB)n$9|K4E&&UiK%vEC`uxsm`K}&W5REw`!cV3)q6w`mEv z@uPBX^b@SIiOLa7NfpV`9XvSY<()5}@DR9Lq0ca(&to};B;3&pDz@05uDFo(#0>jSp^-vWT71zX=R&|j=tVyz~q5PJt`2Oa6G%?pj23h~~ z?DGe$+JjhaoC&%pau{Qn~RMK?%nkfGVZZ8N8&i zBGa;G+EWF8A%oP-JJS%a=g`LnHzSxiUThul2+pIpqKo&V>CbO6W6Tj_IjH|O;nJk&^%g(~V7)xt z$ZeRw{eF3>s9@&BQT!NBVh+l$2T}&(8UYMei zrgiRKE-$Csr6WSH(tZ&8k7plM{QHP2eLqUiBJrM$yhwtra>N_x3BIHwa7J-6E~sVpmD97z!*W-3Zb7*k-fKpnbdw z^9aQT$FgX2#a3LPI6dBiQ*gh=S&#t9dR&ifa|W6B=m!_Y%S&8$0)qY#Kpr6^{YRi+ zhv~PsmmCk2Cw&UGkQjaRgUv(-}2` z4;mB{a$JaFjHoNa+!?adD7i##HQ#*J=z33)xO~VuX8C)3lpkI|e&N&~RKGFb5mKJ+p*+ZbrHQr# z!`lB=v-3gWNnOx>wRYDAYwVy?D&;s5xOh zplywRL4!*|v5LPKLG}%UHbG&tqd^l0TJc7xRb0~lK4}gC1*zvF>if#V;V&s8t@Yf} zp3<9m?MswLw+*X`_c2!+ZKfDPmR~ps3+Ea$WY&Wh)Wnj*8>zs|-pfb^X#R+?O` z8khHPk;tQavbtd#NyY&9jj0}3 zse9NrC%@~1m2usOiB`^1J?yRQs#P$nl-G4w2tq~Mb*)Cv>SS~+J*Qenu#)-@C?u(< z*^EOe2pdt$P>&H3U$=w?(hUZw$r8hvN&*>br=9+WW9PXAlPFV&(I=qN1HmRhqu6;$FN`H=H-TJ zK;%jCxs+3*gsh?&6kqf}*0L@5h18v94jA|T1{I3!V-ora+Pu!ylG@Kbcbyt)WhjMj z5};V_ikXiOHw+mhur|+ftv)+2c8BSWULY?_m$&^4^S^w8B}ov`t<`IYCN7ev-~H)R-mcTQUYGa0-aeWb8G- z`x-Dj(1<^}phXs(_yvA`+UO+P(x*18$}DY5s*s=&U#TPtETrAxq@eal#mWqLWrjhce%Js#)9UwJa1-brVRv!+r)apO_!j3 z)Zv0mS#s-O8C^u6#J3j!%dM6Nm$yH@Eth47Fkz+4-0d7*nAg2Se^17J&RufrEcW@0_WqU>f5)Klv$5yBUuWS%4OBH4h_Y;I< z;#K3^+pPV&P>H-JlVf;?MhCOiw#~~RdFr|u_l4sQyFfavm5C;9z`P3mFt=|~6Y%1$ zeaifqDcfB3Sg)Q>m7a+KoPb1Rx;P(1$!24Wv-GE%Q$DaTsK?A9oUX_P=Or`JPx+xR zWy#F?vFmvgp*+H2FV);wiJW;4*DI=4vvN#a_cnJe< zFI;Nw&Pr0woTdN~+K$UQ9VGJ)sE%)5Dr%NHAJ4_y=r`W+vMqSZ7E(E$IiPLn5T(`K z=M6q~(DMUP9Ivo^9`}mYgw2H(tkBw`?R2o~d1{_jJb8A<2iHhl;KW}K`@DblZc6#b zwxnn<>wOP@d8xQ7i%N|6b1C>D3pFfsBM*Fva4~rNPeOj=WAlHhrZEw-?qT6UHhVP> zT}Fs}TWh|j^R%-*pmfqm4xmc2F&#XY%*BM`m6AYRTVWR7RATU8AVW1SQf+I{zp;z# zBrad961!RrwcpS#VvU1&-zd3gb2EN33%?R_TjzGa^unTZ_-ZtHInsny>~-v`g|gBi z0Fb9UQx$^Uh7@n#Ai>8Xt!?jh6Gs%j@DxM7UEfUyY)$i2-A?+NTxBD5fk{sweka!y zl#*C-xh^K{bKu_`s~eT2#T_-Dcm&dvBhI-J6?V#mXHRTPrKEcA+3O!X#8wTsjC31u zO*u@z5bm>rr+WgH`??JLC3r%4?7y;oH0BJ2<$h?@h7c}^^e$<~iTp;39_uF{nN!5} z79&9CXO^Q)=P~V(7JSZ_hU`f5qvYj9buY}L&#eS0<58jqFC?8=>XVUR|N0GGVZHW0 z0?&0p-^RJWFSepq&ZG^WnkSrEe!_`N3o;Md!)zQJ2^vaKA5s*gN7Yp1QZ$ z`J;3y!9m^*XWfN*j9XXXLgK6N7B0F8+4*GO(3#9W%rW@VKZxAVR#G4>(Tlc)aljbV zqz?ZiV@p^*U+i0sKi)fkJK8EVLV|N**-7aH>ZGdrDB`%@rQF)faDV@Wki!U4!qvrO zr}-*U4mCr`aXvTo8JG*FahFv7B(>e8<6fi9Gj$Yikljt%^&$y>?E3KCUD){yG7XDl z$1?%hf(EP)hy9BM5=?`#lYpCG1`M>x0xae4Zh@8%q!ffoSJC>Mwq{emv8;sx2Gotd zMWeb%ES>vZc7C?VEneZSF+_SZKff2K?U3XevdA?_*Wc8v_JzH20l16W|;vefpM1M1O{h)_tMAnHzDoC3`Z<6I{N(z3v zUjP&;S?~ZH(WP!fJey+sMBCxtAPZH1a!sPAP+4M9D>=D`FCOUi$*5=5{1#bSnUNY- zw)|QvEiVb?=0k@i0iAZ?K&NF}trZa!p0#^ThJ+82a&H|xAg zRJzp;EHZ4yn_}^cYsUIE(UUHuHh9{Y!390|m1`RCzkUYqoaTz7HcH^OHG7~|c7dI7 zqhu!X%S#RWOFIq&r>e7kSikdmQPuenb8 zwbQ61DUm2<&F!5!>-­*cwt^TGxQ3`1kLKvmW#rx(Ip#Q8wD)P$1Xng( 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 Jb8eQa>P?e} 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 J|GEL){{gOemJI*^ literal 0 HcmV?d00001 diff --git a/Source/bsw/Crypto_30_LibCv/GeneratorMsr/Crypto_30_LibCv.jar b/Source/bsw/Crypto_30_LibCv/GeneratorMsr/Crypto_30_LibCv.jar new file mode 100644 index 0000000000000000000000000000000000000000..27d33fbcc9457bd0af477f3c3e432cc7982bf786 GIT binary patch literal 2581796 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%0A5qM8BVyYB&bxmaJBUl3a1ZP>R`*(s`ZFH|h?+-J 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

Ut^s=%lg}u2-fY0M_okw8cB(@uIUL9Z*(th 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

Cn_xopg(2MZq#M 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⪼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%0DHqLAj_Kw}#5R)GxM7 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%0A&mRRLoYp_zjUgXBcNvtH88 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%0Aow@P&v>bzgyt*!n-|=ZZ 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⁡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

    ;zPZ!~$x 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 z zXqjqmId(cuEu?WQG+`tlvy`VaccgikEF~4VlNE2Nluyg8-s6jxx)Wh}opxKAH3_-e z+%eD(GS^11IT$XXzA-J!Cm!O&MUq=bG1=lpV#)LnpDX&Mx5{q@IOvn;8evJClqGs*;g|T9GzP8Ot7q(5Pcb1!UXZ6YA z5(=!%-2o^u3STb6_cMrf^{vv6ZF-aqLJ~Y4Z*%q>=@}dCwe(O9cY&QWNdyM%V1Fu; z)O4;cwKr}N!Nt@bdLUFvO-e0j?G*!JbE~hkO2sm5#e*V{4&Qs{ddxaxYiL&dy$7OR z5|!k{KtM-fn=d9v#rM@s=UvepR7f4L311_|nzhVYGKE^ahFr~^)U$3+kf`}HU5nNt zY>>i?)wR3Kw(R6p>$fv9L|2e7vh&xEU+;+&{S{(26d=Gv zRu*U0wT{xYZWLZ|EMYuH7jUqAvHEghbyO@x} zqzS>K>&I%$W$!1wH4K-qzBueo)xqZ&y5KCDZ65LqLo${%^(O z{J)Llo2#>%iR=Hpi#VWz;HkFg_Kp(oY3zzdf=wP6)w{F+MHE8G1-~i{wO!k21Y7VO zBcnKt`gl3tYxiLTqORU+B-`93A<@-gw(YYFJZm844yH#;ySYnpk<7z_{_LDWN`up+ z*BC?k^iN#XE~T6E_KP)_Nx{Q4mvU6>RpXmZt<06H{h8biOX@2{)#(D&g z9M-(tWXB3TUz6hkD|Qq=9y0=#nU}}*p#WB34c#jW0AWmVFiNUkk`Kt@(6=HEWYb=i zc3)`{>NO)fNiRJDt^hbd$G@^X-^#-QW!4B3PDJHA%QB5)Hj`#%^HmP4 zi=_Cy%gt}zXie6n+iP7*%!c$UR08d^&%chzw}U2<%feeyal40=8O#HjMByZ%hHf4v z#rqry{1^32Tz}R~V+dMn=hKp>Uy4hHxDACOn+BC<8#57SMwm~D-ahd3w`I+t4b`+i zQhF&j-#G;`?$~Z@^0x0}qg9U_HJvDA=l|xJH(9=V|9VeN`fX(7^Y6Gue%w(bhqgi5 z=6o70<282crEIo1G+nLGHfTOcEyE*Rw)I-A=b&u1gzO@ac$t}ta=NWxPEk&=;u3Fj z>6o#40rLhq&=CjdCdd2rge12qgSr9w#4!tW7i7u_RaLXWePJO7Q{9!1tYnH5d{X;E zc~S5;v9LUDschmDWdr$7JX^IE*bMj>&6+_JsfdMMc&=UZFWhKV%nw$5vV~f~G;l@v zj-PdSzRwJfkZ24Jk*)S6&k(CPD1ZLyBf^ z3UFcckE<60(&81~SqJZTo$_O**Qn~WV`)593L=(IOKWjix71}1kQsme$=O^0!#HJ1 z(yQb*!)I#Rarb+e4_fg`9ksBJJD{`@Q9+M@04-apxlicy@Ya|wGyR;Ms$);>k~z1i z@Ge!ENVx?rD~QV6|M$Tqj~NBZNq%29(StLdBiWHeH%O@O`nV1g)-iUycYq5?EBk#XaY*Hmlmjq!8sBf>0euu$>^ z-mMSM7QQ1=_53A7ZdoRlK?odggeP=RF3hnY9MQGv9$ypiA#!-9DV&v{YIo_;a{(;k zH0J&VM9&1b?Zf0U{ByDARapue0T(Ym2+OQg0tlT?K&Y2rr<%2pyq9BdXl6boFE5a{ z4OA3PVdo6S9PBija#W|jZBR20Smx>iVi&vd88GRqu;CD+39)uwd_aC`s{e!4fL+6K z)S7D}x^VqHi^KNIX(C~YNydb}Hv0fMrJO02;ueK&-&8oP35|y03|_7<{7i6Ov#LMg zm(-qJJRLGmi=Djc2MSLdx&2fAD2g9Dq7Eb%y`2O3MjaO8Va1K-)&1ywf zgnB=zuNpwbWerkg1fLKcdUacwQWd)g*r&Z9GmUJ=#$0CQ2jXqyXZDPNuAv|YP0tWV z%UfPkcG?SF=!?D>OHXc-m)0egTThgYu{(LC`lZ_B*8NEZR+BCSo(pz2Rmh}&QG8Er8vgpg1< z8ZDtyjy=(-O}mOAb3Z)4S!6mySj-toZlSMu!~-sxH8 z;6u@0r)T){Sye;r?NhKYCLALxp<-FxRN{uP#v?{p0^Wi?7zaL$xXBqxuB+gZx1&dw zY+;9J9dHB82322bIPg7=1s3C6asK#h_`u~C*mr=B7(kVFF!()+prZea@Z0^cmtu~P zHPv(dF8KY?f%cX6UG$G6m5FrLI$w2^K`smGyX>|KK?>FbH)23UH~CzKJ?@N+Y>gtr zkp;;;`nw8P`0~8rwY*O_OxSvMkkh9=G#@40LBLtvNkF`a(f|jBWKXIDPw`rWfA=!*vQeu?&=4)D*xqogd62(^m{V zf?XM&=LAwWIqaS(Nessk|4vYNF>3r_Uy#AEGEQqvv=?q)q{{;=j!Kwey!6^V{rOrT zUWsTZY4NFXRwJqjwJO6cG*6dyRGBWpErz8-y2dVH-K1?|%vsY(D6tFmOii3=z&i9& zlXgXNl{aN1Bn_GKCa}Nw^m~?TyJU5hr>Tx;*%9)}0MYNP)W;k-5e890*J4Q@TpLCT zOmEC}36J{Dw<)4kB7`;TesyX$n>mT24rBB1`)R%fRg26dmZ7^u7K?Qh>FNqB$-dQQ z84LO8&Y9L%ibY|1diHP&Dar9~kqQdMQ@^t+npxvxkH2}s58+=D;wii4Fh~%qUuR1s zH^5a4l_6HN`!F&MP8%RsRtQ;(w}0Y|%;OBlAnMRlgi~Fp$wqA9neNf+ed!r?9hVI` z3f&5UWvW1fjuTBpp6GizQ zXshQPda0b$REgzK-#NQI?>uQtU#w(d454!IS)b^f*2ZEuQ2c}|7UIi zJH>a$SspECR)QQ{;wII|5kQZZaYubd@ToMt9^8;;j3l6r)0;y;i@6J5V-L01bAn$B zhoGSdvoJ_=7>(j6C@-Pks~!|Vu^o-5`{YGrtVf@meQdv0<=W`k=rGiZd5gIo!)#`V z)xF4OeE{Fum0C7a_yme~N}_=dKvrwh?)DQpY1mnR#_$>>w#yDM>soJM(1u3v3F25LUj084lL*^xyzJ6_i;Nep4{bYtGNMOWdE%>BhjZHHl!kGkmv z#~W$?+jJw>e*A+dcnYL#PRI$mqPW(@=4OTMBeI|yAa2^C+5=5B0*9TY4|XLll9Dll zX$mNbdeXC>9%_e=6nTV*akn+)ZA<%|>@>fkkRL{I3g>cg<6dNxSHKC`A)}vvYTNIX zKa6-{`&QWpSs2UtZJDh~5OQ(-X8YNt{_35^pS5PTtw(VzNbCjEKP(np{U!L|*)zL_ zmPBuDVR9P7|3f@(cM2Btz^FEbv`T$7qP*vIio$cYRqVLZ^KE#a?P1_;lFY(AEl zZm}iSHhHzcdUn1IBE}BoBjSp3`45ilNKnf63(_&&MjI=AmLY!6!N%7$HklKj)nZEw zvC7YLY!Y@6EE3JE$m{X>gb5A&Qa&yX-2pby=U4e=!KYVHOkxHri4@8C23!)G>`N__ z9Kk`O&2PMlD#9mWZRzZ~P)Xe?y70MJc@CefwG0ilk!kp};0@X~F`8D#e)lL0t!L59*QWrJDvlJW-;Uu zG3Hmr0$|`g1h^aCq_3bvA3@g$Gnz-v5oMho< zs`j>b`|X@{=^6i=@@t_N})P!8|Cy~VWCb%wAQ6R!uu z!5+cjO*OB_D#yo+h{z9dKt{Ck2=z^phc`09sMYW;tv4S_NCaPn2t-Ng408W~*2 z{HlwZ+h(cmSm;DWC|L|hEAmgV$HaVvxYB%uxhi5*Q$}@77s;kR+;EBS@E7QWSQ>Oj zrUkKcTVLrO|DidspFQkS>p*YRiCeK7I^?jn+%{PJDQA!Z+-JEq9Tv=mc`#*H{(($3 zU-YT05})t9rHwAbCyV6PG*b+;O@Z+2S6bG<^~)TWHe;O-)}hgz(jEpS_?ov6m1eW_ zjr0fyK{2K_KQNX!9N*$B5!itCD0`&H0N4N#)n&?mH#{F%K9(I*gSRD(V#U{9Lc&2f zJ~3QXa*uveC01qof%%qr^yHnu(4c#&IaA!X=ry3t0EP!F|aFCc@_@s1MGPA&C6>3~g7T%oa znL|TIw~t3J1wXP_Vu~}Vz6MYdtd@=E+wC0EM{jNes6jF@F770djuEs9) zha(4eXsI`eCDIpwcY@i5NOzkZWk3WBLZ^In9t8dDhK)FDI6`5Idd5x!*YE~+=ti?re*l)d{6l6oKYni|`#l3Gx z`q|$f=&r=Wtw5>?!>)Mg_T^M!4jC40#~KduCEi+;bWuoS{RQYs;mIsmU2M3T3=z4E z#CeRFl3aLkIwjire_~nl+PeCCs!X(M;_7R{a@(5hQrPmKcfyH2yRH@$4dI=51AM9lFk{VQHFrh&N@wNHj=4F?BxQgSy(ext%A{?2( z8w4w!&MhS;jF8|bHoBVFT(TlW2M=)gcHatLuk<*Ju@fgMHWDab7KE%9bhuWL~_9&fx5& zE68}J7~Ty;ha1Mv#Oa- zjkYAeL@Q}Z*;R$v0~9O|blpdfB!~k!O0)<$#+0>mrL-I6;pHb6^O5@15jb2MHTh(z zU_5?_0Y$O_Y} zgUH3r`W*$2gYVta6GtTHrDM={T_bYiG~(ZD@x{=0)XdH6NX0_F79rt#YmvfKPN-Yd zh44ghkFxMug-KKI>-|#BBcMvOxw&pdo0xfgUYJvMa1MH{!X(E{y7WcVWsWn81fnFd z)qc;VzR*gmB*v6@)|*j2Ijt0z@(;6YGXF{ah%-zh#;ek#D8rkW(ov6gkjF%((q5Fo zK3#d1HH7H#2b)Rz%z!Q*lP#t$Wy}*ssmpne1H^}Z#S;@?yfSLuwu!GfY#c@(_LFZ} zwIuGKwn)0aASZX*lxz3vn+~9Qx7V;zo1bx>LKW=f=E_&dyil?A3p*w#FVhBbL_9Uq zgEj`-A8Tz5q&$y5omUG_6TGqdfkp;|aaN`JB<;x#UhtK3M@-6->C?q+JNzLhY(HSv zQSXbN6)eE!Gx$SdZsN-lwTZCC6$h_TDW7(Q>|SsvU%FLg+*7j#wmPuXgWYyyQ58x> z>sZjjsVqB~U)X-gZttOEohuSBnUxygHbFtxaQ787@njwG3DIob3%ePn)$3*#xvHG9 zpq%KB7dpF3@6l^HJ)C}S?I)zaUK{Vllzn;Bemrh!$z6ilC%L1|9y=b=ue#5&zAms4 zhSQ%BBGg$2t2bLeSlt`Z059e+5_7$?xZY!m-!}0CsRSz3NAm(3T3&v`MVwE4!@^t!84D9f2*dxk}(hvqEy65Jfgm| zdiT!+YTFIg4zH7qLV_(!eX*qy4udxuTv~`9uEk~#0Sj4Sv9CurF#gf+WMVAc(QIPV zda=wSk8E9{KWXFO!O^_g8cGiEknfxT!^3NwFPC3I=!?Q5STTF*pg@f^tMifl8|Wi7 zd0kAWQEaY(hcyb@Sq38Hm^b3O&f4CD)K@MrNWk$3)jx{wVCa))EZl@g>C+qWOm55h zqmXd=htc3P&;Gl%nExxhaNMN{DB{2p(x3eH8>syH3-i#^g7WKaT6(3bF^WV+R1i@u zp8{BMqwzQG*V_3dT(H6uC7epWj*J51wz#ruQvoyI{kPIuYaMfR?2F~OV}W~Af6DC? zHG~{GB2$4#L-t2LQ9?#n4(~s%aRQ7Xkq7p6F?iuk^uXCvt{84Y(VB@+tL>iq7S><= z&6KXaKYsNyx1U9#O;cV@7G@YK(2qFTG=p)vUB-dPdM6IAhw#_&hN}*eZV*6oq*e* z+VbL6HH(%ZOHIJ((@k&UGy5?*f5*jBab&=i&2O?RnXi4jND5va&%pLsu7N^fFb11J zlu+38l)Dn(VV8oQ!~qzLw7%gvhGe0g4wfeMi4AzFm|@r+sPtY^3sGBF+_1P(RAT$E49TdZ1`f1KU<%p+1}&0#C&IG&cWT& z(AQLOk{Qde84*OT4S%h&R#bn-wLa8=p#9i;9j2=tKr#auBG8hDUIev#hiZv^4=2eD z%7%Hh#`$Fd7#*mG`h47qE;PE8)Zoq9$%sS$9FgWA%*4ZuQFj4u#EkQWuU$`9<%Z?)LMtmP#3 zMu86F=+=zG%}bBXTZa?Jz}=qLh05$)L{In~=I)D>Q+@l}fEAr@m>3PhH+hz30`Qn# zf#!~SYplIf98Ej_O*ui3YWx-Fi}D`7vL^|pJ}K@8#pUzdA7=}<9~a*PZ$TW{8#D`g zz0FQHMHzR{8x1H}-&z{G{h=K84+KHY#PZaxLT|oOcuV|BF!xN5?)-2*7q&(ha-V!Y zN_&Jzdd|0uh||BEf~|~*(Tw;BYVOjEh}UEOjK{?wJht<^<}!E^BU;NIKWuZnD#5=7 zN0<3cdUx%@M;B>CMW`c^UZz@R_KAOBQoT^KaQ^UF8BV7jyy6XyrktIguCXV0h}wM@ z;ua+;a(w#3!A>Td%&)>07m1#Y+4aMrXxLvaR$q>`Ft!+x=?^B+k%JcZkBi7%A2Qzy zeh_gR!v~VEhc7kdZ{TZR)|*25Qg@d6snkKk9}gFuyO##_0MzniK2T!uB@OpX&P@E2 z;jG4ooyK@~apiM}mRn(RH-w>SeAC6k9ftJV~&s`ztjnxK>AK@2qtmQ|2!-iAPK7aJWtT z@kKvx#7-y&^F^v>V3#yiMVRVxHS+=IVr7s4AQSvGepS2KHEK?<$jB=rd+7e3;3GsL z1gy(+MNurzdErq1xr@$OH&@&%L8tx7IRLB;@K?||Mf~K);k3eZM2xfW{iHJbDw3<(I{;m5*!pEgNaK}=ScC> zZ<-7a#`%(w9WFnWD{YcR{w=l?Vdr=J-PG828rh*fl1b3^0GrpxLDIY5!Wpp{L)-<& zctVi@_9tmlseH_9+=8a>NSz{GEp1KyaEC=9W>hrKc>T5xlv_eZw*{UNSN!t&_`jE^ za?M{#oUFgl$%VF_2#vJ=?!*5l0uCCx?5BVCztI0%<6-`RfRvg2-#PgIk64<&KK|c_ z=HD}=QfzV3A!wBi3NdM|P_WUP)sph;g2S8a=JJSINdArmi6%Vb!+M2!N5Wx}a1_aW zQVG2(g9;;xRc2Ubw+XnJI2G`JeSQAY!!CfJ48$#P@0&9HV>>zPG{|n{X-kb^^DOb6 z-e5vK(;S9(O_UTiO7y*XTVUt6*^eN-amikX! z)+LOSUv>(|J+xKhE<~FTmWBza1mjurqPC_=Q{Qy4E`-g1fRtAO577~uDX%?v?6Ymn zq1g7&Et8HshnHk);u*PFGB~>I8p{mK`a?RHn6qDtUxX2s?@m*myh-i16~C_{F&_-! z0bx72UB2~~32Nzd&zFYJQWl*M2 zLA~e?0WxhcUe-zWpFY9Lf8}B&d%NG9{l%B*e}*r%|HaoF3+j7E3`pVAI!u#@SCVSM z`n?f?(`wm_wQg=+gMOnrie4=D6>M{uKII0YKV$&ta|#&`$>b|dKTnxR9vlUx+`as% zLs#1P?$A{ACPYUMI|?Vr$&}5XiQLASNC6{TdP0h7ERqQO34aE;GE`BFa~qD0@GM=c zNB~>oQcE#OLj$0HnWE}2y`G#|CG_yy$TBC?rT1GdMwc)zsXK}b(%7V?v3$HNQIgQ3 zIA(l|3!q$DYlNkFTbdj2r}Ldv%tRd7Z;q9?2h0g7;^CLuWGA@mql4Of!g%`ikq+E9 zDykgatEHQxNHU3wkk?5=Y2?yK3}Y?QTAs{A>4R0u~0_6B^FonUSgn2ZhsZ z+N8XdFk^W4hGefaQEj8NI@RL!0@AA4qS{~8*j9w`k)|$Z?5|3W5v`}WAbjK_0~~3m zC5aguinlvvOLje@t9)>Ci0S24e6<{Wh*f1}fYc!riX1$zpS(pBl$U7T4=g@S!udiU zo$h}v;HfH7r2P$;*?$Hw_WuU#zfwQ`GBE7F4XjI+R&|ER_q%SH>~xc;gcW{c2^`b# zvKuzeP?dYuKl$=h{~?YdO_O|@)|j)Ikp=j8e7eK`ZsCdktB*zYG%;tSe>synA<|;z za!Ijx0V({I(@RQ`!XdGb6Q)(x*9G9qJu< zM@IQUltJo#BBLL`0UNUgbDisgxh)eFX`xZGGW2ZRLr z8iHfS_Q0zaIm0fK*f%V4-Igo)RV=PUpnf71R zuwHg`k+yzs?0rg?flsHoKW&JPlyF9_mME|3O~FyjmaLg3$N59eu&&!1Foq$hM6+6( zkJ0zM=P9V@e$qC$A;O0{(*jIXF4 zj4+eQV&RBT;UpyYV)|+uveGprRt&^e2q+z?XKp?O_8uASHu)b(LZQScgBBk&yS9v| z!Cf>y%crL92i)x4X`RHv-Tt3y!qwqEA+={)T}R&nlDyBJyMibJK0*@B@PzGBsMilFGItSY8Z^KWw%6wHUp^ zwZN}v45&6jh)#l0Z4m0xs4)zN`dL1ccXw(3C*YSzQ4qYK&f(i9Y01d~fjxe7xw@yzI6RJHN}8fA_5lw3=Mp1-8iDFu2|ze|7yx<$kU`q`qyw69~6 zR?O;)wAISaHW{Va>84Kv5S<9QaSdJ(S}JNk2UJZLERM+3SGy+Smb-Q^u7@4}RS2KT zFMLDVPF`TMqx?H6PQ3HbO6f<^*oM(9#-SC?wgacwG=cLiWTE#iM&GlA-V1zpYBvke zK{XT1sCI;eTX;yr!)$sO9L3x+;Rt#m_SN?aMARJIOJen^-FS?CVy`fd{k$;bDQW?! z&hYEJbPJ~L?(;t}gipkouJ{YXt^bV4a{af->VBIQ!F*4KvXVgnLQ|9}-cH3fW)j!ZBJ}K1(7sh~WkJU&Hl#mVO^3@>HL`cO8gX!a z-r5P2U;2NS(kZg=Ni-xgCu=6x95(o6=f-weUd~~Q`DCw=8MT=9iSUG@wke3Cn!r;w ziotEJyFCClUcWsSnzz_mKgBe`?DNkQt&zbDCF{-m_WsUUTN7Bd@yw@6`i7;exP_@- zJLzYDCHu%rD>!hX&5AVV;otBWHm!44P|<3?(8Kvt_)CYf%Ua!K{*jaiE;p_>Hcau& z+ODi4B6|kzqD`~>+8_zxrx6mpZ-8G7u3mQd0rqq&%7Q@OE_Zj|xLKD4gyPri=`Y`c%rOJKJ zo-15N3-&yF6Kkl7s>m@WJoIN4)$$P|UkY46qh6p7E($e35+fxTe48M1@Y_0m7SJ}WhPTih2q=IHpnWx#ODO?TaCT74mC2eqy zhZkxn1cEG;xDuQeLs3TJdmyPd*>5ZN=_9(8BiOv-ah%j+F}-&rKh{c!CxcukeD7%~ z!@#-1FC`9oB=w;5r|5T&kd`hsG-95fiE&K|TuW49oAG#WE~lWE6)uJ9W(>I0rvj6H zXUsjB1Zl$rX^Je~zTc4MCrs2x2bYOmXQ@(%Q=EpDYvLf%2*DM1oDkUM_4RKF@7u*6NEaKA{w^wSwujF{I&+M9oC$B+#OXMTrm zkQE?e@VledPBxp;xD3KEZE`OzZ!Ug0srGpudq5$E)Ds;L#Q|sHb7Yxq{~>W*108yb z@(%o3Mp7e1Bu?O{ZhdJWvr$xk960{PG3CzG--}aIgXuDEzFg28n?}wbR^cR zFQs+YWuLdck$P{v&mBZgm5c+O%}l@@y*=kikvY=j97PT~^OlhmJA~ITvvJxVc}Sg( zVIQ|>Uh%SzBh{v;$Heuv(>hWl{~?4=Yl@4mZBi4}tn=;y`cu@G!oPjpI?8N+0sVuy zC2vplX6Bn-vsf=ns=n4zl)WrJ}Oi<8B{zqZuz*lh~l%hyN{gC(uUjQ(NFI}*nj>?k;Kh-tE$}Wm;yAnkqV9SDUwqf zEumN=*-J;nwW`uX6HN5BiVKOS7sL^7Bh6u5GAk69YM~3$sLSPx(A{)St0;k!|vQ8`b&ZSD~ytVAkoKrB~S5E@w{R>k;-{) zp%!d1wE#~+Yjl$S-+Tv;J`+&A9o?oq@K{7LcZz#l6WUi$j306iYVM@MJl~V0jrfAU ze$F?PVL*-LC#-oRtSJRLbG3x;$VR$-*@vdGQZhy~TjS>Kg@|7KSKPDh0q98aFOf39 z{YON~^IsxWS8>3XKz-+O_o;QU(wCi4mepNRJ}r1e#H4Y9Z*fPLKcjG-A=!tioH`jx zzNvC+N8T>J4cZs71jXq{b;GPkhkdNOxEf9Upqhw0I85Qt>0 z2x%ie4gdXz0^Uaj6#;9`wYyqYE&I+oM#{bV@(=>%Dw(j)|p zpt6K2Chz(O0aE~C%o7ueaaEpC;+7*q3IG$cGJxawpf#-IWLR+^Ce5R6zrkjp0d#}W>zmi2)BQetw9O1 zixp9mmh)r({>MV?R(SlF-LSM1zdSTp-pS<#w;um2x2}%4sUR*(tKuf;As9=vW%L*; z7kdbaS5+|&mqK7l#3sH|5AnJM7m;M+X=>Gy({BTZK1I0|q2i+A0pDW;d>^5d@+F8L zE?L1XYVHw3VsUJ%!x;5g#GfC7dRN_^8;QWKPA?_Nu4a#OLl)5&r{*tc(}HP53p;@d zAz9lRwNIN?*PQaZp1j3h+uF^O3XTd>Na|pr9Ybx1Ee=$)K6bVkp}#1~*^iW1U{IS%0#!l)aW8sl*{~O{Eyj zNZVDK*aUb5sgjirtlym6Q(Z6pk1BL?h*hg=g=Xdny+qAiu8Ev*soX7GyG z2@iOOIwOqTP8h>{;m}uf{62f)@UO_vdU1XJzsk_6zsgYS|9J&Vh`HGQ*W*_c6Ehc= zzemOXU#jj@+jN*w#ufB{(b39+M>ZQb#GtOR($7p)L8{6%K?tMs*sL;Hz;hn+A4V|obj!e&jPzt zZYogAKwkwf9NlFl#NihdZ%eDR+5}bc?oH)MZs$Jz1lj-)N1>;6n)3mt#b?5QT>VXL7g1y*j)CW9fD@myZh>!gV!jD&a;DG?F7C&0g|(8Ql;Z&C=oYBCj0XEdjoK$9%*+` z1%@K5@2UTF*thy=f&~u(f=UkpLhXMX;s4616+rM*o1Z^iV_;4bXhMbOht#eEDnrIW zpo@Nwv!x(~pWiV(p!8x%0~{!jebxJ;q1&L-NasHN*L{GFj+C`YqJ7z~e#LLIV*PC6 zeP8&{?uP1yiXuT|?7{5Z=OOzo+vmJ>Z1?8F>wFiYMwB2$gkvT*I<#MIbU3J~Q(X6_Z4l^cYtOB2^eathJsBdJ;oKs&8UPAF^}nis zP`BZ9L-GcEXTxH2b##PvS>vxK9kZKK@l@h4x_-Jm*rdS{^e|AX!WTD=p}eltndt~r z1*t@?oFX;PutQ{pF#CcO5%S~Z!v4gPrjjBj&uoh1wcUuaF6GGmdDNnXKU^o#rM=v#VO|a&Yc< zpy4$h+@g+p1e)wcY*|CWrLF*7$F0ahcx{X=ktDAE+OlAmk%ug>n%Hop#U?%JZC!R) ziD9*rx;#oqfpJrKLie$i-@NSP7{;Bb5`z!KS`(DBIeTVaC@xE!? zJ}CXuXvY@vl2{&ws%`r(Xy$vL(O=8hdn?==mvNEduyRO&U1jPoKdte3$#gq3qT-~T zLou(O__0iWDJnNUJC<+~P<(k3jB(s?c+z3eDRxzd^GjdAT`)fT1F0c^ZFhf1^J9HG z)_76zqNw+4&9l}SjUjm2SI0p07IXd`6^<_iH zxu>V%IUBg?r-|m3pf;Kh$?N%NF*g7Pti)GL$L*YK~Uuogy+k_6@nXero5A1i3~jescfW6g(Uc)=}N zV*DRvMHdN!bAs#sbuY%oJ#;ku^SDtzQ!yBd2tomP3EyyC)xd;Mvf{Zpu?Y~on^cr# z4YP*B)v7S~-{tdQOUg$e$*14C#@ZTFSE`=<4wg2#oZZT8z=UPpd9_wPN$&|FW!l@g z)CrO9@KRc-qf5}3M&j9)ZBy`x8YxKJtAE~hR2p?S8>%JF*g$kKT~X`Su~15rIsvg) z3*@GlDGg+%8W;))@a0aK#haf6YG4;eYKSz*O{?cy51{&B0Zc&=6iYns49vG8SQREz zoNN`QRJwyXBN9YQwk)mkAazHyKF)!W+T%3}cFIbk;qPwfbL8?eqp$+X7VvHQAOx1_ zPZKp_Ke0!@$G^=GBg4w*_$AMoS_WqcAkb)PO5}GLREg6tFgeK=yNgk}EK!0nhYyRn zN0f~O^l8DaG`BrOmokn?^ov1{6k_;~BkI0(=|ay_orF65(MH_~S#D&e@k&r!wpfJt^seMYeHr)o_QrQ|v%8z#Qn z;;6E*fIhQW>GU%;U^J>N!&J*$V4V#7G&rkkR`OjGVFR>9*xa-CV>ObfOCPlF2r1kt z1_FSXJVpwNLO?CT1i1xGt)7{Fb@97Hg1ZWCcG@~F)iU3A3}xu)KbQd5B1KwDx&1m7 z;^jTpTm5SEAx2!1>V<^cJM1r+He`KbXX|Voa2s+AtMet;(URC?*Uf1gGwYnSW zcrOZ7OD~3e(tKbfL)zu{a0x-|4uA6&xI%Y4st2n9q`A6q(9pKM^bhBx0=e+mlKs~Q zvFuq?ej1zOk8CFqhP9Ib_@P|e5IMPOgBC|_PfZGio>vc9%Bh|^RCwZXnMYx$%4KPR z)?5K70*Z{PZs~x+DtSwP+e<_&E-m~FzaL~kU*R*DZoo6CN7!o=IcSwC<&-8PFA146 zEk8Je)U}2*VlZUFj^njk+8^SLT0ElBlVLF5Q+d6F^()lk(&kA`dzGkwmmh#i zA(X2UPAM32JGz{5Q0r=lW3^RNYwCouLX=PdNa%?l8zGLNju&xeYt3Bh) z9BCK(lHbyVp$%(+skE}-HPqe(-(yA!BHof!rMvK~pAH$6+d#n@yt(9k;YzwzkhZ;= z$vIwlhc@g?om&-CU5ONosO)HmrJ3bP9fM)8BC#;a^vaH^qGB75i-+1Rq%^!S^MNi| zE~5ErkH^QLp1<#_Vgcm0nMDeq3*9*t2c@)Q<#fdPBn=RXhf}7QoLXhz0m!sDwBL$} ztndjOnWu!YOt0@5M^3nSonz?#7-vK}B9o@wo<4BOV~yCPq3i6+I5mD4A&uuh)@3

    {Ua5DNZa8w%helDh@IOnr%L1fS=D-(UsTR%-WM&Ya96O$ZC?n z*fWR0*?5R~W9`s#O4@L+3TVR6&Sx+@t2q z6TsI=#{MMf;=*83yC+D4l-_O4VDd7LXOr6@7dFhjj^IJVr}>X@XeKHQY&YQdMycaJHWcvY z$um=yAF^_MCD-*cN&fW}!_>EdU}E^^{T--fRc*N3Ph-9N0SS0)371@f7YFXw~$*7O&k7xkbHG2@~r$p*6S$6!Ee!QkFAP7IBty zbQGD(I?UWmI<3TShs@f)k^EM-Hn%oY1XFD9b=cGQjEHsB-}VgWM>0$WYFpBp3g%*R za~Y=^we30vMB0>LF>K$fRDMOzTpvAbQy6^Hi1j-SY8AJ&mJ4sHGEsO~OgpvSe5I3p z3W-2semm*!_V>#$Fnj&fTPoF*QzI46QWL%8S|7kp>xhbQVL8drd5OKY57u>CCzZnzCvS-vMRhq`B>WD)qeG+$>t;GDFZg%$FOj|{I%AErY>@6%-#Cv7 z--8qK=cdZLrHoaf$DZ58>^n9n>WtXwT4x^A3FzyJJ!}(PE1-U&5ZTeQ(-?dBHxWA+ z8jvKjKGM4sG{f^K%Pb^?d-r)uKD(Y>2FC6OesmJnK2v;#!)q&d6)vu|FLbJ&gOu)P zW_`uq2mrB(7%(9l!ID0DI|CF zjdW-)`c}fkOZvVBtWBUjtW8Y9fs=amxs|RV2qZuF+7oAaT%>Yr#Mwx)BvT*popPl$ z#2>nU1Lm^(sQ_FxSq7Fd5-XmFi_c4|4YQA$k20_=n5wPccS?-Jif-@>9lti}b4X31 zzb=Od@R`0PABDPI|CSo3;BeRyogB~$gRE1hoXm#=$jn7yzxhW75bmRd4=72|&KwQw zG?flVhl{~R>V05iY$a&2rA5LYb?n_Kr`R6HhFpZE5AHBpH<2bqdb?IUhB#>3WF*F} zkVtorBx2~Swx~OinU!TTg?|IsqhvFgUMW8Za3QhuOKSj4K(fD7p#D%!#0aP6A6+$} zz{SOBz@;fENf;nAM9?D(6ZK=YI->AtOm73+SpV?=spVFvKueZ362Gmn8Vw22AI->*&|z?k(ZV&#`iKPsv~&>5-w4X{sL7N@sy zK_W;)2;Or*lt?WriQlQt!#8jY!`o5JCYy5RUYZsX=4S^^PNfZ0ikQclbw zY}5ulM($kx^r;)N8?RCIIOJp0)n0Sy;*U8 zn0qig+%Z2S={HaOs1Nd;3>A^5%@uFT@DiM|WVuUFTQeOU(6IB%q4ju(iH_KGOG-jB zdKnMlpbQ$tlDG9ImZRcSQ_r&~)$z;XUSL=GlC_}<oJs&WKl(u?v~7k zX*~oXXq^>_YKF@VLz^oTx1E9EvRlN48w%^?lV&Z0NWQz%!8Oe+w8;6pMh&kLzYWyMc~?sKST9c zYoJ#kR%>$Eg7|V9scbs5WCnv^&ShT~y|ygXqJXA;E+Dh#*358zXg;`6o{+u#-SV+< zB(<|ntIUEVfOa02qZ5^XIK9Y%o&p=Te(Jh3OL?2cXHtnxH|iRUzXW%>i({4{b=Dy* zITadUk6;@lD+A&vtW6VsRw4K8EQp#-Y8NV?h!stR{O3+@wNxmu|6x~LW4&KkF3&ki zSw8?wk1*yQc52#D{xk@Y?6kH1zT0}YlDVDMhKb&b9r0s-=2^0wJ~Eeo-8H(3z#q8M z+H_Zppg^)%X|3_c#EL+sSvv#&>O%gA1M=}pkdc4QZSQ#oCi-Qh9vGoWe;z(h#VQM) zCb3R-nbgmNf-#u*Q-p8FQ(CODx}0vCL{P6SI`wgM7hi})Nms2MZYO+Fo|Oqt|4y8(l<}%%N zckq+0-}nZ^?;JsqmxTpSsvX+kszs)R^rrLv@+vxn01!csyA^G>-PNEJ(@%2pK|t1L zU(Cqs@JWD8;+; +1akU8hLuvZ0>TA8a1VkvBsZYLuV|j}#VT4Jwdo$D-S{msaSV zkG|eZwF5StLTlcXa1k z?!G~rV%;>A+tuRUw$0%F;Lxdok$M1zW}B;#b=0jV>K!iEOcwQ8c&}!)n4AJA&F_F` zezDa3a7)$5vQ7G4)IPQYMs0d~bk4pB=dQ=K@2S%JW;5&?ZosynEzAb^HS~3e)SIS5 zVQ|4>cS87UM)`rI#vGY_Zf?=E`?ogqXuw0wgs4YAE201Bn~Z|6^$FoTig6#T8SO=I z5t?0#;yL{UC#c%=UAlsxPxjhNalH5AtwIf}fD;(;tL;2UxV>lejfYP*Qj$rQkBIny zv$j3>*ZQyk$K6zA|2wIk(8+ z@&^;76=buXc3tLuRKJK5H43MC@f1=gkbJh1os6w?Tf6^Fc-#{<&3`UI>pyveaTXTaWmystsM3E-XM*BN0X{+4^HVln$N1%d2M8_)mA#o`F! z*vx`orpNAs_I$FypP{`NtQ_6F?jW&o4^VBY<&NM$+v%BONKr~25@UZYK<+okZqq=` z34lbM_YG(fB>7=aKluk@;Kc~li5pgvRdjm92*pXrFXw27SZjKqHRs#N5_4%r)srLF zgAHGJYXwp=vdABb8uT%%b_Yio<5T`TBwr!z#`1eo)%!ij2EYffHYzE!8Dr_>`0N5S z$zgxH@Nu|@8mE2PsgTQNn^*kJE#AD9Ss&kt-ZUj~7dQz_npR2N+ zBc}T%?6upOV|`2ij>>DH3P1|H@nNLNfDu32pEGu7 zOSQVjAH%&4GLJg5`o8%_Sbd$ojPD6 zYGfDS(Ti@En`Nw2VHk%_DIm@Fa8Bjn0P+U8j5a&=oB`Xl9FRSN4(oM|&aXgOTp}sB z^G$+WnvTehQ(O4sRtmp5yNG_AqYXK`f`;y@Z%V!6;njW(8xq%%A|+{(nU*h>)ng>_ z_9%{0pj!E}H-w7BYotiqO#acW5I}J=R#Y*Z$Zj}c} zy9vnc1pFR{`{T^7@v!Fkyg@S0_Bw|ozY`60O;K^^8q7JNopJZvR*XhIBe7W!0ApW{Yi74B6P&$4vK}1&fxU7GIckWM}Xst zSsk@unB^-j+XVHkPCAL|-7i-;|3y1`2Ng0ibItQrk7=_kVz~3FQI0n1^tRKS10#-I zIr`%#&0aaQx%lZ3xF>v$ksqz`SGBF?LFG<-ssiKn=^W`Nzgn{7Lp4~l!@1nK*$5Ab zdFjGl2Z*I1?pX=%P;|vPi{L!H7!vz=^E9YOWz&j7$Q8^uvIlVMJ$@$qsW^(S5H*6R zOA-#Uba78pol12fJL|~+jT)fcSzKFz?67*gryX8~0x zoVR#776go=$97g~N|$Q=vce7#WevpS=a~|%)nTUn8POLl+G?s8Cz()HMqlY8SFUs46v_ zlG=F-fZhKAs)Y_XhMzT-nx*Hql48DJTo;-d@v2`+dyvtVm?V-($$9JMF{YX&6Q*+N zm;{66slbrhb;=}@Y$+$?Q1?4`{jm=fE;HZpAzrTINamgYeRI;)x^rb0-w`QmaWd%G zMXak=^r$*+J)o^u_{v_aYhl-`f#g4fbYYA0EoLvHs&O<~VrFjCb{RgM9NaZ_}XTh(fK${^rq` zfE#j|0ucven6cvs@dl9^koQbKjQkY(Hh^+NxFBkf2W$dX1I_wmZ)%=>fKGj~?P4B3 zaW@#z7JY82M`<~5An94gRR5eaOEZnpj!nD@AU6$#T<-0X?81goAcaPU71ud_5&ZiJ z)u6W$d@(o(2>&+_5UqdwgzDdt&N@`jlyOvW`8YsTduK7=R6Ps_(jZP>OB&)ZsX#4P zkz*ig9$Hqk7wgkE#xILlysnXM80_9vO-VHcI6v0AM(lZA@64!V#~@f)Mm)0}FRz^M zuCoQc!0ceR%tBzTG<5r#X)34h5G7%6kVuvL@e z<(mW*DaN-sH{mbxaWGa%xduAYIJmZ`xLV9EF_PLHHo7gb;?6ZhKAc)B!9)mfH<++P z%KymctE{=i%ov7=NIGk@45HJ6(_ZdMqvHpo4ffh-U`bq%jS6OMBM~Ij!rkWAd4UL1 zqlTkry@*@M@f-0^03*?G4$SCw9q}I<+VSqiEVcGsCqkbGvi4E>ha*d-9IQcv!rN&2ikuqe86gPC0VB7x zTO~)FY1OPaWXC)(R##azjn?e8OS+Ll9{i$bV0tn)41m=ZRO-_La||1PeoJh@#~u z*ZMOs>TrOpB2nK9@W?ZQRf7dAVhYKO2xVv=1MDq$e0f#bDqv_4brGCA!YrL&=Bx^B z5qxh2ce9d&@j4*!mh46J{W|yZ?&TWnQ&A*15HTJVn=x*E{}3>+1hG|EQo?EraQ(u= zdDhzS~)eaW}BJv zHVO-ZdD>1U=f!*NXP+9_8O1m?;~VW}?ve)H-n;3Kp#t{-u365o9j>UC&Zi-x_uB(g z?-a*kyR^N@Q7qY-On`03#jjUa*`lK-#!TJizLxs|zVUas2b9x^?dny&9#zVUd)t)G zB^@uwYL{dRSPUZ`R8X;@m#LWV?FMMo@@#k3w5~(h8xo2+krVeFk~i$$5-3{F zIHqjm77F8to%-cgu4sC@XN9TW|Iv4KWg9)H=PxgKfP#SN{6qX8C1Pu1Vs5HrYwILz z;0Q4O@1yL>7(O^KCgebh&q^2kZg4ZU$jrnl3_pRKoWh8<732vMeKfv|KN(Ah{8Uoakp_Jz`?u7F083bub0;w77%U! zQg|!Qnq&&cdWzqkUNS1K$>4AAYJ)+a0x;J509aCV zdy@9Wf;3_tihaWaVDzT?K0U)MwZuR|;%tUrSt!C#>@2`(miAeT@1_C5Q(!g*HS_V) z0F-&nT^j)7Qhc+ck~xk&kAGm6XvVkf&a2CuppnSOX*S07Ot^^)K| zPex}}B=qPWDdfmd7RXZm#FY6vyA_HR*73- z&BRDHj!)0E9{O#X$&*7qMs0p<`kVE&#!x{sB`S9HyaGkn*^3}$L)J*=#3b7mN*H%+ zY**GbbU|IB1;3-_YtCXYzxo)^`%A!%!n?}9CH_)?V@^~4z3z*$i*xG%@uMjzBGcya zgE)BOepaM#_E(u3wpy--wR>_8e_F7-DcVD2DYLUMTesTd%OY;dS|%lN`VOQD)Fore zD~AgUF|M2S}>jWsiG*Ru>=b-Cf{;&~KAMV?jO5Lh%Y= zt;LMRPI2EaN&PGhJT~#7sQiRhhMqAHf_kwww&1xFEiA!9h*I7D;GZmbu|XB1&$8n4 zKi!yziSG*TMD)D4M%h+Y$Bxy1wadBgo(sowZK-vl+^~|??b{9=kRPACqx$8IR5~tJ z!R$uZOs7I&Qd8ZZ(&;u$-CH`0s*uui>}MaD=r@Jzp<Zhr?3Ez8^fmW*zre zcsn5fT%iT2|Bn{Tm639Ay^R0b(Ew+1CVP<5G)h0=;A{YC@-i08zO3l&Y2T2xbNjck zJg&EI=r*4|dG$bQz$*=Mw=MjJQsv-Kr{4#F`lZa{Wgeyasck`e zo&S!7WwM+zJR}InBFaBkY)$GvZ>SBZow?w!A!pG+HciWR%IgDBPo@mB*t&f7g$9r`x>fZ`uq)xg=fym$S zPK163a4duyARnVo{4k0_fVNQ|FG8L`*4ff;S(DAvvbFq<5tloMZ!0cK#soOu?6O=J zXwF3%9)HZW#VDdBEtK=(5ZmZ8jIKFnb^%6S|O zL(2rtL-Hwx#wF#FDpAS0lnW^GI$3I;au0yVlRT@Gg_1vQ6#leIXHE_ivq*iZjjDm^N@+^hDlA?wVsxdYx(3=RkUN`UWLLnsn}xR13%poi@bEu`99GW zamd9G-yI5^Fe!tArS^;0Y{Lv-7rG-tub5l*PqIwV$XqM+(n!FgXXftl}omUpgObW2o^EE3O2> zJ<;WtzADS`LL$^eD(a_{nF~ecMuG;K5pV84=i}CfyOm6#aOI7v>(HJRQAMU&LG;}y z6HeWJVVUe_K7Rm=qS_Ms-V)7uJHVqJuO~}VI{@x5$@t#^k`!WJ>j+SzE@Gm9f^@DA z3I3)bW;QCoM76?!()dnw#qFQO=oV(%6%<;dX>t~ABNoXhUduYoIEUi_=@d$(i6 zeLY<74c~2mhx&of>+I+Zv0@=^m{|6v6HRfK8WD8y$(nZ*|IC&TOOC+8R4*4xRxm7! zu8$OpZv7rv3h~8Qfiu`9>5H^@7WoUcHp^L6Uj)`x-Q(tD#qZ#K*Wmr9ZE=MxvKR7p z+xx?cj&{7G3*gx52MGW9iKpo85XMr&nT@F(Khet^(aU6v2M39_`0Wwa3;u|n@jipp zr-h`h&l}W}B~X9Rwt^tsg?70XrZ7u4bsvuRd_;!SJKar>?1iWNX*i0FZ#E3@npwa` zQv+uiKDXTiWko0dh4An6i(4C}{qdJ}GymEYO8*r7%9=a=Pxp?V8b+jEyGIlEdXzxq=l z7SEL-lNCD|>xKg8;y0i4b^CQXoG&sOBNi5!ljfN)Y&&S`?C*f)^*_~rtJ=MF?b;l@ zuZPNC&BcO2iX0nZW;?==9A_uIACh27ymRJ(bAmqq$G)FIB(~807i8(bVE_K7z*cZ} zQZNy=b+$2fRC6$Q0{nEab^1H!-y!T@mCP8vs9r&MalRVl zV@^oFQG_4*E99t@FmR;UtOD{b%f{lPoLuV|zkT@7d%x3#^v=egPkG&bT|6Oys4`CI z=j8mU?a87Y!m!pb5Ci3?H8)f*ek67>w)Sq^-1a@4pyw`|F<(3`x$pTCO=O_!q@9pm z`;9(RbE@8!WK7;1&hz)4MtWK&ek?pc`gm3AlKR@104Dopw$(^%9P?2)a65K~4JKc0UFb-Bx77UM6V5&ueC|EEAzbT+UucXCrOQ3g1; zm>U89PrSg{;r|WF4y87Ea3*B!;2{*4>Nsq;lE&O`!a3i>3Ubi2MS>qQ_{Kt~#9ccj zJ)pWodZ4crL*xR4eIZa$(UVLsG$taJs%@tjK9sa-L_E$@1&li=WY+3DC#Q*QGQN zLNIz{Y?7|3&PmtWqiSq$;{8~+XMZh6mQV`^dB@82rvG#oxoY`rme$wm+5f^F?(^b` z7ot{=Z6Ftr9jQTEjwz#2fo6xahE2QTGdS1AZT}CqMgEdj;a@`H0RIOqUL}B$t%LFZ z3Pp6p^ZX?od7jEbSr!19U(?T6E1+EVar=(^*7%JAL-`LXgac z+Km%@WO^BIbs6G`5jxonoUyR{MS0JB4wM9WQmjBGS#!fk%CccU@Q_~OA6t8TvZ^kZ z1Z{&@Fw{PUv@zkEs^tY48ZkV7SrU`N4uNepRtoo?m?S+%Qg0jLB}Y=~2OC9a=k}Q- z+JVr_;R`2ofJJe-wmfb_yfz&P{JT6nM538T{>mc^>Yr=fB&BL#<@_H$uojFr-2JQ!!@V(LhGYQ5H(|+e)LN;ste8JM8t}R}E*(VeA_T=0h`fRXWvBgq z$U+54td;ZW0y3YSTM?!mTi)xNpxqel48p!WQf8=|1Jh{#TB`v0L{l^=$e1$6d zV!)j-b^)OSymXlF(E;Cid!y!OrSn<5=25AK_+ky}qce$RStzr^tG1<&Q)+akAgNep$&@#01m( zHNgfh(ZA6Pt6(O8VObj7p=0fL@hd(I6<(qK8q79SbqO&@e8yS+(*jfyzPbXB9L8f@ zh@8im^PXfSUSjejB@ z%%-IhBv9n_A|{KXgRx+&;D>>EPO?;Wcbl&+SqIcveNgtlt52RejGx|L^`QX&2V=6T z1`bj-#^w%x=lL(1{VxwzNlxbPdd{4;sK~B__V&@$MzhuKqhZEL+mHUOFN#P>3KDA-rmXA1=3A)-u%;kn|U@h<)?82$_yh4 zEY-}MMv)2y#}Y0iM!psU!T{IEW@?mF7$#jHh^b(so1)DJT#YI%e^eacb=ksoD< z^AemwM2cj+ND>|=y%@}gHi{%(_iLNfr$4>533p!Ypw*YgOmF{4>=!ummCQiCcKKkAlhC9k2 zlQ%B=c3stzxa_X;b0uX)p!x~N1`m+j&23V*&2LTx8VpPZ`af*&*jHJr!2x}TQ-x@Drq(u5T9x9;?&%rb<_dBjDGpD4W2my{cp&vJa;b)O>=vg z{*$N=CQ(ge{z`Q7@1yY#O7?%T^nb=B3LsGu{6L$S<%-FyS$bF>?dW-Zf>HfVuY3H5 znt)qxcOIbKi1k5%U`GB!sn&2P)@ueseqz`B!(L%c?Xtu?8QPIQ@WUO=fc-(J27Q%i z$=Wfn(Q08qS4bFRWKGzraE*Ku0VGnvDjTN0L6Lr^46WcYsRpVCGLU2IZ11=KQ3uDZ z_c4d*uR*~F2?ApHPr>m2Q11U-6S3i!jsltxI-kfl%Q0#d2y_8tQQB+9lxHX+B1pM- zu%IA*Of=?=P5SUZEXJCx&x+!W$8%THvf@_uALLFa1>k<7m*AG7ku@;au3Hl@QFn)QM=V8FMzW2RR8y=` zQ@j+I5-U(M?jpu}cm>K>X=_K8SNu6-Is=1V2uIhnf#n_4{5zRc5suc&p}7=U}63 zfpu02FnvAu0wM(s=w)xp*3XL%GhPQumq<1We{Z0L_pPGlyXg~UohD0pMX`DH)JA=3 zKBB1|hrtHssD$v$=UABQ~=%{jia(2LSh1cD)MGnE81pZVGs@^ zBT`4-721$x6ca|+v$SW+eKid#Lz^Y;DX zCN49tyL43SRJM_$XG_vooSk20tKVz%bz6D-DH$Je%$VzI`ec#M<;Yr_h#!96Z%O1WYnwOBs5P%? zXcz!q#JLdFB1}a;HPT|9Mh|zd9LG=T97tVN5j@5fa@@5EIu2QH6~c-iC4Lf7x+IKK z_#LV_7|sq(<$@i2t#bOle81ZS{rOsz^<()gzN=eBH^Q*?8hNkhIGLp9~ zU0Uu*qZ^ZWKN*}6U}y)JxmIav!06wxTb=Ie({Yr%8u6!iSgf*;A72FDvh zU(e?7Ec)Y1OUQ*MicAJ054{*l>uXhD;(BaK4)lgXLBkvb56~RaPM!Pvdmg{z4}XM+ z$E$X06hO$58gCvt>Zd?^xgyr7Hj808og#Eq;KeD@ZK_V;L7DbIGnH*~8f?J7!0`qI zub@F2-N>^!CDhcpX|mHnm)V2aDqfq=Hy6QCUQ=$4VyA>Q7u6vo%QK}RBpM7OEk0TU zd7!0*;}3OKGSr$jn=uwe&XX%}cWN!#zeUpkIcz0B>%gvhe#0h~F|8Jo7qFM#TChkp zAJ~1*>V`&d&#oy3+R$DLjUQQ5yXqaqMrBoP3fBC=Cj-hdztwb0>>Fz^PIst*WuZQ& zKmgr;zrIG-Um-!b0@b&eeB(LA)UyuMR>U+!96yap(TgGZqgc+zxtH$JcoiRDh8|9Z zUkqny@jXzpRj;Y!!RDT0$1%>uD=tj0H8!7x_<9L1&DW)8IB>|^koh_)Sx4JIIq#`=;V+Or(}3wEZd){pkIU9mJV>gqzG(P< z)BnR-lj-QH)N=>%a73%$3bwu;;1Jq2mV8tr_t`?q7zL}kFlgE$KXEcoo1hmiRZb?D zVp@5n6#RC8h#Yk1wpYG}SfScy;ObLwg;69r(jitBe>+SV{hDki*Ryc1c(tgrefA8s zR6tu0vA{dTp$1dF{FE_Brf1Z5cwp#Z5-g=hn>F1V(Uaunltk&cN-?-r9@*HkH?y6U zF%?#+YX43H))jW;fPr26Js~W$rK2E0z2^y7tlQ!4G9iwnJ6Ju&o;&7$wFeF7<+uvv z8@PM^sP$~!`!1@@Cd*Hr4{bbSqIqy$0Jm`(!cW>F#Rpf|dQaDrknaIk1l<+BrFQ*$ zJ$k}q58@NVdl*aI1+OlneTXitfX8x4V-O#U(#e{v=^+}@V!yOuJi~-2x42|QX7SBZ zy$;Li3qiT;t6pX_;42wytG}tB@Jn;s_PWWc3B^=~W0F>%+sbEM3h5L7t7MxXCASSA zJN4)39qluk)V_2UbocbZrG=Ka^UsY9Y8I?}SlO*E$j zvLdXJL`vRw6O2cEq(sF);e(SnmcGO{N+r%@)+_Uoq+pt3tW!(A%D!@4j;HihFA-G@ zd72SFM=ey98pg0CPd4} zCwY~5$?)%*qA*{?&#)GGWC6EPS(lw&z1s}pQb;r{veOQlJzj_C8jBl6Z)TUQaf5nP^t3&~+6feDy(#)J|hoacvcZW_WClYWX}HE$wu61cWD59hGVA z^}0j^JPwx?ISBXIm)!6dK;kzW(oDzW2FEu{v}N0XC}twL(F=a}a=Q?l@AaWJMw1_J zkFF+@A5=@Y3;V@ukQ+j-4hxemhug52{_Rv+M~AP7{5b82jg2OHxeac?F;K721iI@Q#6@8cKpWTv2!Q2CS2 zp^I(Yl>_b+v+W3v$4}qDx+c+-P89hxiD{^M1JOsZhUVrpF}|`gQGSAap}PN6!}w7k|NvhjLHeW)v-&5#?E%NqToMrKP@`>QUluY@@53!Jw#8FcTxJ z9f0=*7$H2SJUKVr;M>SNsn+j8*BX9zll>{$x~;iE8_|=W{|e%7EFmA1gNdNfQtG_g z%B9C)a-S+4?a3w&8#vyw@rj;8O({i$n96&p*{yWGb~x_w)}L{DvTIdb(Rq+{Z|rI6 zX-s~w8&R0`kgVzko=rEqqmg2+3O}cZ`+DoSVg1)2m^ZGPodaR{Hk|@$?1{kts~|l5 zyt)HR?3T&1xrB#%EqeNFJe8eVIgGvhJlSF)z))Ox0m0Ffv}hENh{DE=th!|9hBnfo znjMaBe^fS-?TokI8Dyx4?v5nH!2I#3X!!@XCZLGR{n*|;JBQ-ePkn}u7>kz)V z)UNZLkgs$)7-r2&SJRJQmSCrdT4ov#>xyt)tzfda`)N*UXj%O}9PSdBodbx+waLV_ ziG%dWqE_F<%`=6_O!^V@9T(lApY(KPc5790zO3EaGFGdS?&AZud0?e%{R@Q#)!^u> z54dExvI`rp(6B>KXU~ek&UY{MS}&YUT#>bov4I(iH}@`NIS0(;E|G?9ZheLKO!|qJ z34zjiwD}Wyj=WQgtrulN8!ciWiY$0zso>;`ips~#x!f_WUPC^5EskfcM+``i{ce3n zbBqRgS%x$}tD%wSsW{zsywQIB&9Or>+W@Yz(6Qk;$k65#x!Q8@v^Dl`J6RdZMvF}?*g(!*+tgTSs(ZTL zu#;qm$C@9>m0%ocltNtSFkY%coBb-_yh&Ggb(@xqTi8o^lkST=Q;=28-(H$}9yW)& z!s|AFn09cqY$h`<6sjk==}mUgXy0)d(2ed3@G%*)i3nE+Q3)Wqd!8}um|St%w7_J4 zEN|1b!E`m<6SJ@S$UPeU`DpI*S_cTMwyW7a<;pah;$HlyU4y!G!?+Db7X87}BzD}0 zxiy-P>Q(jdN}oG)_8UK)6aWQ4`oG-k(t!76osew1I2y97`$nTH*a6FzW$-3AL+j7Gug`Tpc zwazE}sOM3oluYT^`%>`e*>Z$Z;MVsHkhH3NFjBpl<>hCz1S;Tev3kKam*H7Pe`$nb z^**Mv>uQN!-?yk1Y`lE;{d$JLA4sd@bnyh}%mtm+l{y1ITN-_rypG^>`TI{lRyn;$ zj&X*r3Z%XiO(@ngyi>A1(cVj0bgt~GuItJ_rVllP1^Tji?qqQ9vDt_93a-`mp4-Zw z71JiWfa;ZOTqPq<)4=J-;b?vRrwEU6qxb(WyL;JE%C3`lXjsSqU(;ch6{SQe}+c zuG;NEzp$$04JVOHWapQ!r-m!5o?rn z8PBAr>pp1>JQbAtaONlET$F^$71rJ6*8FJzj(*D`*+Ud~$E!dqs&X0NmpmIn12?XP zY$?W8R;(49%d$Zo=r_p?5T7rzA$0zp@P3!!sHQCeXmooYlS-zWp&uW>G+GQ0a zGWE(v%eS_f`bGaUB|qVkz%j@JsBxoW6uG=08Gkne>+ZvdWqCkZc}HvfN^+kg($%x0 zckrNbG+a~{uq;SGqI$BodB#N~V4U%djw&?!QoN6Pn=sw9W z;Zj=JJz-N*UrNh;#E9O+cFbTg$>h<+T>@0vmuCozk&z*dbxwibUL< zn_)J7j>JCpf{@NBhPoqzRmo{ozN#?FfM4G9`2;{G5Uljd>lxZ<71=2~H4ABZk6U;g z$A(=@bI<1PyHtJnfZZXf*2JbrGNrw?7?5m$bANU(_sX93`5##W+Z%PuGiN1 zdG5k!+(9C^0ATZ`=+zd73DSl@t4P{qVA!i1Wn;23ts^Xtq9;=WZiOuGBrZhAu<>cq}h98k#pXl zRMf|Le-mLJZ-BS^0rEu_P+PW5z#i8akIi&BiKRNLzaFqidIij7D9f6)Tes3SXR^|^ZQHhOv(mP0Tb0&Ko0Yb0Rce20x83$RYn^ks{>!)?Jx1$2 z-gtWG*QcI1-}oO}9<*FfZ5Vyw%Cy6I1sGmWNZ)a*|H=Jc) zWe*V7Rb2kQ83VPj%+q#-uvRuKv1(FXG@)Opw%;II26TmT+1?!z;;|^*ERH(^h{Rnn z5%CWcOS$BvE7!meB1BhLoq|Hy@tB;d|C}Uy4+;Ie)V+GhEis8v%r*?WmvU-pK0m65=sB1wYto2~$z88*DOem+r=l4zKBHj;Ozua^6w?ms z;jA+o_NFdE4oi;-i?!W-L6{OLc}{>Zq87m2broDq&@iriGoc;T5B2jzD9nr(eXD;g z3B1(s>d+|c$vg@dBdqPVa9m&QZvbC~?g3MeM#7K_yT0N|(vCuzIHuh@Rj6J8W z&`!Ke*W?>oP;r4j!dT%^|4c^{gz7L&{muQu!WCRL{$QuT@JoZC=}yc{U9(4LKq#yJN7>}K&O~mFbHp*@G`r#UWVMK?Ap%Rt z`V{r%ib5GdV5`DUxNe;`Cvc9xf4A<;?nQkS{wq>O=Z3sSWH{Q&s}hdPfKjE zSfTs<7@8+$=#TL#NdKZ)`Rs8|!VSjq@>oyeBD6y@luAY{$_i=OI*wHzATnrS&4lYze&B^-po8 z{pzYsX0@qOT*}wT2QO+Z*gx0=qwk{GHxx0d64_=rwzUNVLJrFGCAhL2(3$!)XW(Y+ z@THK~WPDpKn?Qihi>?%oK#?O{oFwqR7?$FW)F}4sNJj1<2a@7O5bu+4Al~McGJNzy zFEl>^Udsl+k{6a=v*4n1OO^fgsuo&5Q7kF7ViuF}($s4FisLT=tVav0t|tlI8IqA*t`&W{fF+k- zx~tH;Ztg3-?Rw>VPPCo5m@(zF`<+e(h4O6k>K7`2Tw((_Gm>aWH6}j%js7LM&1_6- z`WQw8)mwW@VQF5EzT!UBV&?3Ir~nfYCP3Dbf_rTkS5Fs4!ax{6|MiJwrhpq7tsEMj zezRL&Qo>$8V9<;%A?MJvvcJlxVvB7u;s~+tfboSGz%cuBt;WcS^GbgKC^e)mcu0ux zB{igXu(n4&P!m_|vaZEj(d(sTsdqSq1HRNJE%!b6y`^{#70n-y-|1v-jXx z87Gm;{K;MW*HYD=9~DZrI9X>K=)rmI1@PA?|e;ldu_PT46Pvtil^BmZ`ANp76Nf1P=_ zxg52AwCT;y5s+V@qLhwTe{x{r9!53}e&SB!jWPUYPpV)sT)Ue~ciV4+-lL6J$F>Es zK}|r`DL?;YeDg#LjNrE`iQ7nHGVR(9;UanGp#EF%igFfOuyQa;R=o_ z-SAkxalt_z!#@)Z=N+R*zugA9UFLLLN~8qyV=D?V$~2bfD~Yd2B+C16HI+;ub|i%E zxs814G2z73g|)1q4aS7lb8+wj=l0VM(hs>Fgyt^5LA*$Ut-oZs2QHk_4Y|3w7O?Y0- zgHS*c59)=ZF>wxQIv0I-aP~?{vb+V`&YT`TmKNEGgl%f)I2bW2rxr{qG7O^#Suu*C zFgh|j=dy4d{K-cKq>rF=UG*jw}?OYZJmItW4uA1hbbtT9BEDDyM@LA5C@#}1l~ON<+@ z;VkcO2=%W#Q+lTQiZnF(F0+}lAJ-a>KYBs|?&%}9U|4^^b&>lPFasROx_%$+B6cZU z+f@Tsy8{}BR=k&OobW^w>*qJpUfNqqz<~fe{iyj<{E$qIiE|u2Y3v$iH{th%v%YuG zGYw1Mj#RzNQM_0JgUI{@%&Ys~bdW{!@6ce&eiO&*Dt9}5yRf~&%eOn$UjfM<(HI0P zAey1rvloT153L_7fg^(-%3nI8jLiB5O}!x5iZruO-3x;>D~w-iA3asg7c7>1p_4oc z2T@p#Zm(y%3M+8!A*a425_Otb{*&wZ{mLVih%cq4czd?-tm&YkfQ`6pbS-ISrqk* zzxlMj@u5)^^~B1GfLC8!a{rT_iM>GRR#C>>=I?4{KX3@wk}aVnt|!}1wA9xx0lb2q z?3~ZY-|6@^BuG2z#3Mkstg|aJ#T)1XZLnGJrD)GX%@eBbWWc0IUpe^SM(5K}h`&8# zbA%aCdXd3Mc_NVlx~uP$0XAwAK@=D7iP208X-yNAmiyZWPb%(B zoR0MKORZ|c5nU*YlJ=j%_PU*#dOH~G=AH&|<$ zu~}DB!_-~`432kwgAjbf+~)KZ5{h5>vlhCSbQm&9BzMi{QtT%`~(dX}7?r$xB z%4OoO<9N@y;M)ov4Mo;|rR@r4D`X$zttvMJ!#}te*flwpD)785I-zQ(D|C6bpOE61 zooIh`4V16kp1AE@gJ{XWx@HLUcuhlyjErCS@d9Y;kS4eh-dU-eH~hHicR1c$p#nxk zQXr8iqA%sr8a%LOYl+!u`rUsk)JL^Y!l{SV2H&}B|nmMVp1U2V` z%r^E^R#LUKnk|;4b@!YKdD8^&G-idJ5qZA~;`Zbc6nYR?0{I^4y^&@K4{p$S9g1HT z-jP~9|Kp+@FRA)=2*{5g{1E>=g7W|7%zuN^TUBIafP&aLSHM-)UY*+bXpa2LVVx*N z9pplc7HZEbnbC_L?E3?qBb~|XYBPbM}pR?A>uI&Na*ghVHlo}eGXj$m|2&gSy@RBkhAe52PzMWuTmV!~aFH^+MBn6t%WPoPq!d}ImMgl2X}8Hpfx?sj zam%fM)5qKUpJg)fe-BMkH*)@WKC4H|!VrBF<4c^vs&p}^(~=2X#Fp)ZaX`KST8KNO zrodbZlg$10-2SG;(?R3%8pc%l3Y@2hi`3bhg^F|l5qf+#Ep9P-@gRh?oSRR+QEvP4 zYWoTU8I|H8SZ})9>nQuC$E*2ePUU42$`D_Nwji*Oqhu7+#CdEXR*(`ELDY;6dC7!H z&xS2l?~&b5st~s;WlylL2D0m^p$2j=i40=US#%yF{fm4-8x^ym`*|n zE3E6r-plZ;X<=lgG zBiisZ)MP&TF`d*>lGM8ZLRKZEzL@~1%aQUIS+Td0g{?@!L})qdq?Xa16jxRr=R-O# zK0uE)?V3@{PKecs!oi+HxVI8)lVne`@dfJcGUJ(0xtn_$y{mWs0(Kfe5f#B=F7AWW4cjGBCmtMX^8gX3sK!)G=L$daYfSU zeV3HviZcHInC^+W?c1F94L?{3*fmNeze2r^uEv8(dth?zx3 zsHGOJoTZb@$8uAwS`uSyWAl8Hj@@%{(Mmgi*yjr0V|W z@D1syie4Upj-ozGY=}vmv=IUu^5pQP!<*-ww}$leuS!qM*5+mY=z{xo zoJFyos{^VMtiZ{ajA%DHLva-*)1#(>t{U3ApO~LJQRZ7if#LL}p~oTAN{u3C`*IWj zPie`~Aw-8vdQ_w(83X(+&^h_iDnDzc{??U>+@T6Fr|%KsxAu10`bCQ$F@%%g&~$s~ z-ag9s;iBDv5bT(<`kmM~r58H^@~t)`*(`tVRs~`GC@w_zug*x9AL6RJ(G_f-Xxp-- z#6=bEIy?KNnKaA$0Jy3otFqME67=66>L?DtE7f-NWjytDP;*2E_*Ou zF#*bb5neGk*QDyi!M&;8oYS86?M1=Wqfv8ag~a(Bl?Qi`-Q~Z$tdw+)d}UK=YMX zQtvr;I)aU<=mJ?MjndXg`O2hbNDCDE2AO#3Lc#DVB$=w*{iP~586pu5FseoOl2Il) zL+TSUU~CX>IeH%y1*JsAyFwCOGf)miwZF&ZoqPW5Y$iAfCu*^53~!*#>AGEyW5N;j zCED``Qj!2-#xpn*ORbxnDnNigoB{fkSLC)Eze$HnIHB6zyAxy$TSeHF?31`xG&1va zCiS+p%+|4zJ`{^=`EaGa8KZOQD{T+Gmw1=RSmbX^ME$!47aql$lji3=v+RQurhHO=h-Om6{OGaJ7I5z zmkqme@;Qg$#$tG&F1q~I1Vvy#;jBvNh~WS&YQya6kms2NMc_mtRx?*L#wb|fjmbv9hx#DyERZH_eaOA<;4*X~?5 ziN4vqd7JtCwf9_Zabmug>t~wQrD1(CIKr5;61HXJg=OcX8#VE(z$6^DHc();>}T0g zbaAMK^u)`yBrKi)0nmW!F<^4TZWN9$JZ?vS>pV%+!PS3$vf;#c;w?Qwhlz4`2i}Js zc@`e5CoyJrcLUufX6|*8tp~SXl}D)?n+>aH3LrFG6w7D?RdI&C9HoTl4>60Zg7 zZ0^VdKo21(+0p~cPAL2!Mt0Ko@$zS`hC)&FVP}?PQsnpXXB7PN$XYh0FqCJqFt#P6lC;zPwVR2!>Z3Bx3i@lV# z*D}0g?>d{Ojj|C7-N9fh`i7laedgdr*=-sObgu|yiydh{m9WqgdEN8Xcq+)~lrnSk z`baPHoj4_7&JYjMyYi%;Vf5LPp6Bmo&qlQJ)plFho6JF|2zmP!!V!ril&wr6KlEw2 zMNZW~yShh;MmDO?O4^j{@>?s8)7f21<$LUO(^hm1luy4Kbn>olOTLI?v{R|k8&i)5 z)@zfDL5uP`v#@GdB%`;aK`Y=pYkylusIoL|B|$Dr>X@s9$wXKrziu*S;*6pH?!@eg9( zd(rZ{FkfFO#XqHxtJq^oSsR1kyQU;2HI*jlX~vW49NT&mU{h$+vP>_%y)ilUYxl&0 zIdv8fQy`8{o{B2wWHwM6C>&9iga6T+Em1iym)hur)=?RmXNp>5*1oc>X{)W0)7kfb zTp;#Xl8lM^C+NsS{Pzg0|CibQkErv%n(Uj7J9plUuIYNh$*ydRKCew&yy#|uzO8n)Vcc27b0M$1P5+i zJ^ayMdCKCI{3-5;3Hbto^=@r1E61p|R80n&R;}MmP)vY^SUcH|5vTSkwow0|lkci` z=G`)4U+Wue*m=zzG;ZGyqyNQWz=ZdlUpGpPAT~@5YxOfKC6ZG%Xfh!s*4`#5kt%#r zWIj=Lbz;Jsp0KkG{1_%q#GFmA!O$2504gHIX*PpmLjwUQ-OaXuJZ`Ar(<9Q%+O1^Y zCnY^Q$TvC@smsh5pdHW|J1ln4_}CCZ`o=d=iHs9YuQ(rO3WY|sMi)X|q&7!Z!H~pk zYx96)ybjka(o?P#Hx1_jd4O>_356Ai;bcgvJMcv&$Rsf5BNjI z44(!Q`p1tv+#f#_|9cwveSykDrMP*G>aZRfhsq;Hz z0^>d@KU1AMyeaF-Q(>kf;bE>PxAoD65DS+wfIZDS~ zwPHiZZVb+*6ZU>AG(HBi^}M9&g*}l?gprEF$ItwOsDbI6Bxk#=DTHS^CRPcULi~$) zDkCrva@~NZ7;$_OPkeQ?X(#d%3pRk>sktT#8}C2@!tg{o8W;8ej&0KXuW9(v^VR*W zd0|aoKluk?`Gg^2;B=2)-fNE85xkrdU!!!EXUbuX;4x%J6JP0x>@}wCx{;p$=(V^4 zsq1~Q`UhL#G$LZ+6L#BpJE9KupTw_$ac~iy#JY4RFniO4llEGdMGV%cBm12x2n~)D zDV@cUS6ZU27<^Q3Y;KzfX8VD60I}AV`=-)j>j_|6f`X0(RV7{m`%;h)lJqe-h1(SH zd!IdwUD+)P7our(ggEZx(e&?6fVpDOAme6WE+r759Dn7QdT#?|GtREpBwAhS);D(U z=K^txtpM$wJoAQ`F69BqKDrIG#-JYjOZd?|;^kmL%vO8&p7s`;T$Gk`)v-l9jI>5) zt(l~|!w$&ahmYB2crLtN$z;16QGn>A?0pWWIj%TmEOZR?vtfORQWye_0-Xurb-8Pa zcG-kpn9g}=@j6-IDHt;WdJ!4wRkmBLhrIJMsRHif_QYA(H0rrXPb~On&h=@KfVy_p zy~b&$yCEJLDnZc@9(hv?Iypd_7c$IL#M_|g+FPnDIfhM%-dx{}#~mYiWFx)1P$-d% zpISsX8~PiJnLjLErFU#yonMI&ekb1J`H%kmvgwF?`E$cNkjZLVDa7e_qLWEF{a$4M z3=xKtQD;kxyQpN-Lt7GVbg>K!ro`2s+|w9)(Scn))z**+%ff?{i;b2p2F&9ZETUN>)X4cO;xo6_VhSG*+0 zguOAJ(qMQnFX^~Q)1ajN`Ii|?e_=^&5~|ONw5d3!<+h1y7z!fM19f?gRKKv)TZ^<*bS^U(-X5RjAl?~)08GSN{3GxwI2(Tl?P zYs*-locbSzGbRmH|4Dj)%kw#oODHchwH#$p>n)3C1Fu!AlA2?^eo9)m65Yzf-6Fh6 zVUhSPIzI#NJG=-r-mE%Tnvo1X9QhW2X)@}a#TxV8XUINQT1-RD0DlEPUAJJFmfc#5 znj%gnSpv zsUO!wPR?Tm=7yZ)ke$Z^dnn$GF*wXn7$RN;C=PxT+j3w5|5#8%)`oCkhn-gxYPXe@ zI?Aj;wr8C3YAe3 zO~{X!W`E#ty(zG!g>1esKi0K9l=>*W$mE3dF7%nO3SfN&eJr7h%iFRn%SesvOxtEhF+k(nc!!!X+#+W0g}oCAMbwFCSl;lA z9bK2Ij>)6@glm6x?RVEh*mwfb@%YxVHRzX{JT+?%+`zj1wO@v0Z1M9;UqQ$)ykECJ zoZe8w*AU>r(m7~jWmjS22{OOff^NcjWf!;jZD;sB><-g)>IWbB!`9@-ANIMv7*n(; z39okH(aONZmBv`t9R0zsBIEd7G!S)-z~yy;Tb#0J$@u+bkRIEZ=H1~dYUZc5hkbX1 z7w|{7f#jFT*gCFwn`kWMKwrf0 zmlp`HwnP&vEqd)QjxVGmHz0%1}ze5xH^fKPX)8F0+*dX@rh*^}& zz$|HoXVCw6q2g6W==B6eQV(W;y)^^*^2Wb?FuUEU1t+8&{j1-iKcr`w*iV|1Qh||D zQMaEJ?HZo_A+}45piUMyj4I)iS!`OebAa^N9oZBZC$K;JVmIvVJZNz0MG!EoQ+ss^ z+_{_m^ZflE9%MxC$9VKVK2+i#AFA&aXSqg%4BMF8vwP&U{$#XG3e)_xv^h2gO zOETg8b;{n6HW-C@(E&j!*>7#%ic@P%&QV#O8|u1-DqlEMkp?mbsl5PSuNN~w9fAJQ(}Qvo4OaKncEU&?*5QiiOMDDt4aF3=8;;7GA4vWLf_;F zpr_TsrCnE$iUU`^sfxp#D5phImu9y+Vw`EPh@S%imPAvb1MpD&X@kJ#$+yH7KIy2S zAf_@%EdXT!k_)Q>O{T9Gnx5i^LD5PvOx;@KggG5iv7dHs@5Y(BB33zbRW{5kVMIpnGK^rMP% zIEk(Kg5zO(YPHWl;2UI@jNK0%TV5pjwi3Qp%8N6~la$RNo0O?Dwe)6;r;YeyP6=!~ z*{RDWjQLo^2!e1TabbeGm}ML5%%2vm^6Hm;X(i`Qa`7}4e-!*O3ljz}Cii}LFw6d3 zV}HZ3CW%Rr<~^gu0a&7xf67E5Y-lPx91r~`eXxeZBOuDIsIDJ4{e$10F=faTFQ28m z*5g=BxY=o4XXg!+xmKa@~|Is?{jXF9FYu$cz zfC(J$c7<#Y#t2K5T<4<_t}g2c$wSYahsS*qKgseZjKf#tOntfSAN30>|NaH3IV=*^ zG-0U;I2)r7jn$qy@)&-NE#Obg@jkg(QxT#08TA7MlWMdvs-+=0WiI~z zcUwRaJ1{vqXNW|uAlO2aLWdN;AM$FVlt4S+$G`%z0CaXjF3w1S_v$&C|Nc_IhxCKB@o52J?=h5n_ZTkCpinkyx-0$f4y)0-@OD zYR^vAsKiJpie3t{ZcQqoL~v!MP4>X!k5mCiDQsMX(U*dgsyH5&f3?WzpO0K0GUKU5 zE_7+ZR|ZKxo(^+7eQOwP(Q6`GBhz@P*Iq>rlL*b2)e{|)jLd#h_Kohk{T_i|22tYJ zHDU{l$AxEO%07b&^Vo9KLiN_6fLDk=8L3o_Q>!D_CWw?RSs1Tzh;b{DHP=Lf%Oq@n zeMs(W8kuUnW}6$aBm9lMOZLRyM|)0eaEDSu6z!~Ho|`P*}Gjz5S6c)H3Zv^3cJG8^AD%I(GA9U{3`vj+8) z{nKtA_UAvIlupytH?jI>c|iQ*hyMSdxc*Pz*77n$Uj}^l=qB5e6NQA(po0`omqw#k zU`xxTA!{VjnwtDnjY{5Ho9@4s&B;WF)X?#vw6m+WvopDoX(_csmy4i^>XEsb+-@sP z=ex2}DBa1<>}kRU+Zeuw;(6G<@!NUv-?{7M;Ch=9K?2j9wFXCLyhOBAdWpbeWZS}r z4&5@+a`S1iR8`r4_ao$clcRDhkO8>9OrR+I#!Ml(E-;n8F2GY(9ad#sc6^cXmJp4b zs5(>IaMi=vpbiH|XL>vo@h-2iFJ+Q3hY1!SWbQF-GU#O|uLfB|)t#8j#~J{LGA==+ zDoXybS}Lw2BEwrGLwpt`1sZB@4L^mk(cvX-fym_hC^DP=cE~6$k)#pHG=Qm20xX(A z+VOuJ*Ws}*3{cIm*1N%3)hovkOm9-lfT#cxWx2*0%;`zoPn{KEkR$$Vu`*CnsLWD+ z&;rx7!`{PNG)Y(K%k2tWU49Ni*cwsVT3%XE-X}PMw8Hz$q{=;|w<`vd5vLVp6`D4e z_QAtXim4VT_eZ%@`sTv9X$~&uQWU|a!nY#my_cel<0mdPY&e`p;n>?SBE-V4SP<=XG!`}P zgqrJ;7KG|DE67K;W7|gotmb~!Gw1BgaXPH+*7b^t0(9Zw2AkI8n>WGhawf(;P@QMw z>jti3FV0iLsc`j7ry)^r-`J_gal(-hcf<6ljnU{$kR?d<5>=CDm7H``$e>yWTQ{} z*{je@t^3d;QB2sJxYR3NAz#p#YC-D^SF^wr09@z76zr>cQD}=KVl0o`L=$J1nDb!y zJtYFMZLM0lxO2oP%nMhs;wELR*omK6^22is*`)RqAE1;FIy3*8Ey^o5igCmr`=fL< zWFyiJ7Z5v)QZKLY`P#=vq&vD2WzrZj05RTR>z#FD{fO)KvM$hRx+t$G2Tk88FG`d3 z3t7UG*(r$wui%$WAu_R*#g7d0(T`QrgI4MHtM#BoP#8rmc5IKuE=NHoh62kLU`8B` z+K98bhU8+R6g#YcsczKOHn>YNt&Cb7y~!OJWt3doj*-2Hql@f$Iv7{%5EN>wAc8T0 zkn+?giN);x6bpnfT+L42vT!eYQ1NcWKNq#86~veFg%HU{yYrgMLEfHFx%WolxXmIf zv&M8p10HWSZKv%H#(H){XavHlLMXh2Ab{#i;R`VbdYe>LiXO!&5dc^XqBK+%u~m>N z)`i?KLJN(w(Ul&|rC~!qsFR6bjj`-U=ssd}#GYc&O_keN6jDkbp14u!Pkd9!Twy)I zfMs~B!=5ybbi}w~39>RkLq~HXyoVjU;-5WrwcX zgN?}Ie|6NufNl>snteTw{C=iK`MsY2ceAJC!+=lWg#fvpbXTKee0!uydwid^CGV#= z6z<3&@=F}k)^d!u;p8Tp(f}REQX(4Et5{#gr8MOT(qWlim(j#v{#W=)TNYt~s63N2 z6%#ee9@9wr1lKuQcoLeyEeiivM)-^M0Dh8uc?i{oxZkMl@E@PDXLW)~LKG*Y>(b{4 z_-Cst|0C`-tn)O`&NNnf0lWNi88{jc4+~M;6ygozDzoU)$d^9z^@wG#?a26O&cO?? z`a^&J(p1|Jr+#6lu}@<1eLLfX}fD5Ip8!qzjb*xN62uDEpF6RhB2Wg3`MB-nX zA;dwyF|JHD9ciQ{obV__d7~88p|p*IjQMLPW3c)a4w^yvfxBEL!8LW!*oQ^A&yx%n zB+`NQ-ub|jGi7^^CFxsgkw08j(ZpKm#E^ZEOPJMMQq$L+N)I)~j?@ zrWB!?IK%oDIi$V_JIJ?gu=!J3C_9II)``^d3jh$0U9ph>@_ zA~Rg~n0(_2Uw16pc?9e-IK0BA-{g5Ikkl2tQ3cTNNOWKLA95&g_fTaz!%}#Dd@B#td#=*Qh1ViPLDdEtu-J|piwiEAy%abx z;>2iMUztTF>E{m~=U;DM}(plrX8~Bxv zc-k4%3plUkpIg;neogB$uD#s{7o+YA-UC3YI7bNg4@$sMD4xiT4f5C2I=o^|PDz&$t*y zXA$(nQOtA4vWKCa=7ezco=V$#)FfDG5q-KRP1Q+V{?yfAA?ng0cUtDeIkVUWuge>e z0gNaKQC4zuM$U;E6Av;b;2>Jqx zv0ae$nImru{T3>ubS(fazJHL{91lqK*_nc~p{fknLRWZ`8UjsO=MQQ*44qSKqzJ6Q$}~51ZfFBp*<9fYl6+} ztyiScSb-!|O~UE04^2ESCc^t(&U;J9rU@ZTrQ1;@q}>5<>!e~$Ixh~>$U&7{Dk-u++;0~(<9&JW`_gDIf0%5Ev5A~_oa8!=lr;nI*_&z!U+Jeta=)cdix=w(UAi5b;%h=>*sW_W1| z?S7r>!_b(~lk4}w+bE7vpZBjZ$tDJ$dkT;N`eZ?P_F4ogbv6qvJ>$+F`y!?EMq_xbt=(GQTtwIt%D z2RHLk!c;|G4^1-RS@=y6f z$6Y_P?xv*tk6>q2B3mKrLU?o)IyzRq{4^>mT8^bLOB*&Lj7OH7@xY+Ea6O4yadRZ| ze2eB!SNM|iPPLSaHQrSA`KT+*BuffjtE7s%fl>{{QuEdyxtQ(+(T2{IFCi{EDP)Bg z9(t3N2$!Un+FbZP1ENUJ*sF4u2AM`i49_SrVtZy_*;0aW=^tA!lX6Hk-+q@_VdCK3m6ix2f#fqMQSe3$F6WoOvy9Y&eK{ zqaW^dx^bL}y2N@d92!^xj zMn{9hI>kL3^l!c}4532OG| zuECMi9vO(93L#63!b~zW;FEVbHNpXvz?_QxDGgokSd#C8SZ3tEV0@5uIKF3dlhwZKPE358R8B4YB=3$5Q5Q1pclsKed3!b4PU=t+ zxv7USoA2$#I=pR$=UD%~B`caMUvS`m{D`3X@k9N;w!i5J$cT1MO*~SN94t=e9H>j{i~7%Xc8%eDrBHMk6R0Jvf7;sC zyPkU)eDa@rhhC_wHxR|2bEPW-bRJ!( zOyy+&kVe}o!BC^1yB>bARYefNP zH7}9qp{hGK`jxH7Qk7w+p_v5YD_HOnEgA=|+ah zp*CozqQSvauOvqJ*f_`L*HFr*z&*8JYXp#dGdcH|Vcq0-FHB3Bl1YwBu2K(O zR0y(?;JHPJSe-U}BQ1-MM^e)ug@iL=sQMIYm(=S&tn62a@=Gm}Ijze)XpNWf%MN}Z z5M#@}(wwGGv=dzgpsq!%E|UGd6tf|0yHKOZi-}{&w(mW(Ze-2WI>~B01?e(eOjMg+ zPCP|sbTDO+!TL)b7*Q2vkEX?L2>T3y%hR%|s7R<*q#YusyH(zlId3nVYSd(A6*Khf z;!p*dJ`YZ8QNosq2+?3C# zxGLa@GhK1@^Wpv8xu%w+Dj&VylT5#+&fjM z(FSCF)ejsIsZLmNa5*GOmXx_}z(upuNCb(7c5As~lhG$iaT0vXGJmFOw^C&UBd8oT z6hS7W*ar86q(NzV0o<37ZTV!XAvLWKw+Gc5+H08BgopDOed9;S)x-XKN^30s;<=`K zM-rLDsvB1=!t4a3XBl4N3=gvM~ckEigr8%d!o|qO-vkrxny2)&RmavUncza zoDj-czj&VNu;|{mHm}3aJ^*D*+SfXKkEtX_2HionrkQ}rM6S}qWJ6}HTK6w_0a5%a!C&#oOdZS(McdE{3juwt&hH~RJ z&O#6N+Eq4Qk7LeUi+UVUaG19`5er0VCQ03-v1q2{W);)X6>0iq$NWCP2iJ0y%)PTz z)kM?CJS)RK-dY0`;piF+eKNe(YWSw>(9jg>1}T&U?s-Y~Hgga$TB zxSObtz<&}G@iScI=qFQqLlJIM9DEAPLqO8l9qrP3#^#!*WneW2EhA05B3~1wSYzsR zozf3o5&;MYB($KWe9ZT*s5J*s2FF;YnqFvMi^`P4Py-F0G2ADyigs22Ls`=C!qt(D0a>FwJ~Xk(>g!3o_Mfp}VVZ;A0L{F4&K3_%9%FEYY$M;BD0Wd|f-(lOyu z;gcAB(8PbH(_F7zJq%qn_3U_J1kf200ILF9ZmbL<)XDQI_;+18+6xY{`3bMukuuR z{q>|DNewq^NtH1M2OJ?qGl~|tM&Heq8x*%ZfWA>e&d`u6W`nCE`3h>iFgtJG_EIX! z!)FRW0A`Lx15C@+=HkK4*7ns6LKt_)dfwJnT}U4}iQeDoS}2A68|E(}=giHUskL8G zj{I0~%>z^SwwrXQugS0RG2iG9>!QH|*3QlihQD(34&^=Q*(?eaEX<^;8U`K2I=vM*fh|6KM1Rh3Wh zxSCI<3M|qKM9G*5fPAQQKQ~>oC}w{md3J%Y* z*8{MnWK5H(QdNX0An<_e(s^A@88g=n^E)*Gz7YyENs8o&=ny z$uLlpC>$%GGVFUTU<^T|K)%;@(vGhy{2>wdZ(bC5cT&c1!7DB60& zXbvn({VUqTkOjUzkF%KZQU^};g;M?=jaE#|GMMU{XnCRjQY#)ISSg#%5A{ZOvTF*l zm^seG%tqaPV2?LBW2(88FW95(*5{65i<~;AR|7&h zSAxuMoOE>pNr8BSDm9l)MCt7jnBF%~KxY@uU${xoP>dO%gcAjmyHbpFa2Mhlb=zpG zUC~-G1f$S<*y0=6Dy}0;?7ue9JkR2e!Sxe|+$=EbrfZmf*=$uh#U3o9dFmm?IE?7% zR;qR?Q{AyQdnYq{*<^VmwlBCKb_CwlXZCMN$=(d{(U&=66&2hjbp0>d-ZCl)NS4A*P@@RotMO(wZr=b3u^*FcTLVznP41P!vy5>TOaBkvLF;fk#_dS3vnL5 zLEbn2P>S2u_{+Dj0(|1l_~J@4N;`!crZT$CK!zZUk;~8h;$DIX_=UWMuSTyAZ!pNp2mm`Es#$&I;X{S`Ll`umyc1q7z8zX^#tk8~nCD>0YM; z{5=Q%yq0!4Tw?x~U$$9pa443Y;s-(F=^c-D38PJ_!2_=-Sto>G=ucU3{{cIfRMw6T zD_bdnVR)Y@7}HZT#@ZRbYz(PGgQ|70WVUuZcnXce>iac}jAi+f!?q=wFtcS`I`v^r zT*yTouM&OepSw108Y}k$J^lVg+c2-nOCIk?#c$w4)R0=Lb^kw?9M-OOg5PtnR;EZsX*CY4yMjo4&R&>uTHNKDX1f*kh8M!Ir2Xuf;Jq%1{#L$d%!{X?H6w*w*vI zFcy0*XY5chuu>pp|DKZ**u&1w?1-ZLVW}}gGI-|)^4har2VV?$?GKm+t3LG1qk@Zn z_VW$C9yp!zEoT|1vVxq=wyjtQ?KqZJ?{^knH4rbcFr&J>sJXIw{3xm}rCWmgX^&+q ztx9f7s1}b6$llTC)MLreci^3Zds zq@9O+#I(J}H|MaNSYoXzF*QV4q&1lV3!dmm`v#LON#0Z0?qWVY+Vp+_9j0NF^dX*s zfb~{vTxxp-vS|~v!JvyDz?>f%>loi;&6cHY@}S_|Jm zh+B$bB{|Owu=LJw#4xukC%=lKimisV+QbHu!ebcr=HD95{h1*`p&>tfNQ3$CLF2!{ z0S{}Srz^9Vqodvbeq&zi{p8;tnb#Os!%#&POsD)5TK(tt<%4QcL5$-NDY}>nM}#D) zMq?xBI}kTx;!wc!C?D*401DH?CqW$lN&;N*O!^XmDBdW$<#ux<Ch4TgDvaDNWU}0p{ED1Q(NUy{Mw(>^8%FCBjpHITji5{#@^CAV7o{0^eofy$ zltLM>7QY{Q^h#3*v}d}&Ir}0eRzBjyn`q}?VQ+G{7qRm}ar!zB+>g;p;?Y7l;+&)5 z6ue`~&daN`LmOi1)BcD3jcTB;VN3UHB{;_HkgGdJGdm;QS@PVwK-YP9cG?+AdXFdk z3IPTW##7snOi+WolHa3}8gm31iFNRXv(Qn6EFVDvWBhxOdHzosKn7vngIuWMBq|ZQ z^Qv2SRuWQo$;vI>C=fj>H!V~njy-9{*%P1q}PWGIu$x~&T)9f z9-%0N9Zx^wuTg%KeVx za!6B2ab0M3m=rCeRT#)mL+@`rTihd?Tvs4}lsTLHJwbym~ae_pryDai z^fJssM#&mI(QK8&0<~J?Ik5sRdr}!%xPWcNU(`qn7A6+`(#wCs7ldbUh^yowzuLAR zSHBH>0|-)Q~EiMMf}%W zkWyOI9H(o46|@Dog{dZKLMCwPIz1;Tzs0(r0|H^r44kHBjTooiP?Co@H#^W25uV3@ zE#EV$$F>LV;eex@nn__rY`u`LGxzc;*)CjQ#e})GU6`zL_REOK!Dq9dC$Y$gCWhsq z%_X}+7<9AaOa0)Z;WdYw{NQDmMwU}hix%o6C5}N(Xo&|C07gK$zfaz7*96 z7`UMel>Y%O2!NlC9y!i92bO@xR*QH1{Y0=DiSl=pt`}A7p$R3KrDF=8gzdKFwcEcy z8A_7iaXRX83?)=yHMh~f@(mt`a_-^7@VJ3mL#pwG2BqEV%JAoT*$g6vZE_N7rZC1x zg?7L_;eY0;K+4V`9ldGU8vU-bdc;SkY}T=^>*ip0zX2%f9b8keui8f8sc_8>w!{1m z;(!SlM^L6~6Y#AgKEx;1M#dy2h#B6IjTYH`BUsK?dH@GJK9ixjh6ht5EsvqC=&dYX zY%|6lv<=_LSA6TFz@m`t2lW&;EG58?0etp`Gy|gx+eu&G z=Rf^nF<8G+RK1sftk9KN?O{-1q@eUr8lW5|&lp)IL_`t{=N6x8jE#aq-rCmhpmmXF zYZFWIA4890s^GUr3*Pf(v+a(-ZyKFl3cEbwa32KJl!?3~Yfm{&WY&H3LS>e8z`}%fuUSgOv6M}3$fC}&Q+=T6dH98h!dHC5 zwRe9S?;?<0h7b}LtYq1gedalJm-{M9DDj!j5l9GFYC3EgqO2aWnNtx{WigFtaKn)u<%1Fqu-iSm&3`Y*xZlOL-_out8J_5mzHY?&s_6jG$s9 z!IQ9wWJ&C!R{wg9tEoZf5)y$NKB?%1=HXQ~kKQBsP(0!PBfB+2YAD_P68 z(lH5U)e0UN-+gAcG>HP(TzL#-nw}+ti|Vm7_n$$RBtp2=m1WOg*bZ!5ohK!T*^$nU zZuSx~#kqB}3Z~iG%b5{tVY)d@=wA+hiRf=C(D)wJ1TCGdc(OEilQiV+Fs>RysH;p3VHhLPkKM1Nb+xFfPT1M%TQ^?$Rc|K9>s#nIZq z4e0WZ!c$&-UIp`&$zJxeXhJ$1967DMHxw2YBRO;*piHDx#o`BxwU0i8HN&OoBqIPbHvBS021<>RA@27vRJ*wnxLnX z0%Ho9N)Hq@G3}?EoIYQe?;^na$PockNg|4DN;dTEqRbbRj?0+JaF+(O;ZGJB$6Xyz zH`s`PeTag^d;(8d2d0S}A%STI;unRYQbZ0c_x*`(f>|>RJJbVXH}hjwqV(d*dC_iP z#ZNkZ=rKicHp?(=77wss#~IYwyPH_0qlqwbs(2=Gd4fN8#c+uoO0(zO+>EwImAEWkQ4c{ITTWa2CS#E^s+c5a*E%m z$dp)QuE-Ud3-pqT%dG9LenNvMzX<0hx7PNTkirzd-ah;dPG5kC6~uBjY9qP?W#_?x zwCL83*h)fcvmY|(WfNylU%6g7?>-^7UuyB~(|4DgZI)*MuNEXwX%`7?Ur3{xIt5^`^5s>@gTtW1n!p;) zjZG^nsH4;g3R>6sURS@uLbQ$^d35q#RIzjIzR(GZI?GPG`5WIYZ_Gbj-5oH0U?2S) z!P>Qui%^eX$j7ui4#OQfiIXEY)Oa9x$C>*_ZQfIRg4`HqslQ4c9h=!&ZBJ9Z>+&AN zlh9+aKh(o)XNWmkN!mBlQ>@A9VBOlc9L0~BSJ+sk+cS#Dr&J52i#)>0(09W^fHzJ~ zXk4e^SBb@#=xOj-E_9leV_$J#spK~TD1<%HQhQ3(q~f{+Eao&mnHU4oo#)yo9I$v4 z01Wh`O7Oy&^0khn56mcYD5vB_xiG1l$S|OCgz@NUa1^GJ za$`lp6T>cox6g9%olLK{%O@?IH_K46oZ@PwX1T7ADGGwI@?kdEf!7CN*_Y15i$X&p zVOU01?jk(mV$SQ=oPKXZVgz(ouWm|xF+1ew_O2FUb=<^?e&YCsd4#Jv8{LChw+9MV z1DaNptT-z7^RwI{%M?b1nAXCX#O&sFk6}ZZUi`FZ%R8}-# zGgKDB@SqJYj9&HVK=MAyYE49>bjBJ8DhXIub0+Y_P1^tR$XwbZ+*0d_m&WvqwcP6E zceU3SSv~oq1xZ!*_(kctd})ktU(WjAGzrV!K8Z_TkdM;2MHePITnnJOm1GJ){)|qv z9}fu0B6j$|4E9MAD$q2gr23mM@WVE)i z6|eh{c7{aUOjBS5F|MEgsBXU zP5~oO8^pyK050~U`nsi*Ou0yqx$@_@Ok8lN`kUYAZ@os~lrAq2@MTGVrO z3(rIbF^)JkyQ%`_jXOgBbjwKJ3IRG+@KNRLv8zq+%LO!4sK5YGCV0o}+(26X`>!)M zd+aU2bW|)(3$6ctM{qbR10R^=h zb2ZvCy-CrMVrLQa1H3sjIRbvI0dg6RuVH&5f=oU-!&G8n^oNM4fmr?Pjz#)Q5_*ll z=<2}W38L5eba|smTfwYF1n|uez1t8t-x!a6+vsY9hM`Y1b9R3NQ|Y3l>%dM>sFD@E z*mV!mViQtw%zA>jqm$6c;@UAlB6dcfe%ryi(an|w(KDyx>eGHl^T;`3=-2*pGhlr| z`|uJZk;#f=2<(a9-)f3Ng`%j`cYg6f{@1rk|3CQUY6g7&=wSK(;8;?(5`ie{$Qxva zcw8S>0ty_aYzVT1|b7 zm0@i30?b78sEw7C+=mxwc3=OyD}-KrY{3}RPvYqjJqWJpQBKB)wKZ1ll+GUP@^|;w zyy-gtRL?;gpdN`~Nlb*s0zaEG?bQ$G7RO>9VDKsK*UYde!)i#Ndq4vt#!w7JrX2PK zi`4yXS1^j37?rv;gQ9*Z-iZHA8{Bme%Zdxvck_?Q zu#3ElWYqegMU|XztbrBOJfwv0JW|WFgZv8|^i(MiH>o$1>i^lt+inoDRTbq`$p*=7 zD@|n>0&qlZUb1LfKEK~PoX_n}^1GM)r?O&(^v69r!CNVozG#@{pWTDpnyrJa4Stc| zT}?97r1oFEgUBEi_Hn8@(=#4|R#F##X9yEW?Q;K>Bf6qBQ5EkT@q6cp?f)D{{vkV( zw`?$3F^9i3pLv+)zUrQA=^37cZD^8_iZQps0e#uoS_{C3spjm~e4NQC6Q{w-+qU-~ zHm}RDut<8tlkyA^G`kuWjLfGfc@OT0{!j@A`oDbK{;Wm50H^mL7SmGYhiWqdSDbtJ zP;}u?jP(2dwA_-w_Gs#=UhiQH*#AJhqVB0bLM0Fg?eO)Mr8pdjQ zhCKL>zR7Mho}b~4g9n751WlD!!eP(YaoS8L_J{#DC5ZI7Xlo&YN~f>gbFvK(J#f#| zaPk#qAhW?{e5T8S%dl<733|o2!N%7MxMtYi5_4iinl(mH3~Th(jGu4l5Hr{(qEtE_ z#rf`v5^v~~YSuG9Vje%(DE ze++;?r~~bQyL%D*yfdf0rUCxBUCz$s=Gv+ggM_7vP-jhT#sIp>)y9o9YRB=`E$&n@ z0U(B6+v*q@%q$xf?{yeOgrayT*#;J5pCZ8hUbb2u7nvPtrEu{s<@?BGV?GJ+3gni; zvgqC`%W;0Ok`gD6Hhm2V<1v^}wUTxMKW>XKpFTS>pz{hmxrzgn)iCU9;`Tp?C6lQY zw_w1Tkwx-Ouv-nYFtBd@I(f7DB4p%Z?E?y)YRIiu=BmD4Q=8$eVL4SMVEYI%K#v|} z8ziVQgP%rubiUF?$C#&6Hg*FJ3b3B3nJ2p-QiRfS%q^ixC!8@b+QZ2{0{T#ol#;2$ zlM-XF^Ao*EsebTPA;@UUGR2zkx*#SiV0msfcF7;WSKoc~!zD8@dV~4fpPi@bF_rJA zhrFZi@=r%y0{H(Umn2UrVg5@lfo3pU+A$kq?imU>FKT37Ps^}N8&CL%o)Vj<@LOU2 z)2&-_-io3hgfR#aw%4j3@*YkorqM$@IFb@~XU6bF_2x;tsw43E(c_Z|GW|y>IBMti z!|D<@Bg!W|E1=}setUCmf8h3FwiFnSL|UfV@6obM%ivS| zuZ2+(mz&2rx`qMkY3-(?h1W?~5HV<*8+E%>xh#gX`Lgq>Jtp6}twKbyLnB+8B|qD* zB$k!a(HvC!3U9R;9lX2gNhbj+E)d6!XlndHk@&5Us8V@A`s-!|f0<#Qq55KY0Hoif#2^X@v z?s52&n|qPl(!jnQf->vDfl=)^%*u^!9B#vZn-#rz5)uWx6X##9PX4QH^#3_=GywlNvn0vOL5iY+ z-o^%I1vq90rDGyG@v!hEoY2sy9Hfd6F+w_LGFt`?1^UgC=)I6pwufVjB4966OsSwS zH}G%_7dLK}wI$uZ1$K3P{4taT!Yu?s=i$=QBZvVESNgSjDq!+(?xnjMhB|#HYqPWF zu@A;-^I(YfqvDRQJL}B8kHYKNKN8WH2itX4k)5$0eV#fQQ(@B(4|aO^CfRcsYM>kz z=ax-(+IZeCKs^IbrjPt=MEO$jd80>8&$r&Q(Y;YTW7X4-hL3d6y;xR8qg@BVdBP$= zEUQ450!+Ss{8hNcKESbsjkk|wK0{h`0Aj~UO%Fzr0bQ*%Y8XY5_E73f?^B6WsbjPc zCSQ-CEC7!RnOwmr!4 z&uOH;%N6_ztVs%6_&Se)#RF>cnvYaogJ4sN$XAHHph_WxPfv zxn-uM`~faxBX@r$PN_%cvsdgt!6L)hTH!t!f=1%f_o3Xg#%CSV#D_w~42LAx>Pnq+ zsX?)LKCXPV00i$U%{y3&jdY5X4Q&dI^<@f;Z+!wSh|1Kb-c=J;;4RfxzM$`BFb3^m z>1;d4j9q@P%ip7dY|pW@>Kf#LA#xeQJ;O`LM1goQY}i-vV)S(M>QS#)x^tJ!oD!4O;?TCCLS?LbI|u-?h~AGD ztkSs3KV-2shykseR^5x?dcajmI*vGuDQ$lSli2}Hv77qI56e!uEY7b9`e`iMZ?MDl z{0z|GplmgqLQJC2awt&7iH%T zN4YVLNY+dbW}%WPtkj#yi*Un0m2ck%VbCk1XfF3*^Hm?9kkpvWj{STkIGIc; z^^3e4j}Vcs*wDh4C%v&%vSvj_9Mn)|YLX~)28!0{t12F{`msX6C_4mRmqn4V@x*@E zd3`*nMcRry6I17>6OPnRThsMzo*&k9<`c*{3>O<6!m=wyUG#hQ5v?^f%Ztsa;_AFS z6L}muu{mm8(X^CPX~f1cHWj&%3~1m}T9gL6&o)+?O6eNuOK@b~CXV2k&iE1s43MqG z{6qZ%W<&iLihAJ*$fI~G9Z1j*GZL!l@Mz)`@RhtM*ifV~O5=@wXC-W)m?sdT4v$%c zB-FXk5SeAL6__Ozv_pbP1=4IOa=aZ&Smu{lLwJ#!LzB^hktfW8NWSC1!@~0euYS9> z4f(HIo*mJe>JFd-PPT?%v>N0xaL1e~;X2Br(F_?T%;VGE(_r?%TIJPl~wpSCEq}e8T_5F5JA^1-t(t zkl(-K;`V;{k8UdlSl)q#wTHC-f=#;x*ZB3z&#+p!N;>%h20sl`F>2>x5u4&cQZIzO zFWg^(N@b85ny>gGY@toRG!8tRcD}t#{dst~+Q;gpP9s7>TkScDu-(^BhWkborD8qH zk{dUB!@;}1QJDHF$}AmZ$n09oJ0+afUvOFIBE(vzBz3I@W_FMEu)@hCXy% ztAwIc5w}i5KU5)vf1fqR8OIwFE^aHFzTdx;x0inz2BF%=Tfua-4-??{#RLa9fr?Pr zB*d7L3KMQ)Oj1zNK;_U7PRZ>6SprI)43^W9a0;;65fMg{8y+! z9L;im?@)`q$Fu%F7wZ4}uJhlkNL&9eyH6`R@K$WGM4_Q3%~7m!1)KwH34Op}21M1s zzKnaw*PvMJEFD~1eOvv&{z0#FD^nJaf2kw8J*V31)2ByhKIrRwMK!J9DVy}2yNn&l zl}hF={Utf?Kwx<2C0&y0zeAX=5lbT12DUt&+jrOfod+I6>tW0KJ;vS{U~>X0JjB?6 z4{kyQ$h1l*J82(MZ`FT|=ogCtv^t(Wj_rTjlMWCVyJ)&jaawGzXiqZXd$H8?Au6i= zv4&(9PNvGyv4?o39k!M_yL{Ic(itC357JSx-ao+WuXIZ#Q!B|CK^=A@#KB zGcK1CuMy(cXlR*i$fHAUWqDdoYGq_#IsKIAkAx)eJYkXsXsOB4yWc1Pq`&R6vrMh4 z=qJ8Wu>XKWvx~xWxsj;G|A4q0^>9PoD)79c)uiOYqdN%?DPM7G_0{0&T zLX@}JNr5zKJ~NOS`z#ymg7aHlAZ6@I(kfSxnct5;sMnW3>GkbTDq} zyr10#}Kf>8U4m(_c-CeRaMnKOkNz9gK#iPzJ zQDwAB)Te$#vaajcPxm~($8khGowo)A`rm$UAe+U}wAqN4CZuiLqT-zspM;g#Z|s&)h8Tjoox3h`ZIwzO=%LvjhEl z`xH^B7`mF2dPjhL^Mo6f8q{2X-iN=t$y38G9!BpZQhXJ6bCcPqLSceONi9aQ-29HI<*xXiA$l=)Si~E`@FxCHa016f`?X3R@7neMFda2{C`=UF z6-fNJ_iPMZ;pAefYqF{7*^`TH^mca{nI= z|9$FS%T}F06E{E!ZUZ$`c;{c`+_}8opDb^ESeH^2`vQ>l z{Bw-GEI6WhlT(Plu9d7L^!taIq-U<4wemc-x`mYCwwBBAcNh7|KX#QSnH|3}<7$~` zMhvvq@_2Y?$wnJi1+Jl{Gh08ehHvAoD)Nti%N*a2S~ojXhF1se;bLpMZ-r*fMj7PN zN9<>%npnwagKE90(%IJqtzVpM#MkCDNau=ac7}xhQuBu4fc@*o}{aBz)jAunD z6eAkv7KOyMpEKMkhmlMhFd%O8mfajH!*sG@@s>yP7Ba%&Z1CqDm;o7egzw<6k07`Q z8O{k~DawHmy7A^=@Goo3LuTiw<7=qcl80pUHg_c$^fMLIWK^KeGxG&-kX2?^^;~D0 z_dIIn^!_#x^QwVti_Z{(B0ursR=4T5Za+f|Sr^6gg&}%FqdH--Q`DN6q%(hiBi?3u zC1@Q0HpiwR;;z>{f>@q3P!vM=!YTR_5|3n;0yJLYu@NQ;RFqH&S2mNPXRyJGcDYt- zekfEz!13^SMfqIJ)W#xp85!z}WH?d=i~;13nXl%>@0{>6qECdzD6@V?b#g)SOo1GA z%|s^8N-mvEJi|y_ZT$G>nsxm|zNiU}jtQx2GL80kI0v$?mOTj9%5^E zFqlb(YGvzEx)hOzHpp?;(3*ZvXY1)-F4Dn7Sf64;`aFV6)Mm)Jd$8n=7tb<1BkLxq z!R&x@Uz2t~W{#`F0VS4-`9``x_65%XoT8YtB21v1?fZ;kYg`$Rk73?W_tdov{H?l=Z6UV{B1BP_nsSlR2Qmo>>)M;O zBWcO>)mjb@;@pM$2?G%v|7EliE*AVXamviXb z<(vXK!=uUzMC;N?BCk8MvAu|6(u`Qd=%tLieJo+qHU?$>OoAL^hijq<-B0&^l79IR zLUaBT^WSuC8SPQ|1byPd76lo~tX3A;(mb5xRUXln_Yz@&HIW+#hU64uZF>im=6`T1-pc@Goi)tAQ+&?^5#YRryX=|Q8BC-=4um1H zKg*(S)}1a`k0}hx0^>K&d+N7*pEm1WAMe_>J{pLN_rZf02W+d>($IW*Z0xueK>JnR z^()uw2HTD^73jyqZB(6gb$UuYro_vHHHjdG(}IPQQ7&k@YNb4Os=pc>IRJ_~TGeKnrm;K(l;_|FS^8LmRig%Gh>Fh+ z$%fG6r>zW+Q8@ZTSLzymFM;S z;t9cn8Ty1UsRgF!u0dpOCamAq1by$psq9an;FeyygEAW6g|25`=Sd=q<7OF2ApJsK zn4$iN`L%}7p)){L+xDR7@cC^oSZ&G?Mnj*fDXsL*$t3S=j)do8w4S99lqh~h{stTY-ft9 zak);WtQf$aj;AQWgjD@^JfU51B;nU~qU&eujov>%Eo;t)7Nvy)?>K#0mG(6?FO}k!`}atap!t;QO?PVB0+iin(V6KezsO?B358_54uU)V%-$xRHwSgcQ*Epm ze!}Vsl~kx(&sj8m%!7R*z}MkR=<``AsZ6qq1*PimrkA{wrn!6a?T8(rTOmw5#;$%8 zJnFTy!jLsjgdHZ65_024I!oea<7{{2-w;9uQedCch#AI}GExr5e5&!Wq&zRb-=yJD zx7cr3>j&v!NQ@H;^1fXiT`q9O@Q#Tf?edCJbTCHJxp0A;i{>NdQE=rMa}?jA2ALy> z<7AU);5~xwi(CG9Rz+7bDGBxGbNIAJH%m-;IyXj-?|pGQ(Jra$`xwko{QYRHRg;7>(hOy&cfq#`3YHZfG)OUH2dq1-L=gZ4~t}BMF z81IJali~`Opk$a_Z4n$o*=J`_)kXpcR!p62C_A~5o8laYG@x^H_R5A^g{P6%Q7!vD z>=+|A;5clL^II^xUOQl0zlX%QQ}%O|D1@w=wD zQH!S4z$fHo&pLs0I5FhUptYwXi)MFFi1)JR9>f4irVELYQ3faW)9hB1%aRc%0gA$# zgUB2snq0)Nc`g9_i?1hQt#Ic;e8X=3iVe-f|wLJm+aN0~ePL5c^)IbpXU z)bgt!nmQq5=64@_qKE`k9HW3gFDN*byssAsOpos?M3jLCFZt^77Ik)zM{V|?}anM*)`(itPJAW9DxUM zd`y8awPVA46klHCHs2<3@{3UK?)BXV=p0U8GtuP_OJ^)305Z-=_@%Mck-|GxWO7vW zpXapiewP`i8q&ZKPA@S6<0B3dDK_l5)*5wgPqP>aSYQnYMv%%q%ln+M4{$;2KhA%> z9;R(_bv_Nl2@P4|Pq7nje&4?*G@g-pxDCkw)L8am^b~LD^e8JKBO9|#oSXTWzu^*k z8z?+BEg7YW4>z>bYqD@z7W4l^O6OrJmN7e*GW=FXvQjukcV^LgLg{L>3l7G!@zjPF zmiDs@e}0uJh-ZVFw9{rnz7}wuEmQ@H|*e-)I55b`!j|n#|Bkf!fvD4 zm#t|aaQj|0clJ&~LvvD~ic~|wR;bdR=4}_0bq@O$b+PJEvP{K_;5*&><|k;^DeD}} z#`58TuzkK~@Y5&Z!TRf4 zE!dHWoYQSLSW7xvr>UAf4A3{{!kpY=la8!OcNH(Vyvf-=)tm;Y1lr~57?tjRid$SW z&5=WL4n$is_8Dp=vxnzNO9md~k|jML01z1D=cimn@J&90udC6TK0;41`^$LDPWQz+^cQuyF(c`b4Bq=@AGs5ZD8(a!WOk8FMXCmcNVXE`mitx;$>&xcOtN7EM zha0+My^xSYM&f2D)?Doc8by<_vfk&9tdx@pT#2+nedB0dKfXQ1d^hzQEpiTSK zkXsyDgoh*Oc1E2+XhLV>8%3qVSB%{J2%Y7oYnbKMh=DCV%>WSP;5Hhv`01kR&{+{p zdgDp#?rLj^5yPx3c5=9xw)N_Ah?+ z+nGMpCLHPW^6TI26n|U{(I%_dU4(ejn(f3l3h{@q#U;ZgOH8|J#N}W#n~+I@AiJ(S zGz=Y@CK|$Ye`O^Czpn+c#^=EJ6BJe|~NJ31qHS1~EqvI`@lg_^1Ii&_u_$ zo${L-MG93FjryAAhf#8yS}s3P<+P6kFvNz~sb+Ku%r(R%GW-@p3zblbGp#V+qb(c^3+{Ie2~R3k}&lpRhD~ z>9N;Ff8@_N5w@u~np|Q0cr`dqoHwZvMb{8<7$T5C7DNYdBBWXon|7>mb|tc_%1Szx zTKUTUc`fPV{uI6y`KTE-!(6kM3+=3L;GO@K1!dbFUupO3XONSrU()Z2I)gmj1WyLx z?3FQoFnL!ppS>;s3PAP0>>td7ijAqjb5e+=tsWk3fOCNT{9w%?H1K$nU0 z3(x79UTAH6`3p|icdGt`jlSuphUDW1kof0PDVF(5PBcXj z=ZTS44E^cXmK=U*zccZpynajg4a(fcp3gG+J5EFpl%>)Qw1`v#2S+eu1$kF+sb6I& z=6Kjvz=MeK?E#_#IL=B1e5Qxy6V5ifhcJz9>~=qaJEHV>oFi;`Z%H8LJ+dAYMv5!7 zRdB@>lEo7Ir1eAxAl-R+lrAm)%Ae)J9cz^C>p-6NI3fH{)j0W`RGw zJqhBvx`S|D>}zPRV)YC)^G8GPE0Ru^=PTx5(mRmwFWB$O=KDHT{?D19kqcMq&tkm> zPyv-Yo%h7wo&sujxbGRM(4+;*$|);cdB-JppM0NHhe)87_U)~`2m_lOuZ#p8ep;$f zn+bwLzg69j7rp)Z;ahXIl{R`sx?CN|G9-L;s_W(Hj1*5ezyuh{Mv_+QoRk3c|HI(OV^3Ta%@q5LYGd6kRdYOx&7)ot|LZR6Xv`n?}csf+2ICHGabJ9%VU#Eni=kT;qyP z3I)ROv1I?qMu6V>)Wuf2%Oj@hESFXm8wxDN<5t`CS})fhrWCZ45AJsT@h04pmr7&S z_&yn#Ib6u3b=o_BIGLU@9+Og%{GLpUbu)M|Md;OK%yvE=79NfI5G0C&_bp7#EL^Rc zg>4ROn*hzVkTe*d;}#jijol}Xpi6TsGr9pS=3_l9)+&!w=4>O2$FN)1XPKl*2K4I^ z8UAVxSN`2%?9_Mee(JDw0)K#jf#cFA)IiqRWm@Cd#^G5@gZNyO5HT^8_js=TgM za}BHVj_ObWQhoe(L*(1T$XPX}fydprW}^*zkv&iLr1WuRkt=iCmeoxA+~cI*gT{m3 zpvPF`mp*B+{0P}oA!Rcgtw6%%976!+AO87Gt>7KyHLQ9Ugi<45RzyJJaQ)nU?p9{$ z<$*`r@+8!`bzF+E)XDD^J*~*3@(zTiAps?r3bP?^2RqnM`F zthWc@zq+hW`ISbB_xg+ZzwwCdf9A53J%BED|Iln{{rd=^2INgJ0(J(0`D7HH`>HXIr24{*q?0te%Ircxe7o!~*9z?h$b&_U2PJa7WQX{5EJ&vc zA$xRntS!1hcK7dv*7_93Z7d`>NFU#U&COnT9~{fCp%!QG3D;+d@kjsXqxtB1_=Op# zcz_GaM)9AKZQMR9LFR+1=&I2Q>)+OxFO_RZ@EI(Pw~dC$22)YGW^2 z7B$fu0xy&BR3yzgLIuJEEnv^5rbB>!^xprlm^h_Qxae{s2o z0o?vHIh68rCFA`sR?l%wVu4A2P|6GUH{C4y7nJ_L%deZR3lhj51RhGedh?jz);c=4 zRuy|ji%4sw%1+MmaHJkE&dlU*Fb#g#%Gx(lE;7&aCwanod`UewCY1bcUWfI8ie)ET z<3PVAHXN!kHiOOctqVubK+m$H5B@i_KJkqur;q}h7X*L#)dZsBhwcsotXzXDJcRAZ zuzuR^6tcn}H!D zc5<8xe2eV!Eu7eC?p(A3>;PFT-|(CHn)><4=N#&zp$=_dE1yTd1_zy>5Gy$~Z0HGv z&Bj6vV(fQr;@ON6nI11&4|i*CNqiv zTm0{P2+#&t2_o9{!STlI0?K|yHQGLOE_(VTOuWWs#ZLHC?9t5lA4nXd($TC|3f${f z5@)m%k?LbdJ6|u_;OZRFAb~ z#!*nJ;a$nt{em@=(Vg$92ry9~bQCXqSBO!Ya^2_yPat*+h*eZl1?ulpn?~rMAIa5O z715W<-(nPNf!Y|(_%@<%&-N+RC-Lc2IBYmdEVklgG|aZK^zo!GFS&a(Ki~P&Woyb2 zs$k1#xY9V-`5qqJvv10R+orCg78oQ9j1hD}e%zkao#761s}p~E!Y|`AsX2E-XFFraw%V1ZXAm2JJJhj%24rzO}M zp@^MpT$!F>XX+!EWKZ@8!=F?FTERRP z9aV>|c^20aVnQ;g+j1lPIF{F zK8<~s($doMaN4u?;QW0uvMpy2q6Y86U zTaNJtVf*lO%>J0Q#f{Z=jsC(slvpGS%Z$HsJg5oiA`gyVO;o<=Ka8r{XRq0j z1hxw#OCHY5;O|LEdTWb5hGxS%4BlDO7`{ zjF7&YE&-elBEW3`K|sF074hzx3~&^Mk6Nc6b^M(JLXKE%qZ`<_O4O2Tsp&V*6DeHkOMRKujO2cRhdZhlG{x@FDl7Hkpk-a+^*)|*yv9ec+dOB)56 z^~cWpamBnAE%$Rd$Ah3aPhOk|BrAB7M^AVcH=qr2)`y^gz0Mp}u}jyg2J%ZR*Wh~c z%8x4u{Amzud(J;!S++P9)kimE<;FOL(92c~XBWpN!9`_aCuk;ZVo(%>2~G)sy>KwC-}nA2F>_RR@Tfz;(HUxbM;RN_s?| zA|J<8Wj{a+sCJ#!aZRQwr5}H}&Q|ktaY5k^L6pM&t;*rQ3F80G4BDCtU$DE$hLc$x z!bvaMQb{E?N+MHtQLUp?sv~VP5&!6W0r}HU+x&tr7dH@I4<&^DSHFLKzY6mja!kY& zHna)d&z7^e`H}Oo={Vk+m)8r%9U%#~%)F0KRxF4GJW^9LEiK0kt)a|O8LvlkI6&z( z7ufVlWxYKuu1mBoBc^XAhFfYd$L+A>ZON47Z8ZoT25k^yW&c9xGi8E{5mkc9`KJ2XKSP{{lW>Wp7arSiGDo77Ljg<%|{@> zKi8U^H9k&NZgx{-ZW4cSMPaVq(~3g?bW!u?X(@bf1L)7aFRH$^*J=nXsHm2n4fEB* zW?{IoR2#mB7UAh)qc3#p(fYayJ~RzofL4J94UR^i71*Ltp9A5r`VoJr)Fm13f5dZp zm?DXWaLZ6gO9b1+82Sh5J#UTHBfUr)Za+%sQ8Vd&b0FPE!5=b)3d08K9!;Z&2O`&R zhbakm+0iUyNvjdH9&?M!mILD?znRYoS8C9z3kWzyRL6fJ>dOx%1B7L+_dBE0imu*? z>A%!WChAmuS2aNbg#_;<-v zwiQ1VH%oc&l42|_9?FCgH5hVorV3)JqRbY!$j#j`5ND|DYYCc#_RSh+UAen!yVH?)HP{kPocGaUS^S1i z)a>$sjTx&(2uIt&qtMnq)`X@m#&+C`c$J_vzVdo7=j@3g1R;dUxy(dQFgf> zMT4VlqEs8EUaeOW^JZRBGmvXoW1XDCWqgqIMoc2?s!o}Qa0e&>M(HC^E~XXQT5HTF zznK0fru)74{qO$ZS)3FM%<%8V^#2a!b8T-gHBF3<&8eHQtFIxG&MP`+JsPLAZI`+w zF-IGZtm9^s0ZGXBNW?_#k2$`VKWEyHa`~VCG2XBZ?g$+n#tqW6``zDXHhlQ4|AH_u zj_{sq$j8@o?pf^BBC{D+$4Sw&ZL(KBj-7p2#Ak?TUUa-iin|;Kq_w!cj2uN7twELx zz{Q)Vt8WAE{4(cYpLZB%HAfgIyW&7v)JIci1du_0ZfaY`n1izTJjx8Kx5ACEJaVnV zu(SO9d}me8W5I4M;gm+WRyiCK^7RlchX2F6SvEqW8?oFz<(K zfaD&^Le)?Sf+CpT;TyOO$;Ax?DI~rEgrmtHO$4_&(pF#|s3KprS4I|^~1jpy{xY^xPUYNcgip91r+V{ay*o=Bnv`{k` z<$S$H8p<)aLF)U`riqkmgCmU6jP(IV-z=;cuHzN3MsOVsO08pt5d;=1@s{AILCO2f ziSW%@`yv9k=+#)Otlut*OdvStnn$-Cg{+Gz^$TD>8LCerK_%J>LyHeej;5+ zi_jwAV#t)(C#=lb!u$+YQNhSr>0VuDfg%>Svt|ACglKTgE+0;vYjCJ_s6)%|l~$sB z6r<%^iU~c$qS%cC#Oj_fi@9mvI-MXK)UHJ|wnSH2p`oS_IGx{BiR z>&)!nQW-^<>0nb|r%?Me1E4_1az}lPmY(H})_9w!k6K+Vg6eL{E|z;Jg4#;GDoKBs zF{pND`nC4RsM_&sl7F{nwkLZ!)mVR7VjPR)X@m6Hx-uB2cq+Tr#zI6`~>ScV=B_lpENpn|yUkYR; zb?JDbu)R^$07x)T2gBi@w@(vnW_wwTHW;uManrjCRW?jF-fS@KHW<$Nr3J@>$w0}y z)TKO}b!8zV0J&#|F_v(`bK9jpynf{&gLkMMRMo9IR(DeNDTzOSm%wk~CmKkXhOP~E zZ@F!{xw>mWV$;5p>k^VZR875(#<2;j_ENt(?6y2CiMy{CvC0c;OI|ny+kHdEkvP6r z(nV}zl6z~=U4uA2Wgk`!#YFId6@1A2@QC4tpf@IV+KqQ)Ly(Pef&BAL+&E4z-Yyoz zW1zovonye4VP(H~R3Y`o`-Jd5R7a!4VCCgnqQlci>|S2*b~rOyx+#Z(169BMBDr1R zPcvpIR#XB=ln>Z7w|?Jq)Rco{E}Q^WUg5Gf&69T8Qkz$)aTVOLFWwJzk-{5HJI69W zG7_Ml$S~D4&CSD{k8Kl2M*yv+-o-SAP?qDqVV?Rm&jpA(ct|t5#KHKgh_)wulsZ-Z zdP-|rnX2{Lbl(}n@K6&+$c-~}kNy?WPknd=drUD{LjXGpi0&t9wCT-@E>zt!T>8q{ zTROci!1Fan8|oL-n$LN92kFg4$8>@M|FX+vdM?t@y4w+xzpva*DbDej`~y|2jl(y) z5u`T7C(#UT%CnkRt>MROw5>!_2vd~b8IhMDScl*5BE#CR^MEp7cxrqC7hxkL>XzYN zD_j5>v*SQwWHEB6vyEM6Pga>GL6M@T<>*k zuVTDq6TzfoQ}!kl&5^3#U34G8N4@i0{CnqY6Dhso%aZ!KCaNsw^JRYC)5b4oEBX-G z*v5hhXT-z#TyJ)!FDU+4aWA=XsJOCqUx^(u^@W-FV$#y`h6Zj(ycCQ=d8+9jbNVW8 z%&DBTy$@ik85IkDasSTSi5lRY@q&zLoFE!97xj8z+4=(GuSHL#39>0Pnm3?RP&&BdRy{7Z z4+C9uD;P_Lg?(}Gh2zQ-V-CIW*y_^VxkwnL6^Jz!gP-l$X58=)=}nvd=}Cyw{@n#; zgoS3j=B^X^!SXi}hCG~!Nys9XY><+YqcHknVx?|SBnoO@LOrFqABsVC>NSPR2y5m~ zD|*V3?nSN;%|%8&$gsEabF0j9v|aqexfg`*BewIShIDa`MT3aA-w6Z^G$(Yl74p8j zu7_O%!RN)J7jILYZ&IFt&S_u~k3-k&DcaOtndRXWVn@Um3JW~sCmZ5Qp(EX?uu^pL z#igEWqVC_0udbWehk8}p$|f!vGr*p$Oh(At=VwW7(4QMp5ck3n)Dh!0_lQ$hcsHj- zoe)hfxc6V|$x0rh`IT5oUr<-`fV#qoP4yYTvK^DKE~coJ!D6&ScVevXnKK$TH(ECJ zS>vFTR}RF)+`}KY3DRB;ID1dsUU?YkcoDW#F&MHx?b0kVW6F7G+2mV)jg2Lla;hph zAu7~oE2+e!XbeK2-rw)(4@yu5_9C2fs`Ses;&hHq8}u9ZiOC9x-HUSmYK5&xBO|k< zjHkgY5j*t4%&1{EWnGa%!XJ@@qbwT`E2d6Tp-EIzFjLkR9dJsgCtr04<;&Jnnk1b^8H%@JEiIGND1WbvIJg z37Qc|8c+}nd1AhoUCA3Hc}+)?`k6)F zyDLd3A>x@MvL&E*N>V##W{{5{!|L;jWcb-Fz(9RhGIN1yWnJiaiB0ZVmFYrEGz*>T zxVxNoUhm0jwm)E@^Iur9KXH1!Ih`}F+;gS>j;mh^Kc{oi`r5@{A4I}GuAK31RZC3p zW>vFkF9b6&FKNA}sQTL*uJ@+IlIGR8X7GFm0dXt-M%wZBnN}^mNIx63Dz~s*X?mv^ z`Vtz}M_ro}8Wt3L;$${Z3X~_wAR#aCdiIx|#{<;gitFHDU}7*}U>1M3;QYUy68*Q) zBtvmBJS}mLQvc_sP~7Vv8I;gq73)cWJ1-fY^nxsGsWg=|PRE^PK73mB=3@Up&xxer zRerk3BxURiPQOiiPCs2d-5wl3SM zw4^J5eq&|WtX$`0!W^ zOSHA}*hX6uzkdflv{9J(&gBk-55WX8N|vflpH(1)uHZn&7pdpLuCHLzf_Byq1&}(n zJht5cVGoHzOE;!PQk3l)fA3sP<7V80`$=TH5^SMGe8)z~7;f9fXq;|*VJG#EYiA@< z_?vPnxUdZz0r$5oTo1~zx^41L_a;J>@Fxu%$CNUJL;BIO*rw^$Ied~ZAf4fN9ufgR zJL!`jFiV3B=@!CR4X2wr!n$f{snd_8gEU=2$8f)oK203LF*Qp9R{$;U|1q=Y0WW+})xFES(ul`6w>@!D&iW*AoR1wXt0 zq9SurbEYX0Y1}0pj9n7$@05p#t2|ovU93^~_X!kuLImiT3$my10dh{Y^|#28UR1Lb z#w*wn&O@EtUIA_Gykl`BpSqaJOSl~2j^Lo892FUwI={SRq59NCkYpjde|wyRW1W=6 zBp?qlu(RjbWtI#2gGBjGI(LR<2bt_@L2iKk2L<_N$u#u0ubq>6wSVmvLo=SGl!gEU zON9NKy2bt#UjOg%?LVBBu?1}5gF5m_4V11JTg0QigiFFr#ABNB(Uq@p=Sv_LiaBW@ zp7&>z0>RjNo>V>);ph2ZVe#y?T1OExHGg4E`a!v!E3p0Z_Wb?#+dbY_c&}O`yl=+b z+U^S2xk;KaC()TGEx4Wy+M|SSw@k+j2PY#{Av`6quyna@^8+dir21ppr3JpFrd4Rp zqaNMKX-wE#-Cbj_eD-S@S#&H42Ey^6>r#a#+}whm?IwB0uOL%y6u<8RI zdd#M~E(=9I^qhs;L{oa!e&lFXH<(ZCE{g@Z1#`0uMMfvNMlc~{Xe7++&g`b2A!cA^ zs5lFb^ns~P?NC26lWN#;w7az{BQ1Zk_rtVV2DTyJ_94dMb(s!Pqye zqTg^HG}b`8kRD->2zNLl)HwhGPjr_%WDr2IOPxZF1KYqEaB$6%@uD1S%B}GH+^)GC z>Zgt8h9OHhAf2r;J3gz)=NZdPT7vPy2m1ulmsj{cQZDE);>?<=gg_LBJ6RZ^#*oF} z^_)zhBEsl})q#<1aa`>HIf_#bKq#e}Si96WwW)c{iQfEn3pbr`w(@b% zJxPVNZlSvgK=w!Y=rl}z_$nNW7p_W>9&jZ?%d|4==wS1H$T{Q;--`1PAAZm{z$FBSu<(zi+MyjbZ{QYrf&f(O+aERv#WMNpxpf!|( zbQ}&{E=2D;XdQ_i(*ji?%}_W;bRB<1i6clKm{^RRJLih*KA9~0<$C-cY?3>e_#XXE z#gK#ygf+0ph<37MjKB&UUwr>d&6V~_w*wLq49w%tlG)#aXE9?p|6*IT^KXeE- z|8o`umvja)v`)NAmHHQSDk9zhRH(xx_iXEtAc-EurVo)~_B{RZ&Ci2$;IomH2xgRXcT%53hc z+&&|lo9;PJ7JDS!Df|w<_G==0NPo%o*TCt1kF=?B(1m`aUzwZKzPL{O-A;ioY9`L$ z`>G}!V*G~T6rOpYb@K+vKlt@PZJ23Tr-p_fINnvvs=v|{>hK%gCzLDHpjy_|VTScC zjeY@SP(_06@X(Mq>3AzpyS~A4pS=gG%5Jd$=`wt(@uw|r=UpLV^i$AdibuM2|CV`I;QfjX)BVG_0ivI{ZxR#vRL&@ z1vY^4lN3GW`Ro}7Qd>yc03CGN3p|Z8ORsV=(9H=lK`=!Ya@HkuB@aAg)vF3q9MoQs_3(Ltqty9 zW&%Z_?Q`GZRH^1AaF=^!&l&jwpl3{2CZGSt_?0Ye8Y-TPOU*CNJ2L+WI!yU>EZ+^C zZR1qHbovD{I^kKowSMwkMIT$^+*|YVHBNA1Uw?u1j$*yW$+!Lh8?~@62DrYM2J`WI z8b`%HCe4(Y7+opk(h#OTG85m&^amT1>;nS^X3Mv9vo`zh+FKeIzr(yG&VHs_mPg5{ z7>Au~%Y<9d{-D>Pd8d`J#cjT0e1y)Qza*}Sbi*vPq;>vUu#W~{YjQs4q6SHZiy>ZX zkUn9njt`-AVTtS_Uyn+?2|oac<}aB=W|$-6!Ap@pT`&{rU4C7G(cw)BK)F)GBYKN1 z5IaTYir7anDLWoPPH+Q#RVWCOibhkJO-ny_G6=i-ge~_PQ6V~2Gkzqv^KGNwZ zR=UxvFa~P7;=0$_)8Fg_tlfxid!##IiF3lf`ZDgd?qdVKgIoSPJD-#R@}@kIYn!Nl z1hwiXb4a9X)i73RE^~IjLWnC7)_Dnv6u_~ZiH@u^;|J;cUmEu~KT*n3{!tZZFn^PG zug3qN9TD&U>^--3b#&0Q{)d^tAIV|t;P#(%)cub!;mXMGi0E+cDCN`!$iiKB!GxEs z!EoX*rBb9?A=vkI0{WT?o@W=S$AMQ!zv2C^h0(0gr2X#tKZ>0dDkg^Wk==+qET*S2 zG8`>D9wuAk^1$>4w6NU)sVA7f3)vx7_AIt`Q{BAQ7|``B#~yQ$xiDZ{Nla&MUsOt{ zHnP?Dsa#768{|<|YX=+2Y==RbZe`T`>z+9{d|s&@1VYFP$P(e8Yeq=4p!7s0nR%9j z@Tu=nKW3$H3;dutN9$H-Fp4F4Q!pyYaV{)8kOP&s@1MHedsNVE`aFK^P>NEtptbT0 z2(R9(!IoUyUL%aDWE`0&J5k_A#qk9-6{lsc3xHkIi&D!&qbwE;e_?xIE&upTk!uev znia&H$&SS_`&9x+x!$XKX6#R|pwCW^BZpa{d3IH#uROFn61`4%TKQTRwO1BUsW<2x%BASPY(J_fmAKt z6xwH2Hk9NQ?{xgiDNOyhX&LFUNFKCzu(3~Csj(a{Z?p%|jEz+pAY0<|V8A+&dv~ys zs<`#qlMY{#_{JA-X&?mTI~OGYetpcIFGX>f4R1YfK1RrNho0O2zECS!Ar>TO*9bc7 zY@U<0mODbw>l4?J4YA%BA5Tkq>SBTb_UN!NtTZR@TVO!uVfE}MiRWY}E%oSeIzee_ zMkQj(oZNRz&mF81y}e=*4!T3U%+5is*%svX_vcaqY-&C0B)|2R^lw|VwPCtGXIury zO=FG?Vq17UfA7)K4>n#=M*$d%#hnuXFMi}aB}{E(8~8FTS)mnjGaROfF@e6937HTS z`aq#zEy+e$30P+qoHd3OJ0#*YaVGrw-Y10*$56!K?1pnrluuMDtJP>vH4)B9o;v$p zTe=ko!EtZvQY^|?o$uNbESiDg_JeZbxOV3^DY^vN{8VX%e;2{I-o10H$G;!23XUq~7UnMhloZwu=KqD;q?GbA z+0)ri7CjkkZ?E@zRA5KWl7pPk+llI~23iRKxhj*amaD1YYK;<4HUMD)JEpU3%duQm z(EtNrvcc&`1NF>Pt?BhxLaz4dhx7Vl_VjOlCy^6*?zyB+7d168Vt(1XsK`B71Xy6$ z2Uv=vpB#Tql)!hmU}HY(Haylknl(LFeyUUR^3tfRPn6^$->Iqg`PsvkjgF$&{BpAx zAMISnqCyygU)4&7;;G{y2;5hVzkKW8dG7^dErDkK#jX^04v?nm!eCQLn?|PUU?@Z} zgxsKGV=rS9^1_Y+A8owlC2-`d!(sr)n{`7cfdq5b67Af64Sqs+!J&L#4J@FxA7%Zl z&+}swygjB33&E8xzQ9`(bD6y$=o|M?d|?xCVjwCzk_;S}!9Y6${fiZw4nyl=^>dcl zEtcnX=VKQT5xCqeeD{OLK^u~H%~_1&cuvPPnH}G>t(E8S^C7=1$;cE^q}37@fj)OZ z{ybpsBm9>zh^EJuKTU1H0%3o4tZoJNvzgMtMLH9G^VGYz zU0~9OL{9$kKhQiqSG?Q9v>3ymVc^*IZl~9`rrvF|L&`W8qbYEnGTfLTLxGMmIM-Hh zM`N#1!*_+Olhx$g!HeUzv^7;0Dpr zLhTo-VI9d{1>7*3^2B6fZPCOngr;@LHOLwX&XsN$0pH&ODvm*Gurfj|Yw~nO&4Mq8 z6)W|bH*rfp>UlHt`*M-2{LysrC3NksgZtF64=9=x84DZRLTaVWyTkVen=A|pS<=o8 zzy!*u4CYF+dU6f>%$upM*JO)bA5|emp{G3krSh){00+*V`0R!!HxKw+2v*7 zIXyLxE%=A7NZMo0Ye~k5fOCfo(&Vogd7wtMs{((du$-&J+33``@UYfhM{P_ z>V@uUPTkRvbrCl4*c3?y+7j}q4zwFmHuOzkLO_Q-mmb&>l=Mx9Y@GH z4AFjz(I=bQ9B*iswfgySA6+KEqIBbLxVXn{H||-nZ_@6k>Z&JF-_MK&mEB_0M~ZGY z%HagOve7BdrFr9>9PUFkK9AwL5<3OkaKu#XG4iupPO>XZ#+!c%2yi!r8k9)7jnZ*dZc>BeZdctMn7c| zd-YnpxuM|83YsT$tO$}HxM25v3`>is(*9O^ZKMzs9s#!udm&xbL?(3XRxLsKi{3Nr z%4`<|iy60^aDEj$YGd>ADT`kf%AjuO10D&}R(u&Dd-sw*&#ouSxLuiGpqkLA!2j#; z!!j2=QoRQD?to^p5JVUXKySL67N6pl_P`)zYHtF0MRJzwJ+y}>vetx7lBtnAwQ-4w zI*^xr?=NA7X+a#u@n?%5f&JSu%l{c>|420ddt3Og%+mHBweB~Yvy|K-f|vkf!AV7?X|*0*#g^(o};W-mb8r;C*C zKJ#de)Wv_e29y#fdOJvpiq=32QDJADp92~nVY&GxOnew9Vj?v)_7p`{Tgj|P`^pB* z6Z+bdJ;P#m;+cYnz`VHdanU=)a#_V38F8TVbw&$7K(V4sTKPE;6MAg*+ zXfH|I_)_KFbVQ?tYQJhR(B}axh{0qxb^mHy7V%?sz=)TXcG;|M_4m<<93AMRc%5j@ z721Q%tryib*jI$73mvM~1$bJknIMd+zgp$`%fd?5vYI?$!*Lf3k=2eYaT13a&@$p8 zj*`e7T?8G=ys@D~j7EcRDupV1x|&}341lPq*S({%p>mq&lLq!I7o~H@u*n;kR+1WG zRRNZHlN+o1S4Xe?N0T;U?Y*@_60vMM$_B`KaPF|jSn=PYDk2QBOR7$QNDw$O7{fUM zsbFOhX!4Wj1rOE)db7N3V|7&eS~aQJ8WLEHS#7~p?3Q9Rl=tbpo%2mv0pilAj~q>@ zvOBzk5y=e6H$`gNrIi8t>MFG|*0_`BF+cCDt2b!FDL8FKtU@>0S-$H2;N-`ghG3Ch zu=0G?EXy9jVP`3>K}*=?mp8#CgT7$S)+=gIlU&!t&|KkSXNl~Dv{01w1@hvctZv;k zZZA^w=sn79NCp)|jm1n@71!DkSm>>Oitw@#Af3kY8*P3nKS~RIRLzh7jwoLt*e41x zeDBx23}Lj3LP_l^z!q{O-!XT$i%||tB=@9v)0F-w6^15cOa54~S|m^NF$gX>5E^$n z*6e4fpfd&iNi|~Lxv+WfsmnGg*YKof*HDBg>Qj~-)~q{ge&#}@|J-_9y~YeD@JyhK z`tvz)G1W82nL2&BA}vAw2>25{gR#)DagUtw%inot7B577nfyCo`yT^B6)h}W&E5VBv~w=& zYRCdyj0sh=^1H>>#POx*k#-#6iQrIaB6dm3!x1D3Ih2r*c7}8^=Hm(bUj$14mtCni zQg9i@UWf3%!2^P@fX3g87v<3=qNU%A&bK-}XD;S04Bj3dXL`Zfg1?jBu~aW@ruGb< z1)ZJTmsVtL%-uRv9q=~xc%~K07%g6=RA=^#oxgUi@3d^~#3-z{oJttA#~Lv3*B-V+ zDSQjmci{9Vl;ZApdifyRw-lIJ75q9ldkMq_w8{t&+u?YGy*!JQ4GXwfYlh}hd|#m- zg{x(osv14w)Hml&pn||DV*Ot1|I^;%YD3VTZ;ko)vE&XD-EDC=s>L z#(@RU#mAF6_`WZDPp7mU(1WEDr^<%x762PY!Ax73)w(E%*!1E=qGfcn z58WzrnaNfw(lZ$;W_@kn0JOV?7OMX8AZJna$FVgvQHK5lx9Md>I9Vm#1Y7X{=3v}m zS_Pp$0X|b9c3qOwu$>*-6u%(q?HRCj`$7>X8kHZo*4ROxT4N;8L1%79ioD^5{hB)o zIzhWNOwz;1!-FW8@h<8%TeOS4WuHL3`#Bnq`p7E{n@B-^@UZtD$y&bd zM-OVcv7_+q?PvyufAr%3uLU~S=aY$1b$Wm0HooK@`EQ-^9L?zVz9AYR^`z7RL24t} zDy7~doKZ5AX__}1N+ySk$=3Kyk!9BGCRG`YunaW-R{>5di}qSG?-sS$=4cz+(t=_{ zhMb2VLkL+%-YglD+8e1mx;O-tHL+K&6b@#;Nph=H#%IlVC$M8FPn9@oPAME{L`!H4 z$fX1*4wXd&@^LaZCzTMFA+jhY%p?@PBFoA~FtL$lau+F7Mb_ea54-BP9sCYc0rX(Q zLe745XC)s4Jbze9Q#WG*&dk{hrA6RH1K&!$(_@Wo=OQ^_v#{6jOH?ZbD(g`e!cggK3C0R8G(rXa*jXf^{HrN$K4IS<<9g=IRGWqfGXQ2?7U z`-s1iub2lDQe@z8a#lxns7R-?g-eYa`l1X-a>!ZfHjpvricks7S6%p2C4LoJ?7zrl z<{k`#bzHT>yNyyQaRGyh)(ShVguO*vJ0=!0EcOp0_gF>g;k%3 z<|;Z>_tzA987#>P6&X-eEq*^ZGuZO-8|dwKuf$?euu^aIC;S3v@sM4KR70)uQAQ?0 z?}e!|y>V_pa+8fSg*I|s(Xn~aY9!@gPz4Rm`Seo?9Y(?bXp4|~Lsgy+z@o{^I0Y(o&B9!Thz1ShY^nxUr4`h&AH<QqU`0YsX_Joyf-y8``J(x1|DrS$~|1H*&@ICyra>f zRg7qu>gxNuHJY>^*tYbZ91V3^IPwNj=dJ(C4<5^DF1GE!fH!C(xJLvrn2DC^1rCQW z)_jj21&EJU3d?8nzKbvh70N7T4>nshvt@ewa19esH8(a3ShYVyG<}-bUo5$AK`frU zWDo+7OmSejq19vC9PO63+6L<*608|ugKvz#@+S|s8#pAO zZt**ILN`FdoZ6(v;}uUVV$K^wEO)5sh)7uegl_KLb%|l~w^+8VvyITtu&BME7=wNH z*%_sDmHgrTL(&X3@x(S1vi{*{Vk7i9LiT@BrwNY3myIe^IjyH0=AZkuYFOIWxg=f> zGm{esC3|ab24iq&uJSX>yYN$pX5Xf7opdRogIy`7_rQhqwA+giAZL)Qk9!beNrIHm zS15u@$kxPeHx}4&1-0j8@z|W9_8dg zt3E4vA%8p``)I(+WJ;09Gv`Axc&Wb!)N9yY#T#|4BT33gI@x%l&%)U{bsXDjQSvS; zq_@F#)EDBTnfyf9wu8uQc^LjFs!Qa67GE612l@SDMR-BSvKXC3&P2yCp%b#GQ*r9> zT1$J5OEfU7rtg(P0|no7Vu<<qn*4PJEeOe$HGA=`e>MA)AxaL9-^#Tr!k{v-{BlhUj+cFaxC+stCwkR5w^ z%2_Jt8GcdG8Zm~X1W_6k0{aU7KjWSTKHJ~*Pu!>ciTl6+3qbV0e@EQ^dG9}-{`H8A zT>QUQjqMbj%>Tu{c{tfnaX|@tBu})}odCnQFFvr4+a1qJ9ApD;JS~CsIf^bzyDL3R z*`nT7dOd+2w>RjzYNze16}iDnLG;mL<-)JE`@+ko96^E0+uYpN?Vi96u)0_T6f(%o z(oK!n`%+6jncMu5CO27{)$3?@3JGgDsw*uTDreyP4x6^^RUKH-UHTE zY~r4;jnhtE=UfMU)$15mic-_m0)MD9`W5pfm!P4LV)GS`s=A@!Xki#Vm zV&IU5QHOcsC?leVRk4zb{XWi&#+EQeX6|RjS8XinguGNaF?Nswa5?J^F$7=th;-JL zwVD^lTUf^PBAUlIFH(%%IZAq8#%oVwewM>{8i@>uIDiO7g79DwSS*CvNJ!|{4~_|N zgi7jg@QDA}%a@cxCe5aUdCwcGaP^)y+D@|EGTt>VJ~>a&i@k|){q@TS6A*^-v(}o9 zX_%o=;LodNdPkhE;w<5F#4`M`GuMd56UbR<&Jo>QBgYh`0p|hG6{Ae>me@kW$w(3L zNNj>rK>zexW0Kv$!r!3@vxCVRNcYS|OM?Pa*7s6KQEN1*g3okuS1m{l@~q!CYSOi} zxd-p_z+orbP+(HEQS{=EjVs>O#`G3l`A1ur17r73rSoTuC}ycvZ$gH(vdyOJpE35y zr7C|v`fBYdW&n2tms>3Y|8jLjHs7Bx9uf@967g?xzyJTi!#`tR(^nNw9sOhT2BugR zz5wcauCONavw2EOA%YP}NEoyU8Vr=}iG^z;J$>hi#W(R$q^xUS@q#L2Gwb~6~Z!)h?&ir<7tU0)~Hw$ zUcn~T4f|l)VdeSPfQT&Gyu&BaOdN0z@n#cp_zevyl)=`BG!xK)SEYh?vhcionC-?i zwL}El6bHD40^xZHJ z7&gP^B*>?@j?qyJ_NSI;un`l*Q zd5Y-Q%HP%(I%^T~?9wyJdSP9%WK+2}UuV_Z$tVGPaTWS_&v0qm0|&R_$zsP;XB1X2 zgq2-Mpc%Z}f;crzsTW{@;gCeULl==DoK3z#<(D{sZ4S(rL-)Xe1A@&bx3VWE#9~!- zee>f$4Lj@6WqJF`Vmuy)7na~NQZ*uFb7=9E=XB$zK+^~cdU?$Q?ZFA!5xH@-&=Dx{ z=9)tO$sAF1q2U8y2=#~+anjoi2MKT;!3VVZ{%e$)G9)2S1;TzFP|hwxBAAR)Dld~R z60M@Z)FEwM46nCz``Hos<|1<^N;bWpUX-YPM{1-7jhH{;qo|o+MK-t`=A$cQ=8C5q zFIglgi-$JXNWk>Xkq#CegOfo@t6Cx6n{AYc{Pu~|Gi19r-U*&&W+UAMyO7&P3%mAn zTn>vQc$tz6HgF>X;P6s6Q1>!Ht20n}%$XD6#oOJ(&eeWQrDQ16_U-%F_vDC3<>D!r z<+!d{ozKfOJkX=ip(K$Z)$!=u@lCmMHKUFUij=%x3akn6@jP*?Eo_68Gv$Y=(spUm zS|K`+IY2IU(##u}T9e9TKhWnXM?Q6{eJmUy6LODDeDz5 z(Et##OBRE@WY#O6nW0T@=D5B(b7^Lv4yB;5oh?o~l*jdC5v9T82|5=b4Zf2jUYY9^ zDmz~KQuNK^6N{XceLYi+(Udc!E8~M_Bo)#fzuvfnB>_FzU#4yx zdLvZ6*oOJ{hoWwh1ES_~X)LWb;fSJQ^2rJ4mTRSfLoPVBNOKsl8~0wjgii)3)js>i zaZ^?M2yq*i30(ROLa3{l`!EF*9nB3$z8v$kUw`#`{|f%d?CG3)M;9iN@WW1det!0e zc>j7l;EVIT-pzA`^goG_$Pt)h@JA^8fc`g?a8=z+++2)J|5YRFDxwLazeC5{pGC?D zcjX7KY+~Xwl_ODzSwXPSWVY4AB&MHSxan_REO*CW9ShB;B}(lgT}k51EZVe*Mc4cq z%*}8;^gCkR&T!oB^@Cy#8^wjj<~*+(Z!OLVL21Qf^fd3AG;YL!j&i;OYG{!DdQ|^D zZ79{-h08mC6zevhdij&|df@8{t#7OBx`vJ-sc}^dkOa8$Ch4`6m_YpTmM8}pyfxUN zfCmu8*dPT>7$Z|fDU-Lz`gde;0ILt$gQVuASX0m0@}5kX-gO5Q&8KW-k};pFPkM{< zpIOx?Wf8w|SL{IoaojX1eHon>n0+JM(2)X*(%7>t(!Ho!ARondT<9XY`t)T4wiA>Q z$+)W$am}&Wr*xoA0aHq+uDp~^x!9CC3^?3?Mu~f3nQ{K&Q}8qwqqg!rR7#v1wTno( z)P;OD%&LJ{5#W7bMTZ`O{>&j=fEL!fV17DLNa?C3a|wucaMBbu|9{c;j=`Bl?Vfjc zY~M-8NyoNr+qP}{j&0kv?R0EA9oy+}`pld&Gtcv$Q}x!=b3W|ad)MBd*7d6k>wm4a zjIdUIFjH1id*>QVvTuedLa>#UD>W)r09u_lRjboJ*I=a94R+r%j(v79)11LeLVgN; zw5iu0k=W%HPjwi6+p3D;+J#F@(k}MW(La|5MdAM=-2m&9PpH3i>wx{M7I^#<-KqxG zE+&8Dy_uuS|4|l;l_qTeO<7D#;)K2;It^0GgQwUfrU4BDRP)D)s}w1hO9F^lFNf0A zX{Xs6vY~i`d&yDY!@v!v*a(MksUlT{D;C`udd$4Nr_;SIcl`X`!ESJ7;D~?3*z}Hu z&d0p_Z|H<_Dc)A>oc}p<`GKSG$cpk58nST&IbV782lw@6??p_#Rd;y_P{~Ya3Q^f+u?sO6SxLt9Z@t$?6k?a}RguQ! zD!4mt+`lf>qgzGDJsN8%1`5AZt`#pNp_3(Zq@&+PKD!l7X{ zeBsUvfpQy*w^K&+-n~S3v@}U4$&*T_W2VqOl&taQvs$0`+hnK@G_<%|2OdBNF)RvB z(GFIqC z!5)rdHt6Nil>|klcMeI<`c%FH){s@Pl98{xMRRrspuh!VeF-^00Ko^>tDH-SvPSWx zO(lJweT-vB|GZ-bK@&4H^7n7wGQa<;_Wk__7XMel^}oHWk9@!6AU~4NLXix%l8p-3 zTx4qr-qU{dPjens81z6ki9{A_8CR)}OE(JgKuEs6Sd>zgxuA~0tFASVF1E?@jeA&s zB5RK_q#6{Zuwdyb3K7S|aB0gqHW7n|)2c30<^~5xE_ovdiu=!C2@_hy^y$)eNyEx0 z^tnGXj_k>YFz)uy)e>D{B6#Q0aHFWMgzl!lW+@EZZnkjO6i+X#Ywna&cmyxiEllK~ z-m>{L42139xZ@Eat-f=Eft8|)!Xqt%Dk~7Zq&E%Hjdshv#F}ko#L^8s(GBHz^>rXz z$JDi>nf<1Jl0R;_j(CC;;GxW%X|D~;Y2#UbOoB>HbGlkJ{9P_{ZGmz z7+UZs>|e*Q4Eo>V82-00{;eDkw6nAR_t2-P<23)*F<>AmW~fT$t4L9qFA=L3F0n19 zqhF%pnhBRbiKH4!6%tAao%qe^G3iRw;hf%7B{_bT0`cjK|UTK7fNeJV`j8e4Y5dwT1&#?EP_seKDk zd(<%gz{~Xfm+=eruEE6x$J}1abth&KRP84QtihaNH+c+?mlBF2X+x77IcGO6-vwhU zru_uR4<3>te9jzH9?~kyXt#^BblQ7PQzjVP+Quz6?aa_-pKcNHrQkT~1bG$mG@_(w z-@H~+{p+TdKq%_SG2a2eiVa0QCJ#i4iXWa(&Cn$QvEQ5 z`4)`56^8I?!`BT2yE!teX(@`Cq&SsI@`RJ-mj+@k-~dQKx4$bQY9a;$@BlW4$hgZJ zhXZJ;uUTGNlBE;HXn{69iUQxU0aCs*r=p_Zyo=Bkh9sjEZ!{?jz2Ru*q3{a+j_!Twdd+5Fcy z%DUJXn*7H?DW(6_Zj~4^B7?i05u)h1htRTMmN~!+&ES45-CYV`&HeA#9udLq z^O|4>v6m(B4&8HqKtKyrA)@l3kl+e8=F2!$JrRx`m`!QMknXJS=KXs~RHT+_bR4Zi zCbekX0z=3G(Bpm;q>>e4peRP^he}F55omNC$)4{|gY~AEBn&2YsWgrfD|C-6rPW3t z@J?i$xMpZuoBU@TVXPv9soaEkTwnVXKP;=QF)ho3pl(&sJ{+Eo*5vMa zEa)x;T46iW>M&dx9+A%om);1N_9oGG9&5*XR|lnsKY`_L>eN4u-_p#?_L*o=R#|Iq z75rkY``hxX0=Gh!Mjd^6f2z^je#o{liJurf4t~4B%RLbP^3N9Vbx!g4`lm_8T!y3} z^1soH0OY@)S|w*k3tO{)r#9x_&V@w_p5eE#qRE3oDa3Yrr#3y1H7aNuN)r$4U@XQx zH|G*M>vKAVK#}qOhCj}(L{GTCtTD;scExtQIaAw;_$}0&og4{HD19CpHhI$A9e*JW zdOg{Ka`@EAwNyn9d`~GB@f0A{fx&199j(rcN5TzsX)e=M*@2ez%@X3^T#gwti6$y37wt zP%sJnQ0WEF-RO{<#)r0?TDEM046KN?S%m6JEB7`*M!xtE`1+A4(0`p2VrpS)@o&%n*}^SF87UA2G#)xWQX9(V#Yxu7MRdD`X{Z50 zC^$j`acILVkMUJ@BhJ@KO*CSGNMC+F$_}PzLQ5L3oxaXzhbtbZtI^|?H%Nb_-z3)b z%+95wqk?YP-&Zzpw~<+E*}HR$^xz<$e=q6C_?2bQ_!3o(Hyc4kVh{Xyq)}SYUZ`)c z2y3y(%&DCOK^cGxuVGzoD_+CZwQ@OSgKM{lqDPxrI@@<3w$?#{4bs#RL8y-_DGwv; z%{ZW8Dw^6WW;(G@?WS{X#1%KzmkBvZPxY8aqC`^(u@6>1fHKe$g>wigjImGdW!XWG zI9I?06;c!hQ<$fJR}(6%!-Ll4Gp6ia#t6zYa-&M&>Sbb@(R*s(3o22234nvngu|rt zKK(rqY^nf{uVfy!>=DFknRKmyw?bh4}}1`f3$dXG&N4^UrWpWwYtu~ z#NrahCbrHN&i~m_e$~;v2;T*M44HAbX)AB@AIsH8#~^Wpi<^s+n_SjRjBM3x(u9vH zN}%EO356FI0GOsG>GX~|`D)m{;R3(IfKk~hdM0gVMBUj)8@ z#-^EU9VPTd;=m{f7e}CYFA8XTgtPZT3G8aZgPZl)HPeyj?qIn8lSkwC*Og!UJ6heK z|FRML_x9%hWWwPNjnow z&P`d3OY{ATzkUXa-U@g>v4y+4!M^~IG*hy@t|!x-X1d*;&!6RTzjF@=VLJg=bT=`G z4%6MqyL1UaibZ&?o{c`ZG4bl3$HlK@s4gN>DJ!l=dm@0f?}-9vp7X$Z^z0JZsKp%1 z_Z}OgoH|EpF-2iT$bv1NBVwS6>};GUYl-|J{tz&GnZx+v!`M?&eG}Tn+!cCeGZIOK z6ZnVI?$BVb0Tdgd-;pXC2TBS7y-u7QeEedn!eFIZo7e+StLCP*Bb&InZ}oqP_j2nn;^A6~oFAzJLLP>OyV zNE2(vNf;=rtfy-^|9hk>cJ&dM{J7)>I!MR{Y>MSyD;eu*rI)&N5?krnx?e#p<#?A%nJUIm$S;GM|=w`Rq0^IO;Y+mSZthBco2W3DGUw`jM z(B9@}@-A>j?iHqCZqrP|@g+BMX?g1<(l*Z!64urpf6`T~QnG`Kb=F$xPa2yKh*38O zJ4q#DDQk?X*fzfDhF!>iWXh1zYM1qIggk`!_RZj5!qk6gYyY7${8Q=ItYY(*DMh3_Z}}3mzI1(wOjfE{M5_69t7R)G=hA%6eOaZ(_^YDOD`!!+%``CpY;XAC+fu~& zcwzQJCfMMufpcV?wjUX!qI1!+s`ZAdjMuoLZ909Yh1JH!Pn@H3WOcAVV6%rv`83TW zBYR{)=vcttJvJ7nk2)gmd?a_K6cJziEpHWMSUu!+AJ}ig$wEa)qg~LTu-*Y*`R>7@ zD8PGCQ+g@&CgoM;4uCxA@4Mh$9m})d^n^^j7{WWx+FDvBpcBBY6BBF$aAielCbOT> zBzm3J`!F>qN9ltSfk2prv>H(g?NJ#}HmKMV7-K{5N+3Ati~1?<>91ok9a?i9tife+ z|FUSI%W_-(rVf+D#f1!em4A=lk`Dm1%C6AerB6$7-YnE9585GQhp1k(DO)WjSR@-Z_FiLAc1gnY zLlpGV)fzE?DyFVqIh&&jt|BY9LG;Cf!jIb7gu0FE2#B6J`qX#~InD3vuWy@I&^u*P zit4dx3*|t9^8z%91b#RQc*ujL#@SLw+wJP3=4z{1Yfu zSh+rB$tgSu#MQjodM@F3n5^WI8&q!YKLWkZ%mJSd{p}kS&i^ye7PiI~jwb(8$)Nk6 zu2;_1gz@hs<6`Y>A@P4c{=4j}4(*L&0{HT4H*HMU-2hd~x0bSDO|`05UA0kKXP%|t zuuLdvN**wFYuIvS!ZtJA02_j>f*jx5qAUx87%n8=VqOG^APWl=>yCU5X4_sKdG1*= zPP|CbTNVB|Or4x`>w50_dh0!y7&N=;#P74rrzA&S1;{)GKVd77nFJSf-^y>&3(1uC z^dzdd8n4qM4=Sg=LIp0=`NJELgYDhj0c z0hp9$D>50fSrLzLbUeFcu9>XA>rLqT^x{dL znQ||lszWp3A>Yhv8tDg_oCbkpYDLsZf~=)nF;xjG%SlQQw;I|ENV7+StUyE}SFpqf zpO&HiYSoB{ELFTMLXMDRcn~L*@D)Elmzof2CAKD0T%eI(OApKJNNj-%5c||isiKj* zW@YLKO~RxW$=sb4FXYzHK&83Y5BSzaJ}d}OQ75*)uflI|hrHO-SkMV3aZd?!0{h8S zCl!o8gRYLmmNfylQ0GkgD!N5l+X8MC!Qp^tLwf7#*w7^om>yOHKZdqW=P9S07VBf_ zRl%P%1kH37yT-a8yYGx(;!6P_S>k2lqple|h;^yQ0AOg5%5q9-mANsfz`3DAr(`ui zq{iq^Uz-vM#EeIwa|tW~i}IYma#a*UJqt=K;MkKwMu^4lnw~F6s*%BGP}7#&Zv=P$ zP^#_;GOmlbQ<8$nP0~}FviN^d;ps)Q!03|KxwM#6x+BvTNJ~1txlEi$LQ})Z+FLiK zUqvpOOGnj3KrO?NdpUQ?IOZ{{H!ehqY8UA944=V8>ZTTFy4sBwXf{T>ml}ey!ej}_ zuE3~vx%8i6M80#YNerzQ2?mJu7Z;hH1xB9=Gn%UFT92TEXY{?7Qz>i5pa&ZD=15~- zc7sp_{XtgXZ^W1~KLBpi*0HDY=`CFLM?!0l6L&Q!iD0xSOf9{=!84K0%A3n=%P;$u z+jK@y)divWCpwaqhS;gXl-}!5>IPD6>0{TvHNcLwAPa#n&V=2q3s+zOcr^2AMfz1h zQm17n294)bln2fQl=YJvN1?`+DdW!IZ$>L_D*R1|O=O@RN>NIL>cFy;2~4oML<1PY z1!%dtR^bcg@QBCQTK24)P#|u})xYiOfR`;zy*-zU7s%-&{IN=$oA61uM&*j2;TeW{^pCz_#c@=s>9+`fscggtmTAk`|}Xa?NhHjJI^ag|pr+$(K47~jL{W2*Ls8MkF+lSNXt!VxK7_~R|u^a>&fd1u!?+xHBw%oYZ0ACNQ$d~3RkV_eV9xA)EVqT)s(h@)89B}7 zu_{W4G4gYG6R)U@GI<&0pU{9@<4B)diS#I*y?%v=Y|CxRRD??Q5aa-lrY5H3mV%It zXqYOxX`+KmYPH)9?w2Hf8<#vf8!lyFLQnu6(d@Nj@I{IXh3RUNx$%_d(XfvBf#;on z1mvwn>vciYvXS~_cUDPeqA31lbGuo3Sghz(*aYtZp|@o`T)Sf@tR{>4XVnC%axvZNH6cV*ib>8}h14FNAY@PNgE zJ`J=>-K-(Em-ih&ThUA7k?gY%fNyu9+?ezENij2!46Mm;hTinNjh#+*PXWqaSJk6)Q>Dru1ULZ*0X^#?Qu9`_4JfCjGm$kitaQ8>%(10z28NVbQpVob zy|^jiL-psh<10MZ(|UBiP>E|x^vp$NiW$C=qI`pu%~kSgQ(aV;s(8mSsc*E^#y`h7 zzQBwlT1}uho#R0zusuy|X0);Ls;s*5dCHEQ1~;VE7Az86^ajUrejJNY9lhqqfTZ6r zR0Vi)Wr)3pO?EGLki7aW)n@~ou07WYjrNEXEjl~5XG6>0k7ZmDC7Ue==Ib)Pkcp7F zvyBV^F^H|t2ILEB5{b^({j+s12bS8~$61(HbH|mW9DeE`-JB_XI~#~29^+zvA-@@+ zU*xzd3Iu4>3UwO&j^LH2!~*&pG?GSqABP7td8NC9jd?`=NemNmWb)?^@e0y6mb13Kne3b4x;8)>#3O1*;Ax(R`C|CKD{PmqQ9dQ3m{NK`NmBDMqfzo5kY7 zlSiR&d-zCMm#VnaS9s<~(6wGdw%R=QjE!ro+$uF+%mP=4gXn97<~TKVK@=}z!M^zR zgHdA1s6jrlyby$!Bc({OayxV7Je!81E0YaI7FC;m_K2eb_}4!-2%2nCa{l^T>=SNWlmg{_&j$^R!ooKk=D!%+czZF6&OT-q$uM9cTpiRWh)Ilu`n6~VJw ztWyvjP(L0LPR+h=hV@#MA-8dv96wkj-&u>v$rwLGH9X*P zr8ZW7)Hoq-!F!3Gx#x1!AeLLp^=7MTY&Ff72>mRXvZ7hRZd!zY;Ir0DuacylvMfXW zp>=@p5t7U*{xSsf2%?}_X8Obx;~==JuLt1z^Mv@@X`Dexba`cwqRyb!B3(DNPbl0n ziPS5Ehb;Gwvl4~Zx|kH6sxa!7#O_Z|qla={O(?oZoy0eVMZ-p52n|SV?cB7{NK?L< zg<7^K`E;`A@>;6QYD8Ly4aj+g#y((Gc5IB?ZfFed2M0+V&s^7hE;*Pkg##unhPgDy z_>E+}OW)1kl##ahq1HLyLwOJYvbD7DJJ!98mQJ`4tqr@L%)$xg+$Mx4dOnXKk-ebm?YYMHVc4D3T!^O!g> ztD|&JO3(`D?CoNEJAaEVN0x05Q4N@8A)t?7J;Bl?s%ysKMyVCyV$d0HQ4Aro_bCAB zQAL2}_Ow_Tnmd|c4LIZHSf-YtNHUb#@aROgmc9{0hLoIpn>C}JrJ z3r(F7Czpr%SyGC_OO7&`DnT~r@V68-!je|(byVGFZ*cBuSd3EhHH0cG4Pfu}S*quh zqlI>8)Fl&%;9JT3PFegnr)kE{}i6n)H_@cw|D7}f&oA2<~ zWZJc9NiPJvL*mU{3PhP|zBI&``1tYeQ26jS4A#flNige?eN!s?g{!$~pM12p(B28F zL(YlIP4O%X7r)|s==ONxe_L7)l#=iU%_J;+55{e|tC0*`#`B8Qmkg$Cy?Hi*$2c*P`On7M2Y&`kcqxf)aUmfa7vPGPlZ10CwHK5Imo*@Hp` zYi%(cT-6lKQ1+?@?8P@gf2WX>J96~!E8bxz{}?nKVeIM>Qtz>QOz>JsP3t7boH;PV z@};b^N+uQW^3R1`Tpdb$qa1K~RJhscE4%v8m0{q1^@{MU<>;Q4a$Y}ehCUjjW3Wo+uVpkd0%k4c|44PtTT^ubv%eA z%^+8}c?4Nm!{vS1&uBNhIi8v~dn2zN-c=A@tjxCT(INUzO1Lg&aj-*tqfa^7ye!TL zh_QcUed4ozUd9gf2;$Xucz8#HBaHOm!L9m&xbI>I%s9O)J5@zY{(17qqTKbub!ob) zUs!D@j8W!ch$XY)m*u9R@3cpi;b{a05Y3|3ZH;~d*GEzB6ENrf>G)8kAcuz5N`*cf z++i~Kf`P@1hECp8JfE-vrT68bowxWoCU+D2L2ZrLh-AQ*Gawfc?p|+vNcWyB<2*`b zbZqZnjnE5Y_?QXuDWCL5DSR?ljp82TW<_0q`-b~70{82mI*YK|Cd{c2zI_{}{PxZM zUzkWJ**Q9!7|Z_s-O*XZ)>y*W{Xd^~n$m#w#yM8`;yX`UI!mk`YuJ+6bWdhqHZe0| zi`hutUse5Wtb`jwGEt98hItvIYE^BToUJh`naH1yHm*Y8U+*QKM*vgYMyRXBAfZ_! z2)#!cteBT|*aIz=Dcbcsl{2rYpt}E}v7P>>=ehg3`}t#s<$i4?*AKbx@}Vif1-LM` z=zJ0da8Wvycm9bNq2*de$HJ4{fXI0&_F_B4Qm6zPemko`wZ@hfq47(8AckbVi#Q%d zbHgFj#%e~K@=~*&kW{Yo!<8C^iz`i{BV0UwnV)7aK;??fe4QZ?V}|xnSMG-v$#Yog zu;O-4^R5oF45l65-jJoob8a*#lk9#}v%0gORn9DqoMxe^_gGd7j^IR}#eEc}WQHp@ z^L`1cYgg#5ldvdyoc%RFfYE{(&ZMN;`KKi*V#&f0wNrI#(>(B8(ipGqqK!+!eBo_K zsoZ@YMug>Sw(V3se-D$8DRDB-fEc+|hApuLO36-mr&BfX`Z)Uoj#Y`T;TI>BHLeUv zVwVazBTx1mI-WQ?E#3Q&q(vo$TIAA(&eSWDDWefbK0|w5PJxAw-GFS{8?>CO@*uUXI<*OQ~QOq;5vB8GvJm~AAS6kf#d5ihKI#B2H+SA=OPGr)j8TXl1FqxIu*j3Qy^ zsN8)G55yI56-5O6rpS*PR(=nCo*a9!*fq@22nMtBs>2uixSLf+wEi-S4GK1PTW}L* zbI$&>!#3#Y@7@pnqv^b5Oe%4e0R(2LLu>lfM&Mh@^cLw#vh)U!TM|@boWlvKv*`?l z%hkRQ`8$1Ez{{1sb7WPn;Ynjuu|4`LLS_-N>XXHO=Pak7J|CyiU&SHUIEjUk4i@;f=8)v`aiPxF}I)9TL=P8xQ7HAi4JjYWE_{V#9p(E zIrt#H&Oj&xhIk%*@o^=gx*=4}Sn(@9#ZQ#H!Qr_&U#_ zgA?83Q}f4HaF8&`W!al<5@Gahjnl~m8685oI$>pg6w zpXN-5Au7ap5w&N`Bf>g>q5_YGZ&eIXpk*m9d=(OL&BR9Mk+caZBkg1;h#4+%o$~#u zmc@YWFkPx97vkmdm7J~O#f}T#v~F+K7i$t~@RZC4JVCSGTBuq3@}+-bHqP@JL%k6z zdd@Ku?y;q1%=SCEts<0E7hyP>DMDu+*l7z|kGB9vVwv$$9YbK>WRjhuR$)_xY`( z7IOigXUqa@$6o)ea*F^@ST<;@AXi`ZM!#Ou<@H9)ZCN>jf$LQ>09}5&`2co&fqJ)(EG;aPW?Ej>n$9xsBIFSv|BhBM67So zrK4hbh$Z(%yRXeQ1veN1FMY3s0(+ zJ3=a;Mn6ZMjdt0nn6d>S*~&3sUL{!7+K_Fr0WpKAkWt3`H;ot!9qm=+GzC>}hxzQd zmmQtvfk{oGUjW0$2>dKoPXdzCSJwdDZ-l-<18Gq|i9MzlliD%QQkHX^UxY#lPEs0! z`S9yuGm`lCl{hHlW^nIV2G0@TIs4UuUAX~z$3OGNBw?xF-`&A6g!^_BUu-x&k3@Jf z7Q%GjV+M|IJHdL%e1>xL>z~!!lG-1wE9rJ4A$)U@YH}h6@OKe;+L<##*Xl>Ng(oLB z%tUg&z`Z5*VoiD08-o);G506rxi)-(lf;(sZxH#=c{ zMh^5!%5M~*_Wttq6CK?uOgSyG=F=Va`|;xT)NYu?mn7+cXi4=>_8I9V@KGWY6OKJP zpFtwFOtgKgA|YK%Q&DjDXTK<51$rX_6`8lVE!|i|r}E2sasK2MnM-|;oD7cH_xYI=Ml5R(pH;*0KA-S1+7Onkk; z1MNwL$^x0D^qI*@@oo&nR~hrAZfD>`m0(ed@5;f7(X3X*+kU>0p9eZ_jy}$L9+p8? z35V{B1*{I;_$EKQeD|)0!j5E^GL@xnkzqE!R(W#0jDU!ZGb-qy!$Qh0pLKYX@-b`x z++DHQoU5T-rOTg9sD8%r@Tkk=Ol_y3)#;k01(4aP=tTh?2$!SItYT|`%YrQJ=ajMI ztaIVrRKAhNNH&>|Gt~s4`qP{Z4!PvExJ(ga2XHD?>ymeUFj>Jx1AC zeqX7maljX(ffxD2*20al*|st;d$(vt?Acx+t|9M-Kt zr1?Yd;&2%J@Rd3vbAB%(ts7eUspkCSc&yK&Yaq3U((BLR>i8d?sv8vDq)st_ZeQfZ zxrCD^x2bKfjCYNo$gD@h_gY2icoA*Z#TY!E88JjVkx|+r#>mZQSKuG_ymS;!d8selGO0eZ4eyF3`JH zsLSW)5I#C&J5y;bB0F}!so461kEd?#U0}Bdp0~xnt=u2x9l^Y+t36MrV7o3YYL94j z))2Tub9K1t2#k_!c2Grb3_LoS!!FJQCC--4V%NYf`e41y43?z}+1N}3P_Yv?KBLf5 zd)Is6fdW13Z(vtWmqu`0!J-DvUTd!Seb5nsKHv57Xd^>;;fQvPNk1R?j#t#`Z^FH0*BcCAGlL zV3qlP;l$qS@+A)s->*(Gz4G!gg+_axm`R2W>#s?gK)XGUzR~18VOh2Gx0+8;*qxPt+g739bD8Yo)VY944cK;e!rv-7p9a6nZF^65s9#=skvw--8Y?5{HX1JUh>f8Dm+aieTe1{xX zC~Q27r#hE(O>{=BI+L8m`}|0q9#NVd7LRZ}NVSLcTnaV#58IW)TQRLh z=K}}CQjD2}MiFf$$PiEUsku-Pc#ZWZ?#pjS@%uTDJL#9tCG-S!-%bD>Qlt^<*0h$W^bOA9+RbH% zZ{&{{%z<9j)z{{fXC39gHineiexe}IDZFee247QAPAY>2%JI?RqRJ-vAYS7D0_`zGG4^JKm*my!GT=hW_u5q~`w zStWYZk7Xj=r6fDx`uk}xcEt!mY|;6dTWR)1n``Fqwtjpbp2AQE0GKXy{F@DHu+i<0 zVMH!<7?e0F=M$A0qzx(OK(jKOZc}8b!&_&L_i3`J3BBYKCDPCv_=n+sol4Nz@P?(H znY>AP*r=t>%%@3JR%4d3LqXjNI zh_1_+A?Im$V(07z`@5Zn?K)~9h!O!sX!qExl=4} za}PCqcr4^IPH1PRSZjV~en#Ij2@0(l6IrPh)j`6+k@W?>k>o{m|AGkPe7cZCJ~`Nh z96cI^%CD}L&fr`}Va;5fm2jI+XLWPfWoTVK5%$v`Pey!VrypZJk%eYcKP{wNVfSiW zn;hbNFUtvrT{#Rpao%&>}@( zAFN7Qno<-%y;#4vugWs703eIFb^W~WslQ2$J)SdXa%6;MzsfiImIuCvqAn)~zi z_Bi3K(vc8D_H^GatxBizqLyl8c(o!=AkP-Uv!V?wwL=x>-2VVxbXPycJ1d^HUmDku zQHoxxSJghfZ+Xq)Q=1)I1+D*BglP#A!G#SMZW^Cv`BM06-M@U;WN|9}GtEE|M1)sYmFpPO=z*U}Pjc}H`GfCy*_p7cT zrTm#Ib`WD$#XSrs*`gzxoDbAK41jKw$~`UVDW#3D6P&UUI15-y$hvK9WbITrIYCL2 z5+;o*qv1Gw0G_(NZ&Oeiobg;yPwJ8-N3NYSXVe&AD4k}O%m6NsZ{(aVwCYI=ga;X~ zf&$26>3l%`01iO$za(3K17!ewv}NQx(*IhPPal?F$fjMeKI_W+-ZG2Z;c+Bh_M?vl z#Dl?c=GCGhja{2Qy_>RT*oBx9eC+ph?$4rKhyaqrt=xo(NHv8<{l<*&9$HK@qS9z9 znYtRpl><@MMXRzcvrHt;AN!_&+Tn9|$+K&+8R)8=9w$r>HQ3E#T z-vPOO$ZjQM(1E6Gn07|CS&A>eTZuyeaL{0mr3Hpyh#ig`Le{V{R0U$;p)}YKLi6>77^}vOqW*E92x#2uPs^>k1%`x5g_z3(1G7w8n%c5Zir$g&unJ3T7 zL5X+iemQW;lJJ84;}>uX3(OVC(j0KWdqP*Xfzd(=GTx7zzFL*{ko<1tEu2&b|MwW1 zH?QwJ3oR5yIHea0Ly(a-VgSE^TyV5wC6r8O2a`HVSTnj$L7v!bvF$&ZeFHF4b(1h! zjak>36s;dY5t!{V8(5K69m|H2HrYqM-%QQVgT^F~Q}OzOs0@%Grkp$GJ1~vyailEHMSk ze#Qgmv1!Itj^UKR;{*yj@Eu2qzZa%n36m zwl~o>qnmi^@H|kTKT>-$WoOb-THxBg^q$O`tT|MSY4EBYw`t~tQ->ab0N(7$c4(9x zAg_uXv6y8rYh%w+h8fC>Bw5BOj_=|_LC9}rlhMunYlh1!BRIeqR@!sLzAOrGy=e25 zDiFzwcOp-wJjjVT`y$RV5{6B3)(N?5J%32W7Ibx#xO!YdO&51P5i78OeHq;Fjp(Kh z)DUb6cFiN)5h0=v>RR#V4V- z!exlcW=b&$+|f2FV)eBoP{S8~mhChli+?(3=M2&Eitmq~5!X1@32D@keE*do?rNPr zzzb361l3K;v%o_S3O?~%xIl=LE9m}%mC6(BPy%lLo6R@C=a#1Ku6vS}O&AuuU>%`dP<+HfO33H!-}C*|~@ zRfwpuQ`c`4t?rI_wfe-V{P&jhbkVo*g)y9K?zq+@+H1Ui9S|AFd$7|7LIKU44e{D* z?0$pw>IC-ntUu1wyT}0`$mB&xP~??~><-^Xp?3{NXO25de2C?Dv7Y1k^R41g-$a}@ zBb@m|;K?C}WmBIp){@Akqx3T2{eCfUFQ2j>QvF6txV9qMA&#x%CwgI3>MsAybrt!R z#eR&jbUq=MpX0$_zb)rN{B};f&I;-!jGkexq9o&!ZeygT3foL;(rvL1N zG*UF$bzY<;$67H{h>tv`45m>^_H=Ae^vkYV+#w@>ocT~!Q{^v{i{9n)Ag99VRl#YO z{3F>VHi}>=#_ou~&7+x(_UGVs9p;)s^4vQ(2cS7$hM{#cpBU(Ms?pDQY_|AE1HyWp zJ;Db@mNz)Mw9XeKXIva7OAu|p#d&w03t@9!dDl~;(qKPq^TUyo=CK13#e0e=_)@ypLZ`2+&cet%F& zYw7y>Ag7q(dgQT$LQG^YiefR(Vww3AT~e7?=4dZsc#EJuLc*f0#wpuQv*(kRjVqs> z&Mj8#S05%$8_X<*%#S~2Q5&EMr9%adxD|2shQ?&Ry zq^GH54)ME9Janij<0Fi3m-C?-6`o=h zX?XZB&RP=NkPwyYKcdB|r+|a-w(QV0M$+YVOPsi^(YECAyITlA8)onD;U9hk%-mTG z4*_Wg=RNhQH`!lwXEiM;@LXNF;h2FWm9Fi_@aPtlEevUpkL#0%n{ zTvNnv1F-H;8RXN+K%PGx)8VygaLir_`ICd&GzF*7)aPQz21^jAlZxIraCt&NZGtSw zSUHMwSiH)N>8vHq#!-0bNT$$x(h;zAfp#s`5KCyuCf6MqRX3 z5b+7+45yO`=UvNX!M=LpyY8f~*+|4KLp$%qf<5G3i&UseKE9hH^Frc?ZA~>!<*96R z)GBx?F6~?Q|Df$1zbgToJ?-wGW7{3ucE@(IW81d1la6iM*|DvTZQHizIrHs3Yt6gn z!-B-(v+VB78s}VkE|37T1Eu+9mOKNQfYZCnw;rNV~!E8q|%o{XRa^-5Dk`;gp+uT+YteUS8d|$kiU0T* zk3u^2>iSq!;3pmc5W0=(Uk(Wxk>*Ool}9heDou<-cx&(Hyx|MJ`(-O99xWs+0^{W_ zZ!dzcE=QZyZ`ltkfxT58Z!xjc5pP0blSaX4hTd)p@7UUOq;Yw{9$lnLhB8%JMQ@ir zk$j1jZxuFxg+8?-b~Kj-nM$pWVrwTG;h8nWjlgKWN##ybbOYNxs#hXGq9RM%f$}-m z`BmTh37g-AK4|0pXv1mqT-H-^bB-F?^x57P8HrhL+EaZ)&?((IXL&c#uM?*!bK=@E zDaLKcvjvF1YeDahyhfpcGKpgq9Ss1y;TQbs3ErN+>DWlr^}0g$Bl6!dA>;;J=D1-? zadD{BF;|KtaaT4T>}F?WeB}4@EiCQC-hw0e3!kJ{x=AZ3zo>k~858p6aY-t{D9z3= zN@(8ObY{Ov#wJ!-g_R`XGGrE~TOlC$U)3mN{LBv-=uv&4y-hzWJH-|k75^6BwZC^KWZrJ#b05`7tQOKvuJsMk3nRjJ`ef&PsN#$LN75ld)G!?k z2_7y(l$)6?bagKEht9(BUyyL2kBq1-^|QWDpUF&eR4d{_m{{idRpRs z(KQqho5o6wSpejufyR?6YsL21Rn`=>@r(HuTPa!$U0Pfn9gi8qhB(Wkm{}SzgmkJQ z#KV(UDiS@bl0^VUK)Ju%rdAvLQX*%nc0K7-n*FaNLe|hW_K2l9gw9mAFNTOKv@1k) z>BjK}Kx$^!35FWMlTjMLdsejR&Kb>J*rh?$JYV_v5&d8$mk6=W4tNkfz`Rywfo4mQ zM83kYG+pnMIahOAVym=3@%S}|YOcNc&K)$;hP-Hj*Wvi7bA?;ajM|$<*#cHtzMP?ZhKMxOW;CvHu3Za67ZWpF06gU z1TZ?MrtC!cG(#vnPxI|C*7)()!)8Lz;6(zz!*qhr>v!$@+x<2H`v}Mpxt({h|ul9A+en8+y6g7V~lJ`u0E10P$Ne#4P%T=_z8=2|YIXKG zcAaovxqOui6&!Zs?DJT%6SIJ{Z|Kp^o-AnxL380@BL^R)h3FR6f0fCT%pI#;7;*s* zT)yHwSd>E34y~AX38@05C-)B_KHH|iy$jFT@Q?`pzfcD^BnvCktlDTWGVr!V^Pne6 zl9JSJNitny-0{U-0EnROWgH;=FBU9 zfEyVqlnN=h?r z7}MeInv+)kC;V8)A=HSG=%P>9tsSm>)BZT|QW#SEr`;-X##ZY*M$zP*9D&_#b<76!fn-SJTuzG+#=@UqvdSA>Ms4?>j>KBOieea3C&+a}=g*-JSccpY-; z&j)(F^TYG4lB1M2u}a!8h26W7`PMtK4>@|ux;=Qn6>sQy5Ju&^1w24bF|^hS^=ChK z6%v3$VUI!>H}l0TbK^p?khSaQ_gaOJw_3cBicK7v5ivykgVT{^JHG@ z45K9dhs zbZpK5up)PT2Nw`k;*I z$-Nr%oBiWoFu!DnkH=gNX78T9su!BMm&rS+4>w5pz4y+e_m3M1Q;!%7xfhi0t`B)V2k+0N{^(Mo|(fwiV-bdeye}0E8^`Guqg?r(=Y5w%a`TjuKWz)+n zs%P0cYao!btndo$+}D`R3M5Ysr2lblb83-O3<~Iz$G`#dQCGROOOcWV!BttAGf^yak*nEZ7 zp)I+-dZSUIjinr39n;p6%?M|idauYX)iFfkc~Bjrlv8k(x;iY@FIQh#Nm*VB&s~nS z?ryWWa6CWPSZfca%jc5H?^0V!Bgcbeo0Kf0FyCv5OQ+|r>F1k)$Yi1G=bEwSinq8sg`<1;+e32s+>#(lEl@+MTzo8!1?NOFxjS4_m2 zEt_%+H*UT~!uqo?^&{Rjzl83jJujKIoCh*g%cojjy@3F&Eisze%U*5$N5ea8H{ zS2o`$@L&LQV8mUibC7C*O&{i->4@|A(tUwbx1K3uX3@wP7c$5_oAi2)&DRY-`A|Xq zfLS$AZvfQ@vAb6x^7RelN~>F1ztH@$1MLC9D@T6qF2xzuvVhIUC4%B~0+Xmq()<+P zr{}+=R3?DUantZWeza2m_~HEjcx~~2y3%RE_~5JI{MVH((N1rjjenk%K6Jwdj$Wdf z-gdrGH=~fuQhH!<^y2`r>%NDgQgZKXDpo)iaK!Z63VR=E=Ax*m>A@HN0UXR4#Aw(sIgB9>sikl82VR0y zQ!c1!bYPYvFhw;sWnsW-qXeA{{d`rz)r*)i3lQ&ywj3B!DZb4?+|mCoJ zTWCrmJK5M&xw!I-ZkTRDi7At*JPGp1h_H`nz6z0jso=>XL^D~f@bK1H0Fy@J4;4-u zB?vllm9bx(q)IDfp2iuQ6iZCFtyh_jbOMo*eQ_)%S+1fO)y~tkLnF0u+$pPMM^)GX zEDKgOFM%m}vbT<4(byK)m$A{Ca+5-+gIaZ9wLnuwT$PPX9LSS(#ndX+5ItYxY3>j% zs(5A}+AE#4tGHbxX6jX^qLImYmesiMhfHJypD#wLK>)Bz2U!V2pD3fbW0NJK@sA|r zpa$1HDOI`xwUM|cgM#Qxu0Y)LpM@8l9RCs(v{%Db97fT5HM!0)_1dtJ-Cm7$>^;Pi zF?fE|Vte3yzn?8{s=D?oyrre@MewmVJSwX|0zi>s^;e+W-M@671IZtwb7q0`D`Rx& z#tn^=i6qXBs*9Q-_b{(n;U?WSs21XIhKQ`oRZj?W@t7wk*M}RQE0xrSUNL&qGI@?g zF1A{=+0)H%IsqIKFzFOj9i{E`5YEXPK zP~*+%@z>n8Y!#s_$tH#xD78usYY2~LPPYU0WK0<~v@A?3cq=rV3o zgZUb$!*Pu!`!;FIG>ada8S9)I?$@nx4DM%JDXYH@`LX=$r>?nS9@zQIh}^vDm{r@P zo>Mlg8AR)t9JGv@(g|JGdw%2fl$dq_0&?zGZ+fSn=LK=rkHgb*;`~i>Dd&XigtRAD zP1{cl0P*swNwaLtt*@~E>0`%-C!N0?P9lu87$xbL z&tp)qa_lIlx@La}8EQRDQMwvgYy}`XUmvUzFSpK82cPSLEsvj;EJ&3rbty!)s>G1p z5C%T)`SP`vb+K^4xbFW4v9^K}1`)uB;waHIfeqz5!2=XzBL;IEP>=#4NUT)rX2#0P z1tDYj$GU85Yg2KzD1otiX8k_q;!F+mq2s7nDE3NRbhc3?o$FwN($f=xJd7%mUHt7(T$T z%+Z#_Uh`XSO1WbI`Rz%z2t373V5H>=>0#W!L_g}yO@uRtgyEY#v+ zv|56X<)PS2t>QB8Xyg4T1ExQ$4$Z1jZ>!bQwn+~~@ax?=Z(%T~zXfj0r#B3NYo^kx<;pe8Kb%DNeU(I;Y%7=xU6-HsCOxRqfC3 z3#IE%X>K&24v>hr)%DTud;S%9VL=Vy7eG|stHf_NitA{1I64|rjp(@)3+YGlsE%%^ zdj_Mq?gz}J^+;mphOO-jAF;Jf2kYr&OothdTCRs0Cw>N{5p;TOG)oCIo+)ll+e z$-?(dc*xv_{Xp!Ylr`_MhbD6QMVenBVG2n(PU}yfNG|1n7e-zj_DfEK+m86j@c@$RqsZ)=_J%IUnJrTn9eSPL%58#$v@{M2;wuboN|)Uk zSz46)ZrPJ}bO`C~FO_~ipKzBuO^}c3ALL*uT~_Tvr{B1O#=%+$N4TUq&qyI&UdqiJ z8y{|I=ynF>;SMRKg*=}JBZ;sW_nk~rD&)f|uyXr!eCXEof{~+UHIdR}BCOC>ZpPJG??ZM{nH z|9<()qh$A+$_fMi0kgLi_IJvtmM29+)pF+0QcD|){W8L=$&HfptUQ%=Qtty)jx>@` z@(0nh~V6WzV6GJ?Uef)&P| zmM}V*L4cXbrlz-6X(xE~W9=F8b>a78htMzc!d`x^qmizK-bId@Cl`r@L)uQWH3q?K z1vyyTeNh(G=*=myEeRN_5=_J`3*~+Mczuqi-<@=vFCg~cZ)?_?IA_JOib!`3Tp&69!g`gacU1UkDMPzP zekAlbF#PQA=db|%j7dXZfR$=8%^8*pjIK1*6^_>47eyuk);w`{vN`*d*LWtpv3|w# zfxiV2kgArZ%a%tX2fxMY!7dm#w#69_GfPjhV|d0v9p*A+3mvmDv{_!gtRtkk-P#+X zY0a8hZ~urmNzy{<9m$;Kl-ACJW-w9dn%4KWTCuie_{pRcbxi+52gu{9Q_)wo~~x%;25M9FcTBJwEJ-s$v3cGu#0ouc;DZg_{B4}C;LrtBc$qX7OqvmYCb zMM^{ZV0Yu`mRZ{RahmeRy1s@-(Vi<*J#2tfjD=)i8kPWQw5?_1R`kwosN`5|pjlO9+b@kfACm=4DFU z%HssWY@jsYh4%c~at8t+;U+VER_H7=4nip=DcS*z=5 zT5vu(YU$tpo|~fwjdF<`Oz3N;;2E;0rJcku^p?15)KXdrjm40GndzA(Clg(UNAj5g z;Up0jzWHVJL0U6;rs@u-Y=L5xS7$Zt_Ab7cZbTRD3eUS&^;fXByvJKoW-N&u^2(pZ zr~J=Z*FML*+pqq$&i9j?dLO6(l_w!U)c#9DT0%aP5L;RlcqBx~FnHD#!=e3@)g0N4 z(P{y0B%+H5LEiA*W)dQ-g}7tTU2r;v zr5NmwfobsrEkPjvKp&Cp!d(p-9R4Iq4nrxRB10CLs{3X&(OfV!FD{&$SfU$kemx_P z$(b9CA@WrQ`^J)5h)q7fnTG~vSk%SjnA^FT-qbiMPT}R>5CQQO0KC7ea=smS(=EsI7#u=8VbLm1o^dMO3t;QztP2%rv0*k1WO6#WO!+j z7J=N;=`B7}$i!*7kE~08;w&b6;geav@1s~>P2seBQNLSd@Gdqf(?5PC=dz~Ws{sJr z@JDdI2Ve1l($Wkl^`=^X`7F}T#);FEK=w$C8UVAfYxHCk+0_N?(yIdM58(D^IQPmL z&@bIeor6maG{T&p<4swLCjYiU)&N?qw#()XTQ0&`+^7-L)a;iG)WJr|Mf{aO}b&q@uYo5UK~#awF2*c0A51ny9|je$}C1 z_VjSwk}?Dvn49qp)GuROKJMY_l`Y`chpB?i#el)W`!#_bo{Ink?bTDp5@Jsr>vaeoM>M!g3y)@bXmd;p zwMeVi^zGgb(2t(oa-fuvzD~P4Li6exJ$qT~GkW&b6DUlx* zy!a6Ts`Esw2Pn|I2x+GL39~7SsP(rser2E)Z3WydAL}OH{Jce<=xo)%oL{|LJ=Acc znpj$cvn9t|{`j|1)W3N2eJ5kzZtJmYORnGQOptU@H*JJ$!*B38oqQwgPFQdW0o8%- ztz_nZeus)&AScdxBbdSyBZ}MT_pf6ATIpowf0;EVTY%9a<2s6c8{s9QiN_Rj3WFU=@%FE46PFYgVq zHV=_YYK}?G<0|fCToY#0k82u+)~S5-bn8xS1DF&m4|SG6h4~yW+c|Vb2w8yLcZaVsh|1@ezH6JTr>@p z@hAgP$Qf{xqvuYC>XrNqH!ysCj%&?XeXB}Kha?R(3a~z~xkp@=trEtn$>4T7NceO%t=mbMiukJ`aw4;)Q8R|?q7ko4c-80@xy z$n9n>_b(kp8+=I*M|?_%oFV(0Kr#exYZ5E?DHaIzrWOp2*8Nryuf1c4oDnP-nMBq= zSmsy${ z44-7hDNJ1B;;K<%0@?H!WqT*QYW5%U>bvf@2nhPqtvNo;U_D{m=7POK;SRc=nwnGe znONKXL>4a`*S}+n1{|jWL7#U-d$ArZ&E)gAH5YJ~ZW*0wu-}wm{t<%4-^VMh!Fwc~#xy73@DJh_zgX{2>xBtk<@emzcuQP%O z?gRWQo|GJKwv9mp+Du5$e~ZDzr0she>^sQc^i%sHzJ>vNYD#U{`h~OqQA{#jX(n{kez4R^nz>+8>KC+mh@q26ep0LUc8)hpwhcWp;b9MlPfrXSeU?hrLOWbF2wroAalb&etHWAS2nd0ol7vE3 zcOYRL0~EusYA8%Zi${cwm_>DSsV{O7M#ai)xZ+9-8E)8OINGusvv<2M(R;Yo(E-l# z2caeuL??s09Dtez0$-> z{~}0SnGnQ{Mh&`0_Y^tGiA0?50&{H?ZQkk+#oA;Xe}7H>VQxAJ#@~DR8Kg=Y>ecaE z$cA0UIe||g|J|RQlC2k`ny|Ta^L}E))AD?ExjsZY;@ytzxiq&6Ul2`vgC}Wz8iuS( zdxo@Lyv6|tLwfx6(!S!Kebf7@<3#BH_xI=aJH*gvlE6N=4(1%xp|4O`Z+0-2#EFs+ z5rBvFO6rtZJdUzt1d8PCm;C%M%=eSKecJcK>J(EMzGxS`ClH2|*Xh2CY++%DE9-&M zeVpqIv>Wwmnj+Ccv7&JhVW|Rg#U86}h`o7c1@F9Jw+JWc#T%!K=2G8+WPXoHnsGsA zEWO=~=G}!e-kk*RgGLpj6<+l?&57}Gw}N{|#if>=Y|uLUopbP+ zHt_89_V7bH@lkKwo)(m_F4IO}1G;SsmI^PDjD$9SGv2R*HqoU(4qQwP^V z;BRzvqQ!4nl7Eldn$EcDEvixbEc!!a*xseHTgrqM56Pvovjwkg`kJ`wxezT{V`MOt zjUy%9>wJOQT4R);+G1hmn<(S1Y1YX<_i8VVQl05>Kn87*;uXq~#fxhh0Y~aS{*e08 zyyWP@s>Y)mh+(j+83;nIX!o4KfxzL^n}1&=FrCln0;>1%Yyug>%=)WjIdq4~F}Z{D zfmk<jDal=?I&n@Vy<$U#0TmAMu;kAL}Z`r7N@0p1& z`>1B$5vqSC-6?OoP%q#h<#q$g9=J>mNX+(TW?)S*=vy+cc-WHnREEP}CBQz=jb#OJR(5 z|H+VKDPkD~rO=o;lTF{lBa*oP=iOn`OqozSkqQ^vP)N?T$QQ!&F|@@ zb8Z$wqTU*XM3PdD=Ho@9vU-6DthM44mthsYW88k_)7ZbO8l7|4 z5=eAjb+)&%1*B;&u;K?P9(je?d77P+8AEv(L2x49l$`wOfoHh?FR+KieD%9Q{rEwM z{U2EW9|rdSqqh&vA6*^eTR(w`SO>O>8vAWcIU-YT52C7;Y%oE>QHGEWMoHN^d$UXP zmznue`YPMX(wmiUW5MGrX4Tr8u&r8|={&mDZS~_V#s`=my>x@XFn~uH}RvF z@bo3h5O%IJlhEQ!wB3h`QPHA`2|PCDF}QB>s?w?FdO*ws#-rzs8pj|*st6a1^o0cUgtqSKM!BBcT@#Xo zw&28W?TMEz>vQXOHj(|`DD1{);94^QllXX`(A{F|(W!Xj;jDb^#?nNeibfuVwNg$J zAOOMMSVQF!f7uvMO-%kpMci)UpUPwt#aeA+9wfZ|vBdx)@SL@V>0_*&fW;?xx6PWj z>T;gG6@}Bf^{=7KCBq1PxC*s7KCkf$dEibhfO2Kzt6;~HUc`5BI$p-LZRy)wWAdh`2Td8vz!o59|hY3ObH<5xsU zGKL-N)_B}QY(%S-q@y_pgMGXA)1a;)4yx)Nq*a_i-Jmb!mT>mxCu+AhwEtPQTxgsx z{`;S33p7(>$%(P%qV_XU5~t6TRdVhezduxEq_Ys=?nZwG{LW^rY154rh3o0cL>QDN zB5j~2S$+-RyYK$^nXE(w%{xBRM3M(vxJ4^g#C4T|o8e2jvcRMq8oqyOd>{wc&OFQ< zBO-bRI!yXg_7GZ)Sl-g)1$iXQ zG31B}cH2T=Kl0L^crEv{|lB2k( zk7oG69amnMtjIaVh}iRaiO-%{4xqhx2w^rD#&_io z7~>L}wjTDxIr#|C;R>@TtaO`vl8mI90CE4RA}Az#tix!^Pd6NF7|EnLLYrjQ^vEQSv=>Acp@|0zm zzG^6QK>Z8eUA!_?ngD*EYod~oD@iTTgDRLCtc_H=_)ulQA*P;UikI(DIOa-HRV;)h6 zE73}oD~A`)M1L<+N`uwQYB@;BjP?;Wn2j$}U&k4#4;NQBycZKI{}U16HaD>f)OV3u z38p>1&|a@=$#wF@WVGax0Dp&-+j$|^Gt)R$RDL2qYdmT}4#iuD%$ND5#%eIDIjKnD zu)rY{bD`5BMjDqomiDwN@(MLZA*0^Hk?*Y1$$2BQM=<)cMTV=X{|jE{mTWn>E9r-fH5*)*HO$hVPX0ZL_M# z`z`q45973UuS>emDCFXB^j;3jxr}cH6hR?=kn6@-zgVPcqg;c#$@C)~Qfa2wQJX+b zY-IXsO%AC3*~{}bli98{%ZskdeQ6T_(H-sLj&~{DemNR5g&lhfsUuN2C1zu)(fi~a zCzxO;@eh=VjeFW2{I9*@v_rZzKjL^P?wDfFvfvz0TtvHbszstp+4BoliikwJ_(iz> zp3jYfx80~ik|sVCK`yh&!5f_){!nc#A4XJMeW|0r@FMJ+pXl6GY8Rw z-p~8ye?2Av6mo^NwMk*PyTa|2dNWc|iq5%#^Qj6H;8WLVkLk{1Yq@jZ#B93aw76{T z%Vk}AEMBvc?zn_`-q93PA8^bF({tCR8yaG(G^1$=k6?OavHm4sm}g3D4DQ+H2zFEXtJD(1g5axd~=>6VA|f4Z76D8GN;t$qDBSHWg2 zMlBA?j~_hj|8uT_|K0ZgZ!LTOmEKZ)%>Mpz>KZ+8B*#aDh98Ru#|A}k{Y)Y~v4EBY zldKvWpO9f;Nyj>#G`J~STU!FiXlvW#LsmD*X*UhgfX911+O>FhY!-Hm6JEHrcrR>T zHg{-KzrTNOXOgDF3`(thI&|)TzkmDnd|!WkZhhQvGWNjkNWTRFS^Bp?i&!h>z(fEE z^3@g0L)vYxcxCN$L~RS2`;D&m9Q3tqv>Rk|W?i&)RXEQ7&Ts{_h|&i}uaC;J8tTs4 zktdiHMem}Grg)H{RN_&nH=kt1Ly} z?h~q8ESCHDAFh=8!uN^zDl`hyAJH{wmS`o-Tb38BVC5!km=@7%qh`Xc-i?%YWGXO; zAoIbyj3rbLxXbV`?`V%$YBmwihsw$oR9S8RS;@mwarxnj(1_aAQ-l;~%ssu9fc zx_{7_(z~MR6wU^SRSINLpHX#Vsx-f4#}f@IajvDFP%)`+`BN6rSiucLd1p*l%$D}B z`?lcvlE_$wEVL`8WkmV)yHNv+S^37ytChWC;hYLqtL*CD1>UW}Tg32B0 z+h(XDvjl90jG_dQ&(3A2{gRAbIWEXPPQD{QLU?O<}#AYX5&Fg1co2X;e1Y&tv!LWuSGh>a0K=v^Y3PN6YuiPvmY z6YdgnN)$?NjB9I3uw7Eu71XxqQi5)vi~62yPh=+0eS&ainfoch=-O#$$|wl;$I?8Hy9-iiapf&}MKSFt=^` zc38a)`b3$R7w68dKl^lN?bI)3>OqNp;eHf_`iM_DRnYoMv%F~foNX0cwSIe*jZZsm zd5;FQZA8+qROCm49MG+|hDVyQ(_uY$ns?3QA9nRvJKcQ?!V<%|1}5I7g!?!z&=;G| zPkIr9maJE7rDYBu5wh7=LN{^kh}mKXid|jy08=$KTg#b_b^*wEBf_DebFj>mG zOmG@dtJq?L*o|ywp3I!Cg$YV^AkG%kmz9q4Vi!+IK49Q83q=CfK!gT2G7Sca@V5@V z(%j!7C83>`cC{THl&E(!vk91%PXOCgU5iA2B?c$taOC?<+yc!t`2J@(`USztmusWEFPzI=M9V7JcD>=43?@t4D&5s6#oQ_qP5 zpybS7m< zV5<0$7y;uhSN?>Ndv`^5__ZF$7=?|}B`c|*J?rqiZ+xRa{HMd!84Fs$deqkCUW6bJ zd=88TVmm5J38y1jHmDj@XppLl6Q9jXrYH=sgv?B84r2JM`%n>5=j@cmHR_RC|a!C?3EpBU$LLv19ALCt;lOiv432t29jqNil_i9u&JajnbPPL1^`e0rO)=(!_bH`0dD+!Taf* zR35+3Z;}_)%k<30!!V0Vjc`I{ItE>}P&9FrD@L)_o~7GnX!ScYH_ZWi=zN&MBVr1d zuEaGJ-!ETrI#aVj^N;}mNr9*tSy~u#_#+*nLw<3YJ@XsyASn!cXA3`X?G|55qo9qE zZuQ_Ee0AwFJZ%(<^LaNMQa6PQjqWOWaxE^N!>N>NVIo6*36B*oyQAoq{E{WCoNLBu z=EUa{hkD3d$Rc9o&{#7WSIuHs49IDs>dLh7=kR4d4g~b9CXcSL07IR`#B!^pH4RPi zUSbojO$j%TuCz0ZUf8!{XC{umdWP2K=cHbS0vy{NT2Qg^>?uq8#_l)*PDu83p74~U zE!_~*eTQV}kgz?=yfym;yj+b;nO^BH_1ksS5?Mo2kwkeJ%k=%3t2|kaPTv9zd|lI@ z*#Jo_iULQ@6{Mr}JE*?$y>rs~1<}zd2ST;(JDp)dh>Vy1GUPn&C>N)(3p4 zn1-EQsrMdP3S}rA2Ol~Yh;=SrQP^mb8T8Vba?rc|5EU|@T(ikm{fuxoVt*1il&h`&P$W` zmn6EvET@#jUkpZSqr!TWMOT)Re|0BK67v(TGpelljYykb(JVS{f!qR9gFM2=P1-d} zFBjy?K!wj~H2*@`j7W1+D2#HQaULtW0DVg^1rIIL4!hI%`mq0eqfGu?@u+tJi% z?^1B%{WVp_Q5wt$4PAF>&%WBJP%CD4Y)XI32a+VUL6V7RobOS9x*JTyb>=)GNrEO- zw*x6kYQ`n}Q@CRB3+0i-xR0qiZfErRFUY^j2=o&k)+-Vwspd70n~#pjzaYOR0sZzb zhvqO}v>#JpzW$kl(`3n?(pjVMyZ4mOV-_oV_^@!IrTA{|rwmhlQ*l)2=9Utq^vv_= zE&A#OlZa@g)hfysvd$J<+qgQFJTfUBlbbvUlK&pXE-xwEe~?&>*5tRw83Ak<35Q78 zT^KiOXMIE1_jjdBpZ}fMMA-5SU(S`~LqWca6i;qR)R}T`zPos(Rd5H4BTrD1LqEsx zJ1V@GE5JY#Eu5mf#bvxbU1L3K%FaW{g5c6gbrk`@0^kI*5i@PU1CnHIJ{zdzInjGxs0~WbJkm!m_g}Z zbNnlw=A}#-tJ;4Cln;{W$(xJC-q6l`oUhAw{1r<&3CEW z@Vc!qkMWF+YCna>JblKW*}HhJr_gi9C;@-K-mDXJqM4ne;>2_ztMQ>KW9I>J&Juek4kIXP0 zD6#)u)n%5ab~_v(-a;&UxojD(ccjVyQEE^c{PF8?cS~=@O4D2AbI7ljbxa&b zH?{dBj_-R5*uNMpPParTmoceQaq<$5lqweC_q?e320XcA&+e9Iyqi)lor~O93EgvK z%|{JlTgt#2WqU(3oJ}Juo_&VCpF*P1$3|zu3>bI#Qh`BOyvYOj%LR)N-*Bw7_7tm}?|F8#a-IISzr#|y#KL6)=wh}aCIJ)IEHx>BsdBvbf;~8_~ zJ9z?@kBot-}c?9-&o)h z#V@i6Y^4ngt$wDXbj04gp)|dZD!CDjUdZn|!`{G&{eUu8#qVzt-l1g(JPzrtOMGdU zyd}T6ViTl=5D`PpG79wBH}!#|%d=12CG+D7*`_r{xBpe?qt+xy*q@tZsBXLu^YQAK zH5GnW3lj#)bj%hAxsG-r9+0-c zl^kF|NEwF2$NTo$!C$|*dB)|aOg=xs*S5Ijzu(2FD;?2nzrdf$t1v*YFH{-GOvIYb z@#4N849wCE$_^lqr6~VXtTD;_r%p%HXkF$@YU$L#S_zCxfsm;k)rpjS!eiy|qs;Xe(g9 zpLbO$HJ=~?{bIG|;{_sVS^76MgfzZNT6thbPAsPm*%a2c zbk{Ebd;qU7#H!&R5!4~p=Gq8s8uwmaob>`QIXA>Jx;CzQwi?wx!?*!ouc zs3Aa7(xY*d^{eNvcxL)$HQ$2cA-Wb>9@k&!78y;eaM4Kr>s}|Q!Yn@yRKMVsx=w+- zw%`IRhR?G!@eAo{cEx3BOQHyeULZ5dol~f6uW}3GlRv< zY>~yx%xW<+Syx%i^{rXxC^d@C!ztg5$G z^}{yh#JOLU2X9jf#5yA_pEdhP?pri}Wb6aqa62XeaOL7qMr`8DKjvJbFZO#T_5}?_ zxLxz7^N2fP)>fQaP0uvUZig4(dD0mK1Lu|*iS-xyHfwmj+E2F$F*hR;@BE_@ebWeC zgoAV4p!=P#)fUc-&hmxt6t8PyO@0c*hdw4+F800AC0y`{Lb>JslyBnTE_VFQoFr^W z;WfN$W}`ePb<|)f81)^~l+EOYfSS& z>iC3Vv29eVz;KWcyNhhbB%?$@u4d}=4$@m$)!)Q9?smIntH5s7?fCWTo$;@88l`Va zviNWyAb})*pUuwyFsJ$7m`e8OG%Uj}I^v+;te zuDdSRhd%KLe{63+fn>?u!$v@do7XdTu7-UZR^eJ9KpH}z?c`rxOl@3PE|Y$)UY{=L zqBm7<9ha!wOp3w@ueBH$L$_m26tY^LKqO7(t>Q~}jMAW;Ey*&a#SBMi%v9qAh=`S9 zBq6U9Q#m;G=-l;Fb(;iDP~SwmLt0Bw;ya;V{&Kz|yp}?=3&<#%=|F|dYbpW}jIUB_ z6mQuHxeD96vLXYwMj2Cr!GqmC4@v!j`{h)L+8fD}ThCly-ZfTwPb!P`eNf4hmZEpGMf!vm&}JUu z`G`nwt1#?*>s41URaa6*C{C*}N?xcHapH$7&!%VEGNBGpn|3YH*v| zH1qh*x@o2v#i=6~0A-K4U5`~TmEUecPEa*EwO3WVsx?+ikeEpzF5QuJ%-%v^)s8XS z8lCY)i_XSePDvWuqoyi7<=_q*Hxok|J7c{@JX$%>ynh*X0Xaoh0Y-c2hKv=BxH+PU zE0l?J#Yn_+v1n%vyeJM+1J8lbZohN0 z5XqQ;LUOULBzN~=Pn!DL5*C1UYXid>+f+S%WLNne9E*x8cK|Iw(!Yuef=9K{0F4-( zvy=IRB912k+HLO`Y}QU(usS@7;0=}oEu%Q*E7>rEiXtexpDR#G(!GXCCT}`n-4>zJ zy0$SX{)(nVz(Pw$%%Ke3;znE5*$~f+o5v+^nqGJvLitb5O9Z(%#)c4c&04#XHJzX~ zVj|Jc49q#YvQ#^ziX-+Qu~Hx)}3~ZL(Jb&CGj|3a$qG==7jzrKk1?|m6&^lE|Cgr1C?Vr zn2AZCd2zt`V(Pl2c2VsE!;XdN$Vr`y*S1@a%WGg&mM1Uai&t6 zS!+Au0sgDDeXMV0#=BaxwCB+~(_RafiQ1ahXFD=q9Y5>=GBBgx=Jim1-wq z4JA5x8@QVK;qapoPz-P@hG7THgc&&7tV^3PE8LP{!!ta04U zKuR8-C5!4QlcE!C1>V~e=&!?nwn&YBsdCNGseNVVE1(Vq7$`KzuaPaNZPgp_EUW>~ zDr~{-*E`!&JO1XDxUsqIUk%IA=KW;e>Hw?Cc4DtFVV(JYyWROz3Yo}9@<4z$D}S0- z(YA(OJ0zp9x&aGg6)!ODqPMw)?W4~Q3$Sw>k7_Im+sAew#ppMBYL2*scJYHNQOXIP&gnpBSY0coxcy4w<41&=w0>b`mN>$OTuttu#Q zA9jzFcDapAF`I5;P2Y+|#^VoFt9i$e0JtVHs|K^pwJ%QkE3Qbhgr`M(WBw`+xj#g^yFF=D>h;+@u-}mB4HZ9(ETMrov2gV zE8Z9ycmG;b8WPojuV0=ycKBaeXiCG{l$p2Rjw@gYxmC)Q(ltt$YHjw9ftbqQiyYU0 z?}~_6%e`ElV`BzsI;n0xhjt7>w3PC?Q**iQm{rLOVyrmSGjzb^MDTF5<+|VRFR42{ zQLOFb?%(zgj$VRn8|1a%q}xmdS9hO>^AZor*zf&3Do?mx9=1LbkL~x|K8;Hy zUHcel+UR7Vnv>Y+M~K%B*2#=ZO?s)^R4$x?&*klOu2SJK?^-l zPl?)~pZq8$dA_-@$tTZ|psA{w+-iIYbr}4bwBt=h4U_!?8==Xia;S~2uDSYwkjHd-*WuP6}F%RsS$Atm$M zKs`keQjID(bxe~t3{(BrJ~!Aym|s`uHE!KIp*c>ce{Ss7$$4H2A#hdPshuP6l-Kl< zZ_DG(`;F6YXZdiZ!966G`>Z?k@G4mxS8AaB-3J8nmf>=QVKa#Q%${-Ml1RMRWY~6) zo-j3E6+af%$Hi~_~8*a>Dz%20~4men%}su2X*k>O@>blYW25jIusm;J+HRH>DbA_ zdiA$V-IQ=6BD@n+$-l05VsXLr&^01Y#dnx{=Ju}=LvFlVPoQ&FE+CK0@V}~EVdd#N zn5XsHgpe%lvhT>m(+pyrJD%|J-+3E*Frd7Ko?Qq>$3 z$|V3giI%E}*?#G3>C-V)OX*+?SCn~2PPPxzKdKs!V@cq{9EowHi^T9zd!mXea0kP9 zE8GGRpw;N_NdSYzp!QM#$TUAtO$gc3g$EqI>thb;EJW>;!8X+r!zzh#j7qpPSm)%L zfI2J#GPWsk$BVgr+SOjrS$RvO_!Ow5IRrwt!BV~O1R7AeUZLsNe8On7PjpIVNf!6L z0HL=gtF;9}E}FixsG6mtQ#0?}7-Ey#GQpVjwTVta^iIL_hi21NGgus2Ns|&91bZ^r z`rfk3`?GZ``iRdbsq+g2B8jWeW;K0Z>4{qSgiFpIQ|*3t=w!Pn(eDY=h1<9%ohUs2 z%d=0F4=z8`kwHLISpPn6iT~);|Ia)zRp#41eTT{1Sh&AKM-nLDBa_jBQq!P`d=m)T%&NA^pgu&l6H zV;MPScz-?~+V#5EqRq({&sCv!SzWQ#B0fwuplqHw6Z#=}UfM4)G}By^SluSljIaS& z(xqP79aAedZ0HL+`H*piuTa&!qOBGgWUKe)3Wozw6o!nH;3eUFOl3?ENozs6vqf|5 zzF)Isf*x>oA&6C&f7Wd(T@1SG2*hpWHS^qgdnnJq2WPGb!8D{ROcUTnoS3rMBEJmE z)>t|H$`P$4#bMsb1Ld<;wAGsoq7i-`JGT#L|9&$8Xgk^FO-~=G#KO)$wF(I9d_(2Jib_ie_w#j+zr-PlV z@4CBJvI*(>O>h~=b@-oI{N=*TC8jvulb8`pJlCJq}U_k@07+1g7F<=`M ziU2ry77=Uo>q+pzfnsZcMH&nv6~svk(0wlEQws7L{Gu|j(HesGp)#ZlfEcD8zvJ&7 zoo%SJ4#^>^XB22=7-~*Yp|qA~W_5?AOd1iFXFY*s99FFv_KG%TsEfcF0DayMT(yF! zD3>4{;gI2Lb0)SqjL158JWWV5V*2R(<-q%;pW7Zlmsz30T9iy{$QJDB@%Az|ya}AK zJaf!<8#VI*1dfOC!Jk3jXpdaE`zF$r>|jl=$yoNV*-wpVZRe1`I_v0+!LCk;wI+!| z|E?r#PEIwRHJ(bT&DjcC*p|sxBW6J%lAiTH$NiRlZfpAwOH9$$O~t*;sJ7$(w8V5p zHeGc!TYBO=hUu$gc>Tfrs!O617CU@zm>QA^&8f#*3G3aOUXV`6+3cifqAly@=)P3m zSZTj}xP9bV0ki>YrAj(Fp!q8B3p~Fqxqh>S_UMSxU6UNI&2}lZZ)}9MYRRpjuQeVz zc4)v-Gw^2sG1(#0@HGfJ}W zGM7$g-ND*qwhN`D*e}hf_45wZT$H?OB6+ih^bQ%jW_?Hm2It+zf(+00^JKKY|@HWuJ1YGB9NiZXwSygMU#kod6 z-&1ACBs%>(+;qybie#BTR-Y`Z-l85=)5ed0=vM{NFzcuv&rrJwSI>d)%WX9W=YYtY(l)13HlqOy9YtVaAu zguuQT0bZdrbvl_#^e^jl)pu#YQg_ED<9sf=2OrY32lL(=gy5lT*_fA?t6G%(w-v6U z(p=1+nhLySSM+&X97Yd?Aq5b}0~ch*fjNp#95KvPc2mXfzp=^Y(DU4G`#Jhu=aYai zS!8r|!Q0umh`|WmcrineQ6d3Ytg!2BAzW)2vz4x{WKpduWP<;+#6*?WX8b-68(M-c zx2t);!VJNX7(=phmxg}J71)5AGuf*6@LggXqVu<2F;w8L3~d97_e`gc_?8|;BW7Tl zWlhd;NEP9|C+ub_Rpt3K8i7uu1pR9Su);mM_LuDq>T}!Iu9Vu@We%*ppm6t0(Gen= zPJbelkr$IVR*`8xwKx2H)SlqY>8sVXL|v~7bRVo9v(tfZVP`q^@RD4-noZ0_%1Otk zjZ4Sb_?d6rK=`rBexjXN_BWKg*Tp}7O#Vta=Es@e&Q}QXpo(Jon0iwU^VR!pLLSX= zd|Y))F6$JE3U;=)wg!F+)F4#EPo?deelr>&m{q0#mKRP~-^iW@o?kYD{{0WmJ4fMl zVz7weGa(+3pFgi+pC~85U|4OBP=G)%E>D%HFvfA%e>^tDml2Yc%+2%a^x^oEJGZXa zcy6%Qf#Eksp#_`zm#0IiH>eNkK3`L%OA%`H54;`&e<)#qa{lj?jN5{29Ri`#RM;NW z_qM>wX$6&p_0OHGkQR+Zw1uW6LaazibpNn)CZmV8-F!o>$pAQV8r8jg7Q{r09`edc z?#&DmN)Kz<X242mt1)gc}_W5!0Dmq+zy$IDbE)EA$*foc_imV2^NrLAxWyTV7>s?`6#DS!PcJ(7=D=+%I zPW}-A>RrWP@;wYgnYn*{uyffu7IVaR=eTUkF4p9tMNUt1lxMc~tSz?~(P=|1Aq9@v z{DuiZ3xVPZ4KaG<$;}jUdeuf5HZFnB!ahUd^>KpY{Rqn$Km@_a!Ywg4pNf1mE<4v5 zK4p#*l@@W6ben^j5)x%lTXKZjv}$Ln8WGYW5OYf<`QWwFZBb2D?y=cS$PCNZgos`9>?}<-1WV)suq*P;Oa&0 z-xmPQk~5zy&I#eJIZF5qI!2g?CU?1j4@}Z_Wh6=jTGX}jBaU!z)IhC*;V@DCf>jvM z5+#$?$^6?X+Y>YsBr4dE)do%1O-nO4m=n6gpZUZqeR6REX4jHSTTEU1WG09g3XST} zV@)vN`F}chsx*GXt1W8YV+us(hLl&K@FU0BRCv)#8Qe%w$-amS^lrWx&{cN4?d29e z%qpu)5|#Yn6dS%zhgHc-HD{zQ@rVQidm}EHC8eKgKio2T z20uRUmT|ilueHa|s2|2;!sDl}`RpQNUfUYyp(4CpNiG#Q@Y*{?>qu@M+^ywH1^T^3 zAiU%FE2l%D`|KWZBJ*RX#Fs@nT%GU0SG3()tZi(TF^`sn!g}5h`DUzh6Be$L%=dgm zbCEX=tS>FsH|CdTR@T>-n>so;r)KNtFQ9Km^?Y2;6N<4wUxQT0Lq=-o_L{l{-<7uuQm7+9IDEeGPyKNk*vY zY$}F#a5qiOXzMNu&gg>0V7IlzJ_k#s_)Fl+OtM^LI6sniv>3ZbRAj!6Q`!aWeyRTS z;xV3%2f|>R21ouEs6G3NDr|G7cow=iBZuUpTNqLKnU+G@hR9e+IYiB2!f)kA79L{V zy3&QW#r>z%OS+CMXr<@7>9Tcc)EoS3wrQS*y+NTdvoO(0LFC+pc}Lw#dIe?UhJm2> zg1RdGF>VQi(8=*@$lFa`t~0bYd)oKrah@GTHg!uIdsoi_qBI&*cK%tiD`b;B&8|Dv zk%WkDPAXP8s&Yf+SNSSvlhht*gy}`o4XSq%9%rJWvD!wASJ>)C{^oOG+M8I|_?1o0 z3{yw16DxPOq9g&ALUj@a>M*0ljX1bnavIJ)3J(H!*pb|w$@$AW)g)D7&~Zl> zb;xZ=^;9qiYxzD?wRP?rnUiD<;QDI5V^fc@pZ`)_vcN>jleb07AD8U&SVT2W6iDfN?_y?`BN@jjLN@dlpng<^OWvK=F;_oX*n5&T7iSBTC}iK* z1iiFkX$!N>uD_x+!(KPPC?K*A4jOqF<`-IBC8Gju`9?n?g4qOsP$xw+cbE&v;(i7i zZL0m?yHtM3O|S?LbN=InO9~J1yDd}%WJrX zKDgzWlc^+;w$zudq{CkwCsM-?&|9(uCMNg2bk_|uFCrkXE9({MlDN#cx3qdH^v(wk4v?M za4d84<>kL&jrALHm}QM3U)bZe1Vze{=~ zkwzWh23OpL(}kK)m92d5Ji9)tXYVXcs!7!x9X!e;$5&i3noKyHLFZ!+sGp(K;fCM; z$ypbdc4~J!>(!kjM4esCde`aVmZFz`IW-F8DbS7h_QKG)X6YU4Q`;+DGi7xr?EZ=L z*Gb8@NQA0H1P~BaS`ZND|Gy_C|6ewo`!1h7^HQWW{HsEPkk25?*v<_c2B?kAb@XtZ z8llrBbkGmxZjFSUD=0h-Vj;-Y;1Ygp(=7Tc&_LNwPW>4RnZV!b2bEkL|9V!p2- z^BtO;OEwQoHHh-y_j6-cMCDk8^Zh#p7r`hS9r+loNieHD1#uEnmLA`984_O5?CD9# zC>qeQa;`Q&f%`riNRu_-gVLbHyiS~@uHKJ5K!s|Fu4aS)u%NR!k^?B%E)ry4P2sH$ zK=w0OIpl;m!Nhahmn%em0}63`34Mr5KWe61*i&l`>N$%e?Ul0qo){tqEapa0G9P>< z3{1tVcJP4zgqMp83;S50t{j3Oygwg|E5zaqba^e9u+T#q8aiHjK2Kvi-6hef1boSJ z@}Z{fgt4QjG)Bq4QIq!=87*`HwUIq(9?yJ9ES2R*my0d3=oLdi@m{IA(^#j{r(UHf zg9a6iqB9I3nhxir7iD*&Yep5kd^qX|Qf-TnJ=g2zeaQ|o8Pf^n&nO|qJmO;mw!H>( zDgo~Zx=5s3ZOWb32g5QaU8!}#ZRKHh`4j-s_Y(17Y?NyG!E{gerxpmSU>xQ(0U?ge zHa$RF9Z?NZpCOvY5b?3XUN=$;TGJ&CxZZsGc$wOu7=c`(IUCH7_sU6*nbjxaiGR3q zGS57$G^;Nsy9oGMvFXURTKlm5yu#EOMO|%(DMdC%6N)8SR($sNaCb2XRn=sx}H9@b(>50e4@3aI6M&O3i1^pbeu z3dw2CC4tT5(m@p!pi6&7uKqADNV?8W#<-d=$b=U=-^`wVwm4fnfpn1!gFG<|lUqwi zNZ-etN-+6+!-_6#k7m1Yr3PHC0V}`aSOfYb#35QavTm@u6F3n}+v9bN^*eSXONB|V z=UusW1}a!h%7Fp9fhyF-Z$&NXR(>HJT-e3MyEZtiIGi*4?v&d?W<83#F#{pGMhNr2 zcVANO**C~^6FCxWl@(bH)2Txptne!+f_NNa;hi3D&J?WIj#9TgT7X2qot5{C=7^o< z!VZh^iLXLoF9%-T?We`bxM0Q`aCICz#e@2x(D|u&l6X=cmHLQeGvasy!)-3qpN!sM z0_$y>i)4+$6x5A-DoV6h@mM}ow)@=UYS%JR&VbJGM&XfRJycmq9L2LHq&`9R`)~UN z`0L1oz&=>t81c^fL&Cf}bnfrl&f^Y(Tn9BB>C@a$5zDVCSs4;#pQS*sAet)&-tuiU z-u1DbJoFDR-{ZF5@a@i-1<&)_Wz!lEgnekZgp_w#U^lS7(UjcG_HtNr$9#*s%a~Bb%Cq70Cr1h)L506DGyy+rc zn57Y#9|7){j~E~N!0)W*&D$u4ah2~1+u~2mw427#BQ-d@@iI!rY%LS8Z`3~3+h+Lq zvzs(;Lf^&=A{ydD^idZkwZgvOdjMhtrq60Hd;(MX#xWPbfeg7B*>xkov2V14H@Ab_ zG{*5ol!ftMGT+aW`eK8^N<|7l@&*JjL-?OXtp8-q>m&wW|&vRj6zn)l4fD6dAfN0YcsUm$DWY+739pWobCxri^ zb*39l(%8YNsylMlT%%2UC1j1C$(G6JyDDBbvd!9bUmuId$ajfYn1u-P8@R45tNv|% ziwo}LORy!mVB?@cADeBsP2tfH9qn_46p_0EnAGLG^^Inr2r?VKS$T^R!8;mfIi}dF z7F7)5K$TkBg|Ts(K3civPC2$!b5F?_Top57tJ%xc$0A2^q+c{r?pPW}xlHoz$Q$ME z@Pw_UwK?a6YI_;LQlM?JXv}81@gRbyX^&z!R5-slJ&Sg2Jhxe&UT9}s8J0d?{ESnA zEV3%Z)hESWE-Te_*RHSVuu*qYx6+oESAX2dS)blmAjpd7Ohl~N+~OTJqIRKP5mm20 zMv}28r;Ti!n=2?yeQ9;69mhj>q+`X+4{p?+R&5MTtUA3@dQX`bJ&m06L)Oc$z|a-8 zizkX&C-R2jInbaVl+LhkRTnbeOft&zvWK@nO_~dZ+I?AZ@fkh%9=5|)h{D?KEF|2< zp(2NcL2fQUxs%t}`^=BQLq^@%g>7C49XSnyxfsa{g-&jvvGP4!TG2*vIG?yvVl6ys z>fZVr_m+urnuBE8`T_#WyqM_Ah)v4AL}Row_Jj|uZRqd3KwJ}OD~hm;vcLsU(zT2F zUcZ+(1{%Ym9)B?yj6O8!wMxwT#J;<*%PD1tY6GiP`qS^Gdwaed%rJ_GIqzL}&Ai;U z?{_U#9xTg!n&kDZQD;&sl>5(B5ze?emD94xY-!pZvhl~&>mycc*P_bQq~{-N)WKS# zMJmx3H=I~mbZE$ydh}T4cMQO`29^-9#~XN8M}-&#Bqr@94t8rQK#R+mi8UXl6MAB`GLa*4U%2(zx}{aA6sCI%fLxzK%JZ5__t z?$cnPh36vilf&dB9IDb>>()-m?alTqzu=E>+lN_C9q_Do_Z_CZ&Z9$QL?9d-f!w$O z1v>DOVUt&u2zbJZ$81Hd!MVA>6VZY)-u9vRJXL@Yx-~ta`>K;XX-8R_PsLSv;%KK_ zeS0kAKF=9c-?1v2`axInR&p(Kaev&lxG(g~^+ADjO^3=Iy*V(55?y2HAmAd9J)GJ@ z(6`BIB)^;6`|3sgOJ6^cuZKGX3yf~q=^XxUU4D0l&hNw^1#>MH!BLgoM7*}WeXK7( zn7+DpzDQH+EW_WS;)$M~e9d>~`Cx7Qi@5zWtMdUN^9-uigqr2pj15BD3_6yc-9xRP;zZ9dedT;n;Uzp#QbZBAr#`&T=TRy1oaJ)w9C{g_U^>v%(?917^OJ zNhca>klx}U>T?gPmp!G8?7y!nQ%8E~&c)cm1BLA}ViwiDJX-pRjSw~61bXH=D{S%| z)djJHe@HaBRe6^=0)i+6lQ+O%xL}vZ0k>jJD9SXZz{a2uwY%DJdhni5FiGYJ0qGaZ8(9%hb6uRF|&%VF>~+Y}c3hwVZWH zH@mW8w;4WXqH^DV*(4@w-&E)P*&O!%S^EF?n?y-bcOz>TCkxmA!ADd!stXp#gdS}7 zc1p7&eB_M9NlA?utkx?hmr%SImq8>kyVJn^1j3(`CU-AGly#Xk`FIcMM?eN6gRK+H zx|9e#QP3)#WX$X`$mMDNPOpU1>b_SFggb7uXSYykR^yjTYDgo<6>_UODLZmjSk@qC zGOD$9pHy_Bz1Cr`GpJ2K|7b+x>^JCIJ}A(Ftf^dM#AZqZB4hR()M8&j{T0p9uOvrg zFc6STWDpRIzX8qv3x<%3g|)GX<3E|KtB=d!F(VVsrhr&b7X=HMTf}Y~mz^M}l!@YF z(uu|&u(GTPog76Ofus>=$F=~wcMKI5tdDRk6vP2F;TQ#^_$G5qZ zE50i*6xsu_#ojsA3lh-uUDQ1kQp^Is(=1If97`3Q`nkEd#k#^;;;Q!$qf=~PCjz$Y zmrjVzDz%Q}*^iQuj&E4R^W3eG2G*Hp$aG=Gtt!jSuHd9m83~0oXR%v9kMw&RS{MS$ zbrTaJe#%ZpKfJA}rto0>hK(n#YY@l|Hz(|kP4a&!!BghQkWL}En;aOO$YLx;M?;62 z2*nUu;$Di(Z|^(0%@{_Uw@+u4l+o43eCvP&20Ksg%etZ*(qD6ysZow?UUDBW(lSgk zcm}+95+MuVJnOmr$b~<-JkR%VjGJ|cV5GG%Z?(jlHkAy~YmMBp8u3~gJL~?C!L#Vu zdpotWz*FH%K4guopBlTByt};VbuWrVknFGGPvcN5*0nZ;WIH!xO&m*v@4_zmaMA4O z|3I)UFSqrgNiQQwv)V{R9P~MDvn->(xqZFvKpH7Q6n>sr_b3-m67NbHv86f@1c$!( zzKhoqd*R6hy=BahBD}zFUG;^@@Sbmxd{VSZ`=U-LWg;lsw^hbTyf0p*&t3q`P zXLA`7TQg_#e+n@>mJb$;8Ci_-L$vN1TT6Bq!q^6kHXuJGL3YP>!5VD2)tv(lX)CY) zxUm`AooLJ}_D2_yJctG`NI14vFc^}jKq;)0fjni<2s4A?NfmEW-SwxR{2sTLvQ(G*FYCCtU6YwMA5x7GDg0!53N-(<{?Q2EKS;{F`@@ z;t@~ahnGX4Em#I|*U;}tfDHJ*+znI|W8+`-hYBw!2#Dt2Ku5~X!WLlo-wd*<6qpf# zOz_S>k(b;dW%QQP${ElxRP#}3rB)S+3Yn!UV7mu@eQ`$z$}o{aj+QidxjpRu==kyr zwHOr=tUdtu%w;-$Xh#E3L?AZDwg+4w!ZyjKkqaMoD6wfQQqpFtX3J6k)2VYBXN^?F z2owf=|5d5hB~+mkY@v7i9r%Rgdi=be{9ccSJclpz%OmIQE0Or#O3eKo`JJAwdL$nd z2GbtybqP2TDF6tq_g6;YGgC8>f7s0ZSz3PsBUym0G2qXyfBYLHo_o7Ren?12G)Pxh zND8r#xV<->_xicLgg27+y+-HvyE$I(!?(4yH{PM0eD|-ktz^vHtCXyg0#xin%bWt_ z?BW8fjN}c_rR1yv@|&}q%#7qHr5!V9#3K{GfWN=SC2ORV<|d}4R$t~OK_nTN85kMc z6Zi4UAHH?&ppxDCA26{nePO2kf(`O7FC^mEbe9|c6S~shBolf2e|!S0|BXO)9CHlt zJG|&;EgS%gj0;l5_NY1FI|`@}Slzj$glWMqV|-aKRP}-_5PVpG`Oo57Ywyv?k8T}# zGmtNhU~}kd%!kfQ4g)zmpGiu)RC~N;oOJKGDiu;g9h%K~MRnU*Xhzgdk_RSaM&i@? zt!6d_CD>cac^&gmvT7Ykn3+{?uJ{0SBY^lu9KzozB?uA3O1Kjj5kWatene;ZrDMpzs}6g~b)LNH%6#)d@LP&y`j z%Mu;mPnZ~=>S)Bah0u)n?7RoGD~`gO+mR~Pt!(io|zla%fyiMNe1K*=E$!4 zIFhd{^Uhk_aM6s{y7k_g3t;2S77@BeLKg0 zK&|`%X7x7!`#-qOkR2x|*T;k`+C$A&B;m&;+Hn)2tFGElQVKp7;j+IJ=y1A}U{vnN zj`faI!AALz>%&>CgeRMfr?}Ry>tICgC z4K901u>RP>(6r5BA@*k8xZYW2=NC~jK@D*~RLOgw-EAz|`8sMpV&8?r(_3YqA)uDY zX3#o={%M?F-+#rH&frm*v=CPlEcdZv?^QvKO>I3S zg_tUCR%nGY;&bQQOZc)J=MV6EKv0S^!_G%w>np7|#BM40m(w3-{m}sNAKE=%{+1U3 zNUAB>**OaVoJ@@Wr)ITDxmT*62|2rRrCl4zXV3#StOcWYT{*A5RuqXuVkL&zD&u>` zh5i$gPoOxGkKgB3P1vl`GKSqL2eN6x&{$_`x|dg1*Oy;7_`ysD_Nl80HB65S*KdN3 z;USaOnp#epZJswuj5j4BCSLv?t|oAEI_W~(u!;*;Po{vX+z8l6cW=I`WQM8W+Q}_< zYPA3>09me?G!Q3>?4_+&c?Di?a2OMR$0|`kNe(@IFn1(cfP0x@-A)o{W1i0BzRo;g z{7zQpHu9TaLLl}t#iByOsz@xSWqH_KmYJ7fwB01NbmXzuERDt@sD|MF?Urb5!fiD& zlD|=mZL8(TnspoW3#8{%rC)a+C^$$J0*|M}Q`{72)Dgam``q?41>zOLUlUY=Iy?A} z1oi$&kn!JED&IsoA(76B_)&hS3`%pVo;Z&s%qAPa8DTM;A=Z( zZ3OVxL#EJifw*nagh`^$k+>Gs8INno-yVz)5$W4qg4jcfqugPyNvdCAjBN3yB1O

    nE}9psGl=&!jW?AbpVP_P9`vfS$cTjhsE4FT=HPyTe!#(J z9FVdnt=ws_mgEY|12Q$ZOQrUXQmqS#*4N&|b151_`m!v3JQ?G)Z;Hb7D2}G}p2mN;P~(500BV$ze!g5PiKwpdB0f2`2&yf>u&KD6;*5U;zWb<8IlYBUujDe|XELxF%SlPoI&@kwOGU^^I-56bWk$qK>))cG9&~dd zAC7jm94lJU6|<=-YEqfdYVpfZJt8n4J*@qMg8e>XDVqS69m%kX4{uI$kPtF>hgZFL ze+|A2lHqjpPtg8{yK@0V`@aNHr4G|YN_$XIBis3=(0 zGOVgHxMt;&lM;KDbi96{EDMOTYjvKI@A^F_zTQOtDA+8*L;jH(vvLs}6f_Iu$@y&I zE(9)Xh3W-AP9s}FYx60~C}w{vDJmci(-G6`OG{px=E=%bT@{omdzNI~iuQ z`W%+sXw6tR)d_|;L2E$1sd4CRhrN05`e|;xo{?EOL5|164Ao9nc z*4Wd?xH$hv&|n#FB1sAbDpY|o$Fs)Q%0m|ts{)Pi z+TV;~EXsyy<#mWf%0a;dHjS&~?&lLQd25G;?Cu(seM1;RqH+}1QT9_gq{p_05P)5K z%PhIM@QFJrHR1FT5$@!Ns5-d=TO0uWZ#+-hy&CcBHC)!{U0VcMo%?AL-fW_VZ`FY0 zsi-8+V$>;=3_QS2`*Xs;#elgd9LzWMi4| znnG~!{(?MZVFe|upJTweeunw0y!>sBR0{vdi}&xB7t8-6FKIh8X5sK=)OspE+s_b%|XTC0bYE-EHbfREv@qJ=0`|zUc zsCVz2k{<8RH;7-DgyiPPH$c@L8I0cfe0SvtB~4~m)%~;Ii#5yNVC&sePs6!XOgj&Y zN1$y=+7BpKH0xeheQwwUBd7S{&6Kb$r0WE@0aU%H0Qy1dY}#nlfwi7AiJE@Fs^a!I zL6nr{rg=c<6n-TUnwAk_N`Ck$4yq1m7`&E%G<<_C}U5%ZrOp-{I#^)B3L8VwdnRqm$Nvti|Rv}v@2+@51%y{f+6Am9oy!ehE;TNKX zuHs`|PW$DP20=V{nflWm{p;MpyX%Kt{;IqN>xPWKgj4QlSZe;I4crB#-+KL{iDHPq zT@$ST)Wp1stljK)Wbe#aTqt2(bLH+)@$VLn8f2~H5h~<<0Xj7CK!3QEB|Njph8XJ> z)K6GM^zbhMv^}A$h6~YDQ&JMD9={ewcC%Y9$0yFtT8MJ_zqp5WV8X)Z5XnE~+%<4* ze^Bk^&2{3*Q`BupBrX~wux$5S&&3I(D!Q>E8uuq7st8G|RQ~v!s^+UzFtm5;&)JHf zBHqNkh#Lih^<_-M>~cksJv#aDqnGW)y18_x0f_M`8eMaRGK^&CcWh{@>Jj_YymR_b z8F8d^1C|W94u1jDVIwr04f;%|77%{Y70({g_uYxi`2Pk++WXxvpK#3R%^bCdR_3{P zIjm^4&Li{uRXPdLV)fyBu$FO0xbc%m#?ASGd52AdsyikM>Wzx}G%@)%oe{;6)l zlTm_bVtF0^P{38RDVrX>`wK`PQgUl00_7$%ttLBND6lYsr6^zQlV1$=7%{u3MX@eX zSSI6;NTXD!2E(Y)k300=E;Y9QEI+F2u4t<0A99(lE8FNwKj}r2BA_i2zJ2_pD#MU~1y8_~1l3mI zO6Sf-lrtR}D}=N2LiPr+>x|1(G1=Z(dAwrx^QKV7OK43QP1dC4_MG^5*mQf~zg>(J z_yD&@EDj+Ki8$trBCrtiF-Xg721rj*y+nsx>cR%TlFgFyFI zzoHF2M%{FKy<~-;_fhXpKX|Vuhv0a!oRB09-V_u!km?+#CjgwMud~d<0bH!Up~R|W zL*GJ}Czt~iXI5F-iF?f4<8TZ@f}cl(>qz0%-J2C7!G;>(a4E1&+glhp2^JIl5n~(( zEbteYhT}Fus}_h7~{2dt!e%5o2lXQrEWY}jLgde==QC!8WCS}*iOGx%? zcu4VayXiHk{Y*I|`ctr-oCKiZs2mM}*1Yv&G#`GJ-VQK=!p_{*?$)d9#cA;i@-A?o`!heTPbeRWa@EfoqU}?XxT4jhrA=$A+o+Vf@)I>c z!^&oUfk7*oLF<3f_D<22wOzMpDz?pvZM$OIwrwXBt=MKo72DQ|ZEFRUq+&bS?|)kR z_i5kP_TSFM{?65$*YoLZj6TNGd!Kr5J7-M+0S>!=`~sAWPI-5^*vG~9DR}zKFTE~Z zAN^)Jo^moiAD7s{H0SC#mXiSj@_tGG>Wx!~M1x`8{uc0`vzv5zD>* zl7qAbpn`}^4K3|1<8PMMT!Gbvl z0l6Wo+%WcIsjh9b7~+%1#6wL|G;^{FZjovJX-JoRz*zwI@-(u(G8@qVX(*J`OO1uf z?RGO%(8S39`@}g%EN(5Ha6sYVPWe@ZA&>_lWoj8eYIqgK%gst{P;rXXZHT>$diwtL zH8UdFxLV~<4v^?T~b&&Q$fOBD$1o5;+rAHY5=BxpC*37-PeWxh`bz0nv z-=8&a85_Z4o|dFb!8gx|e)ioX=UZve=0 z*HOv%iO*>3zp`SWG(V+zE)f7`WQ-=kq#{Zb3m6OAfuU|GBBjKzuUS-T=fZzVP)s__ zF4=&k?4b=aNv4MCE4}NBDt#t?QVs@cVt8r{?6m2u!)&G6>FK6fVhs$&6@}FU#BErM zrB4{8_IIeaw(o_;Jh(<;V{~GuwsANXl+^W~Gz%cpf*08Ml^Jx`= z$>!T)Sr#hi|HZN_ss}@|UaHSuRro;yPtZTZp7LZ^OuXXL)VN~dhS5EBFFq(v*ZUXT zUc3oVI>ok$tBn=C$4MAiWnHRaoMBz6P)I}+R>82w*Q2+!v=-x#1xHCRN924xv^52= z7m+l$7^JeFug~J->d3_E>|b~M7ULXyA{(hRr;Ru4uJQr}Kb+~{J2!&n)66n_Q6s;> zQ^~&go^^J1wF=b7$j#!ScqUib?jiToF)El%Y?(J3v&R-5A$|%yAg?oeEj*=nFOJ~7 zmh#YqDx}6hW<%W^#z&#kkIf59BOycOgQZ|)z;Br|uVbFOaC|HPOhB{0IVn?uJaTBV z(3fM|i%{0j7Xo{8sX$GL9xcgALaWgk&%_^u2mlCKCY;w)=$kdv%W1dA%Jt48up1YE z`8jt05?sc!Iw3G?`$u_WU%-RW;2Sh1U5xpz>K{`FpSGsB0#r}=1-a0VH==%P&0EbN z)2?*HS^_TgnV;Pua`M>YVyBZNj4`M}_%|MQ0ZA9^ER|i*rWfAj>4Zb!N`p zu>KOAY!*uCb*79`{@@OCFWz|!vlA;+=(V1+!rUz@Jz9@!V*Ee{1r*vwX^-Y=q#Qyi zpn1M}!s@tp4Q!pQwRv1M%$;k)IFK z()<~`cn$%~Vki=nQDR>9<8%-rjZi8{6*cxH)B05h?jZTOv;n$!lwyfB+F_ntkqB12 z*smnG0EdEwAi1!blqA=baK#cMoJ*hj+g(*}=-oee(j}YH z6UD$ap4Jg{py_n)Co(GxDDHp|a^w_=QzM1QWThS^C}WSf%-P}(mh@8ialLZu1p@r) zJ|EKV?D-HUl^v8f8Z+%XsxVn<^8yUrO#ic5 zxE;mHH2Vyckms?1em|uVx6INTtf~^-O_(848&C2&>3E7^5qNj}uSuU19DmV?dUM5u|Q4 zsE_)I&Y}b1YQJvq>I+?$jqYxw^Cj8Thj&NKo8)VjH*Pipr0qqqAyv*y;sZ`d4^>S9 zTSk#F1kbvyGR#NH1nb!tA4kVIe$vxx-4%HHbEY@nKgVnd9o=qmGrkeiBBuConB20? z!=V4$SbLGlD1pF?Nq@TxccewS5n@JM2e*t_31-t@PjQye^%fEzcr0l96ls=>jkK}f zG!g9B4UAe!(mG6Z1vb&8i-=6bI)-|h)Z7kP)mt2@s7#eFV~5>wG>Q`mv~AB7AAj;b z^hbcC92D*7$8e#$5@x?(@X=!`F`fiS1YDBqS~#=$I|{ACWBwQyRtQlyUH{0rjEUl# zd37Eow^ORCm?`%0cf1Q1{cSp~`l}&Ej(q#~jbRT*6dv)s9E74QLhj5meO^(ydZpGf zQQW-`j40_k#(paTrp*qv;?7WRD2aTdN*|@Z-spB{`H{;ET(pk!4+xd_0V>B zV~IS4b4@>ah+a{xkwmJ#Pl)IFn$`bVm#EZ4!%bxnYBr{~i$ zq;8AqVK3Lk6h~+4)UaTpiq=+ZNhI%&Uu@D)dETfkSf`ui2XQ|6SSuFLbNypSMdaI@Rr!C!dj$I7My0hPCLh=KdTqx_7Cl5gH)+KGj~y1Lo; zwml188AV-jy$=eEE%wBxU0U-2QN3yOC0CQty<`FGJxD}3dK+AhMOXYWu{)^}%(SnCP1Z;7 zcJm2XA459k_oWQJ67xzHJhPFKE7_}l3DZt5pEFmTprrl%5%aCsu7M0D+OB1ArZOv>s-+ zroUhqb4D0yI9o0hML;MdY*F0@Y*e~q5!zPg4Vy&-f?@vw!d& zT&!*FW!*mecS1G~IO$}z<6zilcI_KHd^Q2}jwibG8@#%s>T`1lG_tSN^@kNkjd;1S z%xT%xKmw&fs!3$Jranc=T=S+Fqb2lYi{G@ksQGUfJU7MCe4;yPd+NvO1E=Ir4yKt( zZ&y$Q`D25GB7+#;?@&K$u7!uWB5oXUu8P0#M!t{^oVEnT)u0tpCK+oTY)#c&1uYT8 ze4wLh(pl)y2bFtir|ji$>5NSP*0zl_SA=@0qQsLC+;OA%H|3`d9E)(@_Z!T;8Ki!) zGene$N@0vop8fNpV-vBO4SZ1-AC9kYinEc>%$(qtck4t}jfy)78$vF?h|9uZ<5QW` zX*ww};nQhm+g+Lv(4#NoVipod7#@7uwcrUzsmX1tlC&9WvIjEN4U@X~t=)xBenSLc95u)mn zET9o_!Vu5Rm9=~2RX&x$$iIqyK$J2wRh$b^sx8QN17F!1$)zKXLwSPvd!Zr=JZFmJ zvCOurpF+$|o{e2Qw?&=bamr(Kqjv76ZgyR|v zjxgtqT8J`NseFpT=CGa}$G$`BWS$hkB9t9{mWA7j!ssepP91hc-Ow!tub1v*McPc; z2=hKoHt>RvK2()pz)nJJ!+hvk*0X^LZ)3tDz*JoHmBpZ$uB(y4Z(L*pWRUE9CNTF_ zzF1Dc)S**vZ7|*J+TmbUbC0Z2p0!ESX6OjhZjcs`>FK3`G(U>Ga8%_g>&jED@50QH zFQ}c|Gz49Qm}y? zU+VF3ih_`z19}`U30SRO4QKe zQKXZ0yuV51T4-Xe|Ef@soBK)7+s%#MwPPoB(TH!gs=?r@$wshk?4dNx&ll$21@x)4CIh2-6yXBuF`@PGD-(Co~G(ODWdD zbzl91iC}-)xrhDU0B^zm1S%Nb{zMj#TSzjdoR9P&{oO*Wd%JeFH8=y$`A-ks-K|3T z8C<7F;@vFby$f<%RXuXtmg63JPs*l(e%5OT()U=oj<|hz{qYNp zb~J7`KZMJn?X8_qm>bkKlmi*UL(j~ZpT`{m-C80k)P zC&yBhcP{isQga-^b#Wy4^7k&zpHO$r@T#!eihbfyB?P`^4setAR6Q-NLu;XrpQ*E5 zmSS#Gk5~V?gNhLUZLtLn29{0_2B!5N-9i1UVq4eF4MPJrP*J9-Crl4v85=$XR%Q{u zU$hVklFpQ+=SQLRH&zAFY_9ELbBvfhEPA?VSh{HLAB9F9l6rPlghG6uuzB;p_PlNc z$1S}ksi+q1t!4R7^DSq6cAtE9&PqQ%c8vm|=3-gDQ6jztEY#BzUyrK}9r5G2LqQZ( z8Q>GA4;jpl!RbDX8SW-hFJ1AW!nS!yfBsm*LjNd)C4!SFnyjhu8WlAO`cBqASZ_T? z@YFeI$a?bkFGD8#$-_#IbNelA!VvvOGILnhYxBtyhD%hKz_6N2yA5IdjF z-z89t+ITI=6lXmnwC?>*uWg9V9Kh3A2q)EC`JXbuyQwLlIVVpYp(<5?aDI^>(?CU* zthpW8CDW{*e1KMgsYVmtzqGjBfx=>|v8a|~{b5n`4YK{@h@~NICY;0;<-dO}pT>B~ zk*ZL^5U1i+o+B%fote4PoZp5Ox$0381Npw$;bF`70cq>m8Cv`Akn@zQ;U%8x+7gybav zHQh=ruGF3gYZ5j#-F9O9`9;B^h_Q3AO%#+OM%*tiWe#gGR=8o`oSNAi(x{Lt%kD73 z+`W~E4lUulJvV-)mx%m;5mWkBNv2?}ZuJU|Rv~>%_$2h#)VEhM)REhn> zz1UKbqpKOwgd%CECW!g@1)Wzi$$cCcz$z_u-C(MPUCAK;qS(+j>O;&R#x z5+=ixWS+xCium-uPpH+;#_m|+a#gvM98fBp;vFefTf)eb?o$HA8-!L_<_4`WnZ8}+ zs2{SQa+SVAHM8)j-sFj`Wq(A8dwnFlmPW*3Y$>v55LJ7=^s z5Y2|UpRJztD34l@sGXBdT$y5(@l>|{&=~g9>CO~u(e_k6e`$f0mwE6$m&(4@KvUi$ zsdLEpuk5|UAq0VanQpmFR#>acTPnBGUAZ3ks^L3=C|W4j4Mx@tAVe%ODhhR_^vs81hlV_cV$CTfsUT^^ znRjDOVgV;<;AFlU2`3(A{X;E3@y5p$oXS<*cjC{wKP(kZXF!acXmS{7Kha${XaP-r zLUxQi5niz^#_9_FcRJg5wRAtU5F}f4uMIWfjz8;a4V4vM3ido6$b{4jnrZC$%A94) z?p!6guJ&Z%rzQN0ie5NK8EOmGxx=gIvS+PgCFj!!3hdwurlZ{m)PI-*k78@*K`)|d z^F_~EA_DO58MIJ}W;634gZK(F1o|eN9U|^weU|DFANFXz*3nmhs;)5${GpvA?#ZXoOgga2$GDz=z&a1%Cz|(pW}f1Co`&`_lI*YFp_~KmZ5qbkF(eO zYUtWBEid`))cAa_Gmq7db3YVob!72}oFa{RCpms2S0tOWbTe(@EbZE29OM!D1cH_P z`rm44cgGy!c#0L%3agwB6TRlKTXi1VB7D<#~;pQOggX^A7eAc3K zs!6Ngt1Pe)>2#PS{00|2bD0H*D*UrXi+Dbt(8)O7Bz5hN1LzHLaa@rEWX=TOzDWmQ zAf_0|5jq_Z0bClH^&SlLYNPm$UbGugRECcX;?=wp2FX3Wew(o{Q27P-v^sD$4};HG z^GrJjIEx%f(;>kv%(40{K7?wVMcrop8T&3*c={tUnla-D8Hzzn*Uzr+?*`Yvy=c!4 z?1021O61oYPnC!j&mD;Z&kP7cHW5o&DN!4crPbg7nO=jlao0h<^yioLb0*08if*** zIks{oNh##=ycs@t;spF*>MOF66ugkYRjP$(czTsz%w2H<%oJ1j{ZJ(cuuZ_r8?L~d#?P6lMjz2u3R=SXV3+`&|JQR{jEKHW}!Ih zOcTOiYyZdk@!zs% z1v%gk)PT+AI2$#Gni?Z&k&>DSiR%^B#JxggM(yeoi3NA0ic{#6<~}(QG|cyJpENG$ zbbn4r8_#F-9(%I3v({(p+EBno*EEt$+MB!aj9}^S{T;X0x3H55cI^L*r}Xzxav&<4 z^S~v@5Wf6`kf?>k)0c+4EVkXtn7Er zHQVDys*LcS?e;F5`IT1Ns+HbF?gkAzz26Tt&z__Ubgi#3L2AGDz5Z~4q>Di7SyxsUHov&XC7xueLRN_67PJDA}*Bs-eG1>-G99jF1O zf!Si~Pm{Hc_G0UF6Ux(asaDn`9uxVomEQ(3GD3HSa(^6>?jn$*s}PaEg1;c{|4u2@^Ip9qv|W0i*QHE(?MqiTGrq zc-8&*!D*;?)x&9oM2I=*4Zr#|w52vCP0PC@L7lai76wbmfGQ}S1^upm^#_cUtB54rA#o~f}-IRDMX&Ot3 z9IQUjRzAY|t#d{aY#g_}?0>c?Y@#cZ`&OTwl*qmqJ%4feCH!E1Etls3Z3kCMT}0Pj zlD}S7fn&GMJ1s3CQgJrXq?QhSHF5l5O<$v zEYT@M9zO!N^@z$MGv-}iLh`X>$C?rRXhJ&8)s2XLMdeLw(?NbOXJg`YtWJ+2)Mabb zCCp^<*qna2{6bA;m6rhCA7Ph@dOc-AND^K0u;jr&Dm@bOU#s*41jvb!J4l8AW7*jl=$2QFH<&CVB6s*AP5vv$8)-|*38S;#gnMr z=xMuX?$f@99oPUark%09B{OC@LBj$b(jW4B$DMi3bTH(Yf*bCAn9o>&3Q5vz*;MAQ zC>La>-qA&YMhkqcncDdW+=%?it)spYlY5YX)YpFR!M45ybe|l*-;8fd{R(&4axuM; zgQ{@~frWI#VuP1dfH09=uQP_`y;+3rpEze`V@#Zdqt18hEa|agQTQDi*<~198&P99 zTi!Bz%+K^1=%zN1Hiv#!7W;a0xS8W#e3p-!@KyR`#X6CN= zaIG8kQ9DEkg}1x|BtRTa@`v$qOm6f>z?PhL5`uaP3r!cW4hxo4j&*EGHriDI^gA}Qt`9O_@IFwrGN&BZUa0^D70 zQ;B&@Nnh#S{*wg&9YJNfyd5j3-jK70^*$(}{s<2IF;$u4r{4i{{-jmirEf|7LHC%8 zx=Ru2((uIVu48E?xY5dm4^F*3` z8Hph0mM`|pO}x|89x@+6HE1Tj=l*Yni8rg-~o*S>1~ z?-45_;_HYX09Ae^uQe_{D93?({TF8r z{-^jBZ{BAIpwGhRW1pm1I9$W(=GA*Nhn?pGq&MRF`oZ(;!?Snj60dk?1X?P42)$ba z+=mdvpS}`|y(=9EdgOP%`aA=z^}@bdd#$D9J_e<4nGU-rciEZx0G=C1L{=&UzXtGB z4?plfHGmz9E}8EcJAB2q9GXF~=T`sPWs$gso#+1PuKoWR2lM~z;r^}CU<)pS8epb4 zTW%59&y*czbB-xet2#qPZ3FD|;^pet40pqNXP_qyC)tyV3XOxT-bVy>`&{oJPTk!5 zfwBCc7LQA`*1Dxy+|j7+bDd$IOrn>wqOSU@ro5l_88w}}+eDV##X-NewxmwRI&-VP zt{&yh-;+!VK6tKpARLG^xNq2}mw}E?ZWc#^v2grMLQtx*U)AymeAaWo#F_ZR5ZmyA zRQeia-6aBrF)% z9xfP|;eYTm{-3SP)7o%a1glt|#IVpq>?3Q5wE~&86;ELcf zIfx6=v4YtumXb>x3X6<#XRS7!&|XHT`>hQGlY0!5+c~8QPdy$_N5c0@Jx-Qj!9%Jc zv!}e$?7mliPdiUNU4r=^vmIsM^n-(B%8lC@ZOqBdWEZ%mq}lSK%rOPg*&B7lgpISj z7B+t}QYTO?C5=r-W1n%VMq{fyq}nc^FVB(pH0CGU+;}?~HZ4ED$3l_-`+a4Y(WmN7 zu*njvqlf1bdB_sRle%kclfrD*RR9~`IEyDechqq&bvd^4v_my+fWEHkE9}v8c+3kV z+ssR}zCwQe97iqyO)38o7Pf4389q~T^2XoduWp0>I^^BG=#~mxBZ%9L2c0#U6rjCo ziTL0gw?>;PQLgn`!aMn%r~NFK1Mq;4)6CzzvR2b>)xHh3NMq|z?jsK!Y3_~onT4Ht z%Nl;dKwu#!k-mLD*PRUiU*BL!E8IdfjoDNJ+9PrsYkZs7p{Dh2v%&)tAn>A%CHL#A z!FoGyW4n-9@`o_p{LuVQOTg0buIn3Ppnf!t3@l4?^}eF?Qe$_Tk>;rW{YD@`V%uQ$~HL$uV8U@mdt>y777`nH64ZGSVI1C=r%lu~aH~ zEHZ$OH)D|o%qwETzR%i)udXZVTK9@_L%O4@2bp=82@VY)m##e2K)`HPJ~hD$pck8r z*5A+-PK(l#UK8`93m(#^LtNbVrmQXb*aR4dwllVU@p`M{_GOSqJ3^0>r2gMitN<%_Dn%^6a`PslTh-LqL(rBC==(cm~7Dns}4MzQKubniI_Fn)7{A<9lG%X zo6}MuCtlxHb-ndN-f;(s2e#E zvLOEs+vS-PW#^MJA=w*1eb^Vi%%ue?Z13)h800l*eI?7 zVQoo}at(g+8l+w*X{-m2Y-m3YNk;i8yUl{Fy}pfhU9(^%vFc3He^A`tHnOS%GDrmm zZ-~1yNcWtDciH&!Pg+JL@d$8?I9Kw?WC=Xb;u0dQ-@!&4}PfG!DCzUtKN%rlSmX>sZ5hG5-XY^^rj~ zD1W(lwdWgl+#WTrP`HxXJw@DB`*l6UutW6fuXe$uzuYbJx?}J_1v|US3=Tv0%ec~H z&Jpa`7|r85LL<}~#TNeQM7<6(!>h@Y035X=I;MQGq28$*6@U5M8?&O?JoFA>!`703 zG!p}*GUPHBK=F6g%3t6^laGU`wDC5%#R3%@MS5)IC7jGB76&^#Efz}qHgHPwycsjD z{tB43ziJ7aBwqai2WK-`^j^mn)97}6<2Q`+Au`2{%Tg>0731qksavfv156oDE2|=t zlt%~8#G_5my%>(Zs;xMb_mnXj&CtRHy%bCno9A4f?6K8e>S=VPn5$;ET-#cQ`gNuW z__UJ=zxJ%q17)AaecCG%@TAhD2OHvky6R#}#<{%{_8FH?&Y-XgXm#5-{ic8C(@|2v zc96pznfG^mnY<4P4?WDrwAo$K4?^r#Opv5$`qYM#9X?oX2xI5xy zedL6H-Oc?d6;HD7gU_#IrjB>OXFy|`ZLbqe335W@*Zc>|L32ZR}89${o0wsB;Eid^7sC$v<0&k&4?%#}b~QbWjODWxQ)>gU&ef&Pzzc zy{#@7jP$Ld!3uv>eQ(A2nW2_HRD6`<6?XszkBWsbkT41k(On?45RN09-;!lXr~g8& zJq0mKyckzzA#y)H3_%*FVCMT9WNhI`*X$ttb192v{~3a}*^!#J-8U3@)2TEZ*F!k- zW6T}JH6|RKM0oEua_3D7Pae97(4FHD>9aSYngl*wrPRe&klGM4Q0l~w+Ln3GRvJAs zED&xqua9fwXOLM{SipndUoX$*R@q4p-P4|qb z8R)Gc`TF1a^j(#F%Eu{He$k7nIB}Of#31{ol(j_9ZCYxq96&2+-?;CWa0}{E9GS!Y zGcBukba`Q(H5PM7uem409q^x0ID;&T{D!O;pHBDwQ z8UKN-r0W`<;>K0f=jnSmB-~agZ~uv{jf{fje z-XCYU(AApcqD>nL`aO~`6e`?LVnK*Wj(-rmXJffD)y>VG6W|lz3q3bj8HEUJAVGPS zeznPU{^B?+T-u6)3Dv$rPQkeCR)5AJT0V|obM18bPG0L?fNrbO@W-GKLS$Mif5C)e zyDk+jbRY-k1CurML5J)$$$af>s$iek=1cxWIi7cmwwFsRP|qgql4Wbfs>rjOqvL+j z^H@I?GC?{VLlou}DeLS!jyM#gtb(S)pvz*y3i;J1QLF_iHZF=ciFi~fzwM;t&aw#` zbg6?JRC&HiaF<3qr%I3QIz~WnXnA_TVm`v^b1*gpP6~CqVuFgCdj99n3VHNn_RY`V z1baPYA%9D1Mbnd}*S*ROlos4uWIAQ<@fv-)d=fUK_;>y-R%X+ZhiUzv!%KntkHj(k zAEJo<_kD_nkr##p=9fZ_=cYS6?OeL)awM!xa%T~ZtS#08cyLL0sWJg(?zv*h@U-KY zqwkznU${{}Ou$@*`h7oWT?s^uc4gnnL2*NPlqg7@wcgS9cE$a)^Ko~z`wNT*Mh=Jy zECsFH8`wNMigA0=`AYEluGB2+9~Z5*OLY}7$2#3=>g*5hGHh8!nvaWM z0&$OV2WZCW7y6j`EXt{F>x34jL_d4iusRuYqYdu~($&VTGtDzEgnE~n?bW!7_HYx( z0Oa_kxTY}m54Qo0<1Uz^xFa-ws~H6nK-NWzQqGxCrqH9DQ*4Bn=q^(rNFc>2PL1w% zx?PbZ1CiW4ocb`^>Kpo?x)nGxo$v*1_bgEA>PA%ZmeI1#K$D`iqPnUHVQq_aZ~i*K!_9rRfD(Mzfs z{*|q^InN!529JBUREG6SBWWZmAS>WAr`O`F<63|{_{l{P2$O1FmwF)PFOGFF77_S_ z)EW~mdtnC1pgr4S94${Ktq{FDv;;qP2__Gv1avU%XdcG@26igwqOR&%(Nx}Ejap)h}Qa7#!mr*$SUjKXW;HCJA*fd92=OjWPb z2ensXj`+82LoHbaKZTS#(Jdlwx&Kn4UU;|p&TjSHEtbuk##x*dZJ5u|w*6+%+tzBT zA(%`7;iZ7q{%`TAxRVM~Dy(s*R=AeM8vfMMv_wO=1CkMoJdwL1KUj7!l1UsF(%SKW2H;XYY$41QLn6&vp&!Ra8sn=61Hov%;~>sHR2vLkPbaC>k8;a ztco}3A~w(!dDU1wT>GYBuTT7JxO-YW<=lDYe2$!}f1P_UCV9P`M2w_wi}nB5?rwg2 z#d)eVvw0+M0oUrj8B3?>(0u0aNLn*~eCzFr5DRy&3S`b3u%0(Y#+J?HuWtq>VJk;vmc%WVT;X{5C50-&Lz%Q zw^)l%O5DH@cMfhs^vH!KYeP&ZtF#Y$B@h`rp?nb5`2rLEt?cZ- z-OB zclbT*R;*@LhQE$Fo9MoKzS)LsoN7F}D~uTi)CYbj)*7(wy;*J18%6a^O|_)<)2@h< z#pLN{)^}Jw2cDOESs}QQY7(nO0cp>6VC39@-@r?t(UMM8G`s{fi z>}-QnIvcc>io>coM|IafxcI?24a(01TKTz#t3%9Xi9DvY@MF(jU-(a$+kcRM!Yaxmgqdq8SF^MyoN!#_j`4|?ofW*|zf z&HFoBYhDA%okLLeX0LVo1$#5K+8O*vQ4+650osV}B$sVW_4uW5ycwYp&2w&%&m4-X zs?3!534PST&vxLMV+kSAecHuT>|Q+ zoQ}{yxrMyqaIwjQ%T{`t60F zHlyUUvy^cRr6SC+Rbit=ze69%hui7po5G;?02>jpx?tn&Tk$W#7y$sggzzbP&A-;~rBFA*o$eEG4K%J?BW6l){X{&mrTAlMrrM_dRkF4u6-dsV^RFcP?I*^12%6+KmmjYiI6IYuL5 z7(Hwc=`=N%2wJCIA{iD{(AQ)Y4_03Y9dKb>Y!_GId%u}XR@IU*Zv?cMcKKj}L2g|Ate$o=G;Zek8|?8m%lf#TE*;@1Dd zgAfxoF@|v(^<>f4i@yXx07&Mj`+CKFFL;GEB|KpkXTN8iAsaCN{D|^#Pc($m!gQxU zDf@C3j_>l|=Ngaq?3_*f-0`1|$57d&Usfs(FcPFKHIi^MM+1Uiw1MPw8H<#;OCm0Z zI!_Wag%?DlnN4^h^#^PX>=Th?8{{ZFl>#5HIe`e6MtdOQT&`+aj32~8AySQ;8iC%e z37WTcca$M52KM2)uorL!7KS0${GZ_eS|Atjuh5vl!N8!Pz`!*B?+c{5tBIqVrIV|J zg{y|Ujs5>lHZnn9v%@D}U99l>dpYXsBaGdKF-HHpqAXb%Eb#JkcO&+_~ZF!;JGsvL9SjJ7~hd5AYKvA!R zUBZrv{GBqM&bkuCu$O9L;(eDIbEmM=ID*(*8&@2nM_h_m%c)Jmo@tR8S+be_5nD&< zkyqf0#VrVeyvo~@d7-yywMmd)oyZ&|LTSU(UA0>u1;1pISA)L@LoI7;qb|appJc(% z*Nt5+c=1yDP-&Uh#6v{!f6g?fxu_h2<(3}%`xZ0zC#ciqz*q0wR5d4cm{_8;D)jL)L;A8ss6e$_2h9Zo@1R`tJ#YpDf_huR5*7(a5L=yHWi8LxLMIhIae6*h|o zA-a*Uy)R)Kv~xFd%S9rp>FRv}Ch#s%NDtkUdU@dwNyov{8$zhFDw6#0h5t<^(MtuN zMDq_q&msSRK`7h*i%?8f%+F2)#4co4wC+79i6I?tYg2y+nXyW^@sKcs$7Oe`N$vAy z^9|Bxgm?bekSLT9tDw}IDf3VoT#N#lV@l41vR@BgU9sdR-Bu+^uISm6*)Pr%$!=Kb!==ZE7yutv71dgbWH|z_k&Gf zVu%=T`^wIY@`Jngk8t?LVJ5YaY1%o~;|FZeS8&uXXIrT=xRRP_DuHo@_?(@HVhYh( zQdp~^khm7O*f21!5MtD}20y(P@sBr!Ce8X5tUpSn^(H9j5%2grZs^hsj?|SV9g?Ed zeY0u^%z9{O_yFq*w~;X^3cVI_<1L02X6W4D@~qVc@rIE$Q!KHR3w^165(*Qy?!_Y# zx0eXa-d{rr{6tY(7#Di&7<*j6nPoo|)|f6twbThu$#U}bt4Q-0_(>L`JU^rum9wkQ zmxEqtJr5QESTxhv!WGRZG@;qCv(cuxl^{N+hsFzct~gFv^Y^r<7LVqw)X%&N81Jci zj}~U8Aq)o9Gt~fYXd00o{_+NXiDZz3yCSJ+6(`>Hwg&9%4TN^%60da zeyCd@EZvn!qv}!CU6#(F7?(z74iNcZj~JfEyf5F8VZGWlw zp;V3WzSF;nn1>U&v2g1pPkayvSD5H_UxOMaMG?W003|?KBLu5>fb*}|1YN7PzJ3D( zTZH_NLm%W zTE^QM_g2~VGKYujRU-R*vBFB?x}oaTUrO@R&h0yS?R~IpWKry&uBf@wLK)Mna~&++ za+WFNp``zc7z$b>K}|IARkN{Z!=0F3;Ri%3i84);`(_Su07YpWtSIPTleVxxt&tWJ z*WK&Ws)%uLV9-fgUA@;*DrM~TwPyt z88i9FLURXfYP6b*JNOx!h_&qXqfCFCfg*7xH>R!uNwS|4G>jN1ckScKY}p{2yCQu% zc?T%p%>i)W<|NV61|Wv7lIe0UKeP)`F6Aw!h4Z04@{I%2uN1hKV2hV*h-|AwcX*_H ztdq-mmz(t9ybgq@PHcl#XBKN(D~eB(5sGZU*2yv!+C5o9x6R~zUi^Ac1l8O)x?Er1 zjy?@ZKxjbM6_1kzQY@&Ku7Q21nODWCJ_?^+&N;-B74x(N#%9&=7Qo|Z!5+?cgjMm{ zz}5rg8GU4T`q%6yEfVj)$bclhc|slvywtI1qatR zg{ek^mEjA=Mth$->gQUg5i5lyYZ;CKub`+;xP#mU&juXgPKO_x_MV+qmc34Yrn2%r zpFccE`U&^JH*ksRH8nRhutpmxE#y)-mQ(jNx$Lqg`5)DiRpYA#l>X){WZMpDRma*& zcV^8yu+1~7$=2zlW2AU3$qxqLPo7Fjwm`YF+&fHmHJXo=Qq?#*E_VJ@1W*&3U`T=3 zBBL!FPw`hxv}L)#u$lQI+1!~?z%$~`q<7zjG1eb-oFWlYT z-QC^Y-GVLL-Q7L7%fj8A;GQ6X1PBBwZ|!rc+I~;TZl^sT?tjq7nAe=Wk8$_l!|KV! zICAU23)I~5&N0?x~76hTe_Lb@pz3uLllgpfSKtA*Eg$Nm4^|)U!M?!07C8 zTJZI;GZ$4Dm;YSTN5kN1g4R$&Wnazpr|4{%=)=<%XYbM@rHQ0#Az`}&wm|-uiS|@s za9-Lvv4fRwiVg2j1zaE3ygS`^g&cu}ZEVRkmeD8S{uPrtlGLC`vaY;f z15}xT;wOsdD7PZ1f=@q&y?RDcL_-JBT{ zk#rm8@q!6yyC8>*OiZg8({`$)O6oib0(Gvu%P$K#`ocCdj%V~t=QEj|42-Xtbcq5| z^}*&V%06U7IkU%&b!ZJWtQYi*SlEzb#1{aWA6+K;NvmSI?%4Jeirt7@=$WXc6aTg` zZp)-iq!a3If&DEsi+`Zd{tIhq*L3t;FmJa0P&qOw5VFWsiRy3jGRjSx zyJBF#L8a(Y|5^nQFK8aSX^y&FkX~r)|JJ9MO()mNn8y4lIVyrUPyEi?5vonnYfqeT z`*YW0fp6bu!TsTA&1Db@Z{mySXIBB2tW_IFo?Ee5)E+_tIs$)@1cua<<#2)7Vv-Xw*3Sy=9Yzxp9MLP(fiW&jl&t2Ke3v#T zd(C&;4Uck65sHdHN18~_8&;MN07pQ$zolOys{0Mz0|{)PqU7&KR0JQWctKBrD2+xz zbfW3Rtv6szm^lMr+KRAcG`4CyBB;z|n|7uTgO-L#jrcytkQ&W4a-&<>ZdiFV6G3YJ z-R6Ldew!OECHE=$&NR1AN-0YodqHiX`u0(_^KN>L%K?jNu7TIE?ES~#j-?OOPsgVg z#Qewo27UIB4)Y#qjiaKWF2%P6grq>~fh5+cNH+o#gg`mGm#91}#m``~Ay+RMi>U4^ z9+;q>UxiQ~fO!O0)P#;Edfp^D=Y-66A)o7#9#DfE@M(eenE)65Xh6I0L9*M&-QDp4 zK4)#fAk`Vc(7DG`(+()ftC!_9(a61S@==%2eq$bhnkvLq229W!dH7IK3E}~U`i=A( z=OI|2z(M2mZVX;mZm;-$I^IKVAjww>5WBq_Sn3V5^-`1mK=vz(pWb51fz#=-aYsI= zDk`e(6Mh)vMlVG5$6bW~*bayIxR2y)L7_?sj3rJY6QSf<+bnE}VesVp~_eqhrwaBN?(OEM;dv zy!XAtS9YZ5Zz4EZiJwr{p4<|NQgd`&3-ug*HHxy-L zKSMJkOmS%YhFbO# zTKE+Wl9J`Y;)FJA%=7wR3ZhBE2wmZmf!IJdh?^lTv}4*(O=voIbkaVK-qwe_g8TYE z-zUzSAV>~FLD1loQ!if?{gQK!>&Q8$8sE8VPr-KL=LI>3h!KA+AN{u)Pls1ygPvVA zrwJO|35`CwH>Z7EnkaeU@`*R6-n)lKA~CvOFD?^ITdKtBhx?O^4*+Zi$v& zhT@52HZ!g&^p|nf0p60LT7tA0$CR7oHqPsiPmBwb=J9u z5{*bXjH##%ivf6z*RmF%QfQkp!I-V~5a<|n-Eu4v1u@d_LinhDoCt9}cGGHfrSl5N4cXO#L5yM!z zXT8akz%^ucon1V>I+X}XfZkbJ7Hb9aWYD)=f@|c zThJLKPSlwoIwqwJ{aTVPUN?)`i%uV5c#zaGx#BxgtV~sx*5$D>sn08IQuZ~cbR>&8 z6j5Z+e-`&uZ$DV^uehyY|B+?w|0eGLbwq4T^ZVbM50=mhq`|fny4agIuE-8#Bhc0y zLC)@3O@k8MNnDn5<+~^TZUNN}-O@8aI6g#v@dD~X0RNU*4Ncx$9@D2ar<)^Sq5FJx z@6Y?g0}sT5uQ_n|ZW|#mK!=wf-l^(vyHVAf?(UB$cHSXjZiB;3U&CbXA93G`wPI#L zgW4VdofPbJy4;=gQ>K|lU7gXo3Y!b?K(GrGfxX{endTe{t0ya&Pig_-*UMUlo#MlH z$01r@HnDFRP94#6qE&+p2L?k4y-M9aD(P$jsK$qoLHEbTOr7OAxMqkr62>kF3eqRqi_N8` zzb@;s5tC#{+uAW@E9l0SLo>#qou&SG=b6>7AdHsYB^9VeF-?deVZFQeVFJBSVy=Pp~f#w1gMjsUQQQsJVVxFJ?(ma3>g-h;RI2Tv3dRtlk|n z--EY(LI6(pgZ2;h3a8%LI-(2xMmf(0jD()Qz7Pc+dLU^EAba!!6DZ}&;BdJf+1oq? zJRc7+B&LtA`j7iP#OD_+tgk6#4-p&fx~3O{+!ZIhc7eU!>RpNEc&vn!svisp;bdyG zx8-g~KAgMO%^wo3#6E1IOKQ}fw6rn<8Upx$8RTQT*y$K+C=&M)#8O!0FRa=8Unbc+ zwYvDHUn}LH)>14L*yfrO(RV2bZh4i49ktjAZa5wbR_(24P^Sgu&Ev_c*1HcUPC$kn zNAnk>)#&#_F-=4k8o$MtFeKzCV33aQ)%+(HcWmM8<%HJnDY;GegVjF*{Y=N@f)yuv@w(ryw&LAU)NU(c&TjK7meg(s*SH{ld zZdujLSKm?a&L~xfe_fhcJObhnHHWx3iH3kp!kO+Pd|Yd$BTZ@4 z0W1+Dr7Vmr(Psfy>``8MAhuYn;b>ODRzbo3x7qpa{oufN#Dh;acCxHQ`o>XD<=Fnh zoyMEHnXw!F$`cv}p&$8e(zNwD0m^YADb7Lr4hmTUwcnplj(lTzA_q@jkDgV3fBgeR zHMh@=Ob7bY`Y@3U;A5ZO2u}v|2C!XFlld5KrO|UN#o6_+#9M70^mzkiSwnYEV4OaH6|AeA11I<;b?2WY; z-K9m$#mH7}utXm2OnVdcb)&IabxtP7h5 zpA1A-nA|ra|H_b!V~u2?6%rUuuqW;O-L)rUHELMKMjwc9eL(vT{h#$s9q?Qk{8!(b z|7^4WfA#&pW0yVU)xXWY70FXC_6YH4PzuHexB2t43_28aTCNnv64wX}evbscqm8Uj zrfDE7>3ANM?c=A%g7}qE@@8C1vX=hroTmN!hael}^VfxieTewunoz9aSQ?3dI6rym zj?S|kVa#9k013Lvx~14cCi<&>hI_47DkST3t4J7bTx^m{CPTzt#j;D<(%URu$_X6k zye62~-d6-zefUh}oDUi3|@nf_haM!!W!H2`qmusjl4U zIqPa`ta9ce=}tztONpOZin;EMBI`mIXjT5Y2Ks(I2_+$;OSj0)qjo;*sJusA?s{3V zA0L7cyESXDwim2!rVSSqQ)}Ren>fidY&{yA9IeJ~`8@6u)lS!~>K|88o*^X?+tLn) z;7?E>y1d#P)7#8-ZLARzlA*I2A||0tburJ=tO^jeHwQem{kb@!#>7tWVtoDMOcUDW zawIlesOElK7AgZ5IMCcvf^;L@Q<&U+`Hl?tvsg}|GP_JBDTVap+CHWD z%h7w`W&Y*Y&co}%lL-X%ouLFF7;c9p$6!P|*mT<=@eE2Z+0oWgQCFDmEm-6gNa_l59Sekx1hXC&1ap!Ptp+su~EIr_<@N z2OTP~??Wp$HkXIRHq=+<@5=@hD9GHch1W{#OuO7MIs3O+s|T8o$z$VfbDZFS=|;Im z@n9unC!S*1R~p5Z4*amdvl;Rk`sIBF+WelLY;7+NfR!nU5?pN_+t!TfBGzQ=F?`rj zv|&ABVp-Ne=T8naVvRKA=u&Qv2Yn!8P$o%KqOhT9G@p3?**t?W20&;^GYFQ=a0DAU z3%@6+>9Q-#kSG@PH{Jnfo?24L5^RG0-Ti9G_%RlR^U z;_w{x7SKNM<9vu|3LUk0$Yp?_iSFFGE@L%lwRn#5wI0@8wB5Uncvp6QK5OWaV>2Xn z?jRj{ceZqwQB!mBKK&;=f5HOMhH5x|5>VK;9fqqS<)<+{lrqJuW>%@NwNAKda0fIT4Dd#FTVIj^p_+no zxLKc=7UJECsXz22T5QBGF*Lo|aR&~_pF;laHV~Ng4Q~w!0zwS|0z&H_sgM6<;B^0A zfz$U&rCulgNURH%di@sh+;V0uEUI=yyU57$wMwl25jdT4_J7>^7~v@jycaW3UxbRX z`9S=@xSzLHu)tVQQ`z-MEy#J@Guht_cQHtg9ROzNaDb}=ginnTgLD%eC)lFZ63GB*edOT=KL}wta&8@x zx5nO}+<=}kUD*A2t4^J%YpnCEdwzipW&)Y@6T@r-GLTiAima50W_hP@mTAYF^Q`fz zLwqvN!r)8G-lRKL!U-&EPDPIVZ)k3_M~qz)- z9a4Cdev>6SPRSZ?}FbRC9jj@4__ zjiQ-&FM7V!!WSuvvv1C|)?oS`ICk)_;9P*>WL;+g-FN)s(^nTr_=#_SNm&k8AqCh5PPk$F- zA=1$j8Ks+ZQd65NzM+_C0eQhT(7z=l`x6jRt)Xu4Inzd_3^{1=|5U%|2mb2Ju!D8> zV*#Ps1@GUcEZ-tX`KblCkFw!RPz$f!O_{)|FsLLlVcDTfMj;=nJ}FZ7D!8>sLd^7% zz0rfU_ho9(Cy2k5n= ztAc{p`3MJWyVTf4Zo7KH_PZi&wdT1Z~Vm>nlpH=#(Ofq0jWSvTsb^ zK^I29u>+sbXb^KeF=_I$9givmavmxA{M&R@kuZ#H$%CkVL7iD!B(==m0kU}56_W0S zB``^8lQ9e}o^M`mbEt*iW9m8Z9z_yD&sWDK2(m$b3BR?=n5@w>p0Hs&Gry?%<;zx} zrl?q5G{q#4f`=?>amaUxB85b6CBGqH^oEo5Ji`l+vA0N1E>N6M9%8w3W(0#?s0Vn% zc1QofvlH?Wqmt#I{j!=l2Tqe&QP;DE`N?Y9VJG=koU8ojJ_4s1U-AYI0bxf30ip3v z_mTexD|Mp`2+#39g2Y{cC_ARdpN)7n$2*dNv6xA1Xas1R+F=kJiV`cEQIBLN`8SgV z5lSm59db`3cHb*!h;L*G^2hNeoQ`g|jpTe*G7>!nRX#w=PXc>n2+0l8n`;lUPnU$Z z&;1X*Ht!E78W7%xq!@;P!{|bI#d}$G9>|n?UEp}TsHzI3X9JiMWyO}YM)Kw|CJ6?% zivVz~)(Cr~&*{9F($xrqLMKi8pc9s7Hm7DKk5C(*(uW%5$2= zMa%&@n~1jAJ4#c`6yj-EFiik*827m{?TaD30EE+wyAhg_7&9&Blc~G1oKmS6X#vfQ zlCOD@maND^H9Om!^wE33G7J*79yMtgL1-bmqVI?j@`@+W@}I7W$}D?7MR9%osEX}&@$+}u(uV%Jjri(iN#9^Ffk7chnDmTU@ zr9m!YF$9;IbJkL3h^8mSoyhd$ggPE4zj`n6%PpUoTtY8?r9Z?5ghFOGd{Z1-qva8_ zm1%%0xJX5_+*CVo!{6JSP$f}`^<6~<{p8~VS}t^IA3->0p_S@)cxsIkUzFsR-yctn zq2xJ#lC3cYVUN{fm_5$$Mt_R!kXl-4H{}KO#?9ct@Qc<#1j~-I($ZzAK5}>lWYwB9 zxAOmLg9xdJ7hszPD$!auMKW2vs14sU<2T{7nDA3~aA@igL}W~niA9%iBPHicQ~C(+ zc}LF~8J6VGG0>p8j$utY8F7!-Yi{$TnZWDr)TV@e45g&T zl_nRVukyZpY9(G#q}LynSH_@@^ZaR;i%-)Sfr7{mV`MpJ}_uuN}l7jYwg@-!g_H_ z76*O1Po=!@N%k26YLGe*|E71k;z@l?O|uJi#uuKHOeN_eZ6)X!K>Xt05Jre9FNw8m zcIxXw&o-VgaG!53epzF1iV#cBQLg4A!?V;S9wJHqQsi!udV@r9 zU#bX!EV8^)%@VeBRn{0GY`tz3a4>^@+y3 zJ;LCdU@3_s6r|i)RfQT4jfKnHXGb)#YO<)QJU`Etih5%3WPm5`BO;oXf4dut0t?3& z@0DmZKLY)XtPrfo9`oZLO2fK5-CL3UT7~^a9@kJ}Px%aV9_vVwU#?P5X8@nQpm!JRkpo{Gj!FM3Bcu&b7$D$=`3I5y`eN!r?0!-V!A4=!XXw24&3!#Lb%!kbdSML6v*xZ5)G~O=^Me;fV|CVy13m^s zMh}vUOrdg~Ea?~Pv}Y0BjybhXIr4HbpD7kotg;NO9TP4pTYxU3nOPO54Ked(eNn3F zE6dLAF+@LN&{Jo4<4<~##H3q6Lyw_d|$4^151wp!bcUyH0M z0)2ckMS@&Y&Qt2<4<+mrw2#a5G6l`P2To>E2}Y%jBo@iftQ<{x(C-SyEu>=YKIU!RqPf1;DPK9+~0em){a#I zTPAeTw-ft!PdisN+4@Bv{}x;qiYm_3hJ=8ifcr;A1^>d8aQ^{FH7kt&!8OP3*pAVhcOsuO%-VTMOXJAe z*FgCxr*PZno6rJMLQC&=zYd0OE^ms%p3&pE;1IOfMg{|AQ6$t+)qnZxof7+Mzt}j| zP$U|^Z^}nN{mWoCS)yV%=dkK8zp#?bA<--+OxWDARun&NiC!U4X4@4|>*1d-9#U<# zde;4yzwXo_C7KbaUPCR{qA=fQ2YXW_NRh-jf3@hEcxY5A@tg3a=xGH~tIW^Sg<$H6 zwV#iV)o?Xsj3_i*@9vMJRdv0ilpP@zyQO@!Jsa>ahHCgP8#})e5pR z$&F@(<9q}a$rF%M7<#RgxDG$j9~0)(&(OwDhc+`Xs$AOYMN?B|*M-e5|BM=r{1`Q) zG>$znYHAahwmRL#1Q;}zzmt{vVj*brY_Is&HCn%)4y))@M|{7#AE;}dx8TA z3Shvs=lSG2cQMq!6~WNuuF$i!dL<>`t5Ak~y!KV=q@#EK&vI>}$9_gFGn9Oaezz8j zu0~+y&03<1<%{i%c)r;~(J-lmHJ*ODd@dCT^-`V`K-EB?Uhm)(n_=X#;1Q&P-~)zM zk1>a)ZNm}vaX?3d*{6Z++;#Mh@BID{>zH?>_*X9yh^INqL-@h(gZenHX3T@y?Zo8A zWYZ=6hh1G*c5zu3Ezr_<$&!FFZdkX_!{ctN!nFgE;C%g@8frFBdZYqiVL>Y^VFu3z z4|_K~<1h?vH4xCWEF}B-CGX&Zo_g4IY@D)@J-$ui3x5cy8q?G1H!|l7Xs{O{k84`; znA=IkW4C;VYn<7Sa%2YL%MHKe&){S>f!!3cqB25dUOGms{Lin(&%^voOc^Cu6Sg!l zbh`)vm&{;E77q&ICnv!n33H*v`zjtDq5EZrAKYMGJN^u!u!YS@pn?cO)7nw(eDduJ z;s-fR*yN5c))$(1;mx+YY_o5)R!#v~hy=roXH2tfjE}dC2{gX)nyZKmp(n^7&m{kS zP36=ywQTAtb9hwgb0CNnBF-90)-?NwyQhK-!#_TT5JwBJRe3xjlnd z0O<;6_l8tYoZ&aZ-38jwJG!tjm;bEZ;v`16(7);(f&Hf(#Q%zu{@{b^hho zxA)(FzSDeG>swtMxtrI*9-!Nmjof7l*u_je*Q_W#QRI3PEvuMx6Tx}I9-s}|WzfR- z^kg-KIyI(~id*1n9EbsqE%1`;L~_}z9Ddq*R>w*u_pY2=%%$KVwn<(t=6IY)FI1<*^|{tu zh52N57g+H{O@{t?ZSr#{3J6EbI=dM~bfKw!X~DbFRS_r<;{jMq8S;a2lH~~G$KFc> z2Wh5ClUFQ8#u4=3D|?9n9uF|WZ(?k>?u`YohZn7^5~Yie|HDQ1+q6F5cUGP1mhVv> zU9{nnJ-Dc%R0K&5v{fAA+}L(0#rcv?A@53&O2D0_W~JOo%I1Zem6-9)Ma#NACSw6I zLjhj^HTH_y7zSRoHI=bvEY6j96sQDvBSPZ8P{>vEX%O|mL7+k~`>gY`m|TQhJga4y zmf3H%qMB)IL3|QIZV7bW`%v>n1{3KMbLr{TVKxGnv?#z{!f3| zEcD!0OtbB*wS?tjwS{2xbzoRbQ<6n4RWy*TXJ=8lLAn)&pi^BWix}@M*7EnaMQ(n( zzHlT;8RV=Lo|>AHPSCp}GSvR?eq~hW{b%YVdtZI9tFf*AH4GqdrUF3iNQRRjdC5Xdl{vMCHwZ5r5^J4EP|FQSz!C(;^%jY zyqRBp{#)U_3X4^DFoEzeN@BxscT|CxZp_qN;*rPnkrw}Ak=DN~vinqIGVrM@sh0o) z5Ky^uE@21TI58I#XQ1u|{{Ce2bMnbJbsZ(*rN_$WrO`9qsgs7-xvubgO5At)ujpTq zF1w$+(;eUS)|1UQh57tpr&wjAUqIUU+y-o$O70a+^T}In8N{4;Uo(zB19ZOctT$f6 z{%q+z?a8F*=KD({y#GNX(Tx-a9V&$Xq7fO|xK5}A?R7SW3>1kDCj)tCC>8cM-iC{# z3=fr@CR%@d^-5gqtDn**jvBBf?z%&I$ToN+`LssF=gBsc2JF7{8IO{i+y*06^1=){ zN9CJTHeWdd&s~g#qA2ID7hOXSgX$H2m{8C+H|_GgcF8O`ZQ}_!hnGBIVma4&wh{tK=5d*&H!rX zQjR4GLwm%zXE>Qrho7(ZM{QzU7nZ*BwXQ@CW9f#4uX+*?!lvmqsya)K;tmWO8wXPvHcrA!{HxG zb~+QU^5v1)BRc7Yq(}Z<5qT851SRZNjVpMW{SnBnSpRN_V7DJuyZse((LdJD|LVfp{jP#p0uAkIWeqh${D8=F>6Wosgb}rew3dnZo4##co^!n)3%1}*@ z81M&~$l?2eW21XY)&nnmf17%K!L5i$2o!5143ZPzy0EcJV1$F;v;WKOZ}DzEqZ-?v zZ3F`qUuzG)_J-}c>PRLVEK{L(sb^Tq8kB20r$k+oucpn&Gp<2WJVbfmY~!!L6ThR| zg68#V%5!Xdi|E@#Q&wsj|6n&Lbu^FpbP>9q_SR9SPcLvo1U38-?J|an&IJNtc}!|n z0sHWhV%kdFMwS=)83RX^IEWz950;!k?`V3ESHqZH$S|u#{+E zK0;#Ng}cL9t3vGqYX5vZIo#t5v*=TWUIfY|heHgBg?lUR->x~1$9AV~VAg#5Fi&^d zP=+q+LwfLTj(i8(=W77e0Bd>cCY8Zpsx?QGw=YmZiez&YfQ;B<^~gYhK<%TL&=GMx#)@kp9w)M{T|&t$$yX9tAGt6))h4nNUR`6n1`|a@h81o^&au_3 zE|j?1$I+-A6^}k`#k#m4X_41!Y+d>AAxB4XlSqAYD|@10Qv5jGKTTkguO{TkZcnz# zwlgv!^eATFP}bH3RM2vi=bpS)y5{Fci~#AdB_3J*1r}qtb+OvX5}ECbmUIQ$S8`HX zmMqOty{#=d{Ynz!ydF2)C^RMxZ~^_wUw0&O!>GAFQ(vV0 zVV?i#jTZwS;WT8~^IG}%_I>6%ZJsu6T|_>`A69^HKvp_h^-4D&`sUp)HhzZsd|EZM zd`8H^$?bUjHxpsHEjV380TuGQoe_*NpT#3mwU-dSK8PmF%MH+$pFg|}Xh<-CmoL$Y zK3m(8;;KjdWtcf}Osu~QGh(1h-fS zX*;K;3u%+QnrwQJL@QJw%QDlTu{8690G`&NC-f>0s|N9V=3CjSS%DB9ARc$83H~@% zAx%JkIp$sX3~k<3T!u^sQmHE4aqCKwUzRPWndiR0>}9-r&yjgSB(odne{{EqP&6nxj$hM9Pv#5LIfza8|^ z^2C~GYLZ%`D$wNzzxR`+EP0d-fi?b@xtZ!?K4UcOh8IO3Z-JO~cwiPGk%H7?DkYmF zZdot#cTRiGJeuB&udO+u!%fju^T=Jg(lIAv& zW}asMdALvz!B=x_?R;16N9vRnvcWDqUWTLOC-j)otAUq*f!Mks7@^*LvF4wR?55YQ5|nuunzK2cE2r*)b8)ruN@ONd0_7 zp1wWp2JGkA40L~xL1Z7(E{g&gf5HkVY+QYnW!1cLa$;~=fvU(Do}V`@79`S_>IOwm z^!AMJtM_Q$R@Wo{eoS0$OeR@}LRT3j1*CK9L~Llaw`uv27sfh=M5&LI5)LVD*s7LU)Q`tU%UlI~-md{h{9M!@)IrVah}d|6O2O&hYh70n3XCX7 zI>_j;?-!QN2+h05B#Xa({5>r}wgBsFzq?owh3;;z{Hy+Fy0^?5aYdZa;V*p^+@G`d zcbzbTDL2W9%@hL@=uk@ph+D!Q%gfWQQMGozuCL*Bvu;}N=oC^7=OwdAq zFk|k1Cl9WW-Z!l|jfT*m+tt>BF>M)~q9bG(YsBcC{UbMh#T{#IkU@dm^~!(t!L=W| zh*S+Ls>IMH>b?LeY{R%mh=merLAF7&oVphG``YmzvAI`)kXbIDXJ}kspqWL;y54BJ z0u@?+)HQg=l~(xUhUs34Px6kC-pSwqd9ATHDay5$WodX#zeEsaC&R#ZV=R+_5dy#i z1mD7&Nio-P03BWz6~>XDsECOp^y%El8O=npV-Elq*NSJ!g>$sBrpkc8Txeu=zRtl2 zM+%?M5o*#mKm-dQrkQ#kiJWNZA09jE(Ts z1`i`{A$j$~%g|6%2%;n0t694YND&Jaf%M_40YY>$V)v7DX1%|C7*~oBhudYYu1eR| z#$;gxiLtG%!nb$`aYoFMaZ)Y;X5I+Qyr9|CJDyL;C3DT)4bvzpyoTDQbu|u$_ww6Z z81}sgQN*RQLEXzC=z^*J#lYHi|=4@Ov)n;?E z)ux=AsU5~8D!5RZVu|T*kt|qT@Ua$pGyeq=w+Y>HWUqPMU5r2J&gVi}Ry`#@+$Y7u z_Gc#(GVIpu2AGb(QB;>zP!>Zua)q|p)Z>Eu$=6Zcp{5<*RjO{*>9fAR&9Dz;{_rlI z#I9+X{i9EAA6`ZA68+AF-Q^+|FQJ)QtRbejmHH@}#|S!mzH<{gem>Iv%0b@=uTwbH z;j8Pwp;7JR1zn;BFE>pUz_GMqfHuE5h#FGmw?CO-{jk)O(~UQj(Fm1mjoEbjSI|vk zqiM9JO-Nem`%)z$@TvzdzAAjN2M}C7jEY`)Q&|@=b2wq?@b22*60Rk7iwNsl5m9GK zkzw~9+PLC5L15?<>0aAIj#qxcbP%C*hl#MkZn7ixM0zrMBw zHUBovr-<-R))z_`&L9J{SYIRU+2a0+ZjBWK@XT9^Hw=?uiMO*C*=Z@N@+2+;qK}ui zw~X!+VRTGS5?GDK5wyeAHRtIjK}>UqQmOC|RVUC(PMBRTK=lR)PGrqN^Y-!SxG3q- z91V_)Nwqzs7MIx!|WK+M!vb3kZ4sK5prb_r)I*7)uqDy;Ri2-;cu4Lvbh#X zzZQl)C?cVom9BTAeC*Q{NU*Ci&!fj+?P51uISd6)x7DpLXm%q+d1$sN=6`wrQaz<= z8KIDBuI=fPtInArAnB_)VsXbiA`Er1dpikfHsRV~MJFv7nusc8Qdkbdb{fSuJ5r^) zsX`H$o9~$i`PI8r%I4JvCNLP0HJwG4YePLGd29k_>ib3pI=w04q#qdCT~bXwG|~OG zV){OVN%hyAU|;nx(o_N5=;GnUK~|e?6)gd4!(=qH@saF-6||2%8OPS<)){T2I*;d&#-&9Em9s2z!N5K9p}67V&Oa z88B-vaeFoWG>1Wzr^Umza;#@A7{U=rXg^>HF)4&n$(NlvS^{d(6P3R%aR!J_>mXZ@ ziUSjAIf>?~?z&-%$kLIaaC&n>fSl#-D`KX|A`dLTI81=66?mL!!9pSfsm+)J+~1bc zOG^m2rdGKFvzoeT#{oc0NYaB^IR)(l(mwi;0raO&V_@NR+#&_eZP7 zm|%No-Li?KxYADL%LjZdPihJOl>a%6Ge6pO)D@T_b!4eOpl+F>)-_GZmZgaCBwnq; z+Fg| zs<&zkJkKUy-WDGX9~>9FCOKi_!Z`TO75SX1N={pq!cEwOry8mjxqxXHrL#(dXTCx_ zSOus~a<>*Bj?UHZw{a4IAt-*7()Bs8JnKsEUDP*bAantAgu4C=-3XnOshfxmpV;WE z-*85Ck!5NbsD-0_D2`nB^jOMd|8=d;ph9u7>4>YtJ|@nUjj0_Qd8W3OAs4567wI}R z1cquD+KREpf|A)x+J;c3ICjm@gkdRxb6;2Mwr))zyaZV~{tNHr&h1rjvhBM?ix{{< z&Vy;VAu%GV1-(Uh$w~c+H%tA1JF)yZnE@utih506CzpyDe2hkorz1A~?p0)$+{Y)& zyx!U$BI#@gL(+68A5jKEkUv7`J1$6t*Kyu()q0~WIHO7)NaR){3eITclD_Nrh6HY1 zh&6$j=$1^=)-Zx(wYkailc%)8cMnmBZS)Iuvz;(@a>Q~*i(`{bT-NR^*`GpV=diqG zzl}nC*B%KhLX-0RY|`#*i{Ot7;xxnzX%noc5Q{ORggyD8z}I2_dN~_Y!(Y%c+({~W zsBhSG$RB}C!4o%%Omvd;6qPsPukqP`TN(dOGp6eB5~OcX1^B~HX82?hgfY{ygzuXP zvLQb~b+;~Q%t3$|qmHpT_OY|LblT{zn~`wZE4V^ravF~fvqoN!xxB$N%k#iN8#Wn zy1D!9+cK(DzdbrcSp7>9hZn;DzS*m(Kz5n(=t?4HY$~|}5E!(~QTMTFe zNW|NQj?pxB{cO)xn%Amy^~78{Q%}?J^)rv1F9m*JVBKimi#IQm=x_t5Q~fS0erGAD z1!{j8FMzWT+3bhtDO(wB<}YH5kZA(GS`+viNs)KOqlJ5BXeA@^)piU644BRP+{@89 zU!FX*p_tACA&lFxS2T7&3mH)lO>LY0KAN>Vye-QwyDsFzWFZp9`(R_Jm+yntDpC77 zmp@W`?mK_~L_7Zdc@*xREV!n;E)EN!gtDX?d1Um9;;z`TMq}P*A^Ll^GaGA4Tc!r1 z&DnTg^&^&N_q?nlg51FZp+74aBw!mfV?uGt-U+kykl_MLZs8~v+vmWy0Ae~<9SoCE zlhm>w&w*!zkZsE4&I+s-+vDUyf|w@KLt6PF)R-m}Z}OQxt}#Nu>hs#ShIsGMKaY^L zzw9F~Hi$XVRvHY_4AIdD!_LjNqKrRyDIy85WENGs;);-lH)yl0 z!OXrEv;C^LK4`*E-6xV^7bbFVsr$;=IgK6DIfK=<4MZ zeeXr58upCLOXuwM%C~mrg5oRDiYZjo(Q>)jcp-mp9Ct72ktV-vn%6$LBuj|XQOD7p zaM$f+cxf>|m1^Da`*4XrG{0onvI}2f1jw~?Zo-+dP^7CkYOBPL(r2Ji>Dd25h?%5S z*n(`8@!6%Qy52IUzxFqdWhQmhM7Jb+ZW+XSIf6Kr&o&vh&D0r|)xie{Mr z;5F{~npo~-eix%rJ__Zk^^0F2cFP=PB>mGbef+YErIc8@V>J1e7VTeUo{d;hF@9L>6Un7+9cgG(RJcVkk}7E4QT4?qJqk`;3?2DE;m1*Y}{X z!{ux}zOg{Jax5fXT9WUmc_v0Rt@zIT`myebc+Wq|VxkX2$9L9Nb?Kxs+F25vaJgDo zUuNu%xsV*F^Zae%>|1mZaR;mN8_#BN6eJs{?a{Oof!7tTas1w7Z6W0Gv$v=At8UV8 zq}HQ#VRgkh-5&K=3JpASINhc3E0PvRw87n}wIYT8XAmT|C4 zjAQK9AZbDfk?z1kcRr4bWycov{Nk8nI|NdEg_I-7mT6w-TN~UNSiY2f54laR!D2oI z-v}K{Ca`9mq_GBK5%9J`Yjtf+GppAQNf?p=vP4BpTVQ|OdXaf_1$`ciCXIlFvB|D_ z9*a1T^GjPzE;j$rZyd?&eAy=17S0xG7&TM!!PvXykSn24^my$9+nzkJZF^$dw$JM-|d zoQ$U7Vwo^s2)RyjrL|AF&m*TBt=L=+tWA2E7+JgzFro%xaw;CG==g6|txr_lkKC(W z->;vmu`gYV#YPtkZZ0UK;c4%X4Nvc5SaS+rfEr*t#k^*^M!COzJ(1()2{G;u{T%Fw z#l}!`4_|qPQ(Q}4i!UA`fbA*#8=57HK@~jtxDHBXh^wSx=+fCNj;y(JGEzPfRu?r5 zX?uzKpc1ulZpS?#kAMm14`hkdr*4T9FoAF7q~IaK`i>!W73x!7Wf%sVs)ajVA$Dm$ zC#EKdQ=iT&jg+v|z*m_r-D=Xi{8zp5zbi zUk`R;UZEg;2OE~9X0UWvWv#1kFx{*ma|gE)SEM}%uSGvAb=QSr3I>~Gqo1;$4pSRO zRmCWE=iFrd{8#o4rf`7?iiU5OeVb!*w0%eNPKTh1{%<91dA;rnFZFiJ(sXVz_4l8I z6?{#6C?M=1b&r=STSED$dkSl#4q&qhpNKyz|6~egNne$rN zpqcg;ET_~Dp{U-w9?P804kxXx1@h?0t^X7Npu)dTN-dz?S@y1#>UJF_4*U>}QfOx= z_Fo>L@F3UlV;B}}qv`fncX?9=zG2EJ$lW@mWlZ=D-z&D)YQfR8%J2w*vW5t$07yW$ zzajJo9g0ifTx3m{NrsPXHNe&A==$NUm`jBx+l)%sXv|+v=xJ?_jq#FQl;Q|z^Nfgw z&*qsS5K`hF6c4J|_3ojTm=p=uP)Dtsp8cn62qFZ4`sSyZh&{=VD_WyESUEhFM1#$UD znsbSv5Q3hb^GfRWu*@#FzO1mw)8=9jC>)g4cn?=W=s)j~(@p_FLdrs;^dvn{Mez#D+KJer8Lh$L>I9a-0jq zDZhA#ZE3R#85J#t%tYW`QUm+)Y4<;T%rseOLLW4J^ZYK&UU?Ap%-RJ?}Ll7?w$3L=R8OxS{Pt$#{4wO0M#f)3Cms|yr7g+tlakr||lltMFy9NBwyM;G}x17Jl zur^VMBe-VvnXA`IFn3Vusl#m1@<;xe=m>NxVXy_%CiV2{OrkJSh^;~$OkYCs-nQGl z&SO}AyOM4WCsC=N7p9c8iBdx{+PtoPK2AG|+jmrA=F=+t`B6<<)Z?(p($V?448@?f39z4yRugl~U}r&F@C2dL zF;D5dh~~El|Gp2A0x^Izrz^ZK@=6so(K8WF&r&4en`VUe6#2Ea= zw-%B8w@aC_x#+-4l`~gZ#EGaLT7dd;MNDyOn^t-=3I(FIL;-LA&-$w9@bZEo+Q(3# za1A72Zg6}jxhT)ZOOn~3J-}&5TyyYDDN1EAbr2QZd>Wls)Gc3g=pf#y&s=lp>B))z zLTxroU>@zNy|(6!3%9p&-kGa&8C@lTP95sp-yW}?LmJhYg!qYEXIP5A$c+>aXEc1X z32)B>3rf-5ZJjG@DHDK!GVIhKh|Tig(a#-5i>kt2uZ*gfrD>eGn&?EIl~KD6CulPu}ME6iue$A=TzrrbQ0Y;(jII!!03mBzDr~q9_;fFr)m%rCT;~3C3^s3yfM$nZTkLww})^&K!K^{))Q@G8fL>s&X$oJ z&B0_`zbB`tkKj%vl+(u?^)9i33Tc34<|y|$ASTtJvbA`>^KIvxx85f0sv%Ir36hX)A$I^ZU0pY@6PJJx(_S zdvpi-0F;Fmx($l&*Ez5m^3VyBZFYCvEptg7@luaAwt1TF$x>MfcQ7nLxz ziNmBt8Z#B@b+)K%wraLCnKgClaOwFnsm&CtROfcGngsz>=|-3jCE|4loR>)!>B$>p z2fIQuL%K_d51xA?!3Fv>uC>h&JI+qGmol(#)VEX2UYMDXDprL2FWPSi2|kbHIj%pkMyIkq9yjeT z+!px{IWF&`JH6isyKE_epkZnowK_Tr>i&jnOId2kd8v07ZaX?~!5fdNssr1a?i0&V zuB_a>BziWi35Aa-ig7nurIw5b(t9=Dv5M-zai79KtijigRg^T^t}HdG+GN-;de)6YA{HwnO-!s(F-og93*(`oob$D z^c@Z2LEG%eteX{Gt2JaIdZ0|+U)%0&#iGjzGfGuz)bP8qKu#?AN6*j$dc65{MHVD9 zu0hay%*gUWyp@TT7ZoSGVP>!!CRsk4Bd$0P>Xp1M8R6_pBG++7vt7{uxT}OhHMT+K zK-1pHjsBvcGsdigj8PxB5q#w1;$5lcR;-btN$z?t5mYl{oN})1QAju+oi}JTB?x#O z%2QJZXqxxHB=j0=R14QM0n>~R!528+p}M&p4Ud5(w7f+$Wo*;;(mF7V$RD~H7rI?k zKypSQ%%rzk{{CgH|HeyXk(eo*Zh_^8#9mv33|v<-v)(t{XkIq30jgAO^`D%7@VGl+&i z$$4&ujaJoxt?O)-n?SYv^;1>yx7<_?fVL&~7yC8GXopoiPG=qU$y*J@Uc{QD_wW_Q zptYp)v_nsq%qIo-@96_xq~pZY7O7|HyhE#&qI4#k=(s^3AGM(Rwx(ki4g4^AO*Jo z`L`oi*|TYd|j&a-s=_>K zEKJvOi#~Y;R?Vozf1N8UeoM$s{RFjQ6PWO%=h%?^u5E;S$^U#K>adyLk%Hs=ih~U?aFCi6>EcfjZ~vGAjf%U6_=3KBaxM66Yta( z$%n0;MfLSZ^kNM2?JaU+18Jke&g4M%(lEw;GkmSVzw;pH^%GVD?i}?M^1o}1A&aax zH5mwqL@)@5<^MgcaW?xOrm&g0gR|NHdR1=p|6@&8{Qr~b$UY=z#e{+e4V#WA3bBoX z$=dy8#0&#Y{D-JQC zS!46z>E>gGR396c?Xv|TKKD)em(sP1JxM0BvV-KfhvB~Aeh*0%|67LtNv z5PEZDMegUsDKg>3Z#OTo~Avm3a{fL(y*<0*#%d#9!b681yzw6~uWAk2H_A z$vPgcD(IOebI%B}=E`CF6M>AH+aEhgn&=5vxJ*&UjIxHcfXgd8^oS0FJUp@t1d49< z5|=O{jAUGp8fF0`NbvZFB+&36BpS7bo+|PIf0)uvGu@LTAVp$p+_ z>fXEHX^V6r9Uk{N07{aaLt{9Ma)JzaIhZW1@)4vT?)4#W$A%!4UDYIKx>8pw{@)ol z6L^iTvGC3uQ)*1{HI+$gSOp(b!@dx(hQwMrwvINui}bAABO`q5eP=M*dvGCDO%P;7 zWeV2NZzgP$GFw{fzn%%(UnPk#N&mV8CJ>xGXIm4R9K{Tuh!=n7dGTL;$I5)^dCPQc zfLR2sfY~{w0Va{k;DFX8I?NE0MiA8Qnmfw`OK#T28y*?P0H?-9VLQWxv(!56U^Pgx zrlB3VkeM)cY~g>REcpURF}2~NDqIN@#Z`QITls7mo0%Iw+VqM z$INp_l@Y<1#x4*-)omYozh^bm4Tl8P)J;48YcYe1fjdMG-isxBAZU{ehINTZgrRA} zVjwo&f^G;yeL$KN5ooQ95%tOpn%sktu1cdfaMYLCNHVL5#w4O+D3LH?(V%Y28b_nI z*YlC`2^KN=xyB*z}pw;k`8{}i*gZME@0Z; z%yni;Qg6mEmDA&$SC)Ay*{vC|Pa8Mq9=7<>TUOQ&iVVj*QjPR(!^8&TOx3K?;48i*JfkanDd!UU!{OzcJKd0ElgktQT)f z{jX)IMkqc7?09pn7p7g^w^r~1scONRQ#7w|e4>p#ON7#=cDYazM~#J>%xMD_)U<}u zHAdbX8N^E<`6{&{t;6u45e%dwsiU*>aKCNC8Y~+U4kQJ^ zgp|Kph0p`dpABVC#wC~ULv|2nsa|RLY{<#wAvpa=27aZpV<+chMuy0;Ob0BiT($>6C48A zp)}z`d*x2~Nf3K34(?>{jKmc7FWN1?WtH~eC7GvU2SVvrpsKMpjU0!0*#~dVv|c5u z61DwHU06d1Xafy?LfXTG@rUj$8Y&G=S9P_>8GsD$blp!9>(sQ@|JatITv5PenVwMj zIJ`p>39ix_mfEOA{|rm!m~Ci5zdD)LS?ll=2v5aa>-8PZ?#jTkIK%ESGB-9~&*GRq85zr}o|EsaN>$n6}<*F0kx zNWEDyRB<1ddfpiyMsztUTzW?HQpf)usYYnrGl2P?PUV%rs)A^^c>W=p^5_TM8)vZK zzoqFKX`j4+x`07zc8<`*p32tE>^+iq7Afi{t0?;o9vbn>D8)?jOc>@a?nkfuTi|)G zR8usRnvujfQW##w3P4|~a0EjOqxRHPmdIgqTIju*i>yV(rV8~N6RXJGd8k4exT#x7 zA;DQYn#0zasiRVv0@=-#G!cL|Ox;jD&l_1^KFoqwQ}>H@T=O&V537?&z;4(`;7Hnl z-IAZC7%0xDbH`=0y2e|aZ7GCdrn;4TA^b! zFo_P{qrd70!l7|{QTQ|rs9>2YGquDN38=C4C**-aA@j-Y>E?|3AO!YpDnj+AcPm(r zptH(pUIY^4)H;GPklkL3Zi3f32I)|jKvvzlhSqojgt;A}B#iIiyCnK&B4_*CCNc2+ zv#9CR+d`;gNMNX`nLw{?RN7)b#C0gaF85pwDBDUTOddC z`zW<$d>n%Z5a2XVtaI9{DnFNd5-vh-4FPHtI@7!4HdjM(IQC>4)O_xtzc+2|yjnt^ zG9NMfw^$4>CLBj8?lXC+ecc!MZ7b>S!oj)}=MJzy9G*-hjWCtB1>#-}vQF0vBsO@o zer!2$UGPwuzPxBlRdJ{JyFTi5_8=q|)d^zOVDCQ<@1e+L#1?hd5DdhfL80{%xTrs< zKrN8Xp_pq)pv!rflDzmo*D%OIeGK{S4|1G4L(^7fZ-qlKo!+@8HsQwpqS<&x^5*A| z*Gx4-GLB55>BnhkihGxBqv~KlhaI5(^Yp1Exqu7JobtY-Y11F9Miw`JQH1pW1L;f; z+sr=O;YsbEkO!mP&}7jE*187|BM`)ylsx5c-3O$(?$crG!rogYjt_u^FHamPxmEu} zx>?V(A%uz!)8HweLs4iw2xspC+pFuh0Zo&W-OKgFOuaSo%dRBel+?~7-*$zBKDQ5Y zi;67u2c>-+McWR3(FRD-HHGn#>fW}o5Px{#jEvqTUEq5@ zHa)9o(cT5LD*FmzgmKIC-B^Prdn9%mrfz*W+jc2_xUq(pMmuD2)9Lw6P8n&af$ZZj z`a??Cyy|&`!?4;kcDdag#angd{D_1K4iF}XuOG&1O`@xJ>^*z>P1U zbrE}l0*;4YdWkle9&G~OG8*4_;k1EydIw|n#2{gYEK=|k8>I{ zm+H5+jxm1gw07$zbLUed6&5!)t`h>EA5N>rcT_3y{0n$`q-u}t)*1ML64ku-Z&Bw! zQ9AwZ-?edPcjulZS>RkXHbwlK!440gQxR0kMHvP}G}lmP{xoqx!YV~6{E6ue zJ^x?;UW9u}1CtDOBv`BvJLXqWE@EfyjAQklTnA{A$We*XG5g9>>wd+1j>hT~;?dG_ zs%<)+9zbRqW^vU__TvRfU$dBY&JE-;gfxqLUW|SO=eB7AX8Bh(W`ezn{)>3oXYB0C zA#mnIn8F!Dsu^08Nr09q57$}NC!)6#qJP{lhgjsG=kj?FvyZXs$vZ{*@UwSNBOZD0 z>h5r+aTSV01gR9DGTGEFx8*BQVD{>C&V;#xQh?)`Xehk>wVkC*!Yh!aj;?g1o)i-= z#M&j3OImhiXdY_ohQp5B8oalWt=H`>DDC;-c-Ai8XL~a(4T4skNOZ?f%5zAmE|juH zKN664AKAa^%b#$HkeQW~rO$6z0|OjIx)`mO&S2!1lgdOd4J}h9+h4O9fld?1Ef}I> z-r(WQ<)K(ulrwKw_4_mhPm4aRKJxZxq>v{m#zN?TsPu=_#*lABaTyw4?(~mi7|o6u zU)65)a zsmsv`X)@yt{XM77`RlQ)?%OIcg&Cc~m75OU6~~Mo{AAGUH@{=xd|q2KnWSPMrT01B zA>?_?FYm?ei%xcdPMfMZ9NtEoi@WFU{~J1*ODB@O>v|Ao4g=mE4s!520b;DY0qYQt ze7W8r10{w&hGp&Z3eG}`Xp799X>z=3Z(MB^;xgNAI;>>%founXSMnB|% z(cP6A{#Gb>wPJ_@xk)@pJO#P3{Zg-Pon_^zO>jGx-I7of7Q8J4^v2qn1@CatwR>0TLG0?96yz$tLGYKX(%$WnGnS$kOvbw*Wd zAvrO}P`_eGY~MJRy{1h)US>OeyOaE(LhV zJQN}WwsPb9a{3IzzZOy0m%InOu4=-NvOBQ~N9#l~Si2c+5Ce^+{3IhchOW|TTi$aU z)}15Fj&>tTo{Z9#bFbwOk9QA{le(_mDL?=D|NUZ!l^_%AqZOdIUK-+uD#x4%rgh4H z z4-DJ6Y{X|vwZ9V20Z2@#>L-0WWqOJB5bq+z=F5i;jN_loGsoARSaTQnItv!2Vscl# zLMR`RZG`icjU6yB8{=jj3nLjjUC=3_-2Hs`5~bgV1SUK3mG-N1+|(gV%z+MHG-A@a zaChwFJq$g+X^!K$t3emFH^QuHz>u=SIt(HmA{}(Dy^JJ$wfN3+!nTEV&V?{GXDd~D z*s4D~)nBw4-}%XV82$e+2|Q(0*#il=Al-jH*z9I-(D$8g+{V=-4x&V+L12Za)-l$0 zhvn~3$^B{k%~Pi;`LOo_U$(dlSxHjPdFQkzNsEUWQ(nn=qmeJ^7HsOet{=OCDqfp6 z@+-%aGTLuQ^%eKUww)PYAb(9h$@5zifbyx_+(o6|V#{@1+8Z4h4$`655_w)Wavn3x z*xo^se~-y*obCK}B4EGY9p0an{uKL6oiM9PRu@H?N8o?DAGf+LYZ-PL^KW_WMETiG zmgoU3&taiVcwL=jll#Oqnr1Rf68NkOLb8w=A^j%*E*=UPwpkX+r5U~1z|;({?C~4i zihtw^H<3@*t3Se?zu2cI-^Tb_hJ~AX8Qc2K)65GEQ;vjU^+co`1Fs^@Jr0|xmm5_t z*Y~WvZYfV{_2YZxq)w&V-x;o`lMitRv|fOIxCvHunnfmM(TP!&dSzh3pXWj?K7_=( z+;@d_OD7Z1IKz-@T$E;(f)kW>(9hwl=FysKQKTl3YEJ39c*Ph(*Qv${bA^c^AEX5? zKqHdi4{&IY!;Gk#r*(j$u3&`#{1p))!y=@TO^`ca$RkqsRux5+$VXl97i!0$q4tE4 zI1k2cL82+Z^u>&cL#AR8rRlftRBrsazU-uJ-EwNzSP<0;~)5{$})Eg3LX zj@ZcKjm!0Vm^ajh`J6j)3deCgWc=j`76kJvBs4~XiOFrua@|6frRF$vs@UcIA!~(? za2hFak!Gk11gBE9yFIH_38Eb@=W^A^{<6kU#EY!@p5{n1)UuY+q&6a%Bkl{uVNYG! z#bFPgDtn;}KznVC^yjUZvI?InddF`vbB-sc@{vEOBxX9ItF)=-g*k55xjY2teq-LN z3h;UZDNZoQJP^)%oWplW6o4Sq3QLD)P#3UgLicSGV*7%R#Iq%zLJZ=XTrs|V^`0s; z>Bo~0aoB8_NK#q@zB#3b&fjae`fz1YOFSYfG#lg9O^gQZ1wft*NK``MGnlYoy-47B zKUAMT1(O=V2%!aSJ4NaaMC0ePsux8-PU-j)gtCvyvxqd|@}276tfu!h*kn`8RlUDqOpZ7O4|NZ&9EF2o|tDNW?bIGJ(p#-yvx>wAo(5oRf`jCO82( zvxK1E1&NAGSqIi+)F;r5X2Rn&x~Z}aGnPk;vTW^JTQ~CD5_z#(q^)8PNr<@^m_Aq=Gn zyyWr6Z4OKM9tc(My}g3fSk2rAkdHf_6EiW7a1Q09uXj-yNpl1bgv{Kr2}}62v3!>f z`*9wmw}FTFm28X`t;K9!lmph7m!jdfq~HXP6D3I=lkuj#KBh|p4|?a)>Y$gPG~iz7hlKI))8eV#xZk`MN;F&YIs`Iv-thCMEUEQ+uDh}9 zfF^stdua&A>o`#NT3#HR-9_jKo;=`m;fWcJ7$hy7TRVSUg0%6^(GqIBR&53|&9~z% zG(>(z_;sYmS5N3Qkdac{vmZUYLasoYy`b>-P@@!(IMseOP`nV!P8UFjwTic##zs$% zLe1@*SuFdc_-gw@^lzkE39sIm_W3Ue`}3gBs)iG^bD^vyo!SfR+Pf?Vcct9`7fHN! zEo_{9bUq8`q6~E%2-HaOaSky9G*TyPy+MvvQhg-_Wd9h@j_$15?Wo@?wI{Fl41+c) zYU?xfnjHKDCK)6ckbUlW_zWHQWoa`6n5w*ICMjg4_)FUz2I>qN{YNGt=BO9=Zmv0h zBf93H6}}r%O0&NSfA7RyM2J3(z}MU91u|T)vpj?d;k+b1XF?w9C-;hFyv;Zzv{)Fu z;SV$sS9Vea#4{cB6+n?=FyX;ME$~ru1^zg}byWRPo;zg}#@>nrGs+`-yav^6gyoCx zkC2!K^#62)!Lw!cB=$sGTm~trdtj$zPjBkkyZ=JF3PH|qoh4TnDqX6M1u)`?=U!OD zV>N~dP|%geQv+n}Xs+pbwly{(7m=TZMN|@N$NrdPN&Aum@OD(!b;$fm-A^tlYL?5f z9g{#^rlJ?&ERAl(E z!)h1GI(jMxG>rPZ0IshSaI3DIc-Ie(GM>$|HZMb0H&@j@d;4gQ@@@YBjII3=C!hvN zpuGzKLaX5T2{3`-^2=>x?(V63b|{Y*#z!x>S3?xbDNbPJYCWvI*MvqBq`i)c()|$L=?oXq35{b{)m4y=OvRg(nxpHx$@)=!c&P-0C6jYR9h;u_xNF4^e&g)~biOb9c0R_h=HPBS-0iwyNsT zJqdg7Hfcy4_twSYBh~yva;F0HYBu|7f-`6xJ9kz^O^W6&Xc#Z@m^^>w&<^l~{Ls0J z-b0cgcoo>2`0Fzmy&wwR@NcmZ9%qaP+iROqP_YpSr>rr{k7;h^01xZ%a;8Q$#RmoM ztpV7!s(iCv(I)*FMV!(AuA8-JRm;>(pL(=SIR1Y>nlufOWot-e)F26Z@#vW z*`!G8iBc6Y8`&cTc;wxvW!v!Ufd*U8=iC^58&T;jeFBzOcCT8$zD z(iRVr{nYqOxJI(-#{qE!vf&4ChigG?Je>N>OA1#x_! zA7n$tV>W&$;xB`mRP!M06$`hP@HS&xOCXPfWK=F3HgiJwI5`RD3Vj(}UpP}7j6pb} zY^UR2vcz2D^uOSjv#D@!-p3UXlcOUQ_fSB);9G5OS@=68F2XJLm|BbL74cNH!vVd3 zTAmOu%hB7&;0jeU0lAXCSD9CIsJ};C(QbGYceXII#iyNN-6N1UBcz9PwY4FalTG(t zZh++%;#6tCOb;#%UaL!zqF9Tn`EF&kU+Lj@eJQ4Nl)0A;yzY>Z+S34b%=kU#DE!?# z>y?CrR;$eP28{y>uy&|1OWaiRL47}}47r<$StK}1-C4zo97v&PHj;v@E@bp_0ri`7 zyiVeMf9mZ-wmAn|NK;vKF1wrP6MRMBDJj!WCq zCiF$_c7d)7I+^XXhU%U1Z;|XV;;jTNcK^+TAcFYL!v*)@UL_e^fF0raudJwZ_{{}X zI*ZgXEp0~mit<-AF?p(_5L`(R=I6&e{o6Obv&(`h4fRsBRB*V>iJCH2zeGbHu6E+p z4m3LbsXBoEdbkD(l4=&`aigDS?4PBx(OwrfXl?mN9u$nl-aN8qT!$iGD2C10R;Ql9 zt?|IE|Kc`2p@@qEegE}+!1*#kyDV}dUWJmv`3`B=?#_G^gl)XN=~1kL8)O#m6?V6k zBj%H-Hcy?VTgE{>r9phl3`$dvD~#`S)fm z#_77eYXiCc206;VAXzBsTBag{YOIvdH0Yy?00=dvs%Tnr#qTXvsy&J3LJVbpHp6G3 zv5KT>$W7j1KbJTvXOl|U-|e@-64^U%ePk}=Y>2TF#QpM}ecO0)4{9A~vVM!l2o~5T zAG|3f)x{-8@>qX((YNx=5;9(f{?P*L%J|%-vTr^@e!m_te4?HtstR_Q?iyh48c1b~ z?EEm_x+$An?`?2;2aY^HXGw#0hIrDXvOYT0a)!vVN>&b%h@@=7Ym{ihBbutEkQ>F0 z7vTY-4_N4`*rKh<+)WSt1yUU6Xr!#TLX#ya_{Xi~kKn#`#~}?K0JbwM7>&{JhZ3&` zDfLih7>><{r0sBcIyMo=ykc+m%q3 zYct8PGFc!`RcbMTA))c|++dFxJU7LFJ#qZy_$qa{JdC=ZSDA>}V=2(p4-X9_Y(e zs6P*#v1ac1N@j`%k#gm5%&v@Co!*0pTQXLBh9SW6OC_^P)*5}&ByZu=6GE+G%sv?A z7j;~l51x~@i@@)ky-);1yL1J}^nq+ckQwO$PW-}IxDWQ0pQ_AYqOplvLv-W47OlDq zwE2`kcTL?ZEEJ7atbO(9YTkynjstw>=HSFFGiNt>cUY$-XQ+oINH^tj~YLhzhZQlU6;u)CGKra_{EG%>UxK>L=j{FA@^}f zn05DNkTx5ZZTTozb%82)>?}4z13cjoxd>%&CN*Cs5!ZQmeITO)9z+`~nZXuSap^H* z?Q<@B%WZE9-04WaMAu_Z_=%>Va4CpG(`iwo2{Pa?v5Km25&Y(|pO+G#H{Lx8{ z98Yvb#7+0D#Ito3bmNSH9I%#|5KSb4a})ZPB%3P9b%6j7K<~f9!p7ReJEA6TX&F-& z&Dh>+#nz4Qv*QU9*OW9kN?M~v&b7J{tFuQAB6$}4dxXB=;Qx$3&mh6qEkW&YY%^{_ zjSXFriU#!CGsCd=9gIt&d*QL=;gf-+!E*N5OFR6lhwERMnqTv}%q6yu(+vAWc@0W! zL}ta#xR|{S;c(jelAro1A=n`gBqI7r$o$mjN7#S;?xm&lYXS>ur3U7~{bGr0r!&L} zPMgZx0xk6{#&EsNqE?|w^~Bbcy)Tcox5<-R$&4VjwzMa+E$&66G=)4`>oIB0Ld6Xt zr{BWci`K*SX$E|UedcY(I-x!!D)reNtb_E3dRF>h z067nUQ-{8zFGn*3oB@{ENHP0Hk<}Qyxw|hWR5r+d7JH6P>vk$aC_y8TF5la}+am%2 z8bgO(_0=UGsVg`U|K-iR(r<~Q8Q-t?()V7XUdxwOMbG_j07?sU@B{5ydPrq6HhE5> zO`-zdxh{GIWrzX>8Zp!xc}EVY*gbZ_z1AE2o7{tSudlrSO4obdXW?hP*AwcS%Ny*Q zOi(_EG9GyVd4OM*!nb%2l>rTPGUKGiAz|N3z<-Oa zvORUlf4hUY1GWqI9yq`^FkE?QI31CD->5HFRoh#(<8E`_7#ytC%5m~^s}}B1>dwyF z&AxFZ>nFouXJH-2$7|8qbHuCFT1HEE@kqzHlKup+Qz(q8JCwE=sv6g{50KNjN&TDW zSaNXeJ1Mso5_cR`oCQ}$pX#JL8bD$6J#x+$wJ*ip1DEdxws{^Z)najCzpI$hD!lyyQab?n{@0o)+$-u z+kF5!QaUIDxdNPQG=K&){oVqZtM>dA2!Mud2(IgxTQ9n zO2l7<0)P%$Uey{sUl{JzUcdHiqxi6IZm~#9!fMqHy-FoV>DuNqt5e#*B9vWf-9o`p zIpET@|J$N5{%^vUNtT=yTkGZ!H_QeUm^SJ1Bm!4=oPmQ`j(%QT%cEW6!3M7#V`p=7 zzdRzMS&k}~LMV#QQOq@&7hFQwoGGxmLZgDz^$f&AOMgL*mp}t^48bBEKl>X#BsXhn z0xUx~&?_gtWB?*$($x^hmiCC3)V7_0meqE}0$U}UA_JXOs2PcEtYULT`s#%L>r%pJek6mqz!aq*)%ir=b&T?7`0FD(S+%ni0hQ$}y zc!&kGtf^+mv;p)ilUn=L@e){64cYZPH{Bhl58lRlfr}+VA6BqT;YhEwQ;kznJ{d@c zFxSWfM79n4UO}V>Pq52yHf%XaBbeByB>HQXgv3kxnq=O~tt;WJ3JFw4=8^<*-73!R z==WkrnO&Qxj1mO;+nGM;9XmJXW{Ah_%b{+DD+Wg?)U_yWB7< zjs#`w-Q`A3^zp8GH%fVf1bdGBd9}BE(>+j>Oy#B+j6z%Aud)~zjB_{9_aJ48h6Icw z@Gy+?hf2ETOhMhea6a|ho|OXe|8K0eFBYaYXJbZe^J}$}8>Ng=xy@?k;^)jQd%@BE zOTSBdPc4hJNPw3uOF`I^S$9fgp#Bl(3tLIPn|j&;p?1_i)NgYoRjPbFOtdpKlZ$q{ zZ@%4_dqb6|OwmZ7b#EHRfut=pFiJ$ymiLnkU*TRP&Vkqy{eVlyP=$*1X5$VawADp% zF)*Epf?M6_=P#7@dBqJ;30vgMuW>Zxsmm?T+5sOZb@E%BOMx|xl(dKEZ6#I8&+)WgW#FGI%#?R&W%3EqvoftmK~&kMh+MDT8*r~vNOQi zNpsfuck)1Ha2QBvD|`kO8b*^2k*@VQwk_K|*+NY18&ZG(jd^9>I-Qiq&;-}n`yg@z z{R8u6xg%qtL2qU9Q#$j^D0C-{agG*omM}}xY&o2-_NB|hzh^7_8Pj#YTEooQUC_{3 z>ucE*O9qp;*|QtjDR2`Q{AWUgzI3#niZelkY=#y1p_BwBsB%#D1%(E5~02iYeORpc7_iK1LsZSOk&xSB`h`zR&x-4TfY{ zg0Z>aP&~SSNjoPqy8hSPDY&uV{7!ZT_86LUp~YK!ph1KMbB=C!?)Zz%uigO%H2<1h zMU3?2oQ7lH-}V;=+`F1U!kNY$b&|pygdsGV&A@=Ze6;V1c4*Y#iJQBWhPTFViYZs5 zvN=PBfI&gDZ}~P|A2)5htGDD%HcH-h;3+!sqr!7*swRX&xCu<*6Aa?4-PbDZyIn2C z<;T_9-<>_5LF!%x8u{Iw*LXa3#^h=V_#iwUMkreHx}alhw)`rnNiLxLTmmVb+4WxK zTiuPRbyjYU149w%siatxqv{!IFov>l+&{le53TsRh7xxcgBct+9_e{wb-}mF-x7-` z!l^bl&(M>wIL77AWksbS9o(AMzk0!eJZy00eE?71t}4|}KJu(-5Fh=SD38=U&-7N#^4{-_gR^|< z9J>}Krdp!Qgyr$~PVOVnjM2ye6EHQ}^@=l^)tnPwDq{? zq?!}Tioh&1_VZ+`dgo5OR>9++nOdk!hgk( z2`Z-NWisej|M+5~>Gd86#pGZV($DforvD7Y9RAJl9#eJ=HHX1-|B%h`ep1=RcFIsg zEbk-RF*=Vw-shG8a-lE&o0VdMcQkKzqAa&giKDn@2xeiE~np#kc3WL%RaH;@!{bvfVYOYD;cRr3h%r@+?Ah!&0r|r;QG#FWqNAbWV&pGzM zuvFbKNK=``6E_7Hlwci?KVy_qy$~OaRpu79y11BJ>#ArAdw+}nqhEUlS@sKFFu4ks z{*NA|;fh%DaVVfWLSL3ElTwcD00vur%d&cl@Y(L)rB?t6XtIuE#hj2|m}(GBQU zu(YFE$lApqg;XOWa}zL}%T>0JY3DI=o@3se1S3^5jswRpK&0u=d62EiK_$$EqmR1~ zdAG2R2Td&R540Qu2jC~EO;ruhP&6RSVs79ZnkfX0oE1k26ut3#l`yWm$JfkV&;R84 z!c0%u>)s!HoT5ev0DofLEW1AuRmjX@kzY;4dg>X#`uMI<30@X0(EY*+zL>3Pem;_g z86H6jyMOJpjVw85-=uR0N*bs>LIjl;``)iW)-=4Gjw^83avmKDHs2(P9J=pBKTW1X zk)r=R8gcAS{rukhLGqKE*Eng(M(4C=(a4rw<3{k{i(a&PR%&M|xqB%4J6esW5Tr1& zjsFn}?dLa>?WsLC^+o)bk`4jARZ}F_m?$XGRnMQ>q#l@4bTc)bE}IU5l*hM-fGhES zUyUgI^j8JS7WAYMgFJzWniT?S?E^JK3p zoQ(1RL)$q9=hnPyKHRZw?<7xbW5>2_bH}!ACp)%n+t{(5*f!@qGiRpeKXX2vI;X0? ztp3ndYt^sszV3T<_tn0e9K^}(*@Y}UVC2z7?md=?WN@1U#4w~z6_u~d#P$Pa{Km=} zsrx`)Mt&ke*&X+OPX@u$v_W*hjamfH?%z8F&F$aY1Uas^fS()MD*&0MrAMsG8KwZu z9p1YGnKes*jW+{|ywy&f6CG$X2*wUyffUl_;_Y%{GSJ$NM!h_l4*%%N9-aoZGrV0V zJvi6sV(P1=-NxOurQOEa)ur7gDt`kp6lf7$fx5F27-}VojU2fbeZIM*EGUpain==9 zn8m_L-QykGqbYU(B{aI72H7#X{R9y(xLwr1t0+9r8-JW<${dAwq1gGN@4MFgpy<=r z{IJIVzS?$1j*ABNW{rd+&Vvb^6KHh4BGZv>N{=?x^~(_yn%c-<(zJVHSo=PVLOLzr z*0>45`vTHOCEbKiNVO6_vwN7KTA@ck`ve_WFg>poW6Nl)}#EN*tx!)Cr3C>Ep!E zZY`{~y!|(s?w*Zx1qVMYW;t~i`M!yDCs$?(O3x48JiI?Y$|m5TTVW2Q+fFbP=V@SO z%d~V|{OxcGSFT3Obb4YLo`DZ1A)iXeCjdS`!M~0js?OaJG(B7ZKk1$iS86|~v>g)F z9WIx@70jxYcdCVV&l0a%`3e|?3aUcDPY+l($9WAEXGVJo!o`Pr|0~nma)18mJtt6~ z+~G9vH`plqa4+JwpWn9q^^=5Rv!P-0&CaKTC%PY0vEnIU)K&hZK{>O9oM`uV6r7hR zHcCyVND2=2)Xyz5f(p^I82X98B-IsQ@ogir_-K*Lzv2W`n+v*;nH*8EEtp}KB?6}UM zi<@0^gB#2+Zvz$bg~P%aZDTU?W`tQ>l8rO5ipzFi%T6K0z2W{Y6Chl>nh>t`g{~Vt z*fa0bg&GITl-AcwMscN=8qynHCaausg8q&E0X~-<{;V}0D>6_IGpP$-5Fx^9_BJR* z;x}YuGfs4IEzcz;KV{QwQ#v2@$|*SrHqbDrQ(#Pj2}6X>LVbgL)W9d2o@_k)@yo5N z9xSR}WNxj&tE8_$XG0x zMK7B|kvnVdMrzrTGpw$rP1k%216my}IQz%+uu!^c$yhJCwM!M6iJ4h~rPR-uU)qCj z1>jd_$o3rJt<%cTZIzQQ?0<|4i!@Drv9+i4Twhd!V@abOsF^-c8r1=~>i8RZwHmID zJ+W|eQW}YLe2EWqX5?(hjRO^O^=AR;9?ggFsPuGJwZ@y!uIWIL#BwLoiG$x0HEqOA zrxsYqW=zn!V$4{9a4_1j!IwJCM$AQpXxcEIBPOAw!5$vNW~`zBhlHZB;ou6#5;liO zc1)nzazpUJUvB!r!{9R;33^7TO9T6{j*$b%4}20E007yB0y|DaQjY@WBJc~BAhc*a zT4xUDmeEkwQLKU5mb4;2?H>izb9OR`Y77A#Q5s4EjfIgfaB4-xnp~+X9Bn{gc!>8y z6|-ZIIg^djf7pebQSjzYjO(i3-9FIT+HotiGk4MxRYunA@oca8M8Z(~DA_V{cnLE& zE%*muzJq1nj3v|lYVXJ=NH6I?sS_%H>1+d@ zcThw!L*mUaT5Rp?YW~k?i6P3{+ei2b=LL4-?jDhaw1#P69OK)nui=Kjt!M68Ap4G} z8M5wjcvqoaqi`N=C2lM_DNSEHc5PVq(snb&`? zkoJ^u`6W4hqY()#@ehQC#a$;Pc$t zAE$s`Nc_?#&K^_s8Abll6#Y{A`4gA;d4GGfBwt61JA7j6hdgwcKw&Qw> z_9tIp(_kY!rs_PDRXr3ce{FxFy>x`u-ZCjM7VqOJS(%mX>%PfS4-$GuDKun0e-IoY zndewmcAax%JLvx;gX@1K3{ctfQ*ylv3cSl6b`7ll49B27x(unZ*mO{mjQyNewz*lM zWiabDN^Gk9m~WHIQ4P*Jec|%$Z%^64MFkV}z{X#ML-j4*r)FZLu@+30xN@(D?VZ2X zwnU$u_RH%Ce=Xfqaf?uS>O*ajd}D%pUC%Y~@8(2$r-1S;-G5HhBc!=1YcBBXmASs# zjl&PpLi&>7ES_=0HcV^oJhb*nf)Yu(9hQI zHKHpakkhI-^1wzqqA7!SjG2HrFU9pzY~B&JG2AAx3X-_kgHt^zl6I_B zKp#^W6lQ_Bhf@#T(ros`RJC&E%|Acs;yY6jZG@qewg)8JT)XJsx?3u9+N`q+uw)c& zdT7T!Hvmzs{L+v;c!UO$Lu|y}_-z7_m9`V?!&D zAmC``Dz#*$U@KZ zlB=f}JmCO2vr?BSkXvSAI9_L5;8VnbS`XNBv3Qd4q#Oc#*>#wA_lF##re_sCgFFr= zANKK9ncnyTnqR+&o|Utjqrj?6@@lZ8�xhND7!YpQ0}puoKq(&n;0Yx4^V8%z^$e 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

    aTP4^$uqabKLfZQ{IJDaWT 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

    2b&TPfeV>8)oqoJ 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%0A5fr+S=6g@V%kzryeTb5Z}lP`mb) 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

    mO`(7ia$tb6;vZ@ypp+A;pUNbiMk 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

    mRi8@^VPQ<>GLX00d%wJ;9GR4n9ywpEZ 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

    Q?aFrd9L)_LnoukBW>Rmj*a!>wj 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

    ydYxT%&JUcV~c`d#OFkwh{GM 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

    Xl4V!Ix;?dML$a3Rf!W<L87J%AW9lnB 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

    3T$7868wXD=FcsWG|>^1*- zOT#ty+&}&zMUs+k&})&Z)HGFHOEn0|tW?ISBqZaYRit4|dH&@M22X?c&;%ywtK#G7 zR?dLXJXz&c-WDk){5^G<0(o@f?nU(gRv7RL7xO%PU3; zrW9WlF>H(>eA%6avZ!%YQCTU+@4auEoL-*Y zU5_#D81WHq=ya_SZf@Y#USsGP*QMI*q!)G>^+FTr2*#@2FCJ98`f9vxWv#edaOYOe z7WZf0bq!Gi(;cuM`uBz=hOl7NC@u*iu##s&VXkWncl7{CFH;*0fV5pVq^=XpU_Pu~ z5Mi4RM#1FT^xvpitILa%VCL3QST}y?h`WO8KA{6eNx4M@%}8oQN{I0~Hjt{kk(^0} zFqSJ{U0T;r2a!-s7Q!BR$y1kl8+ltvq9=kmEE}+CU|!m7KtTEY<0$Rw62ER?--v@4?oEO=+&#QR zUWDo#Nj_wVewQ6UH$sjmZ1ub`_^T7*)xKOA8V6QdVYuU8}o0i$;{xK zb{Kw6-EygRy72SR0Hq(*OM3}0TYr_T5hv=Pf^$Mvn)2?qC7A(UI7vIwd8RIODfm+w z^xA_l&6C;l^f;A~R}sQM<m=vT0Ij-Y-416}BL96#Y)Anoc{PA{Yo@Ktiro(}dC@{f|0 zm?JsA{eqM#Q3`8CBEvnQ%R9GUgp3v}wisF*I-V}i){WwS?cj(QR}U-2>&p(?#Ql)| z5Ge}C_#C7TW=##%Kzt^DK>!y@SoOka$(by0&B@euHRaVx9R(wNU)8)AUGbk*&)M4& z@42K^J38+Z^-`hbM|T0secJ-$v-?=O z>nV^f3O~L)^n_Zso(<_#rBFD`e*Ll~9}m6d5&uy_Y=xUV`+(%=mYN-{fQCOLhDTDi zZ*qf~h(%%1_loj%i=JI{!}t9un_I%rQa zPc)tWI)x!Bj3w|mwJF;e6X^!=E~~#dK1szw`lM`8_AMTd>t_r@v6whRP8x!)&f%zz zs>RNAfzy2e_5GWQp1@uC>TS>8yLVXyr{6LDnd{{L)yNw8|Jz&_{eL&u|5#Z63H_h= zq@HA+Z7SfQ{cJ!b%~2?*JXSZ#=-8;<_)Q6Rbke-@rGFp7Gv??jkxV$6x28{I^*uWX z{wk%l*SJ9HYia(vyz+tXYgxST$Rlp8**wH)!ivwboXuz6^LEX%^Mc_2Hbck{<^a~C zRQnSsx>ZhQ-gc$srj%1oO0y{=$Gu{Gn67%XWHMeBwv%eR2)B}Y7@eB6ka;@9WSXWd zX6neUQl-%hlv{!M69&y@5Utq?xN~G`1ao_5YER4AE66I+H6@Fu#AF2#2Tl~X5l{5wosT7%injr`nV&FJyiM}0S)+k8I}&--7nSh z&hI!3*6q{y6lv(vWk>U|Iyml8R;x-nml~+Z zOxdm;%m{qihksp>Ud}G=^aayb{O)?(%NI$|K$bux z*=s6wY!Z(CaU#Kx{YFBp<2C&p=JWjjQ4bX>qDXTCcaH~8j zB*mUjwe#4lO>jd4CblLnR7LfEyt1K_k)Bu}g$QD$+(rhJU^iEis@>97Bf)4R6ljN{lKHYKjXrUo$5gDHoJrZs&{Lq5tH6RrHlV`M-)wkE<9`_&-PT zH0RtjbXrr|XX3%>R?;nVf5cO7B_*Pq?w3DPXP*tx9-%3i$oXW~mZpxVN#S={agjc7 z`AGM1U^mkXYG*cAof|2aKeKlW^Qh9Kz(#p(6|u-IV#b%=X*@_t0t zSJ2@MM@=yM6{*(VF8VNi8b0x16^8c?rPh_ld#?^^8T9 zk<#JU6U^_sGAf&xpg6)tA|g6x7Lh_lan$%-|5C8Rk`AJ?{ZX(^d|~xYHVO3~`Gisn zx49E-_W$v9XM~<>YyYX(`-^{m+ckn4y3_~Hs6*M7-jLauQS_YZ z@sHoselD1gE?FcQ5Jflwo#$WhBA-49>d2@vPG}f^5WvN6$xA?Q6#bJaPSZS4yP;(&mLoO)qPx{h@|&Y^QaQdp*K7WX|nTT)RvmA{FOMIp3^q z>F{D|A@JV8ZHj`-*GYpMQS{?c|W^7OkGml3d>{@O;B zC;%=e1FB{6s%1-8K)zXvWtfN7a5}pQ`kwI~<)e*VtQ_*;iD6zCL9oqldV2D!y?J=> z-z`2ZCWVg^vk`;O{CqhS`~E*{JwSPG;#Hb!s0tyZRmzK|?gi1>?g}^M$&*Z$ zlMYT&stJh`f3$?2**d*Jy6vZMhGq=j(a-IWp1GG1y*0s!>g+Kszzo54M_k7ZP}3{i zWS7)*)P?jvfkFHl!jKC%3%O?}Phfo3N7*R&K}AX9A@?ywjb=T}58=f6iFSqrpEuhR zN)<#1L`R%WAXPJ{dq*Ik*S+~8U=9B(VC}64OM)KL+E60>HN%U2J0ud#INp`xE^$D{ zPq>|EZ||wmEeo{#s8RnBa4#o+^7jw>vz`kr^M5vlk^f2nH2=Te6#g%~tI$3=st+I2 zGUN$|O_G>e9fIl2jgsrdvMq(sL#(p%v$SNA>b;CtmyCuZ$!TFV8D&z{DfN$;oWuH(1qw&QH?YfpOu zzw=pSkO?~F%UUF@%e&t5w~YKqMQAItrO zUfa*okIr!V<6p5Xz5GKK${@jpw0}ou6D%#YhX^c};ZIqKa}hNRZJoM;d%si91t7cC zFxu~2o?)G>;od{weHbmRonJUU<8RS76}0Br6>NsX3vt(W{)&TgE(0yu*+O-B>!f8M zE$;jv9+4BT8v$O@ZeKWe0LJj53~BTS%rbPB=4YF`>rH*NO?_>ZopsM&0nO>-fcDpR zTiam^g#k%s^QM*-?FXJgtaQ_unbfMYD}$PWhBe@+D#_&<%6&&yR)Ni&lzhp|KMx(( z70&i8f~RbchxDnty)|B&U+~7{glS{@8af=$zn>v%))(j37m?~a9!S@8TSm*6JZ)5# zEznnR_y+Y#GFB_{EOlK+Wtxny((1k09qbpRrWWt^(zw@|6fNefi`vV}9Cc0anpaO8 z`&MrXd3ou|7mi)IetYi)#id?132LX08w|qjV(0OnQ)|;~;83?TFR61ZH&-J@X+28f zG;weLa4r8(#Htg+_G@ABnrz4KtKMt6lKWytN@P(QvFhP9s)w7AQC_aCb%tXtTwIRl zd}D&pJ$H?2T)PWoOaEye47aJXRbST4HjH1FOE*nWTvceJdg^4ZDVe12%Bb023vX0E z<)5{zT2+<6d17hR6WXzS@0DdlS^T(bF^(9PwU=03l zHe@QES^`qjY1S9=6~5=W*FH)X99|U8#nzsqiQ@1pl1H!vZ7ZXoLYWWesV(6`y|!=Q zMb|$*l99>OnjDy;^OuoEa|A`md)a)OWFs@B>@*5?mP{*%EJH8E`wpevB}~qf$BAt% zJfm84HXn~pBTX`FkwtQ1;c!u{-j&r?-KMjFZ$gipc5f1_s= zD&2r{@&FDG&m+a1Oh-lIh%}$pbp~HtYGsQb0dowdsp@V}K%P52VS-QaL{?rQ7ZHbm z__G<6nK~1XZL5zB{5&9FDyWefBPoo{qXpj_6{FY$-nRiyK_SegKXDc^PM)33Rk-6? z2B{ovHI{y_0^MXBKTj+C9Npx6=s{^S*C11G^V^UZ1eaHxV)!w2YA)tXl2JuKm{*-@ zxHg*1a)fqat8SmAmtzMSg94)}gWk6xSag|%2uwNfU6oxhZ?$%1Z9ynmSQs(a7;1?u zm}28$k#1+HTVjZYLW{YGEtu)pd{u@=%2c``)~-?Z>_F_GOfLc>ezB&C4>j?QkTki< zC(EzYJ=)`9re48Jtu1iUwiK$yql#9lHF%~zezG}Im!+)KZD#>fnw5tH5Im01z+Fj0 zi_H7Ti_a4aqWxcb5Ji;xr>GZBU!gMOB(}3gl#gfb3|yi_M_mAfC6&1F9Y}h96tA1m z*r_%;VHFq8jD{*~YB$I_vZ=FWkQu6oBWUVP;+M;;E-VwR6{ML z25Q+u2%m~+%^f1Q*62QXD@;?p4(TaH2Visa;<8M7Q}rDK%cQGrQjlar_{OYM*=x*# zQ2SZ|2*=To;xQP8m(SpYCt}o5v1FtVMVgT>R1htK(ZbX8OKkZf$|n)l+t^DJuSYeV8|*{j86eZY5CSFf}i@F@}87oKz6c z(lFhTHArZXb`Gv^RGKV!=NiQ}>{q=jm(Mtcm$%Z&4iw#ebJ1ybtj%h!Bf>0J14+U5 zd)jWBvYc<61(7zwk0^eRpG*PC8*}0s+6k%| z{?IC0hV&VQkCf2aN5bx0dL`(d0VTGHG<(=9&dyCPPz$Vo{B#|p$Mhm1v7#s4^b_s= z$yB~^j)uu1yF=dd0Vbh`vNFrN{}txQSdg3mW9FIYdO%)KDagT$x%?Gd3+hus5EO>x z7R%3SL>>yB1b?aY8QCc|mV}SKBz8edE93B1O4Zrb)LPj&gV(yOrg`7Ij4oVJ5}W^e zWTje=ClST3Iu{C-<+c%SfC0KYA+wNZQdWkU7o;2GZt<=gx@2Mk65C+bW@ zKo5z|OSHreQn>OmvCU6RbXsIsIKq|EplH_jzZKVgu}C^F21E-{;^@lG0z0&EWSj(hyMGK2>VL$b2r`Lmq?H z=@k)XKNW8nG@(u93r18B&~6`D=Z^J-l3x5AM9#SwMmnDcs)UTnyPxoyAHJy+Hs4i7 zG)y!qr3;C$_y1Z1$A%3e>Xma7I<4Dl;2B?DK0bRWeeHcbLv;7_DzW-58)6g8EFrmu zm5xxCS~=m--N_Knc}1S-d-DW{oQea~QLBm@{*`o!8{AI7yIQ|kE50O`1BH!YSCuHJz zcKyDD`A19349p%|jn_07KeA}PnNCNUn*;&~m~8aOV~7IEB0IxYQ5Zi4hdD2iA!*BI zkv{2wTg<*xoF#TVjY6OkM2*D2N+GbZ6cEQGmYz)g90EC2O|YW-i09wQc@(0$u!n4{ z*C9t+13puBG-O&7b4G68JC|3C*K9Aq@?1|V z>29Pqs`dd5Ib92VWeE2vyaiSBbqa)7s8-}~l{XMX@WTMT6#ZgTFii?HH8~%8daG`! z+37JnH9APQ_3F+wD>QA9zi6%Ur(oRXG5Wb+n+b&jmPATPr57F!iN;&@E5nbeSW}!R zh_lk6VU@CY<{M=5h)*q3vX%E`h=oSNTtaWo1NujcW{nIJi6WT;y7Tr=4j>=~cA6Rz zGAu{bYA#*9b;<=I+ATs3h9+1-Df%~W2q+m6vBn~BfJ>h9BP9xmy0r4{US29S5w#Y5 z4hKLJI2GBjA3}mg^ZTp$uZ$}lT|D&`6qn5l^g?zv=E0A%WZ)giDE9NwaL6Ell2okk z&)w>s*UbDM8FQPNg4YxZ$*i3^c?f5dxroT*qFBNLzO`2}zoj7T_j)v4&~`W;VEs3JmY!u~6RevG*g!9{$Y-ntx)}XycY79@m|QQ% zHq*QiG@0de^;z9=r36VUk(c-I+h|3FUJ~|Pynf0@>sun$+f4HG`TE%eX<{Wdq@HvR z*kze*Wn@nE&lR)AD-Q*1N&O8TR1As64bOvwlw?m#-x4eY6o*zxxw8{qV$YM2bUBaO zDcG65Q8f+hHSds9<2!E{PgTRUT`=co8Pj`HD+$K8;G>Cu&@1kzlEm00+m3dnpxP2T zU!x{X!R$hGsJ>QB;1mWFYbbiu$0kWGGYM@^X9qq2=b`Y9c^^AMr@$rYX@$T{7#q{Fg z)R76oWX`boT!H8KdMV=YlT}YIZugI=??`NN;+|W_tKEx4s84iQAGS#Y`<9Mhmwsis zyrR!t)M+G;l4VNIMCfa0PT|aXa>Y0Q2%Fth@I{YO0nIng5$cH}kGhvi7hdrL0${jf|5bI4K!Rt*> zuubR01)W$!>#kvndf_OS?Qj!K=P(7GC>4#?RO8QD#$bM@jde#gB}O|_ewj)PzAVhm8ZJ;zAou5~n^3Sqoo6*4r=mR@SPy=y>zHjv zOac5HnOIQ?k)a;&;1)-XFLCcP{ojattKd4KbW2l`#X4dJi0M9sv(aFg!Xm_(ylxw{`fa$NkLVe)0Fskt(gGG<+S7os%j$ zD?Zj^ergv%%2{vb;5Ftj#ziTNQxTwmsAwm;mBGqNxkGP^oC&mIU{-noCfD5)?hh`O zzF6JoEM3vySNb%ujH%Es&t|*bZTFn)*B7NPSI+P5Z{K`Ue$3S{@kW*_{|au~2fM6b zqQ@H)c$+m$9|m=P(Vq9;?teSDBa|2$=6Uy*s!ZXB`i4ys<3^m-ksvB~urS1(^sXh} z&F|2uB-je8ca?F|%X~+;Kv|$g$8+-)99PUL+$&6v@ZkYXOp)TQa6uj>!j|qgUW$(HRF} zB;()?uyHBZf^|L^m=KF6h5XQ0O(M{RENPnHU{R!tdy*9GqH9tlxkoBsLwsZRUJtq- z6y(Q?y62I2B_-ROmNHa`zBkh=Dg_i7-uD%f2y`PW4w3rCB>e1?a%Y*}j7adq#6H3O zQqCh%YH5=2kF7Nk86xw1;GopZu(;Q>@T)zM58nLU+qEA3d@JsWpah;-(HlD1halrT z0`&Y6Y>q*=xL14vp-E8~?n%O+6w{En*Q)Ry?7Jl53DeuP6aBnt^gTD3K%bN%rGys+ z<9sFb{Px?c10+wD!ZPZu!})5J*S?Tv)T!|cH3 zcE;#gS5Q~X4M88JHtbb{7W0IO_)iMNI|ferrXthwq1cpEK(cNF>8J*dnKa=99s#zj z$G$BdleV|0R>MMoxro?ylhQWdP3oL`^PHyf$CiccBl2FBF|Ib63By9XMFt^>ByJ*E z94R6X1t>eZ|HJHS(Y+So3+e}($OjwsLXrOxaZJ>Oq1BpDm{ZK>dh{pHhJVoDEqJEO zGS->CjyY#-x+>Lm3&)(h#w@b-;M%8p{v{4u<2?!kI0T0}g zFk?mqc(w%$i&U{2a9%R-$!37_*MW^*W-iLmF}BbQ1`?luBl3XuEaOL3Iii7ks?ZEu zcs9j7cN2TRNoFDA^by>nh$7}Yd1EZ8Yr-G>kj%BrliN5)93W2t8o30TNs)*RxaN8V z;Y?RFj5BK-%bY|Ei+UQl`j887olLNj5aU!ffF#aYMG-Sa3G)QG1@depBr^k`F~Yco zd2*?UnNHqVL%LU?Nub60L#HTnR{@%%?^{AFt|KsP_{TF|wdePF4+# zK(UVf{LvNN=9&b~@f?6;YrA5+OAFr4NUtat` zDZ*YGhv^g&x?xFMG@TrAv`{bNHzAVCh3SN3zk{{bo^#4!yxd>%bqD@_0gFS8prpi} zZO|DWd9J4~Ql=k9TMxV-Hu3C64BZZHT{wJL~V6 zhwO*PH0lMC3yZp=%{ zN)&)>svG?nt*k>AazHxOjbV&dwxK%-;rd`+*RZ42d@3O%qLLc>x08a`0_g)>;;U5B za-*8hFN>Xdj5%Ug`)lB@0gs#HuSRBBbkN5Glv8554zF|JC2b#I`nFrVy!O2xHE|(r zzyLw(;gDKy?G!A%zCU5n%^+;V6~Pd|I_7Azene;svT6GTZPQ9kAJ+QFtVJhQ+Ir1E zO3N9r`2yM}xpsNgp})E%i^ZsuqCY+iQPko`p5TO~#b$hxk!RMfN27w<>HGqqJ>`~- zluT}ttv@6t!(Y%scfwx+E3y-1Rj$K_z{YuTl`TueKRHJI7D zM^cO=PL$efzm2iZv97X0Eqo&XO_p7?#>>Ys!N7`)|6Q{D{r_~b{GZXN|M|}Uqd)eh zs-{lxhd}tU!QgNgU6xEXRNoP^IV_5jlyrzLmH5IqtrMoL4!Oe{yNR8yxuK!zJg0U( z+lF=lw=SE;&nfdW%2u!V%z| zZ~y{?hydVbWEOaLDc9_TY2f9cBRfG%m?ybXT6kpP6ng>49B>oju~tm+I$Y~|qZK#D z_qk{>?3ycu!;*#y+y~m97yi$}!+smBmpMZYZ`%w*alr-Vm z{UxJ9=$CMEj}Cl&J824jYP!oM7X3DQ9Am99e-QmkLAiTaUl8vScUey7Cd2}|Eq9UP zn)wQjovS3^J9;6zt|P5#sHX^5%(r~SM%Qa!4V5Stn*?%X&Iemj9pVDi5t0dV6E@1+ zb{yzdw7gtA0h2+1EuE-?r#O|U!PixqUVaSP^ckfLOoFWKkVw)4Hu_2gj;l>|{I%xR z>h9(mK@1x^>lNFPE-(NE?GbE!KPB0)ZsMGSgPYYRs>1ioy$+*c_Q6KBbi@6fx5kZ_ ztox88OEL=}83^)h(`2}+)%rq z>1dQ5y=pz|6Z1wkCRz@fOU0uQDQ|JhDJh=uCfVKkDH|H#OQV)0z_}1TnWahYJ8T)v zxW$k(DBn19rKG=5+jG*%dcoZ^*Tpr-7VF{o^pEu1v`NS05S|(}wPm`-soL|7CH3W@ z249?#WB&sxVG6ilJZjOoHN~~sQGxhEBcEc%po~`a<_9_U{d}SlMaP24u7~gtZxvN~ zgj_mI<9P8{qhglnBJU9(V#ByBmlvR8b;xHE2DlSREkS0t4R#7uy=G2XQL`*6C>3tu z!CX@poPx6vf*Kk}Rl9+;8MSrCcdx*MYO)Kn0K*wDxy?P6l4ui1B-qx|Fp~{+ap;U3 zQ5sQ7s&;1N9Gmh2scYjF^AqpnxDgJO@Y%R;KuP)ItDg__A^E5$88& zCco&giex;r+D=Vj3~K)_6dyvjGS|}26$w*q#LN%{*sNF#!x@`#f~($Y0pHjHjdzP+ zd5MtWb4|1o1-k^S#riky3%=+V%y|i{Ow}282GHorXuo2|uE->tgRSUMmUu`EHG0IR zdfa$oBBX&Uv4*Qy>9(J`9B9@0Y-*Q_4s1EAt3S3IAU;9zpy%BYJe^0qLwuE=F- zYw_dTJ<*{;*DoFcj4qRyb=Jrp+52DPGLBXo^2Ji6&fhSlZr6guJ&FftQnf?wA07W z3r|dtC;P8CJ`+l{Kc2B^ngXU@Zp8(##!-Q@8jH$nqDhByu0Ln|afedWDP(UYlzH>d zQt3F)ax*^cfG5pQINSy3N&q!&w?Xs9r4ml)ve@I$Lll&emS1d;M~7Tka# z4?ONWM%GB(p$c9#Op*PsRG^hHX{-Ld?MNM&{-5wlLG${k&l(nb>1CnI3PsGr^Z1bt8SHa z?1%cI&y;{r?GgGp!e&DUf8rC#%_r|}NgXw9A~2n>=;`#VOB)^41n>K8{2V?p`TYm# zuPj?w=@8vOgMsZ~|2tWB{Qpsw#sA-Qx%)rWzr-NJ`x)Ru#ziEAVM*#mfgxal6rBn7 zw4=rUYyE4s9}WJuJpovy2gAJO?1?1Qp?+6 z`@`+$fY6_}RR*xI>zW`A0JckIYVKi&?W(nJMPiL3o4|=)MT)IPhUNlpDWzXwi!z&@ zX)2$ItBi9A_DHn30&dFCuQL0S4IrQ~ak|Bx29~v|^T(9UNd+bGOII8jB8eo#ws)Ek)`JJshvb(3|(mi2U6fdX};r zLw(GFV6R`yh)>j_#B*GID3d5z%*o6x%*61Zw#c{olzhus7&-Da^_k}H5AtHL-ktDJ zyUe5}Hvy5b{U(p`k%(78u~?s46~T#?Dkn zgq4CR2Nx8W8`i;lrLFy&^)I|!#hsV(_pVOqV0aF%Y8jY6@iI)Fx$EbVb6;!^Y5Yq# z^d{!c*_ZLXGWa^|7xf2N7hX1S@|^KSpb9ud+Bq)q)KlQc3jw-g5~X7iy7u`Rly0dgVKWqQ_bJyoD8%Wl29)1DRzGhlrEJjRZc{^g( z{mXI%3!&cBD8Eeo3;EB=fYXu7by!Xt=S|iL5Xy`)5FiSuh+YUf#KQYUJCM6{{zU4i zo&Ky_U}vs&F3KB8uRzP)S9gbWqy&WL0dZiN|0(>sx-pgzw2X^6FsfR=Ncq)4h4?~d z16R2ZcHn2M!*6HaG$X%Q3+!c=J`8>Np7iBYzujn@=|Phh-pyueUMidM^hn_BVO=n7 z;KtMGZ@38qH-EP5D}(zMOxxYXt4eATaS8*B2kPm4ZKxTg$~rWyA!m==u3pP<(oLu= zUY>gbQLCj&(zvFv&31k33fg+bErundP7TQj6{hiYmEQH>9i)3THRh?hn3)6~eZM8g zQZ~-zkZE=hBNFg` z%Uxm*Q14oOaX6fe?QV8!EsPOGYB%Wb$*k&hX;FX6T_&RwfTv~&Q*;mECPUko+mJQ? zR-p9d+$IlbV0-%TZ@H^x(se3fv5n#Ctc>OEZ0W{#Ep!ny_8#+P}?=T)yUgk!-ZLH)uV*1B@Y=Gb|g^QHh*6g-v^=bS{8xp|sv+(K%?< zZl00r>wdvu&_UGwO$9*Z(Ot_pN5=uQY8cfx)!t2!zP5ZfoL8O7plm&i3rWMur_cY5nf^?mcrzGoXqxH##rS`Loae;6zZ+o*iT02qQyFUs6$oP9=gOix%Z3 zLmWizx}{#!-mHtB7$E9hm$L@F4whJ?#U5gPNuyD)loteTs9#Xg=n@(kMoEZxNb!`3 zUQoV8HU0&l*8QQYOToys&qoU2nqQbpPYL$6i$K7?2#&{$guPL(1^h8 ztN*G+L4+k0NTHk6q+7a)+mN~0PjTdo`(QRo7cw#^eloE^oZCNs(;bBF8~Jh|pDn*R z*iHuvRSQ)kEqjqzf*p9{{Q6U>{|`jgHCoHga^mV2!h{mty+np$_Vzz82R}Ge0+?6) z>%{Yy6vBUSq~u~0)RD2D8vC~t^V#@Oi{^~lf&?=ct;jHtKM>h8Q51(o4ULZ| zvpue_!iR(N3i=%7>5*QekmE;N2}^#`7kvgg`hR|@l7ILEwX60={+;=Oq8ulHTE8^H zGhU2#tc-4qg<5@E)Bs|OvdmrTf^H>NXxCVeBKryUllEJW3V(e@jjg_hKShsjKEKn5NxV8M9{l;M^RWk$M+MAfxu3Q$$$+?RH7sEqyNhC`uzt zRC&rsA*9QkqnUxDIfM-#EPyv|jnP&Uv%U+TAFARYiQzil_fCA}X7N z^iS@O&mTR`@&A*EYVc1YYH4e|Uuc{82j4y?b5G$m+F@ON_+Th_uerN}u?Ak}4(e&~3W zs9)KrkCnDHCCOt>JR}^a>@iN@;~dcvlWer|<}N6VR$Fks zq=%qET@fdnAE3}7%VQ=bNT#c8uC=w)H+b3W%d5)En(I#KR5Bj~J61#jN1dHnvMTmm z>8@tn6S00Bh z8YQd8e<)s9fyh)!Wwe_bRMd`|I(K^QFdLb}?yf_utd{jUp`VX*!Yia}QOMWF+4__NfU>5(h(df#KO3d7DXkLZO}q;uDeE`Q9heJ# zUb=~H6Q^qaLxLGX(1sBPXyBwGj@nEBU#$mSFoM?A^Z<`7<3aczIl&T3NNF6YW(>U) zTGd9F`KK%Gj4CoYDFT(X4zgXuC0O=f;c*csB?~@~ zz=|N0{5P?famIVnf*p85BnjMI+Isq6UL2dwr6rr75lT!-oCONFB;9+uOz)(bCZ;$% zjhiGO{F)>|ZDL%%_SZl*J54waD3_&5B_P_&q(oQII4NC;qT4DoIHfWgeJGqIK{a_1 zQe4RR{hW9 zn}CT6UO~88j9+XW3&&{i+pEGx`Oba_#mKPq5S1f#q1<0EYMG1tu9Yf%FWXEDAZ!-3 za$PqiL+&(``x1JN63`<#)cuUH%Pwo(8NQrlzv<;nT}LA*{Pb05Gj4hEA{wMyh)OmX z&R~&DuG7#wj_V;*=yU9(J_-B$5RTA!{exQvgYO1cVNonnE^3{N0kiIK0dme#oj-ae zq7nGLmhkqD#^=#-ZlJk-NT%&dxgPuJCVa-R^?lwb#7oZu@&o?S84p0A0R)4Ai{#f} zpZJ+T-s@(MhYahBj6fELq99#r(TQ$I94~9T4hZd6NjlNHuGWB@b%A|wrw|u<=ly@*8m21%!w^2IG8Mqm0x$Pn- zPaid2`siyl4pJXK%C&{5z02PPs|K>%dTxzGbV{SkOV})D6^5@h4gRQs&RA z-fmPWboNms#P!$>Y3U&LBfI|4?LYgT#G=&UQUHNoj=L6X{-gxEe%sXOB2S zD%ib*Le&OWK0b|ZJz8#vi6lAHSJbK;=N9%+g5ck0h}qST$(&Hee;elQ@;z9Ne5=eA zDL45O)DvYGjwTyYnp9aYZ_Q#@6Z#ImnZ1gF^fc&22g1H6M2$?ET`|xhl`P3&d$(`K zf^EW6?k-?P_NUDJ{L^uRHK2(4Nn>+aN$VGiy=wi3u|Ep3S#a>(OmiacwA}Tuu zY5!tEt5c?S77z=;4Qy02;@ObgPvw~gMnMki&lI{p;|?;B@!`i9b@DQ4bed+X58(_u zy3!;@>GcA{&q)7JZx$d?3Bj;+ub|vE8Qj*`HsenSSNaAhw!@0&$$nhUV2;t0NK9{; zCli@f@UDsd738>QT3JWn9itIhr58`-uPJ!D#ElZ|rgWHEwL%FXo-UsayXGzeG5-M*V{ zZ}bzc#L~2-Y+uC7c+i)Wna#z!-xV8XpGVWGHKM7mAWmqB!`M7`qu=8V)0G`^P3-6T zu6A$2B(k_G{Iff}b5#~&Ys|OhN-Z%Dr z61~CYsCr!;eq~VorrR698pt7wvLr8ZX-jQ+wq=xBbWQ7z>xo2p5`kaYsD)aL+ftvK zLw)1%NLq)zfK19Cu;Vuvf}1M<45eaq>=SijR2+ahk5C0dF5HxVq&>XqEZv1*zeO%#ly%5&Okn7Y+wKb#^mMww zmTqbX>JYZrtvO|Bn7eW|!n}XcO4>0tpSnuFEhZPV$wrRz<;;8GB%-=&cL3u8{Mt_; z_p;2+g&AePzrycj5Ir%Jm+i^f{XS=CvCx^}2eXdq4YBX!&gWL^a-Mot5bo0(`{SND zCrnQ#M1)onRh=B@P9?7RZCW}79vw|E1bMySvRQUWB?C)DPsrg3HUp3?+D3+b19fvU zLWR8RU~u3~hyE(Y>Y6G@ImFOgz}>`u?ue2`+CiXjDh&6+9Opv+!y$WOS$r|n>8GKH zL}I^e5{8APy-E5VFHr%#uXTC#)lagO=2I|2D{5Dv#kfs6*&#ODd3TgIq@DP;yRMZu z$wRs);oDfIhkd#MF1S0{O+(qO6)zM+#ZInf_~ec}>5^9sp`UpYFh3vb;ilR^f1vf7 z#4!BVCNJATrmawf9axrgu2v=Zvoc)99GlUVR&*`1oO+6_I}$$~iZ9w?9EJv($ja@` z8#jkxzQ5xL)lUpV9(48XIbkR>x@mJ1mZ`j>SW5b*06sv$zalmPtDY6Z3X-9{5t8is z9;~Hui6RbE6qa|%d-!=HWSbnb4oD49Q^3Au^S|Py{+q}D#Wy&7b&O9&CC;LC7&Tqx%9S;EICh=tIA~i{Jga13 zs3HbI$5p-lmMlmv{5l)o9-`*&+rH(6g|P)Wffa0PdAzY~pOQJJ?e5rcW2qoqJ6z+2 zIPaPEC%$c--?`pTGf_S7&^wGicdZ11LOs+2g;;Q>bJ>a)~mm zCO_M^MkgENlkwAS?PYEaFKo=)8C3+>4`qoYN*w5<}lodwl^)>iE3onxzx>BiMrBw2jIqlnyYm(_8Y z&S#_a{EBs{5)M8~;Bd5d1()|kDOzw+CJ$fIuPT&f=MKo+o#1>AdgOPvIhn#xOE$G2 zOVw0Q}0v4jrgYVZZv97mF*99s3M@rD` zE64y8iPf(fDy~&v#3E`cUH4VUOr2hwLR3`Ny-SGD`s90*n^-5Qz}%;lx2~mTm8EW1 z4+mOY^N8C6U%mWGT^&Y>LmR9Ngi->I-FQ?qf6~Y%}2Il2e1T)A3K)Q$Z86 z!r?Ee^$nRY6Bf^9xwM36Ozdt{TutYr7c}AKp;7-9iASAXkO9;(3qc3`E^1EucAS%5 z?Vip?uj5T*{DnnZC$%0$*g>&FR5|LBUe1bVQKk`Dlv9V304k)(W6|;KEY3hJ{ zV3t$TAYZIR*>ml&3@hyp<>VBLiWcYWEsq}Jj=2hJkCUCc%radyQXLY-tW3eFGb)Q6 zNNRJN3<&uhnXS$HvED?_fM38q+sTzTgcM)L3*(lgx1v~FCSBz=5xPr)*}9Jul)(UM zuPsW?5`4|Zm5`kaLPa$NoLM3VpLU-Y9;O&8w^pBc@2%BURl#58t7Tt=H*v?4wRUFM zEg41#yWtHK@Q12zL|GK{d+%kaD1cv(fNC&wK!=0qsA+7QsT&71?fGi+MMJu3`~g^? zBNc|n^d!4D)+!onl}H?jtuwKWdb+*s)k{@!CKk+UkNC&ve|YPFsIPu2+IB^7Iar5@ zsciPc5V_hu&GH$o?`~xtusHzRv%6zg%@oicB{at_^95)+;l&CEsx=2VZ3$SGiz0Yh zEZIQ?VTMlWI)O5FQi%jsNMu0UVfuiqR#@kQJuOX-CXB4oj*L0GD)fDUiai#71wI1c zs615}Fkevu^_8imdPm1HynODG{H z9ChaYy3^Zv+FY!6`WJURnA(8r=t#?5%WF$XL|vj&j^{GuH!047sLf6GHl{KUR3_!3 zs1yMfZfz9PG!gzY{UYX5Ow86jbOKv@JaSb#dZ|oAkMYn3X!69=wchXiqG5)Xg<$<*He5Ed4affos$* z9c(N*k2L66Y{lWCZTb1~kZ7DUs z@Pyw-{&(-NAJjS~ET_T`psDyZ|Dv!xR74e>r2P;MO|mQwmvq)sd^e?9kx~o*9H#^> zk5ozw$P(kS7-T+56q`D2%*X3IEmDsSuMKz1;{1uA=S;)N%!?{LVi0+HN%$)t>bySS2 zKp;O5YYj4yqq7`HP;y=&{aY3gH^7Kh5Zm3C`TG_sPbex)z`Q3&Na3TF-(-ZK`*k)*9o$VXxYp-^4L9`DRL7V-0{znlX2=?jEZHKmmf~nV%eN}BUQk! zodE&etZzn$NZ{@@h|zp{LI$Fke&elFkH?;i4D1dB`FVb z=1h%a_*jX8z-O(pO<1U)K$_CG^9Q^JTzDj$BoLcbh-A*CBWV#yT0X^q-bX?ik9+@D z{Q}QCR1Oh~jcARcHV&&n6M%Sir;qPPcW}*R?3P=aW!=xI3-h+0-X|B|(1Qi+8yH!Z zQ>;VRJN5ZCgPVh0vs&r(+S^-Vjn#+8JG3g!f|?t?OY7L%mPUQDCSN^1K6&A26s269 zo;rK4*|gea_EhK#e7(EayKwo%nmol+jbBx1t5qgZMP@4RyD#F)dO0a4Z&MX&i;Yw3 z*T=JzS3D!)T%|Y#bS=U2I(J!K;>fMmiPg$9*!;D8a_h#b6_jvog&YcxTk_^I=(#^9 z?2+s2MZs9*NOi4Ae zzXb<65^wd#t7~)g#&60j)C)KM0D*HdbMtTp`mnZYb5vDj_ZaHmMO8poEq3OL1`k10 z1~3q4fOCRlJExc^Ie-JAfWQ{A3NwC3i_Rz~V1VGv2=#lKQ`N{BE_~+~ z<3=h}Jl4XGVI`#wo5AmpFws`Rb@WXn2;b2;JF>e3lB`ug9(*I79*DTyf>=N9h`%pJ zKPkp!8RLQvrKo3^2(zE&BBI-?wE17b4&0@jY-Ky`&0dFlv7y~aO@{Nz`}Ygk4ZqLz zdhnyb@d@aE9PN6D&8b> zSxE5k2d~YO#>)}mscl(3x3dtmj>Bo;f_zuEojj#R-)WhC3AWX?D|E~x*Ve|nNp{qfSHxI6QAZAB>i;jVG^{Pn006?d3m ztmF-jKKIl>Qx4D>SzOO{k$n&(^Bos9Jq!nr?)O(48u=u(i}OtTlT@8Drcj^k=sEJE z2dG%4Jy{n9d^QtWj)i79g%`M3svFEm<=aRen33sFkT;J4b7xaBzLiI2jaJm2O26;V zVIa)qzbBMGGzG+CFeTqqVwX{ zlisBI_i9@;=B@5OWEu!+DWu&6ybM9`zQxZP&<8fO%HkYI6>Y&w^my5SP||09l1v!* z3UO{l@kSu7!gI-X5lb2u4pz6rXOSBe(by%lO%=>i)T`%NZ&J4F=UH!&w9DpM_lP>R zI;fu~Y*emeJV|dA|E77A*{XIP`jWW)<2T)-^j0Z0^%m2MyjT9-w=qx+9bqDW6_ci& z4B@Yf$Psd)*(eO6WPde&SH_;`YoufuIb8&AEfZhFl!2iF zT8x3A1Dd=+UaDBsvZZwY;lqjAqD0U*uawd*650|uKe?UseZr`0zibc{i!iAW98p9N z`C}5boJo90?jTCUp>#U=xpZ^_wagxI#2$G+xlCd@v2vzZwwN|rSl5%uDdCAs+T0x& z4~3FwenZ5@&s4p-*fPQ?t6l}WVFSB-PV5~O_B|cF@WPcyzPS*X@}Y$`*qMANrahCc z5c^4JY~6^9$v}-3OnW<+4Lhc_Rd5&j%3h={@mShVu6)kJmg6GFDax_0_!`@Bt-Lmu z1DK_jn!?S!6r)3o@H(}NO0=$yU82wt9_YrTL7zEoD%RB`V^S8Ybg?tE6Di_fRNxfV z=_mkKnHQ&O`pyJYj^bXweVuuKmrZNjkd*OqDcLGpIv;b%o)_2Xv_19g!)*7#4j1c)kvpr2eLSxuCDw|uSzVNK>+9BGoT89z)UNFC#4m9H<+kW$f zmK5A%Lhw)g?yu4Ej_?_|$aKQA?@D+)l9IrKfrSzLJHMOq-{5!ueVp}g z(yS1BguiK)R<#Jku*O+o{;y={NVKv5wbL(YQxx=@c8-mK8kG;~%{KPGUj2F`zc#Po zUb7UwA8@}i@tn51r=cY>AhJpE^_vkrMkM1wk0*zWw2ULC)(7E9yFeF^SI@~H{hxd zMfOirtQ}{=$kOnLXTu*beYe{L13@(NvQsvd)T0BtX)T+C)9TOLlY`MJi|H}5zjTpo z#z3kUDe}1t7{AuP^GKs`X~!Bn?4uEU@v8H#+?_Iceq`_vUf?ZIHiegKmrLcD;%ih` z?KoeY9J`qa%vNN9%(>Tb$MLhEacI|I{|I^)<1%ThpKV5&4f=1&y|jqcKUe%!}n(B*_}?xL8-y#bNE6wTM~SULC9* zMhl#Soy%IQr}-b#|_K=A@^c|BfQ% zM5JyD-+jIvk?`reBpwIWM2DT?en$tG6yc}aU64ILOOC+?O#n~K$kJWOVN#0%;3)Qm(pzIVd-1h{F4N=(}hrBqZdpG z6$6l!srw6zZKk=rcS<^vAC}KeHFm5UO({<5k)4=NB#DIRerwd0>k0YA#xLPCM~s<| zRX<;i36fOP3zLUr(*@imB$7IO9?M$bFo@DoiiNP)8Sn#W?;GM$H9#r8u_afsR{ISl zv~3Y+zlPtjckWU%!{_1$4E%W8kZ=0 z-$i|!B5(mt^TbrPufsKuQ@hT#qn_jTt&x1Q1H#Eu%4gM7@+X(>5c6NslmgsDBtfI=ig|wn_5V;NuZOW!fNc0P9AFC=MC+5U4+?XoZ!79@fG( z80V4@^J!0TZ7H0rI;BWuQ43IkQwk%6RZD`2{39;a72bUr+a-AodyqL1-UXB?Vvb3m z292Su;3YAAY5aE-DeWW|4&!|=4@$4#-%+I2nBB(+!~=Ddaa8W!Om>zYN}(}Ty3!kN z;KkJV@3Ao74w%c0f{X`Ni`CDu->U=#VxlyKJ*0*PU|As>lR$-WNH{*M0g_UjB~c8U z{B2=s{Gbt<$)TWJf{g0m97~a|FG5?W|rU_J&(m)oAU>5Z}r?H{BCL63i>#I)v zE?|?Td%C19SLmm}Ma}Uzs}`&xbRe^@Qk9le-EZEe7uy4m2-z$rXy2Ox*&c~zU&uA1 z3F!;9sVlNe1a!si(Df7jVGezMFk=*)?|8?a*{TuZAB9%wFo@7<@2 z^z%QJ4SmPI{R=dr7TUic^$c(nL8@EA&yt{xj&aXNv41`7db1V953_XoQ3MEv$sD&_kt6YvJ%=JTsl! z*duoJn8ytY+`n;_#*R~4I{WQ+E3?4O{Kf&jx{Bp5KTntz*QrT(`lyZHZ(wExYq)Rw=F^k}AXvFYvbz=zwe zm4%`bfOCk!0z*)hp~Hh$lyzTma+!G%CWFvAi>l@4U1XC=VoKzf2g#cwVmqZ5U8M2W zOJqAJH?tg0etsw`Dz0sJJAWg9j^X*wIhONh%7P^r{YVeHoN3zv5gbpLoIgLB>uc*1 z&)Z~OBUKCCB7Wq3<~K`Idh$=cfe`kG@JQ!e#*3 zI+%xIzL8;>rq8v_EzhlPUD((=7@pm_EVH+F1KgVxn!lEr)|JZtqOjoQt9F#Hv<>d; ztmyO_8jqmUR8wc09MjVND(jk4r}4-jQ)#dFyPyYfnAMeYK?u^eKE&7M-N-GeNSPR} zwK3Jb^QiP#Zm+W>(~N%Z^LV^Eu=FGbxP#YleH6}TUtA?d34)` zdplNX3M3=AVhw^@2oeX}FIMkSzj1`#0A_9oC~-DHHk7i z#v=13Gjp{Ah?5^#E#!dXEF*5*d#zOLjBI=Oh1f|1F!qVxRC+%l%+67LQ(0} zdhk1B=l>OCVRL%Hw0lu56aj7&Vr{Q^SslBCgeAWjw*}|Z?Bl_pTexsPTwZZ~@J$&ETydGQluBZ7ltk(^SgG<0`(69_1l&?z z9C)o60dXdZYjGd%9ll?!emli=lUwqOWhvmlJsZwckCvBUAg?y%V_{dEKL&6fl3sjC zYOhF6yB8<*{g%YYpO3jybryWx~ z!SOoBpc8j7d4KW^e3Yng;6{`$K+nrrmwYP~78(~TZi<{nsCzI&ErFZ(a=#6;b@dv~ zM`hpxfKXFsO_0}Lid!O1om4f-J()7eF#JkC^7|U>tE`0LBp|6%U)Sw077vM;e(IRu z$f1WOt6a)0j`{27R@?6O2@A9uS_`y^K3TcrN72g~R)QyzlMi^@{9({-D81t0UUR}R z#j+QuI_dZRK3Wg+DM{?WitI=zH?bXekSSg)>+wkpPwYOVb{_$Gj7trMIqNYNC_7)R zrW}{+YSNIUP&TDItF}e+<5`^}zJ#AYkPR=F;0jW6b_9s^`?$pVvg9HEK zS)pbhS;C~~!P7@^!2QJgq`;c*tuR5Kl$z&f9FbBHUU&D_V6Skpf?;Et;LxzwzSTZ2 zaBhl=39-yv^DNDb(BFqk-^MU&j3y?8F|)yZ9w438D|;30GN$VJk3Dyg)BqDTA(eGY zGPjw*k3pcK_6x?lNW<>(b2VsNFY^Ut3S=9+;d{@mvJxvCt`lMvHuQ-FjMY+zDn~i? z!mw@pDn0P!M)1d=de56zI9r5bTfiIE=ds_CB0c3=h7Q3t@O}YLi`)V*6)y z&VRDjDx1L~8V%5s#~m*p{)UOXkSQK49vA#_F57U9NmX|bTS37%qtPa^=gI?bOHnhf zu0?eNEpHq=_zNqPF(T$w>Wp&C_95YDDpB`7;qi>3^;BbsaO|Q(9vF5I3~NvwJ~ElVtCxs+mV=RrHs(bJa~ zlOy3rg9VyeTW$yk95S3P+E?=1#OuTzX_tgi#eT^G;s|?k_@raXe5yH76E8GMIB&EM zatreMr2j$OI|XUdciX<*)n(hZZQHhO+f`k*?JnDPb=6Z(*|x1N8~f{bt-a&yIO}|| z<6NwLlkv|;TxH}OIdaVT8=N2=AdO1GBvr~0%@LJC?&_9c^wsQ~!}q=-ECZ#cQcX)- z*GPm>M_J6rA8+_hQx8T{G3nNh)zbcB*+f8n7inRawS_Yt=Nbh2n%RC3tlFHteZ{ug z2%fc3&C>XM*IcJQ?NacrIaD*gZA=OH#jIMgfqqV@+a%>YoYX;a%`S1swBhXJ4yFpT z5u$5boc|yV2ULa_?lMh?;6NfLKG}}#k+va|5@#Ooy`Cv=)YV!bOTAWYQ69L?o2`{! zWE*xuZ7cTJ;x2WGJF`VI2&lYswx&C?h3DakT%Qgsv5APCH3UH15LN8T`(|iwlC5vi zvDvB2*Yn8lkz}7Xe3A0|Ti!|e9wo>+?4|cZSbg^~EkxvLPnUKmnOnD9wkKeT(u=)S zw1&rzePwbIQFD=>$uLfrNsmZ8x$%nM=ftn#j62{zFeRAaru49m-|$W}xhgs4&wBSC z^LbLL?J|IOmy;eX*OET0cl}J%$tC?EmyA*$@Bu-F?WYn+m4mH!Z^eYBF5}QK7(4-3 zOUoJ9hplRq;s;v(cJ_XOMmtD3;tjQUDp*j;a)F=5A6}Mj`W05g`i9!u@2Du)67+-e zE~ciMb6x!gmNqr-$4Fhd@3*w5vHfRxpq92V`sI@HtpeV%;GWvwYi7HO{4Y2S^Nz6(9kB!CIi5C1!aw=DPdcM;C0W>xkslDRV=2_NgiId_rpd5u&XpKSk>bO0`Id)LRtoPdU{8fa-{>r~(Bu z7p7)E^q-cuyE>2m!1R5>8{+kzM`fuRX=?%F0;#v zw$^NFQ7xu3H&Zc2C9z{lafr1$kF+z<+)U&Mswz6=o;D@sv9t5cpxApmZA?XYyzZwI z5vxmVW~H!k8M?=+sc&aG{upGQ4351M??;n{8SUEW+SZ1k`#{qdFr z!>m-BK%s`=fsOVsQ~9wGXY)6O71vDf*$j7c#g@k5qxn_&WWv17ceq%OYp;{|=Bics3ACd$SU4-m>#unJ?v z0HaH!axiFJRe`j$$&8&tL;`SpuZ+?O8(Sc)fYocVA(aL&^EoFOS!R>@C|=K%Z#erx z0}gFPIy)yLA%^z8l7IJA;#MNJ6$lCO0jiU#{^D`fl6d$winUOflFN!=a48v0ZU!Be znNz4miSj*ulEYM_*LOlZCg`$ChL%a0wwD<1BB50^gc+Jc8{yNAt(V5}+rSjvvp9%) zVgS}M0r_+EZ6Mx)T{T#~JY0t}pc&H#PxQR=^m=E9?!X{rk9F5wTsHK%vfqItY z)bA8|^ed<{aYmN4Gt9JPc@gc^r!A%wtwV6YByx>zF(99%nI*kDkl$r)%>>p>OimhK zE(&G@FLN_)aVFpg*ltQO(t-jIDDV{&gF~wZigU zsvF_63 zq@0RJ4!Q(+NV?;QuX(FS(Wnp_{k!CR2;eUvcd6qa>`u9*v zJ1R-9LFn&jU_(^YS_b=wz5Pbc+sCK=pxe8oy=7kn&XPR)iRgqC95?8bq`uZn(w_yV z(j&i6spnn2x_p(QIi)K4ew&Ykl$e|7Xu zjkl;2KK@3Ksz6^M+&6vj;KC5?cf;_vmqmO@EoqiX4=0JX5Q5yjMPfoZ11t3p=&F%l+Pam5W1B*S5i4strm z(yIgN%E|-Cgl_1%oXv+AoZ&wM3|=_00N<~Cu*VyVN#)`ZhWXRBHr}>2`#iRBKK2EE zdP4{@*vqU8UN=@A|G3MtJ`)$r9Rp?7CSug;PEa_0XikF(iSqiyVrzV<&dgno%88;r z%U7R)1uj^RBxy$U9=Y;MQ~%g~la;P#X`Z0GlO`-fWe#*KNJ-x@<=px$ zqsGx}tpP#e`%-R9={30!!)L~wq7o$*Hd(+@F>C5e%*l)yKLjy=QeeqA=xAk161qKH zUo$m*kQvBA0fE)JG#NvdbYmGj11@Iic0tr%%Yqn9L4mwW3V2-06g73F%)rdzWSsT+ zwYn8q1Y4V?Yc;^Xix$S(m<@>!ul&gMv5bBteP~NiOFkX?74Q6XiP=Ges7clb|>Y zg*K;?q&N(PHkXsCIF0W6X+})V%FqmV5}jp(vcED*(wM2ds;WlnM!T^o7hMMaiet|3 zy%UIek>Xe!gjw@0l5_-DZi(DV%Iw6!UbQ-+;OfP>B`8|2WpNO>RbCM(Kk!E(RpT$_^>R$f(&_TA$mmg zp>!N=7s{%v5R(iz(BJ$&7aD=)dM7$1R}dCk%J6#B4+_Rgsr zV3ljjjgreNVKjGv2DEP@SmAUiD;kx|@8eo;`Pxg#!fe7QAP&l((Nj@W3WThq#=RlN zOE;g|(xo_YDw!@8+B>eF$>53w;{4s-*P%Lux)_2$y|RzLa=*9&YI+|Ancn~*2;wC9 zM$9+TUTh7dWPV|4&K(9TYXF6MhBvZnI5pL%Ak@^VDO)v$|7uyo z)ECX5sA{}fxjBnjPcLMAJK;vIThJ#(QOV5|c6)pS;=2%8Gczn{_XwgshNRPTH!VqY zCb{lF8(H_j%$w01@xGcT6t}fJL(e(Tdmu4H+!0HsQHLhs(_bdJpw& zY|VH%(p~7wVYk~f?C=wq1y213H{1F)NQA9HHmE+`^#}Cm(zNs&n)fW~a?G&C^0TIB z*iZ0ShPeQ=-5sBz{tsWkW}sdBl)~foV$R&5j2X$-d2ME1h(5FGrD|G{!_&vagQHg1 z&&87!M~^Cm*5Ip`B8WrLI8@1&{N}=t?0fR(Ywpw3YU%UHj|C^Yd#C)fqDFXzn`?-0N;yWept&mB(_&W_HK}(+)b1Zy{Grz{sFZ(Yn z+Qr_@rO!cvhCA{+)C2r3u`9F#2|V;ul;Ulx#N42ZG}=aqgg0IE4ub@Ub#?V8=vT+} zv0D3vZ+Wc(gw)nYv0v@M;^57E*hA=0{V@FID&LAC5ab9|$Kv(^`Gyt(=TfXSx4{06$ z(VyN}l&UoyOLWMA$Yj-!gqeD^lZ429WGGaJ!@>w6SWWFND^u3BHID6aN*CxQssd4Z z1s&;=_u2?>TBYzWbom8n1Pv%2S|g4=fX+ZqbJn!i`=u?G$e+MPYsD&7Pec)2OH3ez z?$6vzq6?|m%RNFId^n3R@KYMRTm z)YC=;rN{%!J`+v;^bzvu#dse9b$M$O~( zXIuaiPppA?dknnyGdB~i{;+}54Rg1D-9DdgcW`?5V_*M%OJA%5lkV~0_vm(TgJ$o> z^G(g=?cK9DeGwOpr))vg90{6lELdA{7@Y?;QmHv_ly;XEi0WN z7RmtjFP;kj-sz&&%klO#H5f_t)im6Zz6RH4jew0QNS{8tZwG2zIQ|TIpN5OK;9J5k z;ldDUj^n4F|0Ho@@Xt)?{v~rt{_S|Evj1My^Iu?s{|`?4e;XSrxMHZE*pN-Og#H(mi%l@WKLDRYE#Iky^b zHheyjwT)P$BT|++SWsk1l6mMg%_2{~AxwV?jwm2Hw#GKm( zXG)TM^r1R+?qbxP&Lkt*EQ+e!c;)1W%Jf<{;(3O-O{S#8#+b!mfcTPe`4+arpV&4Q z-FY?E|8O}D|GFHuF=emhe_f8J+g(Z#xj9LltmHN>ljJ*9hllj(;xG%=J9+l9RixTu zHz;0UI7#Fb$bY&V(~4Ai^L8e(C-atm??M!HnIBo1$FsFccDm6SS*dZPcmuGQneMufn)w#==q7wwsI1Jil!w&9kSq(O9rNRIAPG^~yd*zN6e3;5J%-uoB*vpC$?mVF9V$df ztMdw!lA^&YTw5X*9a9;33-_>fWf)yb7zwCoz>nj44Z~)YTP$@4aTkwY0Qs>&7e$BZ zMpARL_nT05vg*cQ9Lm;H9-`W`BZ)lS6YMzC;)Y$ZN=m(j)b_$OO1lC#r^<@oFS*30 z(6z(V{^oT!deYt}9=j@Z|LHvYC$HoDpLv~XI-7qw&;E#S%r@<9|Lm+wM_NbLtG)D@_b>v+O zUyi&OQj&!yyCFou(j1FsdHAY2QUK2Oj_AAqvQ9h^{1>QX6qvui0b1z>csttJQGYoB z&8rJ|RkN`N+dZnB59 zV8^3V)f^S|luZ53u=tzq_%K2KMC|k%w*N*j|M{&8OH&cjT=kw9OEAqy?7Pubrtr$t zbpSLDR~u``C5W`t*>kQ`(1?j}KPLdqB2E1!f5&2Vd%oQhEF@f&H-=Dzk;91dRkE+2 z0>m@K)TDETZ7T3BBWm~t)GVMJv0^uKV9kqq@NO#?y6Ca89r_Kk`lmzu;WPzco;nXn zm$ua_&a^{j$fcPb<5>Y82ui@PLk7k$6-l3tgvPLs)`lx(bo-SPkQ3a+Pwmp{Fd9PwP3en->G`Wcj zJRDRe6I}MbsffIS?olHQAiJ*$G<0HWsV?h!R_P7&25B*nDL`|rNyBrhPNCbASoc@3 z!hlm3dnzfo<|wzbuh7wBi+$DF%wJfMQh}5FNT7+8sTY@TMNQvh=K54-MO=V>aRsX- z9broew(0TWr#Oi|*+Pc?8SaL5V*i2_n3ilf{PPrMYi2u&MvyF;Y?S-Y(Lx z9zl;3LE$gB{hRf*YrxGz&S-h6-V;G?x7VRSjzo_`I#z|zOe0r~l8GIxOf`a=9N^{y z4My;RuJAgBFTyDFp}_VS~B{C-F2^;cy1q^9^XLPQh7=_yH6 zVZ0L^e9{6E^D`yc5L2bquRSK;upZQ2h1m}--@uROq|ZKT!po4qft{`2*?$8&Xywnz zrB(T!%H?tMhc#!1Oio!hxJ^qg7sMc+@(n60vW-d5cC>t{rCJ6_BxToIrwb>=CoJ<2 zWg0J*z0|H}*GezXDb)8oq;=svY8N90e+58=AwZP`;@dZW?0+W!%Kz^Q0I~mH3Sd$5 z+yzGi?Q2u=R{HiRaE?^%&RQyKEDD#*3S0OxtUc<2x`9+>6kd8Q?BPs%OLQ&OLnBTu za4zlEzqxx2k&*>A*LO5LLHKN7CXIm+@HL=ee!}>>Ljy-EEj4m}mT|@8^s2{a>)2zO zPvhs?69NA>N7z2q`oP`gPBob+m(7-oVty4V_4dph_u7RqwyKG$(G(SwUr_7iShY;k zcueEgub3PiH67h1S&b7|MRN_D%75X)Q%nB=7iNgFW-IE? z_?Is1G*PXOodNy7=)wm^XhfjE`7$-z{xVGVcpUO+HtYEfdh2<$Oj4QUN|h|Thz?y? zK=_Y=sA0z>UkAvxxQXu!q2q+E^O$?GVP0cj-G`v(#JAW|$Kk>p5x>>HVmC|SrP+_^K>ny0wN~WfadHNG+7Ps^1lDvQteX(}B zn#L5k77Fc?QdS4@ic48o6TZ1A#7Dv8x~I7+a(n7DwF+nIgBI*WSsQqTBeD*4vdMxV zB__5uBbTAp_i0pwItbBUq_P5`(^UE1EnoETaw|!ri1u96@~aUS0qJd|W2VwTB2s{)iEKY5V9O^&3CJ?SXj@;t#yhJv+4GIiHCK%Zp1b6&*(y96 z^tWGw&p&wKGiZ$7d>5&s%gg&*uG}~rV4wB$@8F?=E;{f-ydG?VQqsrn5Fy)ybUt`zE| zYFkL21>^)r)%1SV#no0_i*D+M$YoXekCX+4mxNqC9Bww>g~nURVNnsw=lB9s0^+Oo?mSxw?lctz6S*Fx1`3UlbfCDs z7o8=~qMxIJ7+7re8Bi$?2=`pY$I^~X;7+82$;)c*~5-gwCZ&Pv3 zu0QsY=8C#tV21^?#wubK(o`}}wTLT}bXO&mNlq4P=6hB|p?l@t8YGsKcN5$Kp@$z< zes{KWh1~ePEA}I(FAazdAF`pIW6MMTx znFV`q-WPRfE!phWUMvrTQ3ou&loKUnX%-!c2*UydxCd*J#qI3YZ)*E=6=xP=q_huW zc%W;UaC?4cx?jjcm9r`%l^nyZG#?TX&GY#?baGr%WWCuNX%rmvh4zGc+>AJs zZ1^b`{py7njRUO6!p$Ld8eOJ40K;pK^J*MxTq=h}wcpF~LT!f}LnK}o!_SRa-ixts+CrTt%ar|v3$LLJMC`)b%$dLq{tVZo z_@8iLj7ug066+g!-1vGj+)v1Am4Q1unkZn2aih*0uZ zYSaBTCweEG<2vGL@t_|{20&{L@0%GzbMwpiv!)wp$MJj#xBal+#-Lq5&d9)@a{`0 zh#2>sXc1-#uiG_q)&y!nZ&ls9b37_O>lX?77o}1NJ;-@yB@n`Xh7Uec8A6Xi>!*C( zK?AcI;sbFf1;V(6MJVqTjG=dVo@>)*_DR(bjNj;ZmATKOe=1_5^RS(-cZB>QWrn6aO`GSQpAyb#d|Q7l#!2crd8qDpR9Hpdd0Kks*#SWFl=w2%)_bvzHWj z5>`%TeYu-WP0Nz<(^ads4MtT0>-U1iX7!pB>6V%rnW~!B*5+1qopa$`p5w`JTdyWi zkfA@}@3&iBPn#~E$2mS%9miX5Lmv{4{IL0onMR?)mTg_!cdeH0b>q1f4tC=<^EqCV zc{RCoxwYsuBy|(>R6lJtp-y+R>lf~m`=dI4TJ5%~ zTUc$6$E9mpEkDJ%T~KCvhD13ETWgP zH1s;u@qys}co_zxiWx1I_+9G_tLKhfnZJI?NiB-6qwDC0Pp+mdpEx(e?s*NoHXhiv znyG8~xv98WX{m^L$$9BniFm14sfpR?nE}quO4UjhQ`J&&vSMn9hou_bI-06f4oqcE z%?0>nI4sw@^;+Y^btKZ!Z7;m*)^}}ru#V_2EnPbBwjQU{TID6eO?+aOz56C&7a0QW zt#}sc05f#6KEP!vuLhnHTRlG!yOur&T8at>U-dV`PBPy6bK^rbOjP5x4N7+%mEMAi z%I?xaqn2$;D~eIeR9?Oot1F{=?bsODaJ~imTy_VaEoh1C?<}b6a0wAN<`PW$ZkJ=u zeXAE`d%tghf!5|&m$_SbcgAiKmY{`l&pY2zN6p5vt`J4D@|QKgIDDw-&R*hlf-)G=GlvlN21>WSnZZ zu0i1#^qbJF#U^k!VLh*p&dRXssWF?VyaqP9g{;SnQL7h8a_yP(8nBf1lps8Ln~(#Gi0jXLx%t+Xsm&7laobwdhr0g@z%JEOd1^zF z9SJVWmfc6l$!S)&PfY)PMw_&D)I*BYCIsx3Tt~=AX_naMx7ybG4E7OcX=8P% zJ7b^OP2ry4p!XxdJl`|;eZw=DV|NJ&6O*eVf`t~@9^Z*5=I-!hF5S(myLO6P$H_@( zHz~+`Dm}b+kknKHM61ZIZZ5}e>#=kI2m=$1ZfRQ*WTF}2REwxVNWQ^Z7(`A)k+l)_ z0F!+gjgD$n69OgzS0CcT589tl&nXXtjYdVK)1K?hFR^s&t84bMTWqxp(^$o5MQ=l2 zyX7i~$FqT2j!$Tp%)lbI&pkRlyT;Z&#Nc3{HOz#P;)Q1| zaRX14Um9N8ZI`vFSSUl#fe4(UAZ2K}3)#EQldGSYv?e7@VX8v)MWv~xJbb614}M7# zz(+HaB$mZVS-PvVQ#<_KNevd_j20=0oB@qSbt_t)u*XF`=L>Wx)~qp3snetbwouRc z0b7)-HJFAps?&{&qMUk-i%>brIVUwX2!SwaIlDCalt6N{eLo;M6?;|24h_4Ek_ywP z#=;PYrN-`W@hkW){$ph8V{^E3XpsbNRoS7GhW7<}vGgb_WmR9XwkTODZC@Zg+I-2s zuC-TTLQ#P{Rol2@)61RA>gr$G=ue8PaXx)BwhvE<9V<2y|FzBUF=7q-9KYK^-&U(o z(Myh>_9L@;NOkE}8ZCXFdO(CiOxQ%q0oMsG9(|5sxm*((KLTpYJv_Yr<^Yf0iQ+AV zcmcK!42tUUx6t0$E+hKxh@|Ua^0JQAGb_IdFgC=9EjTLsT5BMKeNv~)jZs&|D}1R! zfl>pO+4G%zPb*9!Dg-f7&q-_`pX9FBtf)sq2q4=C^{n zf67?HVkjrPhrX&B%_0Sl7G)9;gFR60T{qcVvDT^;4^;P!Z0ap=CMk|e=;SeV@Fhjv#SL2QRz%>AQtemH>*}Pa( z;A5>jK>5OLjDHnyfX0$my6fKglNrVqAMZlH@KEFS#$T3&^6Tkj>dpntB{4N9c#pS_ z@B-5aM?S>M$$DSsBwD^tH8C~^^&PvfVNdIB2BYOmL^ydn^_~7nM+-Aoe_N44!pF?* zumrBfP0o2r1IX^n-@D3T3W!d?Q<3@_O1FIGLF>q%!0s*HGebI#8OsX0jk@g=x_xKr z-9hW*6VE_X$+z~?Qg}{|dKr=Fx7ic=NwmQk)H)8y<#dX4o!eKT8Gw5Q$Z$1!lNEkP zK!ZvA6~r-!`n6YWIp|P~gpQy#8&LCEQz&SQHmf1rx)ie4M-9ys-!vwP8c0WH^_dqX zrkN82FrNNGs>MOdwhPHj97Nc1H38%N8bqGu*xXgfc~Ip>LvJj9_wQi1xtqidSxrRl zo4EuX=s1$Pb1LS_DN$^UVu+U9_d9*fe~+oB?KSOT7B;pgQY%5l7Nd-bPh_IPhOJJK zr{q@mg->e4c5HEV!}Qxed=m{yK&#_&!yBqd5h?@P!Rm!O$}Szk;&V9#HUg~Haq;UY zywge?+VdDbIHiCjnt4$YR#DO_RvkYVWckT#~$UW7)D`k9pJq1Yfi#cob=f*{7`xwAdK)6L;(*Cb*?2D>780P zF=-vtXif&{cdR?LceNo|d)2IZOzMzm)ptF_ZN$O%0!4`5(Q4gPJEh!Vq6StyvcR9k z53Ef~fzRY}0)=~cNLTfc=~hepoC{E5nNcL2l)OX6FQ=CPyq>UALw1(13)E_FoLnEh?qSB{}3?|V|>o|T=dK?hSYT@XE}mlC0lpbM3LA$ zw2qtn;)|{1sxu~n0s1JNGDV#UTu}_ z0#_A_8s0+R!Z0#dgbqGZJdfZ)<|hYjWlM3OQmEk^lt<R#5Ues~M4(k=4)0QV_-&=&PHv83pK@p6!TbzQRp$uMW9<26JXZ zKjTa-v13Q{kGP6~D;?Qb+r4_!eYZcO>b={;3=QuYNU?L|am<^aRrSpD1U& z%D}fH*X}SKUwjKCf8pmkza-bg5&M)XM09T4)uJ#L7X_9K0V2khY`;$KD_`5+>a~Aa> z3ZSp)5EpkIB@P3EY-T4S+PTu`e)r-M}MlA@(V=jnPn_)axXEj0a*;( z>Q}k*sdMpCSLcSiU8+d0Y>s8=mTv)(X|-cV_wC`vk@e*ImGw>WoWZGsI=5&B{?3`B zy_4PCZKbPFdqK_Ob8Xb8eBJodY#{YO;0_-{@Z7L(%jD`@ftR^@hi-N!d-jI|6fxph znfLJH90XP_yUq1FvyOyB51=Zwm}1r-Vu~BB()gm(VnzVSx2;-{?Y(08HI|QGbk#@A zC;XxN0O@lG?91*&P! zS+B|&-AMbsG=$W^gch_P#1NZ&3}LI?^e`#Nl)el!Riz^bT~)nf$eV>F+b2V0tPjfSN48QtRTn)jxQ)xZerAui!ILyBK zy#LicXF2$;%Si}<{%i=y*Ita%ioen|I~TmvWBJ3o-im?y@MHnzW49e2~r_Vb>a7 zdva*TMDW2KZ6TP!&eLc<0Mi7B@iLkIvH6CaE}A)X!S74<_SXIyU4ArNceBm+?y)WM zOfQ7dMSTnvgHUlb{NYnyMa@%2;McQ~oclYh3!y@|kK+lc{wW;<7%li)-w)wAG8(#{N z2>1O&M@$*5uA&VH(?jjvcgE2H()j1po&-7a9@a(0)-R}>wA{^D0uPgUeBPya37^@% zafYgQb<}&cw1;!r^UVz5?U_SGKUr9=-uyNT4wVCzdPqqK*y6Iz-GxN>$2~#Lxi-wx zt{7JV5 zG4`d4<}NmiPnzV}5yt#Ga1+K^oV}Fj>&6ZfboJB6b)3C)=>LozS{gQLkIkc{FwstO z7E`J)X=jExjb&!!n;KU-qnFamGf89y>Y9nu|Y{9gyhj&sVT`jb!$_pFMb6 z*11}ynfFY}L*GNi(JFy2k3uOz)j&MICoD7Ep{AKfGRqpsA#;%+n2Z2%ApvX*GV)*^ zxiA@-XAMjwMHa;$i3Xk;W$1^kPBQu!4@|IyjwWdp#XA@Ne$O)U2QW@EP24dVIm;Ox zji$^>cqtifnP+%l9`S{F36M{KsAPmP8;G)Hg*G9Ni;nGWy8U`drUcbY87&}(z6p0&YaQBi35BU@|NbMkVt+( zK&B&m)^!L~vWpzqY`6huvdF}NL#gbUEL;^rEhBkkQDQ=d{aA4xwrs|U2t|$*KMNJ3 zS>u!{vY%lHiLU;uBY3n1?a`emqT8dzF3gd9!U&Bm5+dYPko5eKw#|_kVhsjAX!oWy z2Y=A+snG6yN547#XVFg-aY7zHU0~JHz|rhL;KgxKN~gxPZ>d9|*UB$Jt+_<=G{e?) z`s#FVReM=9ee!2$)*^V_w>I9M$%=fCiBu?s1l5f^_#y zUcChW*Urx$L)_UG_@tj0qmh3INpAEG$a}*F2A`CEd4irN2b7Wyut}lorl$npBq2MI zYTsL za5DWb(<{X$NvPOn!nZw?q}@lJGa;rHrb()+fy2Mm^TnP9l{&aS?mxUf7TUreLlT|Q z5m$V0#NJLI0zU6WyfrQOq_^W$?kQH)TNnpP76`!hBz6&#rmF^c%EwDYU>^+dz({^C`y;KHjElU0o=_*fQ; z*I{UfT?L#Wi}^VhD>%0lR-f7I+L_?P2{HHwc~ed3XL0zpz`RYuWgO}&#Bz_2!))I} z+1CuueeLHx{zrV=iGl>0Si?wiQod%Y=?9gVQmWGHyro$Tv-(f$vYdjL-w z97f;!gW)70Wg?E4af0(PDVlOk4dXd^vICsU18}1X_vq3KQ?#u^DnU!6Z!pGg9SUcb z`A`~HbAOjogO3%v$6Y;j_I++G^8MU?zx4Q4brT!J8wT(uMn5_3OlADx?V*q#KKw&( zG*FW?E#lfTpB@XPPklZDD{XcmZoi3B@9q+w0l_H7QcB2}L zk-G8=L&|azSh0*iEogIQ)kDz5BmN3wc4(}$h0tv7Z0mFGbCJn{*0o1P3mY97JxW}A z%i2H9ABB*xWYnclH(IgcIUHridKA;^%C^sd&)n%-w7yy@=R#!_mGQWybhd z7VTVQpgcquq91z9!rHb=Vr&DQdP4z=Hl$c_8zfF+jC}0U6e4#AS>edFvLQL9m}eBD z$f)(K)bTp>WIOWeM0%SCq97)dU&)4j61rC0X$8tcV1VMe$^i%g5hsMUHP4jNn2I2f5{o&Mu5U;4sG{lKEHGkXRxmUcNjKTh5h#RtH zX=Z=tUXhijE4@dfW{E5duObcTt`hq<=enn~&KrWc{yM!g5Oz{?8x0CFN{Ku3E*VnK zvd;d?SoZuDePGJcfQc}6V^J8Be>7S~=9xi=p=6rMbN4PdQ#RYPcKn4Vb2p>whnII| zV;HQ_-}>^d1}N9o+3AB{)X)|r9=}u4W|V|}K^`*hILd9_(o;kdW7-2H6he7KB2^LA zu~Q)YF2tWIbv2m$jTDn+n3`AGgnqy_$v`w(i{$(9reH(Ru)Se{Ft%)a6J@f;UTX1;FI3)OW&B@ zBa)vZKYz-TTsDeig%|S=46`O*S8$EIg_n+#{8TRIo^ zT9K?zg0=&}OC3|vNg@ir23{_lfF3c=pRQNswsh!;Quy6GM@1m*7%x#zWHNVSH9q0>4Y}?5 zT--^<8+nOhO7~-0x{h=He11%M^d`rD-L*Y^$L%LTt2Xh}Z?it-s_jb4T`HqFh31%7 znL5<&Fi-Vj%XPBe<1oiz1F#*nlZboC5gd`Xv8A`cv7~X?sjiU^+sYirnPjB8y0@T# z35CI7v~bbsErJ%TmQ$S=ac=eVZ#H^WB?7pF_)Ax{W4kuC&SP2BCY>+lEL!tk$m?>Zz5=#P5_15kNfJe(~}iDkU?yX)Nx5%CwQ!mQedu|OhwrNRuuWFbYMOmKb_ z5)P|wL|?-41@jvbH!yQ|q^kHOBkldG$Ov)9L||@|5eL;jzh*_rwMREH8vjFMcJk59 zt{j`u=~T~Muoa0pG)4V>fuio4Yh*)lm{-Z4dT~jHv4Iu5v#hgw^(>s5&0OR`@ydOu ziWti}Upo=$8Yj=X@->Dlu)2v!Q?8`+!wzuxBQR(S6#TG3Kcv;%q&@R!P0s5RTcZ@;;@g z32aS=7wAl2P>7e;BfWve=t2XgEsX9l&t%CK=-65&t&I&bZjfEVDiL57J=l968WkC9 zrBav8X;&eQrW{@0my<467IP`HQkNdF+uj~GeP!?Uw*;;2hpbCn(}AgaJk}cDXH2?{ z)8Y)cN&ul?naYs?VB>VGm1<#rHEIBnV`j(~mBI}(Ra`;tDB3Wz9OD(gY{d%BSX=;i zbmfo;-r@%RsPM8D8p()C;$rFl;O!oREN!?oL04s^ZQHh4Y1?-0v~An2v~AnAZ5x$V z<(#bVOrP%PGjH@vOng80e)jLZR@~2u`@*(H9C;+Ro-WZ#-2EvkcH@>Q$>{TGViR?G zLD`n(O;Nr0;g7|TF{){NEwv2qth11Ahk}$NXpE)|!EwE~shHeZVWrnH!(&uU{+qCL zTSZ2HT%u7uiFQXtA%Mzfo7=wU=ESUTA` zY?@*R>9LALfsTerZHXb@n)AGH$(&5ItXb@CY{dWqX;x*ml6hPbr3P$NfU4q?@y{8@ z$pAkfAmt{iSi~DUW$xf%4~7so5aeG(x+K(;s5QTG@>Oa6<4-W)n(7(1|EO>wdU|Ea zxRyfs{Tp9FW?9nsph%~+BEx}ku!qL%3NbFc)w+9^ryx#;qLzZYqf6HAiK-+=QrwyX zrGvI4F^lK;8^8IYPwT#(4j~P#g76~5)2q>$* zzXri`BA}rO`)(oJib!o7o#2E>*ihQtcfw+^Zc|MHmIpJA_jG{-iHSU^u#Wu37HM9g(zXK?`4 zS}1&Nz;A6b36uT`(pTHJw76oApD1A@6j-JxUmo-5m1sd=r9yCc!M&8{*Dc&z-0#B2 z`Shv{@BvmW8_4rGMY00;Ma{<`dV`k1v`2Np(Qf?NsSGQ9*p~@}+5OiE(NK*F;RJ@J z&;UIDMoHH?VF6^(TNsL6^e%BFILWo|6sHi|k!tn`0mmn|CxkLOe9fUu%f`{lWBPvB zYT=FI^-gJ-g(a&r8U|g-4Aa3K0-jPCy zkqfvO?%yM`XYSM){}iwIAJ@Rpi5Wk+38a~YNj5f|Q+#aa0#_!02KN4mvVwGq>I1Gk zy-%bM!pX13#hk9=rn>Nf<@@p$E)XFA%O7f&Wx|1-cn3n@SPAG)wh`5xp%6mFu=Bjj)vL)~v6m_FZ~LUrOsjt7u? zr*Gr4XY#*p;m%<;bUCrax^yv-xmfU4x#-(<$I?R6L)~KW$%|<<({ zBt@ESLA^WsQ_w9NVYcgwd*Ae|5}~=oms;odvKSen{xjyyP(-&cR3ue5Tw3~0cuiyy zYmRVpYpMicWQXHcZ;=`R$ZYBDBBrKqW208XRI^RyAv7-XJOZP){zXE{Zv%64<$%39$7?nAUm{PAx=bq@Dc% ztT7ETFj^{#7%1G@(l**G5mD?AO+Oi0oeXUm>BWew5xS#wblig;b_hJY;g%WL=We1H zSz01z3!O_zCYp+ZrfNqW4lcUv(qL&?TDd*5I&)>A)!Ym0Yf!VUEF}<^{{7q)g-j0= z>o{fgr)fGDUG*=Dfk_2sfRbUO^y^B`bHWvKyffj?{_f>E0^Y%}nvgtRD?vBMPXT@O((1CpS6A$Pd6vM+(7NNehy}g8?sB-VkVQbXU3{>DN_rx z=-W4EnJx=Pg8Bu=;wIa=sRxTXJbgDL2Xy-W@FU?Mm+8_@_f&qmVtxHj5AdebI#EF>J-7I{b&{CEY=Fxp? zPt+0^e>6&x;Z_u0FE^EXbv^sh`GBcwPUIO|+a=@uml0NX;90ib{DcAebcWNYAa39y=4n#JaT1XCDEpG?AvQ7zQ4FMbyWjT?^5+^{@ z+p1Qrhm(6%>7ZzbyVZ|AoL1Gu3Ae2&?;ymt*9X!f*9+Q*fz*?HpJ0l|+{bi{ydcH5 zNPdHa8ri;xG+bJh2c00?}29mQw*e8EVU?eR|-8O3JRfJV~L|;!t zBZ5AUA_T4-(oN%>3&#M0<{-*GHL?_Dj4`nbuZg~10)hKMxwoTLC6>NcrMs~N$X3?H zcHt}}-9k|3HQ_SGv%6dSedH=txQI+qFCP?6)FR5NAV=A&?3jL0CruazjGPLIB*Te} z9BGLP(YUJbh#iFg`xz3YJP=Y*x@W3Hjn~*Az+#&qXVveiY{kDEBErGY=w-_wXGfzi zK5UFk3gMWaITrfVy6x5lMuimSZb#7*%v$lruJ3pAUyPaSI2kqOyq3AEQ3R=S6yAk>-QJR8 zc%XspM~ar50Cb~%1w!z4=^m|TxNSyh1IT9Aa~f_Z4dR(>9nhB9aVK#i*~mxc2o7`*QrPr|ZH@vr)HZ`nZT7>)`h6R_S)tFNq*3;VGe zcW$`vUET%X|0L)TavKlpM$8#?Nkjk(xO+M~Ft4Rwl#d3U3L=EN0SxG*;|%Ag#yvHw zg9LCy1ga@$`gB80{@_t;6|7S9cLR@gvtOxewcSmLk|I^l4UCYy|D zQl1{IjV1uUXM~b={y=t%Qd9*_u(F;PJ7@p)o z>0+p{$oqvcL&ZFoNjQ9A%uMC(1m%nUkoS_-Oi~&XA*yBa(TWA7d)5S0sy)bLdbK1L zTn-4HN3N7`I}1P!N<6TDMR?O4eACQgdpvUu9(0#{l;L2Pxea(~aX8W?k-z!MO8q=w=dlnGJ1=(HrrfeRSU~?_#fU*Rfw>oVh zUiB99_dL)fDSCgsvso^hF^)CYU2#26T4ArRGeEi6>Rk!3u=zM`fUxfJW(2*>27}qM z>Q48{nB5{{49SdN))x#uQ1h#?p#)XurB!-ls>k=0zZ)ZSq!zFlS4a#37rwIu{~m^@TxMM?kfH(&)=d4f9V75GfEW9+*%p;G3C}+H58w zuJ%BNN*88%tx(TPlCGU#dxUpqA62*o-(9Fr1JXO6G_@FUQQJ~CgDYkCD20T{5C#n z>sQ`!G6U4dTd-}v>8onp-1f++&0Mz4Z2K>7uJt%i>;y;`PUkA8i^OvvAznRUIrr4$ zoY>^N#4>pi7S=0k&3j~IZ259}f?dJq8j>?wC`y%)I`}d-O{h2x_-ua9 z-`}owguB?N^nW5N*8G;IutrEOQW)=t1!F*-4YE~0qa2BODKJEM*m3NlEwom;`>7+$Ww!U+RPx+=a@+QuAssz2#j{?3{Uqk6Ml6Ojyc zQ#`)PqiTE6)FY^B@LfBIwG9-<5oc-sp(U}&0LrR=(eX#s;kim10^7W_Yi!fHo?*-( zD{jNB;roDpRKDB|X9SfTu-1m5frxtLbL(XIA8e{w(%L;foXkRI&nEg&RISXQgVtKH zseSuN;+Ml*ajiY@X0fRw6hG`i>pw5r?Dl_}2sK z=R4he;<$8s(<)6L3ClV|J~xzqsCNBsFsU?r!`Z%lE%qwK-CSQ7bJ{;*%rXCeF82RR z(D$#e{vR0T|Nh~B^TG~E8T+%N$#K30n+6gUBqF>)+ycHgV8NWiDvXt;iA9b3%=s>! z)-t|swIOdOs04e@OV^i?^UO5q*OH;gi}3KRjls;dM|+`JU7}+VwjtN*e&_X5=k%Lr z_0wav!&mDkkqia7A$tKpAy>X?9fPWXEIyZ5HYB*tu+)_j>DZ)%CLOW+GC7XX(l8M) zsHrq>xWS0%0qAHjo`WFb$S+-#GNJCrm2onq=x2VMS}V=**G~Y$<}tkWlp;ziEELGR zJk<)B=WN^>Mau5A9pUGYVR$q+NsaKCnY zgFKCq`KeLKbW@~bo#_r0VBZ$%_R?ZWn#gK}2Kw*;h9NkdwNL(k5X`nXf9ffd^Wycj zHFX{7*Vb6kEv};+p`n|cogVK+UYmu%xHR(Psz!Qp_VJbVO5|&Qo=~4M&UJ95VD71O zvl`i-osOOOi;TlxTN@hJLp@%*(-A^-D(XZvOjbIQBgVN*UL2U|Uq+&!bXLx#A5CtN z_?|_^9$H2%Sp;DjKvo&Dd#Y#Vc{SB_(+0XF^VQ z_=Xw5(%<^e4ux_;UwlEQ`1Q^W;{CyO>8yCzn(C3z!uc-gafLK^65p*(H)>LyzB7z9 zVS9bPqzuxy&E$xn5T%OY%P+ac!AHD{)#2Vv6TL7CB)_j2opk~SRM}}&^fXalKD+X? zJ%25wJ9r8W>xmM55L?D#}xCRBr1+qx*z-xivsdbFSck1ep8Cb+uN~a=!JFpBN7T z1;^F*(GS?FjXk2%eMOua(LF}kF8@#}y*4Qe!J{zQcJX$#a*zL>enTT$v^bpsGdvxA zp{2j#oKUp72qf-q4dYm7&~_3U&Td*A64yjcex-v1kZNcBG8==F2mS1Yu4lSRm`s4A zqrIyyXBl{A(qGpq6Zu#YK77M|sXUO&j8jahs2f>|UKAm^RLGAan-{~#`qE?w%!zdQ zXb5fx!r4FfMb{+mqNr22BcicYej&`LtzvM zYtSvzrLMSiu|5$UII>bnEh9nj({6m^s7^lzXlb_ z*m+WE06w=71W)W<3&`lH8`=;Al;N8;MdGhFcp@1b!^C`B1M84mgk?}|N*zQMUriW6 z2s|(xQ&Vytz3g%~-zS+i*ZC}shX#g(sV|7+39iv(vqQC(NV0g5xB@-US(7wa!WK@Y z{n2*=OPDebIK6&l6yCuKdIHp#GzYdxZy4Uy#{vhphr_!Rv`4wu5Qi}LaG)VYP@f2V$C*tL9`dEBvn_e)ML` zZLTQQ=NTY2&bN7&-hxXvDxQI1n{D_i+t&@MMPVI2N63rHjUUWQxBS9al@F|R`Y(hT z%9=*dWnTA&CG$JhCyXUNyk&;a{!#djuH27C6k>Z#4s)s@@m#GwHJas)^d$=cVaUZ1 zcwdAxTR8qP2~(_02x9z^V$RV_S43Z6LyOw)E;Fg+HHinRvj(ivfN#v;>`sLgWf85RezGAOW6%cfROr+c%SeVbQ&p?V`)`l-Rx?FrMX4wdNEc8o)L%e^cuy5ZC|M4we?7w@k3;(~E?2~F?s!GckpW5nM6SjVKYRJs( zjr9IRKhOyS+51Ale=P7jE(G%i5C27L=6Iy%21%uxsY%V!X-lmPE26{lN+su5o1As$ zNURbZb^rLY78hT-Tx-P|&!qOB_7Yt`dAqz^xm-WBZ+F_zejHD5d~;I`!z>V;?5g(uFyOzdN62n60CIQohnENy8#9|Ws_vOpZzC)W*5` zljaThczvNdx5$8|VpQSWKdri38tWpdH`i?P@M!0O9tR}ZSX|qAXjm*&88r6eFRWfWE={TuX^pEXuG8ygMhJ$HA5asfCyu)JG~1i*2?;hESju zqZ6&gC-J}7Ax9`siq*z0^ruETxWpa@R;L}|Vo!!rAPvpVmx{IL4`v?&Q6~_KH4MV1 z0)eor2o&!SX1DI84DOrK8#s{&28&dy=7oEP#`bA8G=_FICgN0;%g=^qiYS6?zUj_{aTgt}s zD|F}~wf~0fBS2&W4=S42e>Sv#e#-(|jCc@vM8)vXAifpky7!H_BPEw*|3V}|#FG2t z3Xk>uEs}rpnr+W6L=?HPAVRCo)PqoL)|2llFGI|tB`H}YBgB3#eTXMOaPx=9D0lx> zkjALlZbGs3{=IK_Ek#CzByygFpOxk zWmSl&Q9T=a=t-DS@aM zR0I0Cezd4<=oGpazO|5;X|s}6XMXT7`jSavkX?_>h>1B|I~fPg?pEN{_VKK!(jE)g zzE{Gj&AET6Wy%PLtgR=mu3k$PV-U6M@%H5GN+cIc|5cFUQ-%?p|0_u}nVoMmxE;Bg zExPXF4GQS_#Spe`zalb-VIuXMxGf;C%;STNDp$vK#14w5T5q84!kGmo3Suxe*{q=BH4YZy1=AN7x2tl7>o`rrGAF z$topuR!_hn`SQS2#`|uqDo9VC1!vjSJ464X$`4wwR@b)FZMv2c z(UQ-&mr7o?GwIkEVY96k&~wf6jw~`P*2v9Eo`y%k8ZMP>1vk$~4T4MEt+9%j5W29& zZ~h?hwBAhDL5{VGZskq{tZ~69rhK%q&Hu7!Zhs0N=Dp6;?kqn?1*ZUxI&NM2z#ZOE zyYrtG*vN`Pc4q6now2CsgcW7-c<-<4HAZoKuIR2R&J5nwGT3e97m~= zYf->gFRYgBW8C;TVoTIX*DJkbe_IG8R=w@NsC1`Nwj%D3?{m?3+~e64POW)JQNi&& zq=02LoRg$-T)shPPSXL!D%LTe$TYv8IUU(5*)iX#u2J$g>bcRK$|##A*?P11mNg4i zm-26!a$&oegUu!GK@Z|>lf!Til5Oir)ehO;nM*)}Uh&sWsFYozzqu+^2H!}QDt3bk5({X_mFQ+63bS|f)3j{0|7tWkK{8BJ| ze63JAAk3*#0iv`dqA#vV>WTLc!KVwt1PIH%6)4(tBKuMvvks1I2vqtjFGbc|KC>u(4y}C<>KU%c#FZ@`~(UgfiLfq2S0U zZ@iOGm68%|rx*m>+#P}aAAJeYm{=p+gn-RdRz{R$Mh@ysQQ|@(EC4%UsA61y$&FNX1?RT16GD;swElsrG9QGZ@`HGXnp0L$s&IKDs;1eE zr9xv&OKAb3IvuA+&#}?$=({3YH)gSY=QvJd&pCB-NV20K6(fEHj zTOxWa|DZWB?xQ^yLY}xYQW?mn39Kx~8S@=mAes#)G#UVPm!;8&u{P2K#p=qlUL*)K zG0bh1V+4A(>Z1O^-~Ll#@Iv;Eak`!FaD()*`KL_?k+fXuoP}fyiOj5pMH~`-8Ih(Rm=qADAar~GEnV$(*rTaBg|Nmd?R3!L ztWy~io5nC_n^#}A9b(kh7@~igVk^!G*H3^$=drjG5ZX_xG$!24RN?Knnq;U$6?}M{ zs`8tn4Tj+nrfT6%tGd&ot(*TMk?l?Cw43f0zR3z>n1e<&6mqzwGqKkFd}Q@`m11P+ z|K(E0F&S;kQ!Tk8o)tb|2(t4wNM4DmJ)$7~)wZg2GjA^Vu1{9|3u1EO&UD(^O5ktX zDl})4exW2PuP$n|HHj72n&Vg7DwUwIqJw{KS%BPv9)>vzHNcbts-pZOBOIl~q@~G_ zo)^*P8eQBGcAza-bj_pf4b(u8YmZ3#@>Xs7CiEPKMXyA)R;Xs-5gqk<5+KsbQxKJw zVd7rbHj`@=>S9yVHrf9QNXSNw&{oue8Q*O}2^&1nW@>LGk;-h`H)zsso6Ey!hnCx9 zU`)@C>u_%1$lWmr{`f2ub(~_t5F(+KuZ2uu%=ja#bP-gC_HjH44Z^Ud|JAV?2@IGR zVZd(D+e^|nGf~Nf?u@X&m*`|9vCq>#(IM89o0%)yu=fn_UA++KXq#jSq2&MkB;KJz z2WW(!&s5}u>C2=1g=MtUxPEL9&y#RTXT=?Ds~YtEPU;dImk);@&EEQGR4a3aD7SHB zn-vaFveXbZ(WC*6DOvG7hcKx^J~A|RTiaMflcty8k|YfTFj#7_LsK5xM=MbD*YS(a zKMge6sdJ%hNPTaaL7^atC3x$6mS)M+d~yoO%L5ly-tcEt@c&G{3rYn#gAjR=%w+j&vwU^yS;h^K(X zfTGBz$SPD`)-Sk{8%wGhjOQZhG=GFd1H zZ9cbHc8m>1hix}vmRaH9YtUjEZR0vj3F5+3L4muK%=U#MqxZ?g{R#LE&1AVs8Wo_O-&BYL`qycY}M$#KpyI0w5FaCIo)_i9EDEI4?>V_Yhj# zpU2RWq_5aI7@x?wjunc+iwaVdt_7e^Z+6-;4uyld19^A<9<%#o|48+LuJT*_?EP@2 zQeI0OvIO{K4WGB;>ogn^xF*t@1s+mEf@t|~uq40}-G)azE77Jh9wwtjEIJUQVIE_K zMx!G9beMY+Q(|FOsjJ8m6|BCMbFd<=2_yL@Rx)b5M#Z`bJ7piT^^ZL>;#b8gN)_n{ z3$o66hgTQDiR8%^Cgf+J1=Y;@D;Q8ES#R_Q5GyuhvsAvZgYq+6Np3JDp}KBZaGBx2 zSH&u=@s{-OD?dmiryB5|$*kC9Voib0`R#tdz%L8rPGniY__?)CE1_7XlZ|Tp_ZH%* z(ulT$6blqBr^vJ_p#cy+556{u*FW)@qbA8}57pu{o<=*BQ-&0wkQjFQx4jY9BVMu} z4#{kucDL;iEy7=P9}kO1?w*_B8|fva$+@Firh#lmK~&m>KGzySKUyTMrIQA=!#8El z5Tjk+(V$^uiDr?ix&e^w&cTBorjT$MzN}G>AJ&)|{uIS$l>*_n6zqjU%(ZM<-PN%- zw@9vQDUXuC`^=wO<2HMkRol8FPPUNMFM2s|42ZdKG4r31qE^B*+Hi4Gu=Dc>zw`22 zaPg290mL_G$mqHXt*?->I~Lr6S8v#xa66hE!Ph6BZ$O1OPl>4bWzDy+m&BgtB$R)O zE-AlgnOR4-W_RIsb{5xQ^YGFZZ{4s@YOUXtf6rSvOSeb*K&YaAA z<8eWCa@*Ja_V!BuInZ>iRNIy}Nnza=*Mb&bWh8NL_udl3i zo~9K^x6%3hoHmn@UBBLHjr;+P>A=q8dhoGzO}qVZ_2K>0{xo^`nZW~>1M9O~6S%9R z%YKqd?^$a*u#1Ij7l}?Vtaty@mK+_I5h!}eRPOyjAB$5!IM~reV01Hs7L9&t z-Q*H_)afn+hsi)xM>?wc!<~6d&tmiH^70(R*17S?(yk3GgBGqow`!2_mNXcpo_k~C z@WK&B32tG5Z9-RFSG&K4(a>0$dDUr4W3|~x#p)bZRyQVH|E1#hB~B-;i>6aQXmFmo za#rP(d9bmAqy?zC`Por9LX~kvsZ~a`?9iypGVyR)w{zC5`SC;TBc<2TT`lYBewh@@ z{fVRUGP6$QzjCE~m-6}gq+Vq35Ro?VP2%G!s`LS*h-X2f0(`~n=H1GS%r!fT6i=F+QMcb>5f)|l*kJLq#`sR-y?*u*-K?LO;dD#T*Ng4F~ zOubXzpwKBf%4)I*n$=mT>9X5}a2z5iUndtleuRJ~K$!5Gb4>WF0h{d@Wr=0sH`^aT z^nsWi?f4%+*>j0@;e+^F9+ATr$ibtD=HjdHH`%L!s8foO4J+_l`a3$T08=0ySYZqM zBSXy%%TtSm;d60F08^kCv5A)Aj|01L4Kwm5L;Z%0KJ-t7*xM&ZG77@)$EE^SrwGk9 zEW|GdhOn*h7w-sSw;sX_?xXb?If(`XixSJ`MUSn6db|JGje86AH&+s(<|SGE%9XTs z*@x3@e+bjEo)ss%5s6gT*iV3qv!JD@8qL+4E+oZwuo4t(FiqSTyja?ivS46is@S-5 zqeh=0gzQGV1xJ?9?cqhd^b>@%=TEbvM?_G>Ru+X164^s-1w5I#(g|t~wMGp`jTrsj zWHWz$#1d?q1_WBFd=L~PbCy%o~oBh(!VyrdATJeUwFku-gehpu4h3-Oy1i$yakPnO6^8HAm zyn-EW+xPp{zji+nw{Q%NP)Zng$~SZ?(=qNZyQ7H7J8HYnf*P?u@9L{Bp2{fdHKbpK zV#2T_hz++-pGo(sw*VeDVNKiZED96DSTRiwxt}u~JGlVsEbYMA&cm?Tyj>YnT43=g z`c|yC-2^hfVjXA4JACWr>9-3yhE&J>%cD7vh^cB0+5=T)-2t%^{49k%tB0Qxcfe1t z7r|4xUlqNg9?QWKMpgki(ymVISWLXg_sV4Cm)KG28izOFkG+_*@}qV4md>ODU{N6X zw=FgV4B1im4(21f%$`|W9R`>ghvAUSnr$V5AQ}|q;@mYGEIo7bG)GT-GHJ=$Y@GRN z{8z5@hz^o3{_GUK&s=n3%~B?+EKt;*m#$5?-^L<=D2Z76mRXB{9y~<<^cu z6;cr3MdRQN7{0sV?ke0(hjy|tQfKdqY9z+d#m6QoPr1>C+0LELq{_X-iVB1al^(Uj z*v`)^gM)F~Gc-itbc!N)HI+~`EVD~!sXfACVp|A4UnB_{M$5;UyBQLYF(Y;*NyLFd z6>Gbn>_D0;lsT+y3R)4u^p<(E^Xn)aAh-h}iGCZWLY*ax2I(HMVeVjN+LsnF6p7t8 zeoxLT7A1TwpyL+FHh+W`uO$GAF(INM4OQXLHY^QKmpZd81<$Z;aR*(_Ms8rPQYGt;+`VJw-k-tKv zT}nTrBwh}Paa$sSe(C!z;POhUfnyr{PH(6sg-Oj)1GLGgKeejaAa`qH^_D2bwO7R0 z@hSi+4I(q`=)8yct@v`&`~oZ%;dJ88$pX`eg7k{{%FOs?jpFoX@vcG6%`WZVu;uEv zR`D+CG~w+e*R@9!TU0O3RH_?9FR&I}dmr)Fb*SW5NuDu{a<`rF+xm@^y!frw+GWo< z2ZAc;d%*`pON4`>B-;QQ70>R*1MDOtlARmZdZdzDR|mwBCszj~(|gxO;52R>MIaj7 z>ZI@tV5KFIpFx+vN5D-8YKXQ-2P89+JxDk32V^s{ao_r(Q{D6sX>`IIK8i zZyYCzxjSlZ9H`H@xR~2^w301i>3pnhmg%4bsDFM}$UHA;EU90yvV^?u0%u+CQ%eJZ z;`MDW2x_;3YkbYId?PS3tG4eq$?ogqI=!8x@O*!sqTqJbGQqihTO(rjtN9x%70k7l z+*@ljdd!K`mdfKwzV0lQ;2|vw9y(+UA(v}4$wUgpOt)PY-wci^KL6G~Fv6SUq*SG( zPSGg{1Uq@b=lFy#%nuP~j2Y{-mcSGbDwKki3_%b-B?mDLbL;_rw4t6q2@q+yQ8J$! z4y3Ax+p-UfVPZSiaRJo@tfWdmL-*?|&5UDEj!=xd!5+irPv|5&ARNo=3aCFq)g&5c z_c}m}f|SZ1fRAmSCMBV@QPK4(9rF6WkCl<>l~r&Cp;6M!AlI8VE*WCMWJ#AjBC^iT zQ?;hPYJ?+-U1H15HN?apW#wtPMZRX_JPwyUK$xe*O6sTFqRY|@vUkPc%>;5>=Hcy$ zDp4W78NLUi{w^+M4^yF=TQ^h)Ec%RJ)q;`gw}VMJ_&jELhmPzN;qrgB*pUIMf6-kS zjnv&qq0E6XQW?l&_RDEz8u#8>r=E-EvN%NcR_4%*rT$8le2Ohsii0c-3p!O9!Cxf0 zso(j#KI8{~%RV#3^9da9&^>Ebz4&}Bp+AqAU3wtCebf2JR4MG=wS@jpO!0s7ZvKWSz5|7sYRtv&BZVKe;p)7oD0U>7eNl896A|O0u+tW&u!JR;K@#-(y0wZe`_|NCx^i zV+>xv0{^j>LLU8vc#9d8s->m=jd&cD; zvKFljl}_eOf4qy675}oEoVYbzrnQp#N|eIyxtjC~!$G^Sm!hl*i+<3wnW+WWhvjzU zGEB+MifAjV1r9=%VWdd_oiS!B*8(R&vo$}sz&SNH!3-LDWnKmdR%+vPdS(95EUk5s zv>bVeprl_YQ^Q9_b-_Tr9xV)M<;j6b&v0*JY}1=&9cW)xTiql0DDREw7AQ_s?YD2S z66WMO)MnypA&JbW1^Ho8?wIGs4~*ae^7NEK?Ym2ZGi zWz6m(e)0gc67e!_H2K}Y z{INxNmn8G7LL*tqPweUb1gJ^1hbVV(MH>|kXy|2*h-}iL=FT&~u_j4fHAtOKJTPVw z&2A2oZ&Rly?FiTZ*wCK=rF|n0Vx&HEVfJ!qW~F?R1aVQgnRF7805ck~(zzhTqOCe_ zla{Z25mMd=LM80=8M_Ng0V;zCrsMq|hf3@5>6Fe`k|YvUPW9m)vqLiqXBu8d1V|(QW!L3oYJdYVwI=h zzM~B2$Ap8;jN3{I;s)t>n^IdF$RW|DX9;#V8dC>lER41c69t!>JO{X#D%`;LhxZ*# za`a2ta)o}kL_6h0@4**ztXK1uvU~_4_j&&4i~*4Pa@oNH6t;lG9w37 zik$sH#FkBf5|f`j$Jkms&V%FN48{-{2$ZQWo?8bAE3qHG0qdTC)>Hx}xPyZr$%dZ% z(i;g@lm6utYY5}L{urUBp4=ay=^tFf$dc11I==$`a*7Xby^THLIU=dh4O?#e<|wm} z->LuDV4_v~-Xw+>BN&0348w@xg<*Me`vSz8l+lb={_i^_&4_~xF_}xl%zA<>hgLGw zM%ls1m1#Zgj`*Q$*>G7DIw)GyHEzke4U&Cji8QyzgkrSb;d58TUM!}LabuxDP1p5J zh`)DAv8~71_*=amkXs~QcS_iQn+8G*LbHOk0f3Tp7Fc9Yp*yK3*vOS%cJi5_L0*JS zy>A2a0Ky=ruwptP3|qGTV1;H8LZ>!Fcp_{RO$o4886Q%>dB-MvHmu4d=9L8qd$3~R zgv$G`@)N`P!_mz2ycWM?9oU&h8Be7zsMr`>58zeHV(#^MVq-p;`lovc7_ z7KK(FMZL|RTUA`+4^W=z65{9oTuUGka^b+@VrsP2W&Sgy@D0_zioF*H9!v(>L4#_5+XJ#n;480(y z4H8yCBdR^fpg^8NuQJMVo%e7R42i^21O79Z6r1ELO={=*N|Ti6T9IUdV)ZOpmiAdO z9Y~U6-z79AKp|Q#sLhc#>`+yy3VH*J-FueDzrdb>q4}0$weOW4hyMb50-xSanzM$I z1wKByUJs6WUo~Y7g>(O;cfBGzWc}g!sv1Cnl+9ZQ_zK$l9#+lxI9K+ua+4Pq@eJaG zZ;CoXh;n-){s>42bqTV-%j$`~)W5||>oFwDktS4bkH93;8>`Zw(lu}dlBtDvx`0@| znnd$_1lGAv`he}VKI5Bll+fyLtUj>lWc3T+ML+S5OrD7VocfIAv+6Tw^N~$;`mCx?;xS)Rj-33Ol?HjccnvLB0lg_|L2X2(WM8aQ`t)3jenba^e5eNj|A|`UMn! zcA8>{#r_F?A29cel zm>x!hl!aEvrOsBBE4s9n=$$Mm@raCbN7@t-GoYpC$1)JdD1t1>703@sS}`c zD%S@6$aQ)1QYCcinH_9?!5$|X#OYf+Te=e`pm8#m5(*)FH&caN0ghC=gWkxcog3>njQcV&l-Er(%)kMuip1|?r0CZ#BlIOIhImF*3~OC2=my=-@YV@?f$ zhuw1%ajp|){lUlymJ($&s|d=~OM@^f@po!jW>nztJ!fq}1n01aMGWG1ul*VyXj3?{ ze>G$$#v3D}Fcp-Nu;imCD`wX^=EH{zE3S1Ye+k7|O_P3DczNjYw!yjG)>`!>lUn3_ z<%((U{NvLmp_a7DF;S>4r)z8ol9{17*;0u(}Dms)34N2(g)~ytfc<3 zzA)!CMQsV|bjVeyzd|wV2xq`_u&{v%Q9dORkp=o{hDeC`mr$IThbj^JB@}xkxHsjf zktFQB9Dh#QULW;bKnPrtPl@M{HoM@Yh)PMbKw@Na=_KAl6kr(n?X>6*O15G*)|^Gl z4;@i{TczG&&rY_({K4yqxR1yy9CeQy7Jq9-4y_4&h8}XB)~XuTN~0_Ss-)Mo%3SbLc4V$y%(l;wgYA%kmV z&-MV`OZT)fAKZGDCM3SiuC>hUsM2E##e2CMMMVH*?#C0=q9)cN#N2`};MNTyyBwsK=YG@`R#(qeD81NG zV~u0YT3=DoRRBa|$T6zUmRioiHi>0&){$I89Roo_ESa@Uc<^M`+e>^X<(6ApxhOGj zGxD^IP|KTtD8e=DOZqu0LD!i6FQ9k=eidHK?%7j0IQkS+Ylw~5Gc)(Czd(41ZI|q% zgd<-}LwC@H*fV{%H)*b@NNS&OJCU&~;(As_nemsAnaNNAlIl1;w^G#5*dDI;cgqD8 zo05;G2uaEq^GPP`7h95I)_7eCW5<3-@s!R*7yh=1Rj+a%BG$OT@&-J%5lwUKJUY4k z7G%?PVjC#l4!?6m@2<9W8e|$8x_z`~5@i_%X=8pC6I676Crq6NSgJApCyh*x=c3kg zPTPR&gKl*P$`rbohxe*hnb&xcQKiOtPSN%JbFA~dc<4{HeEs>29NraP^`{W1u|RAZ zWM)M<4f#GA_wII|%=W4u+5-)3Kanmnqf5n&{ z(s?nzo}PZ6d%@?i>0L?=d4VFuZ{QKCzi*RW@GwgF+hO1V%&*KgQ7fe8+H(8W@O=icdY0Vw1OqHoko_Y?Pbw(ax zU{LU-K!_A}j98BAGO93i{`S(EI8pxWY}1@kVn<1{L{(&aB1bSq=Y^v|>_8ZhQbpm=*?;4nnb?3J8UOQbYsCLJp9&vT7y2gczO^nKq1f+4;`)m;F$B3&3 z>W|G1lJ`yos2x!G`?M2Owj4I>)}c}lp$iTZT|(O_BQGhnFxBvNbWnyKV-l3cw@~#9 z-QcKqN;x!r-{DreYXtM!>0I=45$^#lR2S$xtzlWl45&6fP}#=pR|U5b(5f>caJmG+ zz5~D6CK*-DzLqx} zVM22rxDRISJfv0@7@%&GeU|zmcC#yZ;e1-$YCe z1dw!4{-KjJO00eIW1qbiyvpxA_lgPZc&6|+LAwY4B8t00i{}KRch*mJx~2`IGbLM= zYEfe=>S#D(eT>h+X@9gPAv}6(gN;zx!@jFYu?#t-g%wB#d%h;IORJW`A9Z=>+*>u`q9-K5ooj?97jnc_2_#2 z=5>9?yM5mI@ep(E18fVzs~|Ug)21^bO4@pbd=Z*8DQv$H9*OdQ5%-p{k#t*^W|0}n zjAgsbcAA-)nVFfHvC5RDGBZ<}nVFfHnVn{4=(q0G%=COSy4`B2XMThfaTMDBBKAH@ z>#V2nI>no?cU)YKfzG$pn%ItgfP^lr5mZpvY-3!A*>;OoRu-c*g~sFrv1&hXLs@}Y z_QzE2!P28Qy+T4<;A<}ifxBn-!9Er_v(~8C^NuRzq|G=3EQZi-r2B<@ThjK-dl<4d zp3I_0HP*6?6)Gw>6Sqtf9yeECtpczhKBktr(Aa6)%8XL-Z+4@)4&>54*)}6C45@ zq=_{mfB4z1GgJ3256EwB#F&~N5o*h*2eH7aGC41N+pHH;=+|V9#k~c^<_)V)nsf5T zAK_s~+&v&5k^_+=QL!|Y%aBH_o)N;o$6p(*;V%qG z%ksQI=v-Ri?yOr`pWe%V%$yI}=dX^G8gQ&N5QPS|S(y?v2I8Wff{r32*t8hMiasmr z`AZ+0*XeSt#HiXs_TqkoHuhP?z~;xxjXUDB)&Rbs0@Box&L z&g)Sy^MnMrdSeyK|5|38BDsXtNQ_K($R?$Nm-I~LR>rH8s1$LKNdq?CJjz)E16kM` zlJ;^1017%pFXfnUQAJH?NyuY{EMqU0*X==hbjv*yEak~)9RpP!SM=swKVK-;8OtO& zQak91Wro5^w*aui{gL7l{_xGC;YZdl#V+QJlmJ*2<^K62GL+XsZiOkzY@Pn4;=$pn z%qGGbNisJrNhjRnNX^h#tM!T<&Rcrt#TL~p4vTpQpbU$Qq^@AsY()|tZ$ImsnHR>e zoS+DuZMF}IKnC5x4ib_JYJ~Pkwu}QPK{~j)yaTySJF)Kc318lU7!sS-k}hv`lpb$h z2HtYOWW%YrG4bZh@Kc7rSDg{Njh~nY6fXoDlXa2xhA!h6d}9FCfUSb4|K~sSx3-w0 zu`spe*UA7^RhxSKl@&74c9njcri^?3op@`LBF%a=qf+3>cI=&va({-n!a-rOeT0x% zwU59b!aRO6b*+5~HquxrmLTBwm);h} zmNg|mb*^3=fHm5>;cf#Qg^J&fTM2Y-ASFZ`{9%^1X8*c>7RxWW-5qqKa|H)FfB5d5 z`0b-zivT$YdxGHs=jsowPY=Jtpe}ztwGVxyoN53%`?oA@8-Tm)3sUt~kC~ zb{wf)&1H{jDuy~*0q`PB>*O?Yeya-el|fo72PKAsY2V}RvhhW378T9$bZ||?eiZ&y zInG)O>w+PzvR{tnA90!8T!YU`&Ag}i}`-Sg$d#^n{KWr{L3Y_`WmXO z7_|T-2FcSIq!TZ;B`vgm2S_vb5`BV5wfFzIjIx4${tX3bPbqCrmK%oOzglML*% zgu2uGl7M0pD%K8aFp*U zmaFnH-%hEV-&S7d4Hm2NF~RkGVfO89C8>o$e1W_>hD6q9-Po^XZb9!2R;aGqWE?E$ zcy1J~Jkz8W}b?Ek;|zR3SV zHq*i=I%Yo~!>R-08q z()&Y=X`QlsWlO-?l)Z}V4gL+h zX6*VgH}q)S(sen}e}`ALRi(=!-OJOz6^H{4Y3Soc|t29MBU+r{LO3X;+LRKfK}V z*qy-w-SLKgj*;eKJM!mWIASLO<_%yFBi&3!mcgT#waJDixFo@>E#`lKBR=H&ljpA7 z%>ZQ5Y0t2-Z(YVYsnzc68BMKl8k8{YS1hS#CQ2gH$tzK8_x@u*-hWFSq#2Kb9Y~(G zd@b$!%ou9cv{pLg3R1!-%bEBFw;sPSPEsEiYEUM&g586!etoCwIo~7IUjtB)-EUDP zjWr8p+mK_y{+0El zyqmyWc5ax&)OKw!AXwXO{!n35cOjEr`xI|Q4G)s2SWits&_5E%!936bc@p3bG#HgM zM4#M7G4Y#>5uOIPNF6}{ySz(}xm!lg&)3ygRfc(7JGFaD+c`yIpA`oFeCfdX_7Gi| z>#qUS@%HNhU*FW-D6%dJ^OI^8!22d_8(Ys4F2*v;RmP>TnrKQA>aM)gk{XFGxoGsG zPffs0SVpSl79+=yr2(ktETT{VoQTm*Zc2?9NOd|^-Ta^Z0PCpYFpo`u4q)L6LlguA zTFPz~IW-`4NpfnsG*L(~Yp@aBJKW$z(K5WY!9~Sd5`DAV&7#n9-!Vs_a@85}hOsvw z!`vG6d+5C_v0g_`G4P`<~CTT2A@4gQ)i?8lF=WMtPXv<_J zil-(KHnd3n6t(R zG{wg0%y8w6?Q*bQsM5zGmF%VJ%kp@d3W7zGK8tlm6wa5FD;6*hbs+t#Q&5%5Mr66o z?E2jz6l_8&gN*Gcwi}wZ8N2HTBN(_ycz3G+nBjf?hQyACj;ZuJlkiGdcnu$n9V96S zNMPRhEu)2x!ln|^Y9DRhFp~yle*a?_>DS=v>fZZ4+UOde-$)e zV7Q`7zH2RMJ${OMl^t0pXL$yDMW3?!kIzBk<-g4OKB;;i&76Tf!>lplEnlZ9zB~Nn zeT3>u1X<@cb|F2}OS|$Bl3FJ*D);4^8IpLTW)cYY#Bqwtwe0j_E<4xKl*!R%Bnr+g zSjj;X1G)a5=|uYAF{DbF#T)w^#X;g}67|Hc5bn0^9!Rq@RH#oy%DqZR_y_f|Cf*)J zkFaEr^ej65_K%q;Nk_=`&F$SD(Zm{eXGksEzcLsj|CPa5>Y|yESG0_$NtBrwnuwqg z^q9;(%9Dl*QWECy6gSVU6lC?qJw$DE*v9$tj@yCDsQ6-h1VQi1zeyK;#n;E$7J}z4 z0q|-f1!W`_DNCvN&3qt8PC;7mBb{z8<;Xu!N>8oG%E2iuN#NW~dq9!Y=j`WCoKpu7NkoJz1dPV5& zK7CnA#(Jgk5A9xkG~GdUoQ6_(n}~JfOHqz3q8cvLYw?Y)`PL?&Y!|z_ScPl1{iy`2arbW;ogqLH!L$k*{aX#3T>BucD;> znKMm&xG=9I4M~4$cxl1@>^vV1+5GGnh5$dccb~+|JGIS z=wF_PB-S7#>wiWFhyTbUHviu|Lj1pzh_zs}wf~Zcv4I92Fvd&~p<%`lu}IJ`41MZ? zzq6^4p*6JalRcst=mVI9Fv{x}%4r=oOLT0?7c|p;6Kdfq*~rve)@#<&&ePJ)w^*GS zj=N2y4N^x9(*F#7d=vL=dzkQfNdIX5OCr8M*p_=Z{VK1YVjdhcwRhXFZ>yZ~xsq;i zc`bG|*V8fWHEl)PMmK3CRcpsCt}}txEsbkyqv$!P#E~6WIjhw}3Qb|>j=5D!I_y;Z zCtBJTdpj=+igarW&*%BWVH!HyYbb9-v)?A)e%MAG6O+)=(Uj8A5Ra8Ii^E-WrOVD= zOzNCD)ist@Jkxk)umcS6o_QKP56Ea!ob3khHP;#Pu%L z1G-JUF20<-7F1DEUD5=q&Z%q2wYD*GF!7MF5qS$M8K~JQ2^$Hkk7x-Wa!9t;J_egB z`5;zDo1RaaZhN{oW%o|6Y?+_Q6Gv!cUN-a41TT#Bm(%EGaaDDck4+!gy4Zz2Dc%hH zS=xZ+%5&($&Kkz9_C|K@Pk+}|s41!FC;;pspBP+=PpM`_G5rDSC{Z&qP1TVKaQ_ z$El#hoxDUG1g0;^(t~n2BB~FRBF4iHCeyO?iV`1{p&I|lqsv`HXjdznmsxrQQ7mcB zI+N8Vy11tssw~_$=fp2k$@3nj9Gzkftk0;^SN^Q5lGnkiIjhxE*1F|G*4DR$>8)Bh za@=F%g3YLime_dwl4?AK8kQ1q&|E*gyk~9cc)%7scD;l-NPQLYWBK5UaD^3vcEoAi zN*4<;tgwT$^&qe{dASMN?=(>{rp$` z4yWl?Zx;bxLWLjaFn!?N>o9c0U+#QK^vh>@#V|#e_HjST&udlGf)eNO%D-ufiEHlc zF<&53ld7AUuppsGsw*=l?u@#ocR5uxSz~CMKcb@%$I$05KDV`$<(fSu!wZIf!9{@p zDGStaBTEKp=lo<5uRyvcfyndUlMqy;5{HYO7tAcvmyYJv81jTL3NUVuE=B+IJ+?GR zyHH;+TAO^&0+tMNcs7t*s2lXtV?h0rECj9nB{^rkUz9u(m6bU8x&K`5mbf(jsGKa} zq_TZ{bmGtDf-NkIMF#VKaOahPHgmo{yN zXB@M4sXvtidMWs#{Gi!EM7Zvj&eBmG=yRHq7!gRGHbtqO_L`;k?g#E*#v!{|HEwEg5hG`1 z7eV)^GIi^2C<>RdNs%0?G3>4`c+eOq1sulzPDozC`fagvCUy|bn2-xQYWKmFTc8N1 zXfh8)p2Azu;2uQnMm9IUI3i#yVPoOoBV&`7E~%QhauxhIuvo-H*0biDYQB^nqsm+Q z6RI}uD*f@q13xbKEE6?HUw<5~^;!=0;Aa~Byf*(FZT#Fvt$*_n`r?O5_hz4*n6mO> zQex7=z2jWz)&9j%dkHT~=t?b$%zK4Cz9S6w!CkMHsNxd=>~(b3pT_>Ai%aHPr}h5h z+8Biwq1=ZT*n_;E*aTr41jw{lkgb}5W$bm|gO@tdsH2gjoPrA~R{~XCzr2@jZ8GwY z-clt`d!U_LJ)^frAJ!T1y5Q{v1{}h18}!TMPV{XBHZM|#R*`go9YqL~jHpN{gpGIc zakGB4a=%Ct9zf9G7>zraB9wHzi|1Jzn@OK%M{lWs^pL;?yv$EAc@HuO_-xH z9sI62#n(^op;Uo&#a{JD@abg5OEH*IY~)CeH#xX1USI;{(z_qy`*eE0V;u%(+jr{VqRSd zV)L#e=+P+L)v$QcfZ#X!K&@8sZoc{j$BPg=1Fc}jUHEQ~ooNOZ(;zy&GS~;V_+&h- z^=vU!kJm_3mh*2G+*0Ywn4*;&vyI=AY#=@Uu=7nM3a8nG`B9a0qF}%em27|QlMYxa z(p?YW8J4GX9B_IkY;ffk3l?3)Dqu_J4|qv!iO5AxWP>= zQ_FGXl$zLESyhP&&tNQN^R|m{ zHZQ;P4f@iT8npw2($NFoTZ`vJ)Gf=VL4!q2gBqrmzqPtLD&)~55q-KnVyN~%dO;5z za)Ln}o3j?ry@8G=LZ4JCO3{ox`qI+`9sW&CcgldXnjE-fY-H?Pxrxa@t zZCpV?(1NGH5lM?bTzJNHzde>egkEu%h#E3?@VWV@wLyyTBGP~;q+n_91!h7;9`32L zPrQ;pq}q{aODM5It{R|rIhRO*${5o-&bEG*W=*q~DyV}rv6|^ueO^RuOFJbNF?YcL zeAdOVB(+ASZQMVz()s6(HFtRd=hh!V-XrDaE_E!;KV}b*?M88A4v!$ie8q z*}V-}KC*bkVa!L@XBY!p?E~m#LDfmVgm<^^3TIUumSOKY-Cdf@Wo@HIK&j31RE$ki zHP}wrjND4B5?ajjGY{c3G0&I7TE@h;99yt8SEy>Fb3@LC>k-VAckZaDpm&qC{m}cK zF3fWlDoez-x13G6V=&}R=yR$QMs4BX>;zxnHNs5%Mxwv<(or6fs~; zPw11fh#MW%v{E|P#7`yIYZ%|B{;VT(RnH5(6%IvZip9p-PO3EuZXlZpJq6(lqdOs zrs&KGl6;b7Uv6tYD4h9tx=cP~3!!Fm&Rp=6k3NOXoZeDmejBBRf#m_1U|2O#Yvc^p z*MRJo&4V%*Mnv;Ri>np4x9=@i-AguYvBi?{)s9wZP@%;JD0w$S32qoq5C=%C&C_> z08R%(OaPa{d{C-v*{Prn`Eg5C2`Yk)`fO;u4tqXoq3iaoEVFBOHIxiLX6l1}``Wr! zmB4wq*H%oc+xLmsR=d^$>ED&3OFUf?))TW!F}ki}Pu5!}OXiKWgswHu-yL={4z7t~)iyryQ^6uv7=uyJ4ybkK(pe=6JD3XcW$XfhlmZbVRbGnYpAfRM3tk z5O_~A#qI4NuM=RU5jwmEQDKB$-jumX?#J7W#bvw2#uk+RjG{D?3_P`6OZTChXogUE zb*K993I4EMjUYf~uBUQB)HhVV@?EQjb5k=tJRQ8pI~tMI?_Kvp+ume&;cd1xi&st` z`tZ`Mk8b^WBuz2}2~xzJ848!?gku^C?w{-ST@7?x@sB&Qo}1!ePq`>P(k|~8GvBb9 z08T)$zZ%ahu7A`Njb4xu?jctnE9V;G{mGSdZK9T&pm86F;{`~QZgY;`SZar&=jCce z?K~2`p*`J<^5Lp-^AcBkS|&VVTyUW}@gyynnoq@-ln<#Gywmha?GgWeAL`66=2?Vl zivZrnW7ijM$&9fz1f^kv6PLuJZbNU2BKz8}+;C=;xGsy3!CZfCeMDO#Vtlc1!C>B) z%;}i-rBGD_a5J9!K!`Ir@mpZbxhcrYkhpz{d?uVz(MC8;mzl_gaRyQJ*c7Bw9iw}U z3O2zDWm?o@2C2DjnGnxRVuN`_S0=?D21Px~VuOxh^x2!5pHVF){Cb z;&g+e&t_TT1SjH=At8@TA-8Ozo)Iy+W*|00Lein6M$VatKU4{c#ut6R>Z*UH^;%YH zBM$8=G;9@T6Mt=$siw?jV$F@!nx+D#U5Ys3dsw2@a z=m#z*3h!y0s+&s)#*mT)M%MuA_h>zi0jpvJ)ae1%j{DpH96{Ec&vwN;<)2>A&y^nkoGNfLW-X~MyZ&=(-F**W0 zZGl|f)s^6SK>Qp_IYuI}x6aG~DNWVuj#ZFhFma4&8b&#$5Zm7hPR63w!ae{1n}G%u zXP9KYXb0*N+w06MkYhaXwGjrK*af9}$rc6lv!uTUZO1RL4q$*Du?Cs{R4AYvqn6lM zkH`CZpab;CGT=2%j(QFnW(Z25N#P><;{uOTwwtX^t{;CF;%jh_+OsFQa$eAeMgIh^ z)J30eP!{yovzOL0mXy9O183MZ$1nx}YK+rcJqKx+!zxk0aG64@e}%7&F<@mHOY}8} z%iaMi#6nflR}IoO|bx7yY6!^tC`RvM`@aunylE?HT~* zF|IrWb8CW1sQJMREg>!-C|FV)ZKxzuw_%3Hm=v^^3acSX`p?@PCTNPIg2&Q9)NJUv zcR%u?BdCqzilY?)O#f7d%Zt`hA1W^p9I*%rMWQ*55WKIBevuARPR3CUx5$g`tcvbT zh2@Bm-N9LD$pEkzXc^36*lTppW2n$9OR-pyOYIq7B8@@?blM)47q_E-^T;E8i@ffbh=TpV~k*EVEJYa z`dtXo^^DQwBJ}$6H2RIy`{7j?;#9`;(W6YznKb%~zsg_LL8HsDsZ=w7c23H2iG9&A zYr{m!c2HCuC`+3HRk$-%v_}A$^qWI5p-<5maRgoE9V(cA7dvaXs0Yo_9KiF$ru3&WO7GV8J@H-uTu_gS}` zZWjC{hsUI4h==)uh=|ZI;u1%V&fCba&CXGv)opMvUsfOX67(o(QDnz zhMO;1!cjA<>C`K6rx=>px#8y#pR0SJW0;{sbn3Vu`|yc{M}GeF6?ie^Uo#7ohy3io z$Ak2BM@=+j`YW(%NVfx#fsa|+W!A0*ygk2~*MB2EZB=CWIVu&_eN37kSp0iX27-H9 zM(!S^s!zFVw%|)9!>oS9u(?$}pC$N#!xO*8DO&p1c1`EB)osiDt=ltHdp=LQ%*FJ} z$}H5a+_SpZGv-?o?{wz7nE~OoakaX2qVU|l`9B=9Gi67aC^8rR3-X2N4nQ!6PD2_u zVYPV0syW9-7?sR-S=rqSg_X|x2qST( zdf{x+_%V{EVhvHiuzU;0+!~&xse3k!8KjojY)}G!WibN6mHDKtCF_kkTNDKLNY8-2 zVl5+?ne_?UJnq^)>hw~R>40SZUy$z~T0b!l>Zy%Xhz_aS8SCz1Y4m-Ib!K27@AyKm zn+7%w{`3wuzV&Jjf|XyBsBkb%T*!EuyXhOwn)nYdoZF@t=CTO*ewKP3baOdXY#v0VKy%3q`%Y`%2C0}fqh?Kc% zO5!0##?Up6Z}W4)0z{J!Hz6&=&6SalfH=ZuwWdCbAhL`j5uP^8Z&li6d4-XQRw0ve zW>}{HoT%ey{3K6PzDFjNcbD3|65>w^|6)qG}Yk4W-h@6@3QnynFwxf%zjMeeyOARBRN)PfGh`Z zRe%`KV96nB5@+DLG;^DAwi3ODht4f+!8VUwj1*1WnqC$$zqXQH-|BDJ3sd6$4MEty zbr_d4@eAi?_%+XT`0x;1A}Z8FS2@#Hel0Bu1;_Fi1bU)xfC_O%pfy>%DT8c3EHPB;4|=mHSi0w3?s6e# zN5Yx0tY|oQycn|nNeA9?&UDJ*!*8`68dj9br1O}bI(g6M5JJ3L71-arp2jH3Jt9Nr zIYl+nvKYV%6k~-ss`;&Q*pVOFD_zeOb~kUBX{O8_es}~T+(3;}SfR7Lp5FWF96f|r zpw|xvt#pwZ8=c7-UONjDKpZ zuS=LLKOIp8MG1V;__lm#RqYDIR7n@pD@w%elx3wD$LGQIvA?-X8Tar`SpR&++_bmp0P5bhs*0(%DDjM?^L}`%Q>D2GZ zuKl&0?W+esSxn?7i(N}uFr1KV<(3x7Urwn|D~Jb#escL;88i8NkPUd3RK0DDSndU~ znNM^uHy}FFxy7Y3a;kVIRP%wg!+fJjs%BUFC@SU6PtEJ}0|hCKc)v5$wMyG-%T^6x zv>YrlI&V{2q&A><0q)tSNxxjZlHT4%5Y8M_dV8X+dcN%}vxObf@#FUD?;{@n5Ya|d zA*&??iW=<0O?TP;+RwD^_QAX?DLr+&Y?yuAZs8L?sq`k+IvH2^;ndB)SX&n;dz$xg z6|xf2JeT=%LUv}IGAwsiJ%Wkkj)mq?OY+Z!`LAdEm#eRcijVjOC&;gXMvp1)zlMp< z+WrOd?GrPW=$rFKdlNbcqsT;Ci7S3;a@Ngbf8vVNIA?do`24}VNNLTjArXY=9VvMh zNH-jl_xLJmdCR+R2=0qek(E&ilD(n@6jqiBcG8)=Bq;TFy#LE{R%~{|{}<%Dg!P~L zcHsYaeOu&zs&S92uezZQVt*jSw#Bw-1HK4%^D9Cp1pWDqBxw}91^xMplq=DyaJ1B7 zX?5GrzxZAwHa3*hgBhH_j=X40|-484#W*`hW0y8{S&{fA+TAto%u=u=F3ZoBMad-C#QtPSY1Ow^?`@zj{s9m-d>49d)wYWxAfb87?YPAhMF zb80C~UCzemj$o+U5(AubWFUX8TRLGf;k*HbfwciY8oUGggFcne;%~WRaq1`u+b6{f z_rRvcVtFJ)Vj{AKl8~R&qMORqpEt9YzGIWoFXs~J^7jUJo#nLEMG3BD!k94i9 zTn`hR_N^i#bd?E!WxBMA0qd=L7(2GvxUA*GnG;q~pf_aY(%B^nZ}zI1!ZpueoPq9Q zs@#utgtRO>FHqs-a^GY^X9XGifiI%sK%{c!Fvt|h9pn7DT>GX2p>*ypw)MsZDg zbrx1nI|%g`vJMj9>2(dDkRHvxvZy6o@t6yB%-j~u`A3o8&B;QwtThot<*e^%biFdW zu}*f61IKjh@wzt}-+&zYtFc2yn$ur=FVkzfW5IF*YoXR12hcc8G0Cbn9@XBfR%Y>y z<;eQ0yHff_r=}x{SGgfqcoIw0bnbkWi|-l|^ofSRtZw(fWhLpUUVtfh)Fu?&ZV&Af zi&^SgBGWlV(}?}ngvks~iOBKvo3h~7TR1{zX4;BhpW2CcB9fc(rnwLkHk60V+aOO^ z*ND#pkk}^Zr>#MBZquh0v4rncvBczr~J$B6>~l9^|VyHpG7cDdIk78*WbBhkfcH6r>@Q3d_I@Ee}f5ypgcLE znu?-@k6!;S1(TK!k1hdD!TQVZ^@_gEzn@N{oq_IK(6NI(iIoz|N1A^*g)`{04`(^6 z1;$mK@!(GKX& z#x`0OdH)eVCltTm`^U9_YXLWziVqIx+>P-zGgdYW(_84O6KPryDnNeiz6* zi;`q%QK|IYDFvfRi~t?*hN*>ij1UB)ISYm{faQ|TqfM2o<)%7)LgMTd`ZvEH}!b{YZ!dzu33;o6iF?)ca&`ZZK$W6Zw3!GrYdIgYReh zack&BJ}(*OS0t7*wEv#p+e#_br6qjF+Ux_ddWpLhRoZuhIITx|>{hh-+zv0Icwp3m z9cH23Beho*HjCCadh3GQp!BGl!~dS0LN0Izh!7=#?$wK4qJ@wa(CDtcwiC@!XS&Ch z&wetKhXSLAz6K`~xqs!mMfD8%YaQ$Gdyy>sIvgeW)v)m3tJdLF-kc(T%|Qbi|9cP} zu?O4`gXq$W3GPq2ONdJ=4$sla{Z%yl3%+VWG|;B2$iHbIk0Qp6@=%{XS^P(Suh9S6 zDDZzh{a0I9I*dD-$jabmBUy?B8ARX2y z#(Bv{WyuC-OAEP|Z?Q*e2xREw50c~w`y{kNnun%QDaqNjpzs+C4{wVn6RI${FezAW z5euV{uz54h;>IPdbDeWaxCjo4NXk(nI5&yn!Sty6v%3T@Ngs>d+UwB~DV_6c2GS14 zq{Tx@lbR^JBpxGeR;7<&gJv*T$F{MsjM_%F*lL+kuDdMZ5$A+5eVg*fL_GU!>(C*f zlH!iOvB>Nid0`O~6YW_^H9jf6S#p;99QJ`xt+=$QODQ=qjY$TgTMvuk>ou-!))*|e z$+_Z1jiX)Y_a}%NY+jF0t7fY5p?$6RM7157q6D)y9P>wU<*8yg{ZX7G7T2;tofb!p zr!Q)z9|8ezI&XvVp4vl6l#7!26|7^^v7Q5mdw|`!S5om*oo%Pm9exKRqXV_l2*ctp zN)G>QXjK>|3e_Y;ecyjBX8VuvC%m$T>2C#z)DxxWhHcqRcSBT+{poo>|MV`?$=OkS zKh9EV@M7g-?&*0jC6MyeNocJUk!IDJ(UZ9a&}!4K^0F7m@zOW={q(Gtq2cfpCGare z(md!z58}7%-pUbz^nf(=^c6a{>46Kk6ge_RBb-z^rqOQJAKLnS{vH7Q24{a_m-C5J zTUb$*`O|zj$`|#~Y;;heD$<80;S?=4n07JxJ*C^#V{eg8njMs{K&AW;Er^|A zV(!P)UZrnuukN$es07kaf?@j^jF-dvX6}0 z6!t{YVACJH82+;(mMvyDo8n4LN?I}-C1jc!GRp|@4avH1GphNvx>hUwZvzT)F%+={ zMMQ*-XGG&^2-X*z2kgJR(yR$7Y|0M#3M3-f)fnm@gpLxC0+o)F`;$!x;;@5@Yems4 z5xb9(JOm9>J>bc{Q;RYeAXz~x9<~%>6x2p-GykU49E9UT^9+b2%3ZudN7=#LO! z4UHFy`@tMT$x`5W(h6Y`OBR<=e3zWk3|BBdG(4V?5XWYF@WtnbC?>f;JdE56jwqGP zf^(dIdu>HJ>@!I1LbQEU)v=a@G`1E(a8}tllB76SFlr)hPFcjp)42m=j2ba^_hluZWB8a->iRas{Mji-nW8$WIINXc86Yg>l}Q7lS7Dj4fHQX_)hK z**BFqM-%h{In5cG`_2F(P6?hWYxFB(SZ7W~m7Z$Rof!y8bd>X!0IAh;i}R1Hk*k!s7jKqCW-HYw&>v=X;mK7tAO>50(pUX^%Lg@+UN@g5Xal6VS$u1 z#q8>7(pRH8BIsCZP;&&Z?J6!11!PR4I_LS#6(%cKXW3#Y&x>qqWQG27ho&kiQBt1% zH7PC4m|kmAgH85B*9Ik!m5u!6YOsaw%E;RJRP+0Ck|oMXT%)S)qwC=}ZJFpJZ7PcB zDn|RTzx=pTeo(T5<*d52wagxrdR9r#vT?{@w%7axe-YMNS+Rhe$fjvMR|Mo3B6y$I zNO*)=87lmoQ>z?I(USt+wY|QD@X#q+iNuKUa9z=s@Qd^wgUrAlP&|YGe67fm zH08Sbp66^#1Df%a3)2|$Pee+d?U)^wVLlQw<~VuYHzpF5MIEuq$CN_&`12Y+ZUIW8 zTe~2Qa49L(BdH44jV?tFXDE`G`)M?&_KEn_qE;H&6*)VOBN^&|lV#()1Pv?FU#r-? zwhdDI)rvE#w~;MT2=V5?!?xnlvG154I(B?8+_~@$ubgUD2WGJmEfY}=2e5{KNq0F# z%wx;>sR3FkBA+6h=R6==-5qZt%7?n*_v2z#jj^52-(RF*J_0PX^G>xXyMIY?W_Sj{ zL56fF`+ry_>z};=NFVJaDCeNU{g4FeGvdWJDeCR2w|GW$0Qol=ppH4ZHf$L!(a_s~ z*q2Tqi_zX0CFy${=skX7j!av-Ge{2fK?&BQuV-EXq8T%E&hX=aY){5(a$W>NtpivG z8OFIG)8xZ?Xek32Q#b?V15ZDZI_CO!MV#M?ZaOJKE6&K{6tMOQBK5d=pfsoSh?}N* zjol}s$-+qxAHf$yF0hM!b+m$*1zOxQEXyhWJR`}F$V*Q3_(~;aLlcVY!YktF#qzx* zA&M7^DFee|AJsE!d~Vfq-kibAXk?!@mX)%&;hD2;!O`DB*t&Eo9hyoO_aS;Mfgu_( zjE30gou1MD5-cr*Qxaucnb@pq#e!QXe%|k6NW0}edWQ_Onta-*xvny!UtwM6R_V5g z)y=bpDjd8Ii#hae6w``INLhg2eI2l8F``%F3?ON*#9`#H7to*XNv8zIO~n<&_mcQj z$g;wuD}Qa|bOM4Z=TfqZEbLV<|HR(5w`2!BeOVuz2Q$RJmvX3WIUgbAR}3d&Q9H<_ zb+Hf%g|v`})d=a#5V}jaFRCWVB(4eTEL7Z^2!M)XwVvO2>V{2UMzn*}Rb->;Kl)z( z$bu*0xx>x!Ae?{QqFIRR)>q-`e5`WkMLphNW%fC_R|HHN;&?c7NMsJ0rwBfuS~Crt*UfSCba#=WOSLyi3oC$T`ud-Ebhon z@Oz6GAB=ocw+T&dn>(tC*vd!7U+1h&+=$eo(P1o8QeSgpyF@NWr8>-(Rxie(FuG!2 z2)(;@ZEwZ?nyP0c-ODV9-_BXhyMb?xKb!3yKdv+wr%Jvs6m5+cJvYeQsc#zqQJz`E zSq%WHL+MaEPu){ZSR@Gg*Bew8g0k<>3O>Lg7Ub3x)_qeZ_5JhAJKL(vo`s! zmhb~Os}UjlC=HNuB6uDskcs$?oDKI|bvFAE^`=0BEz+qa5oQ%cWf2SWY%;r@q@`q= zQY3|rdQf^etBQ=qzPEAp*(4p>*XZ7)3$FR-y!%07Pb9gGU>YzsI&ap>ydYfJVJV5q z<-9bi*SJ;Jt5HmGs?_Oo4F$*{V*1*hRk_d2PetfW_WINLsy~Td}8KWd@vqETRfDMt?|uE2lU}mzG-_2qL3AY1A`4{!rSeo|bpH_228f z4u3{rSLex5Vc_iHf{6KLXsX}>vro!2DiuRMkf3`oA7YDlzLhjh+B2R<)g}UwsYrgY z-&u?aSA+VW!AeYKL#W6B=StKt`ezHGA+`1WT7*WbTrn~B{Vuamrox<3>zkc8L4(XVzYbEbaf z`Z}C`oj`_B9o=n4iJ!Z6q%w!S(j7(*Gokao(qDc>y<6P-5vipt?C@PiA-;D;i%wH% zU(3DfvFG44&Gi>GAd%1gG57ztLWcVAp8;mX`YVsKNBf4AV)^vMRK7ra%IcgG@5~L@ znW5K|mV<4j1B~!UgzkaLh@r8W+Y=NbF{SLCUGsT-H$yG02MV1?m@Axv_xpZWmN{2$ zQV*eI_J-5(;JD4PR^-8oHY^ypKW5xKhF(3peZ^fB2Y~~QpzQC3S-0DHn^NdD@!uPH zy1m(VCVgK!n0|BYf-actjkMEqy$gtETgk&F)!#)&FQ~rCJxlgx*@n=LsI_GBcNjk9 zaduY18=n7~Q9FK%m%LThb;Oy)B@asqeET+YK@cEUp%MB1IZs?+W9IOiX6@Y5tV-vF zG5vQgFqha>nL3EF6Fhml4YS9#(8+xNB29L)6vsPDA@|b%bDt+5g_lpEjU2cc{PJcF z?G#_W7UzrhCJ`Bj+AqH^(wmH!Nui5&_wedVfHT5<1^UjigUfCRy3S`x>EJZ*rd;6b zi9Xu=dODfzGgFKM&Hyloa?Gh0(8;j}mz+eIeoLp+;Q?UNdEm&gX+Tk&2oKXv{Br}a zs@VH-pIjCY?~=MF(zaxbS60SEO1GU)W(BM{kf1fq8cr=Pb0VeNy^&rZ9Py0YW29x% z2nL*d86Ncznc~dutT~X<9WIqtEw{!WE`1UtI~BLI61G;A@EP0(T~wOQj@Q2{ zMyk)^ww@(P8V$N9VV{^l*z(duL55!N&~r%8*tXF`$q%}xVGn}fS1#poD3RCSRiiO= z>NnGv8WZXDR!I^}h|GCi!o!T&Y?Wl#MVo|4n(b0d5-rv-n=j%`A}!WQnuVD`u9J`I zGmp6R7FMmF;q3fVOkyp3$iMmMM0#b~Im|qI&>z~gE(f*pmS~r+KEl~u0e6;cuV||B za(@w#uIc*(U(maRL&*!9p7x^NAgCR6vYI!Z;i?I+uZEYywP^WIz_G)b1Ywr{c(oA> z^u*kq!*&SrR8#B5-yJRWbQ#i1-(|*dFpq4L>W-lY6a4v!O^mZPAQTcYBjPWQgq4`H!r)dDBf7GYo-8cN>(i_TR*f&eXr3lI$K!wesIfp?G*cN zr);EERcEuf{2AD2IN@&;FvzX15Y@!y`1km80Q~MJK0o?$Och?%Aej(f`O#65qp5*&;pHN_p7`<5E6%D`HLBr}9ji+Eeq z(bRZbwYL2u4C-ZqL?iV%{>=R}4ObapElS!s#HeDt5FpWje6`4awCVR9Bsp4o}`WOTXsaTQHh>%8a;wJ+4sbmx@)KuTec!Kr;om5e>y46&x znxGrm+epVz{P=8?QU3UBq*0gCR9A`Qjju8^>T{|J91W34$@`&>qapFG;&V`=lJWYg zZDvW~iCTn-3XG#=K%T1IL)qI?M<6NH^ba$9Dn>Fdzs*EuN?Ai2nbykUJFd|sjSWqp zAt6f#K_af`t%;1`KR@=<#Avn8`@B?F!JHLQjjF9qaCVrs+t36&9=9m*9TAu>Jl11v zYI40l)^4Ouhdfkyd!rPOy697`3S4{BIG#lark>{Mz-EP09OXJa+15WF)qe2AI;EfS z!rd=$Bzi{C+hu>Q@kW`G5uA`=RGCpzY4dTPZ|WDyw%*;&`3g24lZM6XbmpbZgOn0M z_*M31FT$L?r=#{7{N>dU64m7uOpfgR+LL;s#*TAxazuEdNA~@5^4{hVy@-91-8|7c z%_KNE)5(93cY(B+YNwblL1Hqv*lczv*#{}fh);%V)R~ODYD+*z1|@hQuv}H!DO@C8 zHbi~vSoH^U2?v=QTjhd;j6%?YnaqJy8i5HtH@0e6p)7OYf~pKaw34rL!BMUPBVK?= z!y2l%HfUinzLTbNK}N2Ell;L{y+WGofv%WG^t9nvRVP)oh}?~;a)Csq2fCss-kZO3 zL0hiEiC&Liq;df_{uNX8PtZcavFaXk3C$M<`pjgM_pwkvbMd}L&`ceTuB<|k`dzu| zu@=ugBjIZbbEsd64LvuEs$G$6fzj$ro$aw!E8goOSFXLxrs+mx%$z;y!nXP(r|JTH z$iW@zR8&!b==aK(Y+@l&so;mVz{#Y=f@#jojV~KpuVwAn$kS$eu=T34^(ksTdN2=7 zHTi+98p#oR%ImTOq1Q6&Ff`jLG+&Wx7#mjL>Z0x_uTk&!h<~mL20sP7syD4q`;gIq zW43#cx}O4`46ngx;IN-QpFK&Tuf(^%^D#I;;;<}r&I6wG|@Y}$CRTjUmJ4|&!RbcDEA4s?zMJy5XPDDC`hbu2_sWi6(>{DSV7?9Y zp%P^=eTJ5}GbAwAH7bMyf#-a`AVfD*(JhXto7JRGDe0B;hC}f6N4dzN{_fE`I}KRq zIu{1)wJl88eb?WG{?|ZsBlVv}j&&h38ry(p{kkdJbr5!h3;$_xdL)dAb>)3+2n%NX z=|k;V_vxx-y9cp*Ip9h6+7LITEqa{tI+pXAkHka3!f@kkTWt~m%Q`YLq=x{m*{*@T z;<>(rxMKNh6t6EoU8()^GIx>i-B`apf$a*2I|~2IfXLQ#7B<$E^!7VmcV5sF=QRoR z74Eh$Jb1eQ4aT!CdaNr^OL9ABf5ax%ry3o6c&avu`|Oo9GC;VMyt|u3Pu>gD66XMX z-_@J{`RxAB$DMg@{X26v7e%+Vhe(vyiZ^>LAQWAA2fc@iLvBBCEBj3>#Ffl->?a2t z&yfIL!fw-_f~eiA+r*?PPZWkx>j-vf1iU{Y-v~CyD!=~(zm^i$5jG?(PYX+Ch1ob3 z$*g-0VoNT0G&Qi6nQvh{#rXZSZ^tTl{siGo$KD$+Fw9!Y!si}kB(aGhA`G@!^EY@#OPDgjB zm*{2>@I(*i9f|c6M8AUAl_CSf48?ru#tLtzjqU3q3HRqB2b)BA+Cbc(qdUYAI|-tD zKs3OHcLiue4dr~kLRo8~Q|c2sMlH&&B&RuzfzbeH`VU(Oyr*`)?|k8 zL)>5Vk^V8=@ZmOro=(E(9(Q@4!u@&NH-a1XG)Mg_4vz-iH_mzWF5545((WVjXz{TA zOyzWYT=MvtJLjeTw&woxU6IuMOU9GKQCr(h81sv%cGZj8g}&TJ*h{9r<{d6hT7~Xl ziBSeiiQW1O;aQb9X%6|OhegC6^}A_JDn5HD6^l9V-%nbvGS;DmTjB_hKJ=@8q$O)t zWulL8-%8(&Gfn-IaaMR|L60LRs&81XCEqy>LiXGqWjj}ULn<%y6i^!H%NwEBD74{= zM0FGSKJo96xnCQ;tLQnWzOI)JJ6D!9aAM@CGTRy}1jXId;{rRKm7=I_+^7mHlWl9L z5E7F37T*}85>M*s;uPgCnzG#Oa5;ol`Afs9A__BPXy(KwC6O+C3m<=Kd?SCD*$h3` zi`2wubRf=s??Cz0oAZs7{0((ymDTpkV~)fT{AwOS?sq?^#w(gm>0iClo{umnzdl@N z8O0uZ2Alp?swi{_K7R|b>}!WyEsKK0Xe7nUeNTin%OmHYH2X{?^i~LK_E|qVJpLVj zXZ4LB{+%uXK>jxS&j?i>k7Ce9@h1+^lroa(8^=z z0xyJASQwgToEucD=frTsxpyg;n>F<*mTU^-K!9CY=4MfS%GyP-<%q4Q&)*6NhbDL9 zbdPbIy4uB&?65tee41x^b|G)_alB=O7 zf1v(`QNJS;6HO99K)46~r!cC{|FL7UPYXCl! zXeP7dNvMd$Y;;pgThkTA%9_7esahv-0ikqcF;(fryu9vcyv$PB97>V&M0xarcY|al zp_3OQt>orY86>ckCG;IZFudx@Do)bS(>+(_7Ky+)U{(-m-YBm_$5Zb6#-CiyyM;5f z&!4u?`pe0j!3y;0bK?Ea$(^i5k+ePtFj6`nikvp&(NqU zG`lKtQ7ps7)ka5ZL*^0Vc5F%Nd+5Hj;IsdhT)n}d3d``QE3iE)^|gqIY9fm0MRAr}o1 zxOCmSm(4@rG*DI@ zR6rKH`-gHuipzP7bwzrh&_MLs<6(>4A~U0I)-umR%R-BW$3jg@KP73fsk*#qZkq8G zA7I23N3VQ*fxJ0&GHZbgXV;?YS6G`ZpG{w=(EYSt3^CoUh^9}c#*TXj{|3fJA=Y=#_jRsDccRyFqCy1C zM=*5L?Jq< z#E_bw$kwtR-iA+(gI$h22xU)e!$tHq;I6&`!Sz0|WhA=!5f~6Jd(YitwOu4p~30|*$09I?v z{A}5m=)e#X1HQ>%O$mvEGUzO_mwk|X+BEm{+=7+(mX?w0#R-2fhq8%A*+kkiXWBk3U!Cg#&R1RBvZwN6&}`$fqo!476i2f&!c@ZS9K^Xo`Ik4 zHMr({&@A~vo6WUDpiI;d8c87!cv-3`l-~Cjov2R_Bj*VSih`Fe$;^z+)pqSMKuyUU zt#pd^<|Z{JDk2kWe^y{E7Csi2?+5AgE3&O|n`py&(w(DTF4+W)NC9y8`s7p(+wgJQ z9!s7ES(W%ei3Sh#6QphDvJOSGEnHK#$FddlbKi0h0n(1lb~HO0pK8lxSIy5PO%Ocm z0W{fcI6}y*3N

    zWZbT4Foj^YRQY^(hN#+C*~uX}WLi+D=XF9KN*nz%pYdvelj;q^#uTtjClx~u(nyXA zoCxp4-%LIJ>Z)Hah<<7YMOw&+S|pC=R~FfIO|QtOX9YJ;SQAT9#ErR@US0EsmUkIe zMdUG3ba9i8zq7!6$OOz;dZcss<%9nsg}O{Nq5L!4%MtAo*Fd^~FpoUBq;!? zn5rRCctuXxY<`wODUk~@)pM8R!z8 zqcPw{1Bdwnp-L{J~(ac!U|5m;%$-espvF(!)I|8ye`^ZBcd zw0wo9qNkMcD-QDnsASIk2!2^-uXI`o6zJCD`I^D!S4WkdcrnXeI70SY)s;Q10YJ{Y z0hl>tB0DAcgBv0KacJY|it1pL7=jDVG-Zw63YYl9oN()IHHrEn9nc-1Mms%PEBkn@ zehaV1uY)k^yIvHLZoiOKxR;e$aOK;;i;reqINN?~^qLvtsl@fw>)P_SWIrQvRK@0a zj%f4pHSg#q2&rXTS^Pokw}Nj)G69894(cpw$)qo}4LV0PzryS{hr&7rtkDq)Y?S$a zg*A$ivYa%2y{Ztg3yY0%hKa$vaM?d-G;nm0k=JODLv@wU0K>0k?^W=u=nKQ}cS%RV z#`K;)vZAV0#mOm%ct2FZR*xpxLqP@*x5^ZL!MnU6Th80V$Ty5Cw><%$H%`WmC{^gL zB-0tL3|~Z2tYXF3)rck?qMlhk5Is!RSSEb&Mm}{ZcZy?nC)JVkLZL7FR7R=C{yCg+z+S(l^9XI59> z4yU%)SI+gGknb)~KHE|gLkdD|8Voy48HJgW;v&q+eojrC*2?3u6K1^CUjYW?dtSW9 z-0~XA)0~V+xxTqu!R$G`kX)}MVjv!_J5wxw-Iw`Zv?>JEi_%+K_U|j#WK*kAcUis% zKaSU80$9^>JXnQ-M6_?p+b_S;!|?t16ILytA@!oU^qp{eW4NJ*xXB3)?od(P`MdUD zhzZo?U`9J>jVFZV&AY8_8jezu@ww}Uh@P(gIA*Zhe8L+6!)hmQIyJq}7%t~Dh^hx@ zih{#f$hFSC)P_PWvZWa8Ug*kN_yhh*N-TY6Jwe@*fR?4*dFlYOBS6>*`LPH)P9{V> zE2~I3r?^1Xuv3J-F&2Oxh4|g4UbHk#zBz&ak;^D=r`jv^?!1Ew9D?eA>DDml+{+ew z)sfxt4ixcnK0mT*?f~l6{v=wH4bwDtW3fbohIJB+4C}EmG#g8sdoBlx=pzaE;t2R| zOdM5;>T{~bY0VvP0=;V)qznAF$n5cee@@Hqd7WR^?~erU4NJGi+^KSZCU0ESUQ`*Z zAGAXxpz&cOla$WK%gHIrq|g;sa$SO(kLiE$7wQ^|4TN1AOD`Cpsxzgni-i;ZWELS$ z!m=c_pOkd|;tP8{`n~-J+{-E$;oXE2W}Gx-7snXL(c*jVh%Sy{0MF}I5bQcZ3l&uk z7xmH`+^I4;J^o8x&C@G$;Ji8}`%q{qC#8m!+2ek*h4d-A3+{?1JKIhk&jC-4lZ5c{gqGIfS1mjnNkqV2`^D^b=+MHs9FL;4hP zZ}95Cw^xYYc|VEI#^CoKxY0fH-?O8weRnILZydTq|Hycfbx%be=I{6YMf=(lrd5VW z5D-Ax|Ah97{{KPy|My9X|F!&o)wZ_s`mbyJZ|5T4)Ce`OKUkD`ir4?m*RO3C0v)Y+ zR@84T3l)P|9&o<{l{Trc;@;Fh30tju_Gb6Jucbz#EY=PC0$Dw0_G6##1MY)0*86f( zQmm1=zdv%ojPxnj<;tViWlH$zlC{tO2`b?1x*~`n6zxHuhhx}{)>8W3l_qgV(~R$P zu7bG>y}gvct>N`>>~B_k)!tL)yhIP8)YvTAS;Bb#nr}LtI8iwjCeksv@&Z z`tU~wHTD9V?QLNBk*#60i+WRwZ84)gpwWbk(vp3_KFZ?}B#2*o$%5a%IP02obeE9R z$|EqQ2K9E*7*qD|n+;NxzcaFd($J{(jI@ao=pwKYG9|IPeg}5?JObkSLEG zxJ9mO)qLz5DtpsyPgo?DCq=l8#s@P=v@r20&i!g}xH-H+Cqt&slu)zOb{ll?bc}N= zns301GVa*Qrq0`j%(38#-YUQ}hzK)|ugl2M{{S=u$u1-+O8YyPvo1B&@bWJJt|Fd5 zu)E?7m$l&Dp`VZY%9czS$BO49&Xi@S$S4e{@F2iuD98tK)z}{G+aOI@?qxR1a|_DN zCHGRRPq@GRqiH*r?ZIL_k-c7mgcz86o|4*h*63X>yFT_@T8hx9HS-F=NalW#tnG%yWx&it22sA9+luQ9?thyRyx6-z>D1 zJ2isQEy|}I%i^-QoEYqHtC1ta#)sq{7@qK4Z*GHVF?v>ty#l-|+tJaBfc}jR44L zk8#g|_9#7%q7+{+h%Dys;W5wDWFsDKeLZ|O;W+!;?-LifK097t&=KzLz-&$LV4|#6 z3)g)u(76&*Z06{ESrEU|tuuQ-3;=A5)|WPW+4QriZJ?S!2ujW(z}9CKm{zeVu+%A( z9O*OwY%;NC4r$o;4Hzzmg`3SW!)zEOLuxvRwD~pBl9@up87{>?0}y0Umjzve*Kvo~ zR1sZ6Q%c4d_{z)a8u=bdj~+Yz6(hvPLq2-zCqn*83WbE&UmYoO4;OE$tud716OZ0H zFIzhx1+J0%D@K^g><5=XhKQ%dHe7FSZv{Yu_tX5%9TTPX#Zwt14$lF7w-;IzhfLrr z6aYmkS~|LpaF>DwKUhTYA_*r_k2PBbuXe~>V+|3_!^Fn2r16Hv$K8B@-3 zqIwg0ohtS!oGf?Gbq*^izK4JJrC*S1TK?*1cn%@154G`%PvJS3Ay))FO25rhfXSVl zm)*9q85^sDlMsV_K)O)bP38Fh2(fia5amY4Y%tr(KLuj++J?F*)&HFFZNGIzbCp>| zUus_+%GC}#FZsB3Mi1~wTdGe0{x(&0JjE5)e~edIsqn*wzB#hCrLhR>=x?6>n%=*8 z`l|}wZk3-27us66t1B|Z_M-ph=`XB!lzES5jEQQ{RBR;AVs^HL3~ZT*1H9M##PTn=R)(Iwc8TvS(Kp-IBK(2oUeFe&(9$Ssun5Ag zq>h#=o_zadh{e!YE*%RIJs13hRooryp7XC9;R4nFlp_@8+0`X*Vb)Cit;=DN1g-x- zcnZ+}L&%~m^CLq0F~A}D>I)fH$Yhz*odiM+-2VTNBb4xaJ|0mt)vNeW>wQf|5P4l! zGF7PfAUFCxCad(vA`wTi0x6^{{vLl@f&Ztq)-h|}k}=$6yqemgQz=>nzd>irL`fg}3lz3~g)uSP9m{_O!UNZn3bm})hswg%dCyu1s2>Y zq_x>-4G(#NTqeAy8|2`hyGj&|=SO83nq%(ObuD~>vDrg!mTE=f1=I4RxdsQnd^L`3 zcZ!_vqZ#f6Y3fLQs#a+IKm9AuqipDf4+jCE{U6ix7ymcAe98Y)pTDT>rJW7J|D(Y7 z_%(nv3nGw6R{_AYJ(hq6HH_X!Ma4vhG^9{{GIBX$u}5NthFNWASF<(`e)!g++tSLj z*lsORqovoPfaXK`*lTn3*!OyG_14=2MSf1P7FMR@OY-b@m$jFZ@syb%{Bb2s0yh)d zw_Y!?o%)sHFrz-`L}Ct$2+3zabAvNe02>K}NzQnBA`5!c&K@Np}UCf5)6<=|OAa*xCXQLZ{X%hczdyF4ks& z{xGLu@8a(wfdH3NI3L*VUb{)csmZOyuUn74gfAYhJV*=s%dO`&R#sVcAx|pxC2o7Z zrij)Soz%R`ziaL$mIbZ|^o&d5xC2un@P+gNC2}P{F5J(Bz`{C{W$jF;pOyfw9XpOY33LQ zf$-d&FTFa=kMrA&lDAR`!P7UfwI$}Lm}&GIBrk^u5j)S7G+ z<|e=ejtbL8qr%uxS(-FpwOL~%P~QZQv?z}%TW!%83e+`0IoHpO_hg>JEI*GKs_B)t zU64i1C{j77j>yL+W>3O6telIW(4VsK`tik$+-BePk5t6GqrfUx&u6i)FFGr-XbQ1< zP5`L!GeSg3NRQJT1nhNaxG#UweDLNv4pnfN**TOuS8kwKi`>9H2CTqOHL>tV|sWPMR!T^&_63e$O_*s)`ZJ(iK0)IlT#f0b;6@9 zu7Et;Ww~yE7QYjvi1nbtr!wYzv52@Gi$H3GF^)4N#isZhui7}djmY)mWDaRH&Ft)} ziPsRgHAlf52N(m808z6#FYz+iO0f;fe+}92kaNT>$X!B}a^A}MsL%^cG9{ju_{?>Q zqbOtW(XKwWMYS+sbT<}v$nBqo9A1IALN}{+C^=8Y*@O9#XDFO6u26ILR zEaoh$j2C@^PnO^3P_hAcBK6r>v{p(v_?Hw3+oJmfxl(gu8{?^F4Tl87R&{bNhH(czdT{6UYVT(U>;hb&{lceo~r4 zvFpp2v&yvpW<8ph_WY?=hF#W>{S1ATd&`w|1i_*;)dh+$7vq{GQm*067r3kF+lV}J zqe0k9G4t40F1c${PP>dCg+-tEO4MsL$a}o$I?ycsmJ}gQl#IDG&_=I1sr)MspHyj1 z$2Q~`$g@spDbRM;)3zbNpFj1z#1D9gP>P0R`@AKuXhr2dkSrW!A=62g>+4^Pls~1n zjzbx4`-}kEqo_&63>!mA=CiMJ;5*1uQvCg?uW=`h_NaeUeJv9Bo1l+8D|57%A74It zes9Kr4Dg6ueroLDoBy-sL&MR9W#H=N-rsl%nA;VJv!((*SU6EKOBAgV93b(297xI? z#DxA}m!7NIHhjD-bO4h+$Y?dvD$W6#RC#`<7_Qgp(+Iy<05|94S3AQ$m;3wY{juzD?JXy zRG3z~|E;RPOTT73fB#96wb`aqa<*pJ^@;`5Gwk|g5Awj9fA_)OGUwyE(&(Ocv(FZ1k0PDG; z&;uEx*!mlpP|=yDDWsHBKzyQZIP`zse{Gcc9-@CA`4tyH6B*(%T9-9Cq8r{)2xYet z^04v)g)iXFk)LNbhmVxk80%6>kfeZQ#0fHY#Nsz3?yjUQhN5evfGxn@H9}#9#(jYC zG2aKs@9n5P`Rfl!Ch&#EU6~07OZKT#1I>7D^Pa4hub~mq8U|K5GK!7@E+yEST6|Z5 z0keIm;U~tsg?>c|4+i1@#d3zUWpGMmr7^X{VP*?@VA}-p!*K!iC7dH@qu<8@g=O{! z@o&6^AM543ZTy=o>>+K!2<%#7&Z*F}R(A%n16?;Hr*1i?Z-&$-m_5j8K8RQA3VCtz zJE28gWsc)2DP7OJgGw{7s1>$93A!V#>q^&bWNenFGC?Jl9h7abc`?HXz164OmfsYY zoG%1&BSbu2Hb$;9hE3a#q>`~o=>-b8++-?pu|^;6dmw*P)lg`a_fJ|k&bx?NOsH0s zmh8pqpF&z26ykghd&af4z3<+o7UF9a&($5afI10YmgM)J}ou$MUYSeyjA%>HN7mZJYI3uVU|C zCTp;W+W9xaKfsmfKf&69|4vx@UlLjWZ@QC2lGq;v@J+Tfa1vN5MV|TfNUL};(y94` zjp)fC@G?{+d=ot5R838Mf=Cfkd*8R7QpTGWR83W3RI0c>moWW-{F9-6?>3E|x(U>- zWGhq_lz#Hr+?Xo$#g7KXS0CZyH$j*_WozI}+ zrL@%sA_#UeWq;o^@W7CECVVtV{f+BV67d8otqJG;$k}}3qa{k?3B;Qy{!#j;}bGQH^yA5^i^)!4uD_2() zm9;hb>zR}bryidZ5IGN)A|i7$q{8PFv?K(=Bp7paIs4F)Ctt2XHtDcG}7?3Lt{ zRAw%7&gg7&61!4rZbgp~@&o*y!R#IqyvW%d^;d0DebNL*pBXu>Tsw{s-l7%n(3Dzo z>wFe>f=xF!H9G2>=?a@aUNdR@_vU>LrZX3=?;c`=Np4#G%*n}j#0jYg&in4HWiBYV zT*aG@<>dw{fVRRAz8h)BUMBS~dNEI5Yxdg>doJfW$o z3QrkHGU1#HX2{Qh*n&ZLF}pC&K}ISk z@v!c9PTw262h#0sJ&?h%aeFO!oU;SKn#tZoIf>=X@GG(Y28}8vAN~{aFUQ&H_FKhJ z#7kpswUusa%XFYU+-w|i;R-Yqp4m#HBpyxLV&}kK)k?tPWQe6&4&IFj;AszXjW(jF zIi=WpNjbU-uQCj%`I8)gRuE?mWgc=yAkcJyYJvxZ5f~g3GY1f<%VFyzc}pF-xBq3a z0LXaAxNrSL@LzfVvRKWLhW9Y>#@Z>;DL(G#t@EF12c(vmrT?;6$#i~}ab(Wv%4}1P z4;ym~kMMq)**U`?MlzwoT@`5jpjCvyS!p|;W(cZeC7SGWB*P};`4_^+UvR$u!kZP7CFty99TgJvQ_s@QU-1QBIp~m%C z^|3R)$_;^`2U09H&7bKp?xz`?p)60memw~{(X>d9;5O{Jt5WsCGGpEqeCz29I7E?r zFAMKC>5GZr6$*qw5zNI$)SLSV?VZk{dC`WK_84Q+3P8F{&Z>VnMr=6ZqG-W<+UTl) z1MiSW{A)*}U(U~8*Ov52IR2}Quf479nk!3mwGaCFkLL6sr_|%{@=a?sH!Ou0|w?q~dOBE|Zy&^b1qRuqDH& znbyjuVft43u`SMx2koD<#%|JzV)Ii+%c`7EL~9GXtDX*DQuA30d|c>$W7RT>d)(1O zXDS5|zr)zFVcTbl&6h@A)0Y>lA!6!i#jZsb6)UqC>yz7oB_A(C5wRBQ;lG5^5K+ps z2D>NyOJb?h{tptXnuO4iGNuEE5$MN^-=y-1MKH!1hBt4R8qtak;}^*_$}KT`aB2Ms z6%Q$MzFS_lo}0OlZn_LA>H7-MmU+Q{SSxStr?me%u$q3se^Dz>b#8u3er|wXqu?4F zQv|A;5>ER9G3UVs(7I>O&z(Z#LFW$lH|y6k>oIBez!$CdLoo1s0|V!(04U`7X$@PI zyQ|y@v-G^O;g))sW(ONdWd!Uv+3VXsqO?tKv|5KQul%P;p)bOw{V>G0CXMDM^sm+= zHJ0}^-@B5uI-};y1B8=%d@iaAHt{eDpO|W1QooU^iLa#Fxy|_quV?1KlTK$}_|-LR zZ`mKxTN%O21RSyoj~kLnDidqK*hk^X7+o%Q<)*7wpR>7qwu;cmf={f0*w4>Qu83KR znyLjT#btARdvebER3ajI1jNwaEd(6>QpE2x3a~=r#&%pPXRg$|-Y4`xB7X?~I(y4R zPXhoP1cc~+S36XiNgmQ;>`7lB;g)yHO4a)f_$mjef zmGdLwN5U5>9Jax!B?*b&PebAf${buKG|*?S}m z;-ftYJd~J-aRQs14>R%8%8k=_?AgYY1g@P$72%;`p$hz(7jdA;Q8|Yz^i7}Wb`16; z3t!35w$K=fAY)ORy1KGDpSY@~p03G*)%o_t3-k6q7Z#hMjD8XGRhEX+O8OK%0RzDe zpVKFF<4Qb?bxm-(YCJ;R!%TjuP-Youze zGc~n{k#laDu?*|#H6CQ-9>-_i(dJr_Y!H3D>c%qxn+ai~Bv$FX`U+pNq>W4}%d=$5 z5X|leU?^tbRDW%^mU1wsbM|=f(L`<+cne7rsrRXcODh49qDqR7Dj<6;azi1%)HJgp zaUogbe}x*fMy35_ilnDLa(ZgJ>1L+2h^%ep3Ka$$1*0jtAPT&r)$e@K8#KQ!6^5eia zD#t^{h6E)e?C#NF73;?n@{Pe%pqrsdhmb`<Shevr0qj!kP2l+WLEU*hXYpIgq;ys0{olYS7I;>UsJv* zCAa+~P7;c|p#XYB`i32rMYxMG^;|Y&5SfwIGCg|Qa96uhHXGpK)D6|P=7^U!(Up8#v0dLAzv!mXMH9;1)NAH_Zn|VmCYB{$7gj^=zMJZ4|VTK~V zBippEY(njfF2=BScbC6+m80iM9S{Kyf5SNw7<9rpI(BbemMN!FXyfeIXLa($H!8rR zu1j|fK2Nvr)Y^l_(i?9N3_ZfzXxddB_})8q!zQ8@eD@q0TF1%NgVW;Zi?z5f@ZrcL zs%rGpgUdIIL>^aRy^WVdkS-{3uj`pavJwN{Q*Ch2Ng!epq6b9dvnO$6;dI2z!-`VQ zopzRHM&f^qKG?Zz;Ves;5LJ4f&MiK7a6Q*WY4D*AUK1b`E#5i8j%#Yxl_la}Ro?Zi z@3e^hoNfEe?N_zKn`Y5JD=`=C_#3s4Hj3b;o&7WpWxi-8ffB=gzx)(^Dt*c+FYnId zQ0TWx_HX}8=SWMIf{w=|H|7>E(~9;jTO@=leg3`dst}0Kv@-b2JKRPsT=)5paOuch zViio5jEtFUG;b55UU}~$g~ZN|+&Nd0cienymlDr9s9?vlg=ut^q4!*&_>0z zsaWs+23(Wa^>A}(m*_A*^5!AaE8fNcruRy-SL@chJ-ep>`A}cYckI3=UM)lc`V4Ok zyd!qIsQrr!E1zQ$`~K;dm+I;44uB>jQoIg8lO>tMrR!C?t?yO73EyY$k-sq>-Sh6) zMd;bJsvMOo0-ud56^))T%9!>nYo!lM)hWsC5!6j54qMbIl~rnfs&Cs`{}4e3h1 zh^tbwhsujCfg8R~=F|&__xb3{DiV*f2nVXLBYNgk;fdie7_$z8%(B+RHq?gX(lg7$4N zyYM9J8KZ@z1n-UAPb|{cX+W`XS*hYa-c@YeA81P}#u1r1r6KhXYy+TJF?!oLhw;(uhYa{ik@t-?Qj z{};FaLw0%&A_RCTm_10UE`%yN65B6gjlth|`l(?1DHSaQvjSH$_yn^&9X%Ntz=#Ya zbg~sC6zbF@8e>YS2X!BUIIo?SCOlo@E9#Q+84FXh?}ksyTV0(;Pj{a`khd*-OY@_5 z%Iz&piu66~XiL#bOs(ueuuY~J>cfgooJ*OL;aiF$zwm0=$C`F)q?=UTOLO!#X7vp> z=B)L^r8?VtK=SLcJE)e4T#u5S0ChH7WQekL)M;tHLVjJErQCXFeD+9VJ>(R-hzsF} z3uInboapV7Z=F+3t1B$hg!nrZz0xOh!(raf%Gm{#%QAYISuT90k4%eMKMpu63V@T@ zHkRD9!w=akfo0FiOsffSer4ZEW_O$L89+^)rqS@<32Nd#?;dhB8F9J@fjhJa7fnhn zN=$odO|?%71COFWdwSvT%1!nJsXO+@baf8LmgV0{Y8jXYFkzzb3FJOq=}=ag&@cTJg||4))cc{*nyQnWge?9>v>FNI0$*$@vzC3Rkk(`XIYDbwI07+pg$$X>&vu>vzH#or#0w(D)RAT`j+dmS+dLG%2{1AU9>hW zgaT4PwjMLx^eBBgyt@5$Vz4f_!_JgW_{jxexuy z$uv$mCP*IMqSmRoLv{urtuy#Sj~JJaC56WyO^;{Z{BW)&tuEj?J#qxY z0^V{2S&Q_N_gNbrPNr27x2xaE5v{`WlTu<|RCFFeCQ}YEu9(o7L7Dc#JVWgWC-PEX zTNL79(hfgh8i@r*KuE4}gL03}d{gLc^he6}9yO85^)1)cEuP8^qT$2;#oRkZY0|Gz zo>f_uwr$%+RoZ;he$%#DsW)xgwr$(CZD%F=e5ZS6&FY?YW~MK?=Pu$OaT7POe`~M( zJbNr0jpDC-INP-u#?ZMNpcnVw&Q)_@Bih_`-tW9(!Rb|O3q~wRn5bDkK&N+q6h8%r zhyn0AbgfN=4viX+(!GL3PQq|t%mWh4_c^;y4sWH{_#jx z)*UZ2exgaui=xh;H4xo&+cigkQ{jIVPCCn4Vq;aNp~398M!i|Hup$b$OnO6>$58_& zW>_(+?pttw8Z00$u)I3aSCNjWpxIl#yLXYCz@BWOg?|2NG(NF-L(eU8)Gzi0TgMOO zkjt?Lh(4&5#Qx)4=|!!D&Hv+ERU}z%NuO^*qEnOsk-w!=;1Nqi1-jI8{$HIdD|n6_ z3LHoDq_}q)%?UB+mJ4}h+Ll9k?W!0ERECQm+eF)b3Pxb*Q^5OEFwN)jRu%c7;-JtP zs2N-C;3lCDQ?N(sZ(t9u8U15IAEbV7Xc1kXCUF>IrC}nJF>qKr^xQo#@+XAtszA!C zBmkiH7G$6m%CH+^>MOK;1^wVEW_g7_oTa09OMpEbuq~YayUm1=J*q!Jhh4R6V1#SK zfcVUfO|$-&-p$Ul8;!yfTA$>ZZ__QNedJO{O!ea)mo9A2@8|i3KpVV*FUjaNe{!df zKU{xfvIIyN->^9MeoAH*fcwh%*@w}rU~&aA-m+f zzD1ZM^RmGHw{3z*59zDZ)VNx4vQ@VCTh#uA}!`GZHmukg(Ge_K}+YsIN3kl((c{zvO7>wl-p zi~fI-`APLxS6nspPu+$HvgqVCjj|$W^K&!}-Go66oOC2nRja`yBf3>V^WF$?Lyf3{ zT5-~0kkG2RCX}>BT9OhNH4vKI8AF?^;SiH6*f&7$6>_cr`;{locwOOwY&7DqK+@L6 z->bW;&h7T=$j{sCU!CwdkgjA_hHjFJ_kQlO?9QY)a>iiTl}IUcx)a6s9-8CeLW6u? z5m>8UOA}L;qH>WmK@C}iGcaknDVp?@1(-#3shU1a$+M9a+?mmFm%m>Ej>%WB(@YZF z$zuR8slQtk#-#07GAil~R5%;Xj1fgzUP270+$R?znpp71s0T^fL-5TUlevnMyJmu&wbA=4XqlVhW z0iWMeMU0G?Qm`_(*kIu`|4ra;DYN8ztz=y*FgnqQ_%)9C{~1DUDjVcXvhFWsXA4c0`IJ zAmm0ephjZ2XGcPXS#Y>#2SQ0%(zs?PLibtHcK75djV=ZlKu5b)g5imG@oBNj6pnd4 zZDj{T=%nN3y$?O0c)lWe6uI*tC0#cKF<63}z?6B7wQP9oNg0MI3vj>m%dRJnkzJvF zbUVp=JhoeEknh`)VUG5jm&cfgl2nnda>Spaq=g1m<;aVQ)J0f7GqO_p6mkNv)idku zHuXCqe`07;?6>nF9<{lM!Ml2%%2LdRhP*P(TCAP5R)th_vHg+s&q(p7u*Mg+xaIl&=VgeJU!NN9_@x?jpt%W&E2|a4aMd_CYT<7n@VrEle zEU4#8$%~LD9VCKP9(H0?9Xl*pRB=sW(Ov#CW^fDfHz9%*>t=^FCFVxMq6L>se&{%d z$!fl|9UW&RUa-@%1mw!f_=LjG4$r{f3ec5s zKcJ^s13AH!@C3G#Vh3e@FzkDxbdAs4E6$PZ|GhzRTFB5PD`(sjNAVfC*|9K>p9lHG z+Dc*n8j?3Fra5)WW8<})p{^*zCMXj#6m3b?L&I%s#69cz*ozy>PlJUM|D`!v8hM~5 zjlJ3+G*@VMnHkIAt-5`-9U)7$OLI9at4Ys}FpF7Y-*INS-DitK&=GZx;?vmlg8@U9 zo^gNq1zrWf3}>vkXo`vb?wqDyfI!>l_ac_b`<~QAxo#Jb{nD-H>XFQt^=MGq8s>rG zF{;qWsu4BT1kdN<=nV3$WUVi()+e;d-@HFYlZwTojxiTB7lm#<5xx7gp2O8iTm(Rt zGOwTP|L&(|^sNLpbJEHm#=)&nY#I`?w5l625y(sI)|opgEQTC83V7&%U)LfyvaS15 z^Mo|X!Y8xfc@Y1#`O2zZ=G1`%}7_ZkIZxAkOmqQLI+VXZ< zfX|{37&B*EtoYXr<#@>#~Vkk2A|n0cS=GrZS*EnvYPpi9t* za%aWT>DKYo ze1i|d&EPUZUfvB?m3QevJ%8ub)|ovwySVVcubQfAe-S+9MazqJs7kOHwO0NDS~t2?istABr7{}_Yxmf= zL#W==Pm-b*)KEMRC0(mW!$pX5n8?oWcAq$@b=0Uw{B0iuXN-m(lFL?Ao^OW+tvH-Kudb@QH2nr z_GslM%=gh-b|~8sdUqXxK)2g8|MBbJDRj>x9+rP`5A1&|?y3LZgh2pfLt7gopo9DW zV{Yfad-MM$z=NxT_r;fECDHuvK{PjIVn4C+N3)tVp&Tl|G@?Y0ojUhGYtHtT)jx|K zTGxNOt_>FyYcsz`V_(Wg?fdS1?UZakyTry=tuqBQqEmQwJb(CXAA5E;cYnP0%YS1S zri8J;>YBUsvI;w|x*T}8)utP+Tu}$|WKXVZ*bKG7xZkcHV!8LT7r6;`6tdG=9(%S9 z;!hqXlIk?E+Z@mgqnb>)z`2rS@3vVRvzz)xCvi@EECOgs3|DZzX*A>OhIuMEHh5KV znxo$f18i$+1C}Dns>Fm|jX(yn*I;d7;cUb9GRAW^PlXbxLkkcnya>`Vy7; zLK{;(ajw~fa8zdmVbJWj>hdBXH_Td?!=r72nNQ`x~s@LyI#KWk8 zGWP785c^T6>^qz+jVcth~>b#GIZQ&b>3S5xxI9?-%TKToO(Gi>;uA$w?(T$H0u zmBD?3)A1s##2Rz}$tPA59X`Y*9eOhsW9)$A7A3;#Kru4?%a#hn9F$DX$`v~H2DnQm;iemXmt{ASEK1}Ru zqHKo(1b^7i8wN@}l*1BUp-)rg3Pc9sxi5} zc&emhA6b(6lbGUdS63KS*75_}f+ImWYx(4)g)xHJ2>k@kay(VVPQg*hC>|H@mk-?w z)6XqvAWXpS15rvp@r9v2P%uR;R*d3jI#4Hcvg1eiOeT*%3?z7UxBEVrl&C5=zFQxa zfo3mS|LbtEs(o_JbeeC{?F|f+Yk3PK5M&2jvwI8$2FM57G0svr)xzuieD*;{+!2(5 znpLjbzu#=VHVaAa*hH7&uh(l@6#BJ2~WZ^5@V+MvNA}}J+KS$jDOuRw)8g>^N(h0$t4dYKsT6q^X{Y%(j<9i?dE7l{H@ z9xVSbok`)eru<`y{Cs4>=}r_mKhb2QjN_7x3L(TN_bTEitBATPC!G~Gv${50Q{W6f z0^h1RSdo>El=uu0kF2j%WN5-U-qEJ^W!HqVi1gwi#6&uPkQ$Z!1ejCiunO_Jo!A9V1Ua=dvgH4FzL8kiI3t$Yww@Z(Cx_D)Eoy=kI)f+Rq+r7<(q< zeSsVLJA5e7qnb;os#I#$^Y5)qXR|LRKoVQ97gX^XovAMgqF=@m-@c|uR}`kcWd3zi zKJ5#y2wTi1lIJJ^4&|l+qkfJ2vA+y)(HH4pekPVh<$|9o{c~@ZkeQ7oc=yw6ezJb0 zo|k5ew7%to*UWK*{j#uEBgLU?l%_BxBS=e91odyeETk0l^8o%7pQK*-8dpV)R#z z8_|q6OhMOzZNL1gZ}_^3zHFr;Tvj+WLrQde%NycCN}Wqy!;{K$-IPiy=MNj-8lmk8 z?(pkJT`yq3KE+xAD_(Udu-3fZNloB-aipfVOSLN}GuSnAyu&8$wxx7Vs?hrGUnO)8 ze-(6p-IcEl`~G|Dl-1iUAvxr?Z^*d+2?rYfe}V&||Fb->sQ%Xxbs7D$irk&t-Cg-- zh`(O}5)CZ&cjAO0ghAvw(i$?%(IS5`r_Qz{%mN*ESL2JKYc}h-XWra~Q~AvIJ}0P# z0rO%>o_TZAH$w7xbI+?qlJO)gqWsec{-mp|_G9lZ&#TtAW#7+tfj@>XmHq;tUni>c zts~CMb@6Z79yy9TQ6Et#QfdpG+oq}!vhan9(-B9P4tO=EI(w=lOZLkP{tPLXm z+!14fD{!1&{a`hWpFaib=f&jIMGMIHSY(2KCJSKXVC&zJk1Z9X61*__jRmKO9u344 z{wfj23U>yv&$qI%p^{u}(xCkefC?SmrxAh*E0!-`36p2GN@bJDvRp7})mbnpXE9Bx zQZZ%wcPAhS5i$@xJGa3Vu%*mi5ZC$Rz@OI^X$g{MgPvizl{)uE!m0!p>*uTyEaO;S zkDyP~ZvM)fHU~hRcG_KDv%e8H@P)`U2Kz`jx}`>?KN&4i6N#UHa8L!$`rLj z4K9u?=Nj1~6tF%%Y3iMIuI8pO?|j8ITA?n*o;-9g*I=ovLenSDdXdMKoqH3mN%rG@ z!=Z^UIlEJ451ZkcX3d&93Ej4U|5S*x&V|F>6FzkvQ5Eff;RN2(%!7*^8kE$b0Dp(FkpJew-Vm~t(k^LR-f$4#sspSC;lh`?4A>5W=ASN{oyGd;4w z=AUOJ(?xPFEiu4xlDN#ZAX!d#_S&dhe&B<{^lbjYg8(19z*t5_EGQnyrQO#Of{EVI zQ{&8E8AdM!MoL!umT-QngMl;J|cvB8XX@DOL1k90i%9&^;m{SM2l_IqyL?8o~ zjnUP9^D=T(bL*}afke}+%4!sf`K3zCc$KHNq&EZpKRtK1<%0k zAxT10FpBbyt0_?*;_#2sZN!UvW9cf}p@myl1!!e7SC$(9%3g4~m0kU)JEAUx5Fv1SALTXVd*t30Ph_@jw^5@Vn}gu~hKkZ0S_@zf}Up z{vVZqyc`X?HkiP7q+hBx`Hjx@tM=})gYq|kv09V$wK|){QwH>FB^*|rBo?qN-)jfh zl|PwHh}}q=y^PD550guc>B0DuRxSGMR+-VbV7-XB?=dk0>f1b_xHZ|HH9DTt+agpT ziy<<4har6MW$Y+{4w*KoCP{whz_N~Lf$u-%Lf=ya#y9vgx~Q$VAZMXHZfOk83;Nf1-Uo(pNl+y_!hQaV?e-?f6-si zZw#ScOSJwi5c}ng7>^%Z8}wE}>O{THxE+SLdBv|Y9Y5)>6iJBZg(*K2{1v!TmN5B% zfhG7$Z1l>sFc4n}6xQ+}!}m`kAY|-K0mA%<*@Gy@wiWbwvUG6)Qse6yYG24MgXNqd z{J>YpipP-?u49iOLa52Qp@7)Jo(>lQke2J6c*O&nu}KnYpG$z2Jfr70O;7pnyh1g$g0kR3(NbBa1=GSwf0Kn)H{1 z@|WgGb%!P$g`1N3UGZ1-*}K`Mr72Iyps!3s%T=o!L)2Vl!&S?2^Xo19{>a#b#XZ&C z@7wKHzR6a*>lXL+>Q(FU*54u1ul85PZ>%Sfuz66FtJ<>Iv?}S#hf_6+oJMRVQxQDV zWfY$A<5e6cXl`i-wz=!G2RA&bWd!Cbnwc(YfZ8+VP1WkP&f=cK3Rkv=1zSNl;_Yus zM-Jt^D{IC5rz)FM5qs}E(aYA2?y14cXZk*Yg7>iDG_c`NsfENFUJt72vX5>o810p` zswGcni|@>OmDS4U$4GnSc<^%N&8w9t=#Oz;Rk!!DPj7N#Ce`DH&ZZ?zChIWe>uW}8 z=d5E=7-N+yJ=H(%)8}zbTow%-c~#x;87S}X>r(+9dCrCG`LkzMBPI6S7n^QZ-o;bg z8Ifta3M#5vsd@t4c@<49H61l9-EB1--3={ybp;-R8rF(F8j|LtahjXf3mwrHx+hjP zD2l5VX|PWdXNzZ}TPBu7l8R=PL7rhgzLH@63h7f*;<}E)U@K3<)E9M=ALWpoVXgz4#OZIrauDO@`nLhfd%#?}m% za!=<0G>p4~qr2A52fdKLl-RM16%|xe6=gKkj8EY zi9ssiQstJ?u;bwXIY7q0<(My`Mz(y0}>RlQxQxQC_xsc#-^szW2M#4xF`MD z-F_1o^!5E%ltx44jYo$^2dihw-I1ATJ)Drk8X( zQ-05TFe4(_oF8*1#aIaRqu87-uf{A>AtzFsJ-O+~HnN%?t~yvh(Pb@rcB>xJj9E>Q zZ>-qflL9q=vO5_XA8I(Vo?Ej*ueQg^K_h-lC=n7*cVuOLFDzSK)tGl5k!ML{gI0U) z|0$lbq4OrSIKOd1uaXJBW!#vW%H8^et%`7Qu}M_`9nd1~>>(S6nM_yX0oHyP7=WJ@ zgcE>5i95JqIH}j9VS#&ve{9!LZU487oE(g9ll1il z^CWIL$=d(IXN~BC1c7nF#WsLkll- zbvqVIuPiKeNTqoy77FS2HxSIvGXsv!qB>oqsuxe-Q20x9Y-F>&tm)S&DY>cHp(_g2 zdL_*$tkx(|&ZO->tSW39kh&|BVgj@Yc(#lY5OdcB`vkZW4Q&55kS07=QbXT1^(Y>^ zch%s;7XA`D@UdIh&j_uj=L(P4&|4Gk<>pFeY7l%>EsKORWwcUGZ*V_Yuu0;yrOncI zyO257W!p5z-zo@MsHnPb>X)I@URjwy$Al2k1!)TuH1G zG^u;Jq(L(U#})`AR?#iDc29KGa1vxcxaz6TIA1F_c>sca@H|5wVRdX5V4Q1rDy1 zqpIG5>j+#SrtN8_X@PG>MT20dUv{O@SirY*g?P}f=+(j4kW6Vl-ay-k^yI>VOglWnR0Lb@vC7wy5({`-gg3c1t_QQ1{tG>v~ z81m_?6tUiyl(R8DD2gRzw_%#E3oDi9dkY5V2+{FCqqlBC2B(sJlOJx&p{D%zW3L>r zB7>%AGJ;ZkS^e4cZdnRT>mes`z3;t;h<)87Z5ARb&V_gl7|Iw&YHG?$W2Khnx!}I+ zoGPxXk0dh8`KGB&D-<0SMCj(XD+~-?L8fOuZLne~CaRTx?sWk%QD{O<*mE%-B)MPh z{-r4x(VPQZwkQNI8kfZ{fzpYt07+s@gMF()_46Pn2Mo~U1{ zH;mNZ3J&gN;R5?TXkOcF=#emRlgB-^*CdSZD*ekvYGS(_I<<_&QY@>~8BcSWqKBek zy86G6Oi~OBroDK6!1|C(tm$~UR8>G|KOKqjkED5D=O8If;HWs|m<9c2E{e=OMGE5{ z77B1XNCi7gQI&Ub>&OaOOlVqcOVE*ohFObA{v%sJ#TK~7wdTb)c7&-xHM?=Xe>TdY zLR-l%xTp#=rG%`ct~K(L=ttwDxZ@MF>Tq&&>XIQ}fTVGgD$zqa3ym!imC41a+!4)P zV^A(NDFF)!rg2jN35k)_#az%d?4xxswAeyjP3W>fg)m9>YLWD{5ODpB%i`k~?d1h~ z^ZO%r;z!2y1+CcTA02oCJ6XlYBO|hc?@9Un@l@k1aHOn;qWMx@Rt7)cBxR-_lPNrd zz_QbVry7)%9|a40P(E$5C4a=?8py+*2cZL>NbvM(leqNuQShFHmo;@38KzU|Sb}VB zm*{-i)fjwgIA1H~4_VAVHPVSg;)gnqHXjfxEm~hF7{rmNiJRKJriIhb=}6MK$!PAI zCDcznC3HWj0?$*_hOZ*EVZOuS=fhR`S<7McoG6 zbuzWS_ZJs9`R=a@4coyJuJKo|&YG!hLN}x&jY&%C;^7a6U;PGhE_LU!H$hrX6VNVD zQYlM2q|smF^Im3n6gws7wyX1WVf=B1Sq-`54y@c|buaC2jr-#AQr@vPJJhNu(z(!d!Po7-fex+bnegd6j& z#hm3vs|#Vk!h-oQTo-=g_#*1x@yXLegbV2G9A4o5Sr=-9j|KMOelN|jO&I4_8)bIb z)3fsHZ**qAF~scZkA7p{>&UU$nSK_swU8tPxX{jK@J;NeyE;N^WvcMH!vlwUAuXeJ z;U;MdFWV0nfmBj?fieXIV@Mvy!h7bRy8_nSvBis~Qc(nVQac$$7WsI7RG~S(*krR@#1`S}zcRU%n%l*GU5w~!MUNk}l5#_d zD3s?#m*iyxu-?KcMl>??5BR$?H_<2%uLMI*NO|8QhNxb3u$$>N!i4ae_XF0THwf?+ zlC}-up)Ck|E(da4P@025Uccx{GAAx~iMOMnEC@#~V+Ah**r3J#u0!5`q~tsid-<9v z{KfS8#Zkf^bv+E(NO`j@A~Sb|*l%>n15Ulhj&8oju45}d$aa~Q+swLZ;V>!GNRPyJ}E>%I(f82>XqobfH7e{h)kcd9QI02WhH74i_x$*f`PXfR)>+$YygCf zvJq8*Ez?q*_aCfOpYt!Q1z7B!}7_QholL($H7uv>8KSr=%iQjc+Y98Kv`>{v_!Z2i_7bL+Czjfk6$VX*L zuSgN+K#LE{FCjo*_>=$I7J`>H1ZlBVK07I(JO832hIA=LawI-sa_M707!&0An(wT@ z7T@ri$R8z3q01wp*7QLQCogN=JA|RmX&?>B(U|Mqsi*o{OKwI!-j-&}4{ms(EQ>HW zERwwMaOsZIFA@D1^3W3XP>iv{UO>5a<3=@?8sUUMnmI0U94zipCSFkNOhyneZ6U$f zuzRXd5RP@KB-R!YTLl&UU=S_Acq-v*DHs51=!9nsBGKuWSZ1Ark8lFG6{vZNtmTr@ z!_AqCQ_WRII6;zD0t?#vNISPk=j8BD3F)~Mg+21&d4*%I3=95Zo70o>V-cKI62!Wk zO0Wy^T*8Q201G(8EKCa`cVo9skxzB-Pd_l&%q0jLb~hCYDkB;qV|lPnZ*L?B|Mdm6 zQBK;h0*f(SX8pst67no_tPu}%r2K>k)M8t$i?L*xqr$DFxHpAKxqwxs%e&haFFtxg z#?fJf*A;5Q_Je($*B7pssd_B9(M8F$^+^H>T>Q=Ad0|P?tGZ$uO^ytI)xl>`8 z;^-LR?4P44<>L|#MHS&3vJUWihHjtg$HTFb1P{hY))CoHHd)DD4fW2NL5pu7_!oW1 zE7%)}7%%bd`ifsaZx!FYy7t{Chbg6xQHQ;JPI`QW4?@Ba@}kcRC@;GeJi^X$RutZP zK@S*V^QXxt51}%IjG>L05Y;+(ovP<}6Z6a8dx?<}qf$!D74le^$t*mO&IfXk^mmkC z=aI>=``{8Q*5pQk`eRr{{=g`cl(7(|et4jmgp_r0EKolKuHGNG0k12n6#Xy=@Wt38meUui$WC#aDh&95|O?QTy?_)w_mC+JO(ZlMCNR(NV+wbq`7-3>$ zop1rUlaoyR6ix|^6YICUC-3(fWYS}u;6w%@um+~maW`Ztd4NLY#AF_zsAfr-$=-58 zm`XuR=5fE*%`LD}u;JqSnd-497)d7B#%6#H&M7ZbyV!AtdGh*0je>CdABKGKMYv3} z5PDSc^{J!WAelO<^*^B;4MM3K{W4eVMl1p0H&-$ZeyC#y8YXuc#PN8-k_|xQu>(hw zyCC9t?KI;a5!g2*3g(OE6eD2@cTk)eG5#1?aOwdLORB6RT#DIu+%Y3+R_>*kQSG6!l@ZkGE+=O4qP8$*)vJGPJsf(!xpp&Xxk3{cgHrl{^XG1^8ii&agCqUm~kwV zb7q&pjC#~=Ust_8)^t3)K}$_|EBq~Uv!TocPQ>B)OA0TO-!XBhifs5*r|Lb6rSuU5J*(fVldAxW<5WC(`Xn2#M;O z=*A$4YC7gEI!3H?Rti4d-Z|YK0>&*n#;r4ky(y!J_CPo%y{4PwnHG=js!({cRStQf z`KXf>FMc^J0^LVG%8#hlCt)`*AUz#h25n zaJeF0QmnlSm$%ATGB2IsGUZ+E&*pjcH3DHPwmk#G7&P4QhZVsTWJ^I6D=>^Qqfo3sv|;wGDpe%I3H*)$5nYdR55Wl~FKt8u8LhCXna~Cg{b3 zlj!P@U27Vt8!_m`g_CG$?gx;F050go=U>5wVCs=^S_Sj;OHBl_vY0SKfJyl^IYX1bkHPw%83q1A~Y`Nu8S(+_GM zitV1EP4l#Co8=EYmkU>)a<+3?Ynu!n$y@VRTgA~QhL=~UZy8-PSD%t!Mb#(2Vpd~L zEZ>rrP4Yi6|1n~@=-(ID(Y}4tGWkzNZ1VqFBUZt|*3j6|(cI=gKKmb6i#wu<;(b|Z zd6;ui(NCA@i_%)pq5QrPgi(^BTI{m2K=xWVH`YRklkU{kR3M%{Dw z*mNdP)@;mw{NP(^jAqbs)1$nGWla!?^a0e*W0+2)+q0C?3bl= zo{m_z=f!jTezuE9xS&P$O*qlWz~Y~d3T65X!q&Pq_`C(m6T-~GDuxY>#r3(?(w>&` zfCBot)fx2D(-SM(2$B3rYgzuN^n^dT+JkhtifaZb9rT$ehpNd-xW^0gaSPz7NyJ;5 zLwg>WXW5IoP9}d#I&g|6=~)*x=&m(44vEbh!?qw!0rMu0e81V*;}@+Wmn?%U+tBHN zT+Wu-q%4xfgh4H`gF+iqc8^6dmtxK7NH(#8EPYMPRme-3EMyltVqv?P*jRmV^{D#` zEDf^NrBsaLUZawrT=TRFAwQXXhxw-xG|oDt(=!Z86s+~vUy@*~GnFQW;1+1gtTMEN zG+SR->bI4D}SggKp&F0inxOr?d?VQ=I5HU4tp04rQEAoXUaz^c< z2D`-QH)Mk+YeG^;Y3A*l$@!at zt45Q>S|2892*gN*y}P8JQ{p8;X0qt3B}apy-2TP#*PGhm$E}XB9c<+*Vd7?(l1RhS zZ7bKonGdANGd7A&=BF)_>OHJgwvS3Cblui81fsnCor~BHZSF-B&7p#k+%oM|jvf>Y z5gF@pJjLuFa8$lw{(fq=44}Qs{ZRvQwEcKAgB7Oez;!iT=AAJFX3wR5MOIX&@!5^GlY5u`^cEK zd?)8FXM|;b%heFJo$2S6j=?QNzYt@}roaVI--kFwVK%e`Q4;iuO~ThM@a>*Bza)XL?5-9=oZle0@h)0FP)D zLdWWfqKCg=PqahChGEX5!nQ(yLl5ybfiuxSF<50IfE4b?w^`-xD1H|my&8tWM2kaFTZ}Cii;#at*`QdDCk}@tJMwqX6f+kK_Zn)F zgx;*tL?0H;xp;*Ko%etDLb6S}*)B8Ca+A668vqGI!P+GGyh)Ta!`Pye#jg*yL#LR*lJd}BVbLieYdbi5?$ME^{(om9=q;Z%fNIsWK% zq$;nZ)zfAR3$xehURaR>T*kb87sqkcFU_!GNZOU-{?t}RSpa)&z;i`CK!ItXam^xx zdZTMw2KVpY+X8D?)B#mrp{(49*5Lc;Us72tV}dgZ!z-i3j*JN@qrt}u_aih96bvx&kK@jGdA=5w+ge_ASl z-4{BYqC^1nw6kAz?DZc;rm)B48X#Br(uaf1VywM6kOYVC0ha+N-Smkp?|tWq_+gz~ z!=?4rQY+OGk2^-s;BrE^lQT|d98{)Rvoyn-+0=(P}~HXo@BZ!!7ocua4<#h18(sTu$7 z!X7T^pmSclzGp6(E6;?h;Tux99m=;a?tq4S26KTp56tUXnZDwq{2juysz2|NxdyVy z&*8`HA&wx+6q@CldZ?G+RWYDpuM|y#sFRAtkhLTTuXi}UbQU;eSR_xW_Ucte<0NpS z@VeJV^YB+nx7($DCDr%)Ka$>xuiOC+`R&^z_J5M}l>cp#F8cpo(S~|w!X=S1jkm@Dh*>@S<{TPmxxudNxMkytB_fZNjj}YppAo;qx)Z( zA(rAuslV?j)~6fxaP@IhTgHllF~ChxYdL8(c0o%H3m6ZqDCZiLW~(iW8#}p}=>HbQ za@&_tal`|`ry6{&<{Fg7a67v+F!3lFxmg=Mg6sbQcGfth=I)jmtHK;9nvW?ZH-|*E~Hzh0Ac7PS8D=wVgaGk4tB0kdxGb18N%AGzyX9#k>5;gdF zyJ+U0DBkgKy>O|hAe12t2$5bSwOgbnmIt`Ez)%s-8iz}OcRcdmR+W$-S40RFUj>PO zjoaV6F!&cRa^nFe_guyFy{8rqmBiE7WWZN&>p|B>7nzlt}_>bf*T z3o8V1eRJRDZ4eKqu|J{2gR@jE5srD@?^M)P{7jP@v z%0uZmaRAgRMU~PA{-K&g1NSr`y0QSL&(R<+cMqpCl2Fr@mCBH&0>z~qzoh|~O@r$A z1yu^rE`zyg$Qu!MrRzK`A|?8GnKHM^j%K7p5nFJvIC-lo`DARKA~Sn4&{3@Y=Bv=n zj-BKM3-|)wnrpQyflk1y@od(c#WV;iV&wPlZu%-?!9o*V1&3G9trdz_GXMptqG@y*OKqLYdP;x^;5e!JSRgc9ReifYfgpdI2r`K#P1&@_Nc$7jmUl!aqiqn;4`qij3&%Is z;M)c(EeUJ4*z0X{9ED-mJM9gCMu*mwl4WZeP{+iLJ}plAz>mC4t?^{rk{{3E(o)e^ zQ>=KeUev`bN?KCJRhFRzVs`G?5|LSY&2mnLsMIgam%|Ji(m}#Y;52w@DBk6F6i9>e zw~pYyv~>Ss;3Y3Bzk_ub@L4of(x0e$`w_3^z8~_)9RB>deL7QHJy*r`XL*47>n#j* z-IA5peRj!BEL^pJ=~Ysg$bNZq;S#e0?n|54FwsRT+gg6}))g!)B8^qD3eR4=mmMVh z%oxvLMXwZ1Sb&3S^8_1Neqg{jCdrIZY6vSAyBbKO9%NI}atON8t}bgk@Fv>BTF+F+~9fh zw}zl{PSNi@!2grLQYV5;GO(Vr$}};hwr~kgN~t!Us3)#QB19E$v~>({3Zoi+hL(L$ znV_`Y)jq?R(i5d}HK&CbX{wQh{^b2FbN7~rA0AYGlAnwt8@QL-t^Y)` zH|lnRI>vr>l4XY}=m)Q4)1LbvTaA7!TVH@dcx;wJ5^s^aB?s2=16F?Xr z{yoINH7x;hv>;AIM^YeQ?y)n0ddI#sWL-Juc?n3x43B5XAaq482tBK}$gAqx?EX3u8CT z1_Q_Og>eoch#lz;q4rO{4a=S(B~v{xxR<@4`4>|CqJa;~OhdHN8IV_^{XUwuuJr9y zMNjOGBgQbI=D8fRtbBd9io4ATa8$85kg0>f*q{quzS7^MWVyIhzW@>QZBELgq_Xj;rkMZ2*xK4s%Tue| zdz&+UbMlJ9N}}fDmG<>=YJzi{xBL0?y7TaqlfV@T*UUY)*ID*HT0;vvh05q1{a01n<7SO#b1y&IA> zq2+_?Pj*mQea4cHJc(He9h{ejJVzSXf!^p`+2|ZNj{|7Ycu1QrPA_t`7CFCO{`;Mpwb? z!SfN`z}i?96mChuP zp%N#EvJc^|todh0`)ogeHE$d$%Ke@fs+E0$f^c3jZwEi{t^&`{xVUtW>i}8GVl9nl z-NJIIVaa8wp~Bpz+WNBL8!2JnzKV=sR=VGn2s&kM0{p{h2yw$i`mfSi+JQ->SVYX+ zn%Iw7JXn|0SeHuLp1F-kU^d3d3<=1s3G+T_ZL7t5t3?I-$)a;A3v-pqxhzhfgIb@p zyB{3#s5B+uHSohW6vTnCe#6hL8sbO|uxEoA+$^QppgI@{f5M^2y@dKrm0fNOnd|P5 zIrKP@ToO)8(f=zj`4iLd8VXPP`&6F+xG5^dqAt3$f?zPQ%oxBP%^jvPqxK;6`% z)eG<5mN5;Y9YK9*RS9;mBpMyO3u)22DRdAc;8u>#lzq~Py?Tu1o0vm3TYn1_+E3Ii zG8v6(aD#|Q*x_n4(?$uzK1FNA$>rsON9ha|h3U?Hw^n3rA<6PIXw$6nJw7znp}!u^ zdU}yV$z@2GoJ-3$^}@Jq>CQlZj8(EG&Qddsb)6#!(zEkRrU!Tf_r$P8v%|W<+rHfd zG>K4_)-xuW`4npEpUvg!Kc1S#{L|kz`^EkXbMF|PS^I8#refQ+ZC7mD$rIaV#a6|( zjf!o%Vm`60ih9?(cXyxOyU%}|amF~O`|G;b=XK5NUh_BSa>*obb_he?t5(@AsL10` zdqo@awQ;qHyyn`L)S%cB{(MoJBMYPQoHX|_Gc)Ba`8rJO&E^J#0GeV7tZ&HT=+MhlGh38H*`H2Zc3J+=4XikylRc|r3kK=48GsK;7(mZ$RrQT zEwhXd!QpF@Z6^4~(wfm`UTuSt_9pf@l%BRKfFP4ja)5W0zqV|^-NoBP+aR5waD2oc zmW`T&L@yOxApN9i#r1me;n>y8Uu?w)6|8Hi&!|VH6v>hTenkKY$qbjnzIKJ|9Xr}T zO4Yj`YaiSt4iBfOfazk_S^|USvlmNJvT!U%G@QrKP$HFEfNzMBX-+ZW$sCzPE6HxL z_j^t#f&L(W+k(Sr4y>Sz7AK1WtzcLu_cr_D5*f^t4WeY0$+xSZ7W1{#xJZ|9&}`cT zQTPGjX1Kv?WhW*2WSaX*i!i_48bQU7=E%pOLb0*t_SAxaymr?Z7#CNE{I6#3H@a^xE_h9_dZSiqQ<5;Erdk>BqhB6)Mddt4 zODj8t$SJ^t-MH~F$YcYO2rm)dT9X6_aanMM4f-{FPPjr7#VSong+DK#@^D_hKeTe_5YL&5Jx&bp zzb9HAeJLLxPb;B(G9tflVDt_}Uo;0`?uiGjBOCiS3Z0Y&ae3vA(XykH4n&$b9Evq@ z?z>`MfFy*Y-hRoy7vHENW^*gNhbz6e|MqvHPF13ev7RD;%;)JAnnK+(D?$p)HJ3sm0AU4gL1Kh#3IwA)wrP92*o+{af%vk zfFitA&)o$c>Gw%!Jfdn;rD3d+x2NbdYk}0M6=9c2s}668XfTG;C=B4VRNGC7-(>95 zY{av<%&C2nXCI2@2ZH6p@tgT5uU+t@?BwkCRe*KPlY|nDPJrpIUe#P=Wvzj=8bR70 zdTbP<5=PThYOx<|iJW3l@fG26R1d+s55j892kQ7=gLlVOz@EKKPqa}P?ot8d!Yz;y zawU~}2;_Y?#_}*fn=eOog48-2E@k zG$w;)PX-KX*_sG!CQ*(A1qhR(p}eshv!1i}H?BI2({x4Ooj zH7MaDOwSnksD~K_etKGZt?m(rk#>M9oQc4^*8gy&FEq%WUZGeDhV3zwkoY+;nS^d` zVFzSBb|b8y_p@rRxxNBx`wHsztZ$h5xFL40WRWD~Y!i;pU1~o6oQ+r|U$p6@&NE5o+IW=SoLdU?*MQu;Gq}1biX! zHys>d8S_dSKBNX^ylQ1GDwlZ|v&j3z=bJ072Yy$GRl%)gkZZ(QF(dW@(Eo(v(O;DI z7vznUO?J#O<*0)`7-M2e;(o7EYg{g-O`MhfXskwkePQsY+Bu$_NF=)!t8u&8xu%HM zyn*6d{~WRT>g&DX{bbk+yn&?44F35A@>l80jeU6O!GVBK{>vg^*Z&nt|Np)W{C|1; zpVt5#7++mCg0IhoS|(}3G{$qr4&fEIBKZxsEr@EDMmIanlV1idXf<`?Hdv{Y6r+rc z7#RxLKO(4U2b6Bo+uW-0vP5_eP*ISX)R4j3g}a7fK0m*@imkHTPg8&YNqkD`dj9JD zx_{SN-Rc72n0uPedr!XnJN;v%<}86EBmeAU9r6y=LE6dk~sYf z2Uic)!bh>?zRA0j`*qjOZeqlu!iGZkY4sN~_S1E4?GJH3*UuoG=vYYy*;GMLn>nxQB8rmAr8j&{jO7sk$}wa9}U+*JM%^k6L%qoOt-~ zjVkOQ_~*@`E#mJbZpQIAwV2q+ipz@QIf%M))#4Ow87Xbm`Q&(`K9NREuEv_a%xYck ztS1mIX#W5Zjdj!6;`zI5VA30C=~T8d(LSH!-piK9j($irH0uPNssH|E+}QKs3t0p2 zl_SC+_i<_p#4~2z@8f_CE9WZw;Is?uX>Q&s5l?wr`YL5bZEETgyNGc-uLj(pWx zE8eZ3)_rTI`j=07TldH@I?UEJrilrwU3)>l&AsHbwkcPoYh5{?um3nuCPO;uXECf! zjZ}XIZR#%l0D;Lsfig6vAk9PfJNXGcdTbEZpWq0u}pN` z*xT$gP);i%4Rl$}j!ZGEu`K?kAphvo6iKnwl%3hYJG-c<=6l^oI7mRD?8x0?G&UP!by@Xc1oZyeWwHn zyT?bW5~ePn&ZSq3uN94^1GLCMi-8#^`CeA2UeCdhy&ne7K5#e0s`tpeMh{`A8S*IZzj~U7Q+WyHPUlA zcV;6iUyVN2TnRBV`)d8{{(@`>H`HuESkpkv`y0d2xi&V?_p7Qs;#0%e!RVnzLBF(6 zNN%+3V~eltkxA0j!_ zAn(z7b;w!H9Y75y+Ri#Q`4ONttmufum3Dy-D6rYwme=5q%cJ!SO5nlP8cuq_5l%#~ z>z12l0f+A%o)6i5#u8aIL@gaMY5E;g25pJ~7f=MW-!vIn)MFmCq{u!Dy$IQD9iJTh3wa|b62@4Z5I1-z&TZ=axjP+_m<~M7QtX{B z(h2gCUP<>|QW_?X;iAAAuXF_3=8s{uPT4bSln}9WKR5z6I@emInJN-}Z$xSaxf_b~ zGRX{r9~4mtBN^V|$C&RpGFJ}g!Mr#GcS@B!x(t&Lz^D}t;;sSd2V?aRqIsz{go;Ug z!%r}tVdDmnNpm&bQ9#drQG_&I^_%KrW@$A z)99mi*1ytDCur4?s9hle_9B$UbJ`)Qk_HoNOkLO|di|v!^+sVYTafYSgc(Lh4HV|K zhfdy8TEjHJGK~3#*wGA@ed+fGlg6&u0d%jND62c(9H+qRY51gRWHzs*A2VW13U;>1dO+yI}Fy@=iX2Q$`V;1l7u8V__rF}Iwe^t_y`AYgYFvpA|?=quDy z1FyGM)JJs(Saqtw)E=b)^By#rxIj`^7g{k7xG^SfeQL(o(WR9srm9x#t`~2VG;HRp zw2fN-?2Q!k;@QbC@93qLyMXnpJ6M3=5YZ)~qh7M@3cBDAE3neHIVb2WYy42Z6G4z( zvJ?ytx@u5CE!VV{?NPM_C&VwwVx5VjZ}#S@PDtO|<1yU7JKqu??UB$Al2tcLDu<3b zGJ0%2dIlYOWiq*!)jLVKivzVp?N+2OUv1QNxR8ES*jHk`HdqVx z_LoV$Y}a&xB%pv@&h%1_QWiduJ{UUE1RU(yw?Lw&w9)1w7KplyI1v*lA3NYYXx+!i zW~6>}ZoT}Y7b({tU!x&~ouGo93^E>fc(A4^(4ru4bjq{#au5sZo`nx`8$a}zk{|J1 z^Uuw%{u>CVJ%<5%F#qmv4kj;Iq0zUb^a9tR1|-6+G<2*r{{-qsJqY zyNMDtd;^M%{w~3>2%@M-8zd;!q(nITv@!PvGuVA5=E9l4LrF(RzZRi$?y1D^qAjE| zF?yP98*t1>XUeyLAs=V2eIX{6`Lwk*!+tq$1Rme%5>1xyYsIn^6QE>Ze~gr!-+Mts z_9Z^Erz@8vB@I=M-9gxgq~rCU;1_^=!AGD0e{-!;Ohy_J(SQlmt;<`TXCqc`YWziS ztp2SWQ!YV=l$4I;m*|DaC9*+Or@Ik9Lvt@K+@m+sCw@3o&y^X{Op}bd{%h6EChOgKoH!Y0&xzSA#7OC%`8G>uywP2HqK=HX6*?l^mIC zI}+^f>V{ZD*+*RV2f9@tj(DhFvdX3;8e$?VHal{X3)`5?>5nc|8d1U71g}-{Ycb)Z z0rIxwXh~8wxdFj+G0P=#xk6TUDf%d0GbZ`VlGF1i1hLsq<|PtUYTfF>40gE2>H_}H zsUlG4u}+apMT$H7Zw!UQ&0-zg^D4YaseqAye|E*Zk~7Uf1P~B1&VRKlCjD>R75|@B z(ErZSzpgj1P$MRlY|N_vvD*(xPA?mA#EKWRi$c|u!(1D%!BhY6xNSWS{01bI*JIpum(D;KWu&k}T(n zC%`jZW3F;sk(}73nifPF_M0)`p?I9l>Cw6r6KN?N?Ub8~V^WF|JBlle>sKfj3%$b> zZvXPUD~qgARmJ1eo#h*0hwZ_ZT^HY&5-N)~YNmKP_P&W)om*PGWM?@0q6TY8#IUfamHcd1yZUOY_05(THRV&euWGqN{PDol@X9o7*VUTNK?z%u%mYI5L^SzJC`x`mlo5PAmU3& zwsS^+I#8#1DfV*a;bmR814m-{1;X3Ev;-8PJ*cKB=XI$Dtv2y8QdQ)*83ko0Ce{?BOK7!D+Sa>c(}e9mYag-7 z#UU+D%<=cw7nW!-CT5#rpN)=_CHJw@Drzwf@7ZsY=x-flil-Fp2mE}0)|QeVQBk8Q zH^tWUR)5*GpuXJGz>7}=E84@3pCn$*+8=wb*r_hDY)3x)vAxwkMPWE#eY!5~EXqK7vSX~GV0D^4yehI{n=8e3C2NqS&L4~!Mv;Qk%v&X+ZjTm>`wPc? z;Be@}937%5r8yn|&n77r?ZT~E9|}-#zYl9hiFRI$cDKbi960ail<7wpKyPQ(FwG+# zF0C+jCAXm+(weRE{Km9UE0Jx2rd%nW(jMU~%xh`-c&2vCO4?kjn!I73ue!v@)Pby? z&n7pkq0ukwCY1PCT=I4`<7Nci#TRl3IY`fyPC$5JY-B)!tvMeS0VN%VgG0XN;{)Iu zq@$H9zECl4g`?)N+I8o=A&vEi@PmiDW~?!8-L+W1w6g629jKx;2u|zII^&}ElML^F z6IhjObn951kNx2zG<@zEOsZE6oWCj%S!KorvRvbbDnqH$50F&Ke{JQC0`%hkbPW!l*Hsk#tcEO6A@2?jh8SFWJHItV?cU?q+y{lZJ}GnDjJz zQLS~t(Hc{W2mQ5z8U&fjSXN#9V+Do%4=ZSN18V$2`aN^b!Equ>6~%5)7Pb1#s{E9? zRB&Xz+mE{B>mQ?B5gaQGPb!!-K8Kr?3;;(!xWD^z17f6YCoB4+Beox+wSUm>82@C| znJBb;Dr@@5e3uMhkcKNuet8eJbjI0D#y4tVaNVe*upDl3wx(rzQnD5J+r~M;(d>XH zCRx;b(f-YL=M3w*=UbO6#yYY0guBW7gZf^moxk3?+UVwX)MY z>Dvchr$R^krd6j4a?nrh7S&ay#-Ffu@B}H90K=bTP&dOlOD9uDtc$07RoMhpusM)= zYBRBwBE5A7k2V$$9bQ!$L3!rX!gH!f+qieGtR~Thv)gU)`kn(3eFb+xfg|3 zyBc`J07s~j_82sD0lPbO95QjeDOaOBM0<_q=v`1V-F0nDPO&_$vtkyd{6@$^DbwXa zD3pv2uz8W(?{7BW!>=!Kwv3h?p3bpG3Xw5O)+eoXm)EPEYu{ttkNe($PwYP7cZq)5 zFfP}s)ZD`kn>8!H%Ad84Yyzix)hRX_8JdeYWt4(NEy`?qCaHYJ8VBBkM>ti0j!k>r zF|DIyWh-66Uko{XaR7~lHQj3(Xx3_;x@qgvN=m6|33*|p!9+y&v(#zbSb;>egQCou z-`vt$htq88(@xmSW>K$HVNoR_M+anNp^3MogIR-glds>xeho}eNQ70TYSSc0!Z+*< z_o3@=>_f+=NHm2O_@)9ltUUClU8$O_gTotA0ryztCMVOFBln$@VPT_9#iuncbWDVM z!rj*CVLl-w2`5=b(B@;w%*o80EX1&3ZBah;83h(|RC46&`^h$jXIT-*&l(u80|2oh z)9@(h0pkaGjPo0WiP3t%ok$Vq_$7;7BW;q=sg9dS69P+Gv@&?TuGTF>SZq$RPvsxA z#?~}F$1(&^Q-{z_lY2M&iOubllk;SKVfIb%AFOn!e5}JabwhW0UNn^{W$%gq?g2&D z>7F9k;ykMbWSsii$IP}P?17Hsp6FWf#2bIV(scZ>rzMGGfxDUeJo1Nqh3TfT6mHwq zfZnXDgruGQ3RgXab_>iEkvgu7x~q^_YLqBsQlw+Hx}_t|pUfEevzL6r zP-57ixM&O*60{G$;ef`9L6vBtWu}bbm0y&(L7{uXTVssvMcc7nJSY#kF*9_DgAv1g zaS4qeSmq*ql(&B|&9h}KuDQr`@Tt7L>6RPR(0 z_H*^jw~dRdO-T;@lufFuWSjb}Dl+m4EHgQp-Am%OSbhu)IX2rpm%kBwESsk>(;O&D zk*P4jhNj%vmYq}l(oM}dGaNKcDzLW;${sX0U<0-Hw2VI#3_NvQ-W%l*!r9l<00jyb z$x8FiR@pr%9ZX8e7BJTK}4g~o*EFudNsou$qe zUjle^1}&fI9K-KCP|(`%}!OX3t+#l75<6f z;|UWrWcVAw7hN&s#*nxK!gz^P(SLuw++dGS3Q@PjAhOk6BN* zs>RRdKh)g89$-jZ*%=LJzIjUwp|RX@pdZtcD5M?uWO%f!QW5+6f1A2s~(JLe-kcHlTOKT@E8TUK15>=BSt?^t_G7 z`Dw|7AGG{eE?Lj{{Yi>eGr(1?nw zcvDIYaP7Sk7W-CwJQSz7fE(M?a)dsPl@zH&oY}pJV6$wR%D+_?91taH&1BmF5MQTI z=0E;SK}G6Zh$peM{P4>QVo1BuiVmSh+}ltY0QiQN6DBuu48n1{ zUrvE4=qK@L(1b%c8?h`?)+}4Og%z5&T1LL=NC@EF!QQes@x5_!NtH!7`^L|S84mm2 zLCzH0?_QXN1Zje4niacG%)uG)EAFI?yO!UN%Nto5~Lvw zHei%zk|gp`%q(ofD?lR$2)9}iy~jzl2o)d_w(w+@QViZ>{bQ+A6spAkz%`{O!HyUh-=hK`(aMlooMv2v`jBlHKs*NwIJsA@2DF^KWM1wJas;2Y0+&)1i@h0 zzu?c11xORWkX6C!_T0V~giBSA4Ue3+wYu^qytlDaD_9HGdwu(^zyL*VLn!<0An%p+ zCs!c8Nl14qABa~X(+|Umc|L!}ost{R?=hj&QoUD^??ivqL6=oapz6P=gIkP$r4Hi% zH>v|=H#0Xg6*Key?!kXv^fljn@YQkr744hW6s(d&NS2KmFc)kGjA;yhDoM3wasHIe zl2_3g;$9PwF58mL&X5BNx(G(RZp0;vFAn`67{A3`R_+cbft;7-lPY%SPr zBKe(+ZT>@gXu9*Hj{2k=tT{52l%q+DkqzVXkq0ji4dVx<&Y529mu0GS;Op}2bgvA9 zrsmD*S&1_t97$#~zmTvNG~6egZ6ERFS{|T;c242R8hDc)e`_Ef?~985u{T4K9qB7v zkMQQpcexIpjAzygr*j5etD(oXjSQ)uAiu1H12vQ!gd_b;Yx9=ck8=KPa*PT}aFEo~ zJQIe47UAKcwTNw1lAD2tamM&-KwVCBVJ(#IFrhEW^DW%17EygV(4Lzlt7O$fabdR^ z7>SN^%tv;E+PN&?rD=yTB~49aD+D%i0IKs|$WkY_^LZKa2ED2&3!a_%jv3QO89K z)>;p}Vx!!*6qub;kBwgw4g1^S~H{5?yp4 zSpNOQkigCoQ7*Kk-`xFBL8HqkF&|Dw8FoYQy_zgzErl9s84?)4BVHLAE+1o*JX$8x z+J;`#BJpuAUYoEIXsAtn(h@hZ-B(dW8Ansb$+J*`P|*e4PDzWVyV!EiIKW9qUo9QX z`E}=V8>y-QnE!tAtFjozovmz}b@hkFmEw6a55O3<8}bTuETC-?&Q=pZZyKe2I*Y#c ziW3mn{pehvpU!z}=Bu9HyS;#(PJE2!75GQr#ONgvC?RacuU zsMXwrb1FvSBx8p+53KVt(_!~W{=ryg0>*JpZj^J3b5X{hL z!oydtRi;5B1#w3WA+eO*56Xoxu^Zy(vLMng?mAzrm()myeLjDj*L&CriuIYZ*+A-^ zXi0c}`uewz68UV^cUu~!{r%Wo76ruO?!sTVEBlpXf+UWkhs}MJE(M_P#gSVt-{2mD z`5r@@F!~oaM`?`{#&l|{^!zYq@jUI-!(QgOoCulf6~@vr&EYkFN9GnQejkcQc#ojh z=w`h|8*UT+Q1%yfWZ$Q%78=cLe~0@GccoEeSP9mD{QG33a+mI}`X zE0`ZZ=-MT=v(bCAd{?R+&Rcu;VFOWJ55+~)T7N~h%ERlzgDsuT$+TgrdQm1bVA5(u zO;#Ib-ogT4ve#7@YHU#WTFTBKDvj{i`k?fNwH>QHBR+=YH zfGfLlaVH9aJXZN!IY6&UU}kXxbb7W30Wr<3Jw{Rr4tL!@;2Q$8cQFWzfXWYaLmx*p zLD?+628_285j6XwH@dkS#&!6M0IU`4C1l#MZ#RB_a3Wk8_TVN@I+euFz`X4i(_k!7 z&ice?zRR>)@!j?*uw8B%*c~Lol1-bDK_x;9WtTL|{2$ixKMoCJlK1We1Sq|D-gqvakoZ{@ZZ> zZzBA#l$F+LS359BEo(MF(S+dv>fGseaWg@TgF$pP$elq}F1w`NBaUgoLX z4q@Wj&GrygtHb|bBESB@M65f?YjiqSe>1u_Mce)Q)%k0|<=Q7BgFK15zu@WK<|wOm z(`VLu_Vt=4iOMkG1qB3dtbjPao);P6ZTU3Nll=(J)%~^OA);HKS~Zbc><%WKyPL$XtI5$Rf0Jgi zDcn(Htb_;W1Sdy&E-e`g3M4>3ShFzTFY)=sex?8uAFt)s``&3s2kFbR0@LU5xC&8@ z(o9v?94lHB?n9fU(&_}P!6k2|wvN;p&5pfR%rj9_arAAD88cgzbg{LR&=xsT6)mTV zr?q@8(~7;jdzIliJ@h7u-6Exg(x(^lCMbGQd@}enwLh^iDz1hbF$x2Nbt?CPQJ#&Q5< zVdAu#Heg;krb>~MluQ2|5-~GttN?{6qa>3mb*>uGSbwr86TcwhZbPOl7S>zR=pWZ@7 zuq<$AFpu!?sW*zeOw=`x)lCteUH8F_mCmUoe>nutHgE0R?W4zFW65&7=`AdX-QwIl z9)WFOGQb!u)Z)*n9f&oK>+x&_pfd7DB}~5AtchAq)ZD+|!xzsi9=6}0?Hzs%WAjIC zsD?DvOZAJ0C|qhZU}JU(#IBQ@k3*-0VEYHhI(46eO}G^93(^o90iRwvj%%c*y8 zzobQ&3aVrGs10}4$NXlOtZe7062hJkun4>DS3+0tN@51&V9GFS%;5E^WFL~sLytC( z{1Q?uTBdW-6c$*?-9MCYgrTTGQ{cYG$2cxbX8Ar>1LbYa-lH!5(r4lqOU$>lvsMg; z*1Rgw(4{P%q;F|O zq3vi=?=m;mk=PhV?iB6#ZJAn2zTE$QQ%x_zgYBrHlXh<+P8^iFE!k1862|&G zPJBhTWFDSOTP)6?ACoi&4MPk%t=G-01+F`SrY(kU!s*KQ7j|lv05&KmrwE&6WIhi6O2>8wKATi8ix2PwIBiakJ^n9ky%*jfiy)EXJr~tQ~oQMo?Y3 z#+uo=cmhm$JvwDJFRmIq11F4n2EZLZk`(A09fcthI*yqiKV~Ty+7#^aMLl=f=c8sj z{5u3-9QvgngN-I!wtP^;erUijZEaDlrIu$H1n8wJ!H?LvJEcpfVw`pg=E{I#qE4Lac;zP zZOh}q^}9|=2OFVX>}U-1s3VP}^ciuh1kd+tGh%!}y&Pr{VS%Fofi^>S@)8B#Ox*{y zGdcNnE)LaI4LOYBJmp(rK|1e?Z36++gBky2DF}%(Q@AwYUfp5B&FRZ;P~C?)kYo${ z1EMFI_3=pn?uMujZXqR8*#-L9RQ7Kz!E7(WCvWx4kH~v3a@H+;w_c#_Lj#iPzOWvA zw-Ai63%sr5NG6c}myuvmnHXt0D>3}bi_#Zh(8s?kYMMHK6iR9^M8$cmPyq=bWu zg}EQNB+d`s%W_`-up$pi&`#@rSrH2iUz@Sg|6oN-lz&ufP1)n2Mms08{-3PKV5u5E z)n8U53G-+{^|anNgszTd@R$k+-D$x8p@u)Ei8?d&#EiEbi0n_|oh@%GE(PZS{tL$f z`7s9gs`nwm>FN<@zw$E_Ya2+$9Ag+A@r9r~zEKi9xz&pT8|2O)K-MXrJY5wSe^X&G@a?W*6@uew96Pr$zW*R}PS@M}< zEO|dv=h$fH5$j$39We!$ls_kKgR^AVHxv^l%+*Cglzlzvqy``6x(Fqz=WL9UA<<-U zhLA_MC{(0ILa&aVv5zRS^n(bnov%gPzXQSBTM10_49t0&MePz&`an6NLPFY7b4>S1 zs1^|=AWvVL56vg8BiP9Qg&f%^GmkUjH5Ay1%$P{f=1y^vQVLUiwC%r{e{2sc8&zDxnC-hgP-@&nVHO zR=u>p6-;yZ=9D?wfJEp-qv+&xPiq8L}7(CCw*zT@qB{feX(KoMU3@QJ*w&|!lbr1l(pA3j5h)r#?tLn zR54ZFF&99tvy8}pR+M@tQo`SM*MTiS7s(hyxN>XP4>Tzp9%(lStgXC%pFn6-5M1E( zqRVFw^&#glKI+^)RVBpbh0XG}wsV?;*_OxMlwDVAs|oMbZfrXmh90|y%cEBOnciq2Li<@eeYAvEGH5FLrm#(y%Isq|Jk$+u0Y`E{!4l{;fr9jwi~ zjj*nGo-gS^&)Pgc;2OjpTj9%E;tw9rJHwx7TW_w#Ya>3?coUIN#?e~!IDKcmA7gKq z1j&S@;$vmQ)TOY=N@lno9_v>$V|=AD0FeQxTN2$ReNHv{BrB4k$9>HBgz-QZBXsw! zMULg%5l8;|dP2_V6tY2nd>bJYH{e`1v}cGwWh2c;0n1Zim|P}C;vc><`6}Y&d@xSs zw9NZ*4>i6|(Pb;SvEz9`^nztD*h|5WY+xaNuk`fKePBXOE{q`@2uS0<1V!rpSBn1s z=3ekWAN^lFUjNj0S$X{rz4Tv=K^}i2;^gY&7fYHU0xK;A`Z%p(Nj(#y!hWV&BH4;2 zdM{m?XENIUY+P&32i<=5+xani-xrRtZ6mO)>VNn8{{5ZF_sqk*m0ccF%1^!T$t*tO z+T(~V@0z3O-)ldY_t_xK;0@0*)GUL}-A7>AJ^OyM zVa|^7*J|s~E@8+Ys~8iLC7GA6qh4ObyR+)8=racu6`k_Vnv3$$+xccw0pCs-liABYs z_Nqrv>D84c=X4gF@!w3s@gVuxCvCBr)lyXQZp_<8Y9ug=cnhg+ZE zJtVx1w;FN==JeO?ioF~dIR?e`0?M>7>;r^_cGY!CX zYZ=5gPuI9oV+A0q4acG%#`Q&2j5y$fzMq}s)=i#VdaI95alGz>@Yhh>>C*h~0 z!wPH?tHlEqi|(2)m3?N+c@};%D5x=;e<=POfjF?|XoF;c&BVb>@y7TDj&qi@d38)F zpB<6OPeE|7M@p7vpIW1nx)4Ln@^Cfn(f}Z@?n%@q$9htgwn1BS3f1zI8g^^TH8PI| zTrrJf9mn@r!WAv4^N{$)1GWYLb63Jo%Dm=UtVT9}t_bb)G%O*wlp`2j#bj_z$L#Dw zh%5!U5U*TA#RK80+Hfw#;<%F8Aj&}3bND^4ZrG}c86!8dPg@SmpRXB8Q0aJ9tAU)Z z%*|;Nfuq?&63GC0>7<{UC^y2Rbn!W4L@yRTq~n@$;#61pesscl8}t!uQmfKx&Q^Yy z!v(2qb|Yc@Y<;gCLvS;M-LzL?M1$)`{4Q-c)g^6_!t&gyPWm_Ja8~{3{O%(>k*xH2 z$AMR`YW?nEDWTI@E@2tFsYFf}$Yzt*g9>3Y)5aOB!dw`Hg~KDY73gw!SwrQ|Sw;+(^3rg@jBZW;s`|lD7O8IO{7_?Qp`4h!suq#~N z?pTfh=q{5Wh~Pa^ru1OJ3-iB`aVqoi--uY@C+|+26=;kv;eFJ!#(0OPt+14$K*!IM z_azaNU@5U{`8%7Vx`Xmc%1WJXV4;yJJ)!*}1Kbzt9~*>&75~)dnUZy^2FwKeC=HW& zCIf|*;)hObt>SVJZ-buOjg{l8+He(_i@&<{Gr98M6)QY-9FBpVJV=QP)j@J|k zufU0B_r)QYrtTTTQ81YH%*wQ+0gYc>o-T3W{#{Wk7+n%-SgsYGqFS;f9|o{g-ndTL zIR&@PPWih8nHIHNg63wF!(p=Y7Xr!^4p@pr5!ovYxq_&C>AKjQ$vWMUOYQP8*n1J> z7WxOgU>VsZ_X?uE0ai2=cXb%tIQ~p#K;U(ZxZ&H(aaSiz3|&N(^N-qCpep7ThBsX> zlI)2lLcbZpFFjF@+cNxcZ_vjbnF2G{nx6zYT8z3w@o`AC3&;o>!q4kMH{55s8@L)8 zQ~6E`D@+_$r4?bt{(XrfC0YzrRl{a&dU1x)ltDU_d9_38;O&{DPO*Hm%0ULw&n-eX zKGh7O4jW82zjDB{{-D@e5U=tEFUMl^8|Fje(n%exJF{!ZC5p6%IA!SF+w0W9V9+d) ziGqw+4G4hK&=u5pP$v8!&dVhC_}lauQ`678DP&SBK`>rdI&7QpWAam|I|%Qqk2aJ& z-O&!~h4&Tl1(a>o6SY+VW3Iz+riPc5kwGpbI^6$&yaoO2`)P$@;9f!RBe@3VS?@uG zqVU<-j?BUU_3yx4cyE44PgTVF0Tf=d6>Hl;eP?T0kr|~6_d;22U?dUB4o`6ZmC@kV zBKA58`gNey<`+RT4mqB?@;rSW#CWd>f5ZT!$M0)@ zn%W@oa>rM^?Q!cojq=~n848e~P6C#TH~}>J-$`c>=NAEYg=B4nL`h2)&AYSXTfO-c zPZ)?l&jsV^#uX%Q>Ere=d_`9(_!kt~ieIJv{-PVs0Gl$ymW?20Gj^B#*MqG>m1oihh>kvS*R42 zv<$vGHLaHYd(kJPd4(7b6bQ&U?!OxU_5Xhv|Kk4>^Z&QjmkZh`#uxoh-=Dr=VlarX z;0xd?+AYe=VW=0p&?I<)6zyZ27;``Gtr&=;c;Bu}9XB3i*L|%PuXn~AUdSGbtkK`7&;!zj+01dw23d~U8OpPjt1T6N1IfAu7^e3a zpwP_C)~Q>vqtc>E&A8bP0X4SCF`-({40^C#@L5cj_d3QN1*B{~{&Bg{(!kXy~3 zMI>Z2{eq?1IvISM>-t4#6w@s@Effleqa#hn`$c4Hd!B#Z=T&dj%;~cT%-RGyobcKE z>VJ*@91^qV&oV!;#Z{z4%}}%N8Xjus0fTxH7)G|vbI?mUC=#id2Qz`$+}$bfHGb4o+0tpcnF7 z4Iw4&<%K`(w5^!detu!+SYE=5ZuT1u&Db(aVL)fg0TvnBxF2!n?svB^&fQXO3pA2g z3!$eMOAx5Dj(~3dEo6fXB`91l#-~z82a<}|Xl#jPE06z!xp#`rr0xE7I~{cFCuYaC z?c|AV+qP}nwrxJKZKIQP++m0NeZRH$$y$5=w+_}isDm1##;B^3n%8~R@18TP050$H z(o0JfB)`BKO(wS{)hR=(oHb*tIZ>BtaVp5y6l43=Z_C?}n7}8xE_YB8ga+SzW3Zkv z;@Ygl7~|}yZ6iP%)h|)=$MT-I*iQZed_O!&>}F7LNMm-AUca5O~ z@?)x<>5AkrSWj+WI*oJ{IlxX#&QmNjj54G!Mdi|)+5?rf7UdXmcKe;_yJ|)hV5m6Y z714<6Pz#|OQf3%-)MsjrKboo|gQ>!JeU03$4 zs>39ec+3o`GPDtby2q6bgBja`^~v42-&u1zLPppQ6e824g7u9!(KTIRR!L`;TxeBK zWq?#IX>t7`gILI3Gu0g-Qz~=Q7H!#0m3fKO{&FLycaYr0AyHv)C&#&M+Hlan%T^2u z_M_n^Tmw@A=F(Mtpz>|UoL{nn>X{$>(c3FL2y!9tdrdY;AH{rh2c_YWXv5unMwuBR zMJf+*Ju>C0)F_Xunwv3prg{VkabhiMSdb#98-we4736nm=&5+SMDDm>7KG(2OM37o zm%AX7V8>Ej$pB$?yWDLA;gW;#XS{XEZ7G~4dIiIGZ<1?aueZ>LuzISulao0e20T4A zhipA^cPq5g+VeA-uftJolF^kIB2-{A+H}-k2x_|Cx6Xk})Q3pGH)V2)<1 z3%?EYvG`icjUI8x0f^iXx5h_%i@5iwp5~aFO_lgO>98%x8s7JrKDiGIw}fCrLTX1O z9_f?B@Qx2&0oP%xV5_aWmRc)hSe?4n(55gA5%!Ve;PZ_DLw`6xrxlRPdXKDVpJ;Q( z@r>EvW06gP?)PJBZMTR6be8b=)qza&s zW)~`CixEAGHyfnKcTRLr!ailVt)0C-QKzW$(Qb>z4(-}c)}Ss$v)51t^yo9-7_ zkgL!`=P;Y-Vr(+sjk(t+n7{oi4!4)rUPyoWGr8WGXTHosLi^Jpgza^y$FEBK0(ZT| zp$7^|-~i3=BX#Bn4)KfY1`;L(D~hA_qacE>pPup|(jwRPqaZpGfof zuf37y@x;CQF)4?S0IyS0=#MY5MqAj7AWcYy$*)uNcjOq~Zzd6+->h=71o!t^C<6$O zDC`80k~C1FXT=_V$$J&uoctK!lJjn3I4I|v2{3sy#!d)ZHW9T4=Ng9g7O)08K5->r z)_(9iAN`~5f!0ch==;Lvw}kQXA8iqqTu-_154Q~em!m{$|CivF|0mYs|593LcUfx0 zVL(+bDrMM5W+b)gN&L2KNQ^m0vF0M%`AKXo<#vDJZy&b(a@ZSft6{S#@$EJ; z|~l`PYp!uplxWP+~3RC5njZEmX<;i1ypDpNvYcfw+XM`F#SVjtQ5Ji3KlcTS5l zxU%4qd+L;U)yB>}sXW2wvN06y{nsI-@E0lbDB`qI?}|QuGEUy&G|xtknM6n48rdy6 zVVnyY?0`L5EvuFbyGW^rTzjlyp?opfUptEW%#WS4`xU!t6WSC3!yqvz6n@5(ZnRZSZp281rN-{!0_RfN#bqq% zpNIUxbGUQ2tHI2Vb#ZxiE=$_(hR`f!fxX9 z`+WL$ko6Ywjh?YayuIHQn#CRfjHv8S?Qf@P8KDK(?Rr`Tr2DaAIqIo}soA#}%>e#Cw^RvKhu!OJk$*1c2SR_x_1)J_i3X;UL`r zR#=SDwdj-WFKt0M-bQp;0_khU$|#rrlz}w*?cejW;dtk47HSXG9vEw^XcbbFa-#b#b=Huj=Ce)P}A}LSC3&?2firkmRKh&6ypH$9xVnH znzP7Vrl!p)&SXGKpAfuPc~rLphi%U=$}Uh*(S|luEowEGZ0f8a%6mZqGAwAU6&)YZ z9g-;|<$JE7V`CF6BDG``tqmW@ysiI-$UZ&_DHc5D>)<7l0VX&c>|jik-UDQUsfN-( znl~egwRwkpXl#!5(zY8|DQVa{BD>HrQ=LJK;Yenw>LtcIEjL$ew7TGW^`RdGc2K7y zXhGr?fuCRioD_Fyq|6y=8=RV8SOguS$fhK$oZ9J7CBnS76AMf;{{tm765+M~+bM~19X zCV;%4*j&qN@zBYMkpI(K%>@RAF@7H56V*4?e?=Hqik>x+l z?&NecMbSi500ZhC4?%z(fLFEPH@Gu(aG_%#tIn+JL;1fLza5wTNJ7)*TeaMV9RqDp z1h|zr%Gbb)rt3nnF9^)2Hq*ivkPO z#>)X6NknT3SalD-{^k_S6?;olzVoT67IdFrLTJea;J=~R5TV=UiQd0f-7+YMJgSm5 zb)i10j!70O4Ry%Wc~aE6W2$6Sgo=G@Vm+V~Y9ecCy@o(VK2{Dsmg9vH3~Ef(2)?kG zKGBf*GxeW7_fY~0)%&jk4vE4zGB2$^d}4imd@q!$5eP&Wi?Z0EI91cdj>jN38j%oi z`>q}JNcgx?UU9py=kJjPnw{nQrE3Tv#Rw+4po@n~qxA2p1(z=DoZncB#+vMeC zu*Zla>?pcJDDhtr#{;CVJRnzh8H2H>1`j0J{k)q3*`K=Y$v6}SlXcwH3Pvv9)fT@@SX6yuOF~FwTEq(G~u9JNKU~W;a67jYl@O zUs~ch7P~pr>XA?)TnrK@8{h<*UMb@Zn0th5KQna+gfcin>o0t*L6+b@OTr~APkDrz zq4Kvv0Q?tR0LSvMsZL!zTD_d)a$I?aYF=Tv5(D}S?6BFeYD$GyrR9sPw$jYU5WBp& zIJs25X53C*sqSXg!l%fDsqXTX!u`)DkKhc^zAqgAR({h3(ix0@D*y6-X)Nmg7peSW z|L;rxfA1^g(4k9UN}6nn4dBVvU6F;^ze_tM+EN#goi1tdC%8QAOzgK=ZnpegEZgf( zwx_dIPD-0qC?}KSAv+{v;e|yUP{F^VZ z2QeSt4zMxukp3ThMfCqSUx8sX!Ny2+%WT76KV#jPq((KGlxn3ZgbPxDgL7Frj5UiX zfq2U>voyVSuvU+iOJUtI^I&vj7GTfg!z9F?Kpa~-jmwECXExrrqy*VZa71}SVYRVu zBxa1qnlHiU${tOK{!E^XZO`D`Z1?}#rN9=JMWb+bgz}%LL1#G@%p%l{6Pay{0VcLR z$DfWRWqNQ=%nOZf#Hl%ww<@K+p%|^VVvt~MCTB)I)J?pci87DfcC+A4e0>V_nyA2= zM+~B!XPMlROG*i#3lJCyBExT~^2Xr9+XmAclQwOpR<4NXCWC2xM8HD&349OokP#C^ z782sEOY-=+3As>Oq>Efdacs}q8qbn8^>Yp%-x(~rW^H-WFhn9Z6?70~ImM+$4CkeG#0mK2;xM`7x{k+%yBKqG zx#bVBXY14Raf4`B&IOG-Mt0FJ=}220Q9$F|SF^}2g~_?P^3_&nR9R+?!{-E4>5-ybb1}zsUy_2Sw)bx8e^mdb*>O~1oHye zp^dlxk~x)w^HFVGrQ!O%CU&O+K6IC${WEXj5$CO-WOHzcb&u@9qW55d6dZMB` zL|dn0%(`K+t*|TqV5<0_=ohj4LpdFCa@%&@tpNpgS_n|EebWg#n36CrK4K%Mw}0Ju z!|Q2Ya74bw9HXO77o_GFq|0QL^oKdndxjnMoGix7Y43|TQ>gnQ)6Yw+LWS$Nd8`*| zr{Nxa7a~Tv?*l53d0r;LABT4ilZJ|U(Cfho8IDuLC#MQ!YPE?fEp#-Ml@!l@)fQhk zMxeiE%pP%DN=J(Pf&}9A$Gg}T$j1@UAE`pt*GxyiwSlIn^*|Tsx-(5JkUKf0^3@j6 zB^g#sDX0TI8%4kN6kJ<>^dkcXQ_Hq`)hgPWY*o*3rZZKgPeEaVwrg5#J0vEIKFg%m zA}hAmJh|;3Y@zREWz?iPO517b9a}GXkRDwn=oKzdpaGA@QBTgzk;Bxi=^$ z<==K47bk6>I8W>(y_;l9i<4rj>NIVAsTc7@uV+qqW8PWN-)IkC>-5>8Be$pV3PG=oP(1Y=#RxEIqza;Q(?DJu`k;SrL-7dsM0x?`-Xj>{{I9 z&-c?hvdnxJu>dI_=YW)i%To#u16-2MTqXI%dGK6HpOmI59z(8s^)Oe-!%>wYw6fho z8F@AJah%g%i~L3X?+=X;qJ6Iq11h$5Mm~n=eg!QcYY*-JFqlEjvr9l8Mp2TG3{S{}h{zlL@=^%^jOYaCsbU8Aad&|u8 zAK1(8i;BzJa^x2dI@o=RmrC4ua8kA5B4?D|zi4@9 zGw%hQW0rGmWbZZQ*aY#~Jw3A`X3@L#+ZvxZ_C-(Dg-HE_ z+O~mT{~6CSj}^uIuditOFMUPj|7>cJ{pTkC_gDOnu0k144E+-ay4i*t23a-;XCxT9 zdq2y9w+V}^0Xc_M3f-cDC?0_O`NGMUwNa6(jPcwu6|` zF3Y69WaueOHcwzx<+gdzZaU4aDkUUlrpiX>B(_W`?IW9SMpy7_ZYQz(zyB$iEScj4 zwXyN{qCO0|n=clGgt5#jIin-%B5*49PwDbx;^wT)a@@rmD0SwpFua2jBs;lW`|c5H zICNbJg{Zv6TcaKG~nV;5D)|2hh9sdE0q?-VpSHz zoKp*5`iKAyZ(6&o8VJxRH6Rl)R)lk;OIB2jbXv5$x*@o}xjeIsyt#}u-7;D@qTu2x7W5=f6RwvRH@b=M^|^n#<-a%6Ys!Z6PJ_8FTKtpR6|I+HU)qoBO9OlYqoho6)dM(p;O>o$|Yi1O@iuf<>=ei=p5kcbKvC z4NIe^SPS2UYE!hK3oLdzJSbaq6T(u1Fu+G#+0FUts41VC0}14*utbTA zP}ugt$W!2JsiSQ>4Rw^3%80B5xzl@L4jnCEUe9E2@xWX|LPMJYk_2hv&OwX%)y1H{a13*Sl6`;Vh(UvHsWr zp7-@OjUtaaQwvZv^r35ztA7A7W()z(#rcykq0!bP+@Du4Mi4NN+#;rZ|9T36C|cv* z;(P7gVB*_27+Cl)xDNwFh=%Y$$WQ~I7~w0pBumZg!6ctwL@Nt#!I1c9t$|&4fD$s7 z-&i_PQ-%uTpu@=fA~gZ}dkr_=e>_F`Au$AYP^J`UVGIhMAA0~qx>Xc?b%NLNLzOp3 zV&X$AQ8H$Bd2g15SnrlyjrO-AK>Yv)>SAvz>hJx;ZAw%*B<7TD9WeBHQ~K?$ETSY9CO9BZ+>t{`4SA+T!Vg@~Eo?`H zXbAEHAfwZlr&XWRf2Q0Nyzr>7v8&e8 zWsA?$*eO`SFRF+r2^<5DP;1hYYlllaWa9c!TOnFS`E>(nV4NT!4RSf=(jk1Ycd~^K z2pb9^_+l_|+ zmDky@Fm4K|wx9W0EJ>@~m5y_sK7QAomSPzhr&(PY_>~NN5F==#AmBCf`=BQ2xy>qapTJs)$%R znfWt`;h1#?uY8K_h7IP=vqxz|t|1lLmXZeq)zD2OD0@8HSh=`8WS)OCSL5kcz~*xK zsPJ#Jvz*Epv>A5DJj}c;^^-Tptk7EAPgGo6(w5DT2*uxM)>vyJr26v z%OOc%L%emG+5uvF*Ke1inhkc)?C{2r2R{#h5O<=ixjacZGE#>>+wA3P-3)q~2vpZf zVAAxrQipl2!TxG;Lx(p#T0Seq@X$rQ~t+ZWh_)FUf$b z3c@zK744$H?t#&|6}cms4j{rJP-^^v#NqsKg?AF15V>#3-1dkq}|uj9ehJGF3T> z^h2X+k8@b8=MB$k9Vz-b$Es0Lkwm++1BDr5*&K>#p?OWru|82Wv$wo}G$Yv0vejH= zwVF(IYY#u$U8gdf;hS-!%m2JbDWlOR)C^wF1SS&k$Nsb0#+GY+@a`L}9eM5MpL&$; zsW|6uzsgwGm0K=9bg~*^nxqc9B@K)!@(v542WG&JO^moWlJoc`4zuXksK;cZ(!iY< zI9G+*0UvxxTRqW0lG!aR5W4For<>=h_*`U5w5eRWXsNJ`GS=+zrexh}aSm3o~syO9aRGLvBLh5p&c*!eVte4p9Q6UJUZF&?3 zxx#|!z(Dn9I!&GBJf7iY(JZGHuca;Qrx+IjhVr{qndX~e{pMn9T?L2DFL)rmDq^QT zy=M9B)hejS1D`jC{_7xQsgE951aOzyh-gx1{N;TBc3Zuv8dET;Y2aM4XqUfR3-GKN zzAx14gR5!wdiBEqq}u6ytmlqU`)rj#>RJ?26*TFEY(pd;8p##L_YNDnbZ~msK}K5_ z831gN!Fgu}HI8>h*V9`DrWsd4nJWPcdtGkvfujWt(Jt#mcyH!xTXd_-ZIa2DDmtTp ze=`(i)g}*izxiRIaq3nK3-;mQC)xyo1EtD^O9$LiGsPsG7T$Ngl>6KryLJ^PhyBB@(aqR zdO81X)nUQYQ*?OR0nGe2L9sm3DfauXHu|tibY;r7lWw}#ciAOr@7u03h`QR&m5Uim zn*P<+>cJe%W*5IrWDCBA#>HUa?;wFS$xYVWO$nZO_m3rLF&SA^sg{zC+I18w|p(fMdUJ zJQk)DihC59hkKy{fdJud-ohVyqu1>X>Phh)x=#6|g!i2$>7>u@9milNbE4j94IJvX z^oII%``W_lb@PoO;GOOBAKsQiNPOLMM zm6UKoj~5Wg8OZ6Fo6-YAbsl6bPT3Wse0t_+hHczFOLufh7m0dsPs%k%x%_w->H*Z#$DOfd58zP8Pe80NV?! z6!ZKqD)tw%&?VqEmHH{1-j+{PvS%dKd z`990sBJI*WB0Uq{^CIV*17PPtsTf9o{TY*1PmB}i$v0qR>&0mOO&tQX>waq*mL0@- ziOPX2#li5@mw*0&`|f*=yS};gO#a^M+kV%&`#d3rBz8eGo8ZI{muxve#0QszQFl{L z8(5=oN8R~>bMWlS8)w~e%6+F#a(%H}`w0yDNqx_>2R*{u7iXUUq86vp*ehBIKiBcW z-76IIYfq#YeB|@;77v>L(nsAY{7?HAp-+FgLeTVjxM0{BQsJm2G{mP^_V*WJzhm+T z%1A)xdS}S>PzA-So}pyUZp&$*>3fGe9g*gd1}stk@5zW=FsBHVCp~Mh<5XXQcj3N| z#hDXVSdk9~U;cL-dl!h$AOB(rc}omf+do*M^-!QWfunV(jkgjzi+3uU$Kf9FCMlwdTqs{<&}O=FR8k`KevN{{?11^+iJn z0rc!ekDGbimE277szIJ~pk~4k)Ycw?8+)e3pTOXT*crk1oIYE=lQ0fhy zkMrj9M$OrvnkPArN@ACJJlKMr^?}$vm#iEr6;C+uBE?Q82N$E?koDfSmYx6*H zZ+EK{ospFqd6J6_Xfg#xkCzE$NB9%Q<#(AO_AEx&=4u;pSQq`!PJpRKp#hhOx7hE_ z&&g_yNUt#K?j&E52~l}}TGtB$pAw2)Lc*BRLz2ebyud+GD<0X=Zm8Gx5vXv9E@R)w z-2)VkA)JBv5~E1urlPe54}W5w$*UB0E2pgUne!o}Hsamh!B;t?kNR4_JW2$6Pd3`{ zEj7}_1oxQ-_|)dNVH=sSqaa8b$O13aV=D;~-z$r)gdk@uzZZEi)gGMRL{^S*F39YvG#rdA=Y>C@!q+v6;F+QX_rhL&!#knkUH7fMzrO)kzwhG&{Y zH;RTtmD^4}S*z!~QaxQW6QnWt@A>GdVt9Vij@X;%EzGnPG%6v;W){;9<_XylMED$@ zYEaXk%;oCWWmj5xlL;1557+k3P7+cY;KkjM^f)CL>%>*3R)rp-BY<^5#`_b-n|ez2 zQ)zw1k%|_&O!UU_hDI-}ma7D3l{)M+GJM&+rE=NvxVn8D;D!~M5(=@z^)2(K;6)~k zhdVVjj)BTZ>lx|MiwKu$6LrDPbRSE2z9HL2Qj9iZZ{pCUP(iH{2#9N=>ImM2#ZA*1 zIG1G-%L(d=!YHlyxi4a;^63(0WMKHDu;>Q^*y)IT>Mfbv{w0iOS7djPRE4;nlCCxA zg0*$3je-$98NI9jL2Wns4fMMD)7=wLU+WVgB-@>LFZ?t%V)G5iPjN~Ri9MTz*|;mD zIamvC4GeF`fM=PxB2rqX+SFqVFx)h@16WOc-&69+!o(d(vud!lLs_&}cl>c((wqA- zX;4}@)s|*V8-8_=?CU8yvLmT9R$ML(QD+jf2|7vRynRzH6Iw-4URa=HOReNd%jr z#5mz_cV4NwO>^0NILu712WFTb^@eN${i_^af{>8;MdjNwnyn1x+oq=jp~4*zLD4(1 zFC`!Q)*%{&h|c4uCZ((7NU2B0;OnWI_ve#|hsucY5QemE9);F5&Jj%2gV<+sxTIlx z`E5*4`KegCH40$vkgNS%%IMEmPmgnap-@jiI(m;}8GWYGUDIuv@cT!K+5_uvC?1h} zse8e}i{VE*~r*zg-h9mJ9~6_`)I9on!H^Up27<(cGWI8qT*TGu#k{vF~ZBj zd8uEpZL{47cRS`HY=C{I!1RM>;I|b2Z**_)of*IXq*2oU#9jUFVvCW#dR8~DjqqJV zydMf0m!ULq>Wuy~#lDb0?1&@D0-$?wB8q1|fpS-T6gk!s9kR0E>q+@ehqJ|#wYof0 z;2Fn3$>p}F1WFP(Ryy*jNsXo(gX~b4)Q`gm(jv*HA0>n63}kl6ZJ))2@P*mo5k9zS z?1TEi?S6J#Q7q2386DVQKnx9IloZV(LZ@Ys$dle!ULk-qe#O;UjMr(khV_16FwtRo}J zAA;N1f0czE$A|&F8*?5BscO8~&m)2WZ zXm>@HIxcuDSjJhe$_6bnoT?_M%Q7;;l;uRxyg{;W(J)9p;lX_^`9Ies?&Dj&XzLEj z#-cm(az^j@vCjNLRImoXUh`us=rn}ZKqk%ZXXm<6Mb8ajH)tyoCASnQSoun0Z}3R_ z&Ui()z9HB0`_jDe^=DrfKa24nV=#!S)NiS4NsX)kR-Z*DR+M?@zyG*+*7}*sFG|`~N`)D;hBB+GBvvQDI&wcp~Eg^0-`9 zN1X()%#n4bjDW@lCg=)C&ZgwW@CW3k)`8>@*-cjKc2?b{mdfrj=|j?1WeGW(OVYL_ zGRqyho%H{!}yf$}nV@)WOa6GxWz~Eiqz3FWpmS;a_^Iy83bARE!W!-Tg&|uB} zI8=OYL6IDlbvNKWM#N@%);N@8#ftqA8_`XJ0_YcF!9$<`Er|;g>2snlB~vY}+YZAk z%j0;$bssj~IZ)cGnvd<=Aeg-g?4hzSBnqEW44+zR&ijlfQaWyT|7l&!glhs zfE9)D`8;#Ezz)k}IUDzQ3;v31uVqP`Ut#dqQD>15BA#pfU;Fa|7Up}`f!A_3XS02? zdPpE#->EgtT6lo7*$UewF3v5p$}H6lAr{V~XBgJ%bmjUQ%h}zvmBq$%gOyyWy}UU% z==a~!*y7mO8MqZ2OU;5Z%PnDUZ5$lzReFWwbL)dm$X9DEhZxzL!sdCbY-ZygE`0<( zFFu6Wt=(#^CyVG|<3hhfauLlvwy3uxGfs>mjm@z4;Ji;chQ_9hj%3N-jmHrLQrPS@ z<`vrLY*+M>@xxt!eF%6;!POMivgu-s-V9*zzBI;4a1KL_;u_ylj@Pp~!zbeI9i_0d5{N{oWk zVvPV)uuU!?1SOy#xme{}`L}M)obNU01{`BRut|vZDMj)DYOo%>Y6wb9gM?z809Y^| zJivDqSjHhmssSsocf4vy4Uz#qJZl3qd%}|r$adzGr%+>Ye`;>C43Sq2(I!TMc@mN? zYzz$yZiB%L2a^CNN&YX>9#aRE1M(uCn}I(c=Fs(h6kZ z%#dPO%xd$bXW&VS2OS^F%9HLw?7CtFsgYSx!B}`R;m3^a?B^03Su;_UiL`6krZNu^ zMN!s}Ny3gFM^z>n&6#fkVMrX-p??PkBuaMl7FEzFFH=Q_B_BYKk(N=~Ce1x7Q4aG{ z=C(MG;^Glv@reGyMx;wUbsnN~-&)oA9??hjUTVUo9=YBx+RMU;o(V;s?xcpzA9{GF zFkH|q&I*(reF!-qNSJwqezchr&uIMpr9Ealm3e+O{D|$N1M-E(#mG1-ph_Jw>Vk=r z-}i%}_uM0te=7fp5*FLJK?ORyuqcljp1u7xMvUjSPt03%U>K%tx33o`aYq#fxN`)) zcy@Q9Fp28tAH2}=OS~oWr!g9dPH$D)*Hj$b!#{djn&2T|HDzku=T&FK!S$68a9*xZ zs2a70qmfYe8r>u{{s|aY)c@u2U7oq7eER1U%imreJ3aR&GtLf|YQtT#pFyvzW9p1T z+6n6}cpgw=tUj@WTPfL>*%m})iDov)OHh6_-(vLl|%*K{k zRXcneX#|#`E>!rWR9Lk}I&;o=V{k4Q+4E@Bp-Y-Fh=0lA2oE7@6^+DZp_aN8+;74m zHY!am3Jy%6=8_bE^QY)zn71Q8OYW+|mf&Xyhw1R@57>+3h*0GdR+>4>4b$kA)`WRj z4M*c6#3mdG>X(2k!9x00PKzbJo6w7{wCS-MqqT=2+BQ1<1?&uI>F9Zae<($!e!y{+ zCZ4q_Jke?rof~+5bS5LlQQKc>MTwOhn70t5TeSSQ-7JocU1pm4MR+feew7D*9=V*z z6IqM!`iJVNcDpQpvjo17>JsXDE}F>a6%h!nxZiK1r~S3u4ssumx9gM1q#}TjsD%Qhh(ajdk9R;)+LjEeIq?5Eo!+ZFjs z(`osabh!MYaYl zrRCC1t{K`&YN=lS4A403k=i~6Hs z4GeljwQHkZCo)tn44Of0vw*cry_L%j+9I=Y*0b#uIqc3+&vuvWS@LZ4O&=yG*FCU{ zeCEW5eU{w5pjGOSKlGze_Ygdc=ZpsIQrsmpiyjz8KJ!Qe`m_(h<;sVC^| z-x5B7QqGt#GKn=zDy7Vk1I8TZhi|##4GptW@xx_#2Ds~R#msOVRE-2lA$dz7cJF!+ zxJBW66X4kpmjIOO0^Es9p9hYGuzT;oL{J0(hxHL%2hsH}y9jb$?lmA&4nWiI} z(9O2vhucwo#tB*zR}gL;&_h@97duPFpe{v-bDUtgBhMgzAsh;6(vnC@Y)Pr*No7-` zjD{*f$*WWo#~RX9ZC7gT(i3y2`=b!oq)N3lG9yF9p=_;q>X6!~DM}wW(~3ONxE~N1 z(vlz=r6oJnCQ(xAz05eN)6ChGPmrH85?uZ?ceqr348+X;O;8LIGucYc>miWJFIb9{ zv_>#_UMlnW$HNR>FZLmWldFm;IxjT6nmsb_?2fGd0zR*bFSwo{xOG3|B;;Ya!lhTE zOn&}e3g=xp<$GS4=~v9<k^W%+uF;Le!8Ur zb}t%I-jSXf|0OP;a6@mfiBqh&!Z1C(lJC~3k90Y_VbtoWkEn8agYi|cyJ5vu`*?bW zoWz2~-^UcMW@>AC*Y)2JZCrPcDC=sy5!*JqSU8ov6U!`!?N`v21pBrT1t!$IUdb?& z_aqg+=Y@9&s_aA7fTBBs*Y)C)qaG$db`13UKUeCCTU}u6 z6G{AYVv{W%(Y(BMlIEZEnYAkdEj`pgnt$_GZL{7>S?|MLm7Ixs#usw-dl>84FR z?3QpYr6Jd{i)FHlC6-#OvP-N9rKFZX8f5b1bT2orU56m%3J3$*Ms zHR7m%WgsMqm;$;Ga*5rg%4_cZFVnW3%pR)qUzo2`J?_^%&Y!0_-q)Sad2eBSgjZhB zf`!a0P@xWmpq<2aMdz38JYI>dt{&Gcn);FM%HmegPF3q^syENEed*Z7!2=hEm0lrE z&V`Pfe!4{UvQF06^^y$k)J`4yX&09MMuH?I%bCxYx&a25^r74WD`dHoU!|h zM%di7iD$^MDPZb?CJpVEs)XeI{T4pr%*BlMRinF`Rc);Hi*e?vT77FOsuK7l%F4(@ z-}?LCxYahlS^E4f>*r(3IC_cl9pf8|mCZj^Rce#9FGL35Q#7#>8r8pCJ#upS%eO}U zd^ZAC&$ZjPoVIT1Ui``0o?QiFjyJeT%NyODp|P*9w5zD9p|jRe)nCxjRMb|~U)5O9 zQPb5_*I(%9vnb3{ zIC$#VwTho>M`^8p`o!sb!IQSdlXEpomqxJYZClr>2j{kF3d(iU;GO~I|LwL3T%o7Y zUzyiXM?32bAz60z%O}W{i_VdAY5hZufOw~OU9ekSsjY_Muqg&Q;9ow_0}%xa6uPSg zw$8#LxzOUJR2LTY)VXPDeq@bby6rf)Be}YBSRl4nuUu~!khcjs8u8 zqo&Fs?sgVrMng04>#*&wEnVo}`$@j6Tw97|jmXydUcJ=WDpfV9Yx{a@u6)gO_fEV+ z_tn?n!W0gol(;)KufkBd^+g>O9hLP}B^|u8;OEaZA2Z*`9KtPQBYkISM@2{L10RV2 zeftljzcg`dt4Zs9Q5lKZm>3x8=)ck-!njL6kUFo7>s9~AB_J-au3!%iUGW)3VI(NU5%th1)f7e-Q5X)bs7QGOT}Ep;nlDx4Tu zUtP_@wXRb86123VSS>5VHZ$-b>hV2D|`r zIdi#(^XbSTU7F3|F2&@MSJdQ2ixz#_3? zCMwQfYi_PB7J1^{(mdAOU7NM)9K3Rcv7^T$;&XefG1Jn1_NTL`90djB-2>V*!f{>D3w#1aXmlk8%tLhsB<&<2%AnVMD&6nPWy41T&w~W9hf1xOG3_D~(ljVy&TzS1tRzYI6^?Xf|6BeSdd)2x4lu z3zrHk0M!mNzP=2 z7sV?bwRC#JX+}JSM^Ow#gXgZ-6^w6|?^_Y{DW;>oCs_LwaDYDquriaU$rkWS@Zh4{aJ0S8OjFZXNBwx?_}&j?i-k;zcY zyH(#MM`gPtj%rgSk^_xFA|XtJ%JHL*1kdDON;Y*Y4T9}Tlqfa%6&ZnA7{Y( zi7wJl3&b7?O!jZabwnciIk=1XK_l2I?d`Ki{`U5Ayp5&ds|>2sLzgO-$@8y(gX>~K ztu!l}9@)4lHUA9}+RxS~o8yv0j+a`5xj+0YyI3&NE`bhkAtyH`+HOW7#=SWQX=~~! zY^y6AQ-OAD-Y?IqzaATK2#LpvD%oEB@@{_sIx~`^FiVxcL|>j974DCC@xoIFuivAi zI>(98HIL&c!y_a5tHwb+Dm~=auejw;M{PKg8a@_w(69G5)W4zyenfUQycXPkh=}pS znrM7TkMx_u=cuS|X((zc3K$^wnA*-F)c-^^8(pPTkVUuMRaK1mK2)>LJ7|^5=v!a} z7Nz7Uc(~smvK4p!`jeQa&9Tr`oIM_MkrE@{gcF?So3DIA7z9w^?;F`CpvIq>WICcP z2%$a~d6r5418D&#HeDm7=n%JPSL2JoWI#CiXm=B_gnH7BBv2()$r7S)K8whBmK|c9 zGPvPZ;m)&S9Aj)}bHz?nJpGFeZ^)*)Zp9X>ScyE>U<11gAu+>dN-E?$O^^$sbw;j! z&f1i!LOpj4XfLO5$Cy@ffRa_RIKdhRnq??6+i=3oHM%-Q+B6FG(t2{JK;Iol$s5g>st%ona{ya7GieL7j&=iW%w{CpJoStpo5+ zOH8y6Wchgt_vQm&fP1wL>SOf7781j#@X$q%H1uB2A?Afs?V&pRLV2iMzy`0>&A_Pk z&<-dQ^XJbX4Lv}k-bG6R4`L?aR=4Ow?{fkWo@3nYw_xlGaOOnbGUg1-HJD)Iy4^4t zW~_joeXPy?8oQ@XS=%qso_>rkJzEAF{#|QxC$#;c#qW`CK2qSYc7ia@hTRD2Z| z?|H0;Q$BL=IT<&EpGNpbsE4es0~NpBToeG|M0K!C86Q%|bi)bc1I#hKEmOLMkh=)m z@oEOTQ>v{gxV{E~c4wn3?*3%-g|e?RIGfmMRWGvQm=`zK((!qjUM@QP>4Yqo-};0+>njs7i7nUUPmJu# zDz52Jt4x(X8Y|A6I~9DN@FyT*qd+MzqA@bVB3V*Hn5YGR_7?UtPH6c;rBZTP8s$;R z=lT=44AX3er~ZF8p?S;heW^H{2j1bbEeoxDGi}h zvN+-rnPdJBrq!wGQO@C1j0(=c16-o%mCu)kcld&QuaIJ`%B@9ke8c$7i|0_8NitQt zg81bd&da@BU;Q{C1|sOu>?8X0QzCkk9EvitWT{*Lfs4n3)vA9II6~{lVqorK{HNQV@LhVRm5D_BWy4Pr^cjVmH&$JD558XR}?u+eQKTQY5L6>a}5zDxpaMwlMwhy{( z?1wa|eH3|(O#ZdK!R6}O(E{SoN5)}uzD=zJWbV(>g+w!dhIOz#GbCDMN5E62)mpZA zw6w04exdB(jNFSnW&u5J@ODM`;q*8$+|bn8rPw#+DzK9Fgf=XG7}k-wL;8@JCjBt= zx&HYFk7ca+p#M5*uIQ-h*>l#C?RVi)jjG7fOZ7lDHBFe+I8^h9Pf#m8kY_% z#+$xO1-q9nnuABmDBi&zG*ppvnYm@;PMaKX>U&OsPc4t!3=5x3tn7J43Wro$eTfCq zQ~=`!{HqslN~V9BW|4nQ-F?VoOeD`$tH`Pjjv86M7Xw`jW8q5g=BR5+SWZG-7=GTH z4xKf4$+v2+k<ZTq<-6T-^7i%)UMf#DBmLiqyQ|o^wk~bdacsv_W|tXaW@ct)W;~^Ut-v;}-E)dypo)L^gm@yhq~hH^4I<%lo7YP;m2mFvJ55 zXK?eW)eA|@@EVDYW;&$Yoct0Uzk5d!W3UiMVMR7beb1U*W$?EmExYsIa2BYs@|U1J zvD#(a_xkd4r2pY$UvAt&Q3hYC5v7G?U#VwrDF!M29o~Qk66zC)LEGC+0y&lA|41BI~k!au)Vd?~AE@LV#@cR7-!5uJ5D&*;-59x(8Ye0Bphkxh#ixvOu73zj^ z{F4{MY=YpCV#)+`uB?%}1SI$OV>A3a$6x7wsW0zTV++;GL(|pGDfzmGn2xvy$BWNj zGGji!YnW=G<%o5nV%-TO9xV!!?OTw)y3;4o-Iz&n_p3f%`dfSEL5#N4wn0#~$j=8b zw#csstXR+8Z;e^cJ?7M6mAlupV42*1vts3$4{&I)vxc8I4Q_{swyuB3u|it_;a;kN z!LfHb7bw=ET>`Jx@@lP-uS#z?rm)(c++VZn!Z=%VXi8sSvr4WzwfW|<(ND9|ZSCq0 z>zx(lo&e+xEo6eGG{sh#0m~3hu*H=ga3ARjY7u&Fg+#+Ts1(SRxUsp?N1x+?2 zwHz!C*dpAw;D9Jq3W#&8q9Gcc^q<_SYq4RtV%N%jB?rwOL`z`=%6LxuHYMRBJ#%n# z9`b9I=8!zn7wkRwHC%kD9G+PAv#_W;ymDD2{x+fFO~((B^zCzVtbldNT$ub`x6q9~ z#j_*vk9Pq(WI@4BWYa7N_BrbT>WV%gTq0c~Ao3OSFCK8mPx+Qj-#ed0ay)bmB_hp6 zF8ZyOdHafOgkd+mBR)FDeO!1$J)l}v=GkKmEY%$FE>^>==9k&Mj@F|ym&4AQTH{FG zTJ7uyLH2GAYrJQ0q6AKiGtMF> zMg^I*aal3pcm95NgVtI(gzZf@v_b^$p>epz1w0}zW|jrKqQdUOeCB}K<3h25LG)uN zk(FLC4+Fw>Y~V2v^myL-$+2LuVfVXOfiC?_HO4W9h&v0*%&C0b23_nz@Y0-l zr+`94AugsGPcJSW7L-UqN)wHThFSLtYBKJ4FfmF+)ggT(e0dX8K|!BIAE(3O z-js{p4BUvf4|NT$Oz1vbQ+eFYcD%}wFJ`f3-Qu&bQBe--#Lwk`Xd+}62-6t&{M}vi zEC+-m3_6yp{t>~@?Mq8z zG0T_{^We9|@Lg(RIi-Wu|&!@Lk4dYnL-+K{;-zI1(B_7n_`V-n4oInnX! z>hiB~vP$)~be^Bad4akQG#k+d5X%-u5$q=AwVQLoGCNj!A2XKFvO8icLpkZOY4sQh z@iaoHy2V6R-AWzVsgCkP4fYMWQWOJeKwW*{qNeJ#yUO(! zm1_}|YvVt!B!3o3Y)X!BWjoIxz|C*K)yi^L-twnU4n~*_I#h+eQ@r~2czgml=j*#i;-0L4pu zEH}^Pbg4!+uL^|HQmivVNEY5UeMlJ}kpwt(1v8MyNqBwVwz&sENvJgQ>k7odao-EO zz_^h__YUr+;ScZRFJ)FRx<|@=znxowofqMOysXC@<7?kRw&NBbxhSYee+vyMrTx+; zOMp*;{kd=QXc`?MMp!_K11yx(R2C4bDj6MI~l(GL8 z>i3^7|BFMKD8eYeIG|F;8L**Dl<55Vex%pb0e@$=E|CVpy@GtS9meNU#)}(9O2~y;BHQ0zJ>=n8|y z4K*&2-sVTzRI0xAvz8|{6qCD3+satsurx8QNwd+PAefm3;l5y)(eA;#2o;_w5b3xH zy+@1$J)AX&r7?tsvBGo&vwLCMQIEK0e9qm&t-yd*o8{V+Gv*71gmr*E6}QN}hRd@n z5l2C4Lp=F7z?QpGatjd`mWkEa_s_5^TPi_eR|(cAom|;`rz>t1jR+_6S|)gw^O=`= zJ}JVU-X!t90{~a^8?Kft&(+)sJ)xf3DF!rUIR{4g36v&OkzTO>F<{1C!&jyyE9z2B2c#Oe6_mx8}^X zwY9V9I=u|Hw79md1?JAW8C8|j)GwXm0c+=>k@C2jrc_8KmXTIehZ3>0@w`Tv;H4&T ze%u^P%wex2kz3{fX~_I86rB= z_iQS-1g^d!eT*^`C5A}Kbqdcb#>5BP^31^@Ln4%2I}DUp2ki7t$_7(%4H=>592XaB zhfI9EpU#&A%{j><%28_Ihv8umN)=ra{;4BDZeOdPu-IRkq$86`$h`1ifd7)BD)iKue>P;8iZeMcq>%0Ac05?9p8X*h|DI%LE$hwsfL_I@0phDK)!*PnZo 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

    G4l-ukcu#n&r$5db#uR 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�aW)d-Y^qWi;{5E;4bLNxIi+wy zraMQoFjO_Ha3B*J%jP1;Nj0vPrnT9Yi!GxiQ|7*GWHv?#FQo4p(U}qJq=M#_`y;}H z+mWO{j!Rsm!6p^L&!};mu}x|S9azLI?Rp9b&a$_)q!=#2FogzIs-8%xG)P+SiDAcr zR1stWGbq~kJ=jI|RdjT<-zvyslPKreSvMhR;mlnu%VIIf_9O*ZswC&v3CJ=PI#)`O zm94JR`%RfF+T#|qLov>l#a`8TsZ$t_F!GY=^q301Mvo=%L_%*0-^Y>L zvaDfUmW8Ix&2vxtm;U%0)rY1MeRF840~@}z^pQj7u=yqpqYED~ykU5AtC!*kS?&R{ zOGeqlQ8u&y?B-o3#vz-h#-G2gwMPvsx=5;3nS0GT^b%$|_oxk7a(Cea?f|*mH!+X6 znR~E~MKcz8fF1ni@#TOj__@DCxtG^Ky z`D(ni1WPil(Inh*&G$Z9wfKlE4NvBG%l>$!l%@>0v(*R>#jG!^_(bm9=6=E>fF70% zz^ObWnpHdLlzg83^!6319X(^dv%MWeKkFmpaQ{sfE3G51?v8}rWXJgR2G@8h*j@c^ zTE7IoQ0K|7mPq&O!ks}@Tb}lXNHuzAZ?|BCAf)uLQfU6XEvo)u(~NAvQ;B)@VAa7a zmrX^vCRCrFL$BAu!R@=)X)}hbu~&w{ruOJLH`zo*VHWzpJt5W;UEdSA1jeba{(R-aa(wE zS-!zI7Br<*%d2cwG29JTReA_S9On)Qc|vGuQIAN_h`@|QH!XB2#wP9Wq204ymPg>S z%wTL26zE>@m%L5|kpz!E53qJe595%}>_drH)qhF#_4yj%;F+^8Ei~w0M#9qX<`d}8 z^E6~`!vFi-%_l<(D#CTvH0E^jN*AYPmlG;_Hx+c`q5Nysi)PPTXJHJOCo8&k?VIjW zQ6@MD>xj;DBXI=kZp8@nU4$ zdV2*6-DvlFA9pXLAG4`c0geQA*XwS#MHulh(OhA^e9Uc=C(cOa$04}krf3f#;;QdQ z9c0!;ab@gw%=*Z4Zq4t8KmI#*9@%$&DFtXoE%)=dJ~L)w8X%cFh>j4qJN>{of1ck{ zxqibTLeE0nRf^CEWI($R2;1jhBhH7ae#pD~CLCz34y*pB-oZnksKzlp543vn%!!dF z(TO{fuMlynN(o?uPzJ=G)QasY(k!hLP$Z@)htdTGwPq2wGT&x4N!G4Ie)g3Z=yU&Q z{xqz;pIjAfrQg;Ov%Wy3UzNv``Ej*E&Q~h9%p!)%FA?mC&vyOea2G%VVw*^eRH6c< zQsvTcvt-=aQIeR&=PkvCQe4fp6P&qblI*~0U7G@5V53@D4UdT5CZTrPBlH3-@;=pG z?1cha*r4lto8*nXChw3r34?c?7ZLMriQBV^Oj^Bnw(l}91;=urpo;>KYep=Z67iAv zW$KBFl8jAik656X3KYLWI_Q`3bFVR>W(;rwiL6Bu?NAZGC6ah7?M5aW(30{;XA^Sk@V=i zy}LKK(HC`a-xdhpDLsrPME%UX0s5p^G0rVb>PS1*?SSk(A-e``wg>uTU|Fg|Qhe2z zRM$XwH6dg`T48KVL6|aqaBNtF_CTN^Y+kO_XAb^|WSz8rV01+9tu8|7!6ZRqfRT)z z6XW0v-)eMf5M3>*VHqE86&@|>8g1xDTda5VW>I3)E8CmL$(M?{>0~pDvgEWzI-pkC z4!~34UDweZbx06*Iv=$zyZM8Abwz*i#$6d3j+xWSZ*^`=YI(uB9X8*H`j< z<0lc}RHhqj0=z@BfVLn5JBrjbIoR8x0OrT*FaJQjfVLQe3#!yEs-QL^Z`o8C+0+}u zf&=dl9wQ%cUoF4!a}Bx)DKLI&|8iiT2qNu_ZbXbab9jIgt*BWOB29rU*{qL|YpTdU z#L?iL1pdjY0ugan!JC0dxm?HxI|jcGO;vtwpSYVQxxCwS<2p;2pU(-c=DbODN}H>h zXb2AC@o@2GwVX(+%#S@Z2Q$`xQzwX6*W1l3eA4QM&_;0C)=y>io5N~=hK;rG^kTT$ znwCv%kYkrEfn8(Ou-zKuI`C547SA!{-0G}B*O=zxdvV#>{6l620-UA zk(Bz!sGXlEyDsaL%P2YO8<*#a)Tf#8PjVM=#-BGGbyB1rRbNJlBq;J~_I6L@|3Afp z56cFAG`KHcUjJ9c1OET}SYFK3Ov%*jzg<%Eh4MikeEr~SaOVmtO8pXWM@sOW#N`L$ zXxzYlyaSfV5r2FjexWDecdkaQ;bmzkDJiB{qQ*~jdJSZZLA_do{@^a7*9n~m&Ws6D z67s9}x6fV4gNa*k=VixbVpdvK%GsOwIOi9sKk{gQpo0&R&<7cy_mfgUyElj6s0=*n z=nUQFTI!xsav=rmlv9L#(~to1_E`MXJs20$nay#X{C#2Q{!-nNrSS8&oVOKpLvpYe=W32k{N7nuN(dH6sP`; zY-e!KGBb{KFcmgmNzFua8?yV&6T`FUBesWHh?#0K>yUA@h8iB4pa3tQSV$om3pP0! zN+#Tu06;P59N$ZGwC&O&|hIMT}plKIM^{+6%zwu zOthEZd}lpgp|&%(6dVuVvOmiDXXi-*l+KOUr!xl+uv{r)j3In99Nx9Vcq}xq6ec!# zVZnbAxUkWM4_r;& zVjaG~(R~|2w&u*2;He=;XAb5))6$VH43Av>{gRJ)89~Gg#^*UUqs`{~KeU`>Y$d(6 zrn|$O4(u>9Cmm*HX4*-InUfu+4l^?|b(oo%nVFfP!buGsV+l%2=5|Ym+q{hb<_H(={Vt|jg4}vCj=9iGWn1UeI4HrHHC--8G z$>R)W$CX&_$you*GJ7-$i=9^)WPCh3HEuROcmL^>GZzZ{a9fpAVp7zzL;_=mN>^z; z_2Tgi($~{GwYcbIph;?8{TNP~#a1Rt02CqtYu~X9T>CM|9eOy1vm<;qUtevO*(=M6 z#AKMMdWo3*Xl|lE65!4dW01bLeNT>E?yAq+L}w zV4TA^m~`1B)jq?ZG(07^6`D4N&CiVKnP-8 z-7gj1HJX)`TFa!!uDkMXP(w=dszs~3_3!!Jy^sS?p)sf=1V>y%+_HtfVL8vO2>z>{ zuS&Iqqfx%|IbboNV9d}b8NAW-S!-fCOy2I{()H`>T~Y2KMGU`)f|r+h9Sg&!j*nCc z&y6npQS|4cp1R_Bh&>+9(!gw%j;o(VYV{f6cyN%(0?I}uhVP6`aaUk-lZxy1{46Kl z`J6Z6^xlN*l;aySWhwxoAnh?&QpX6c>SB z9p%qK%Q$Xg`gI;R(ar3+P2RhLQwt51(l%$7hvLhd9J{qM7i!ioJljH{MjWXj^>sve zw|F-rxkq;=-l~bj%yeqkH6^&xa!rD;pf?q?%<4l3j3ff+vz$K^QM$L}&p{Y%GXeNKvYB->)on+RfUtRQlfN?baI7ay19nYKTdpX=r}u^TDAw55xZD`5FkI7o*z+EO?_t;3s9SL>y^}JkNQiisK$vhY7 z<6E))ApJaM?A;LY*=TtvC$rcqpRUdazTQ#!WJ>Aa7^*s(nf;GA!^sO%s}4Qvl$!{K zK6J>o z(U1Eg(RDB>Ts>@xn=2G}5jG-*8HyZDutO^@?D$?wu(o^(ZgeeTTVP*1+_ROv6F{d+ zplsH+7#@tBS8zHK4Dtas^F*R?qrXN%wvw@81NjiGP>9g0_N->^kgg-XKD+0QuiARk zkQ+ap8FtuDJ}+xMr`3h3zg{ni_OJTWtTidj%uHnQd5vQa#b!MiR@0;-E8YM#E@9@| zsO?Kz806%wl~;OUB&Stn34Bv+fAiWT*1tx>;$@g^8;z+<@OR>nuWiSf(^mz$zm@#s&aSnk7VMnq3C*;-g%5)7Wh zd{&x@nR1IZIxv?F+|LRn(#ja)hu?*(&*cG%WxjT=&@Iq|=F;R!WnDLKCw>@}fgou^)C^3kB48le_FK zSv@$j_?2hs8Y%|#8^qf5jOaHh&_6m>D94n?;iPCDQj+j7W_F;@*Ly7NSivD&%k-h4 zgPaWkn5WSWD8y@r!eHkpg&ezqQu^Tj149bw5LXiRXL0gj@w%3s$h7dh>F5&aeugB^g1}#Rl{5e zGPU$#YcfajsF_puKa==N$zcrLzzM<^vDV21?H9&r4CpMFlePwg;HY;05sp;-;P#(I zRMDl)3+u^%k&br6NP76P0T>p2U6YJh1b(rp880QurZW$i$H3VXMj`)@wNu7jlS=Jf zkf3QuD(2@$Egm45(LYlGM5h$<+mWd3Cen+H#rG~?(ljI#cX9ud##zxn!v(C#sBDKf z8zrR8VIFD?`qkYDmi2D^rO70^{8%}7I*9MA>da9)`6mh|nn8am!R_6Fe&}zl2_anwJ0ls1ueH$Nf_N#jG!XL3sWh{^=8dlQGw zQg~p}cuFaMU|+~88q_o-tnF|$`tStH6|p*m!`;q_Livx%nfEp93a8N^#F^G*tjSgm z(%hBC5=|bkD)o<8kC`JTl=mrGm`S6tMK%~&rdrS-Bv6>LDh;rr9R;Tq_1Rk-sX}}X zrOzshSTT!?d#&aP`gK?I=-W5JkrwuPLDWYF3iaYvOez@^HmJ`)Ad(k*;IpQtmh@3s z2!gC z`d$G#^S<_!xR{?2YFLzyS$_I`yQdNCHPfmF9Sa`pV8^=_Y>4|sG@M0!_di;YfO+mS zzjB51Rof~Yq^v2wWmOH^sd*%6H;l4~DBmmN5DD z<8u#Trk?eVyvCs0go0r2{M19a^5T#S=cNww4rVS|gKH{PiPf}Qi(o6wS4*I1oBza8 zRBm8gIyTh)EYlM#?KhVAoxP{Prvw=Rhs(xX#p6wO#B49WWx~XV|A_84Sa)tl6#>(K=?1s zInFvu^1G2XOM&B39;OYsD{QR$fbnR&Rq%k(3Yr^VR!b%8^g*U8U}3@ACUf^(3N~;bg@A7>>QL#`f{J5J_M~t zTnL8{Wj0msV-w*T#fJ(z6fzF6Awr?;<<1MonFHR_&lsAC#H%kaDu?nUPw|=RC_>DT z*nNu5cU{Pwhr4h7^3ENsTjUfcj1a4GSp*ci&k~T`_TK|w8j9fA*2VZB!}T|AfRKpO z4XCz;8F21%a?t*HAxFj3L81CKPI^Aq@d=i6I40nUfHO$@d{4oDa+4*+MHdxuGctT^m^Rsxx#56kYoI7KCVU6*VOM8K^B4!&q_ zV2HNLSv@F0O_L0uVBWD;*g+DorwX7c+Ee+_f?MY1lj~?OV)q;x&Z4SGmt-d1PPFvx zFpl3)F{`rgRJoCIt=9xxl@fXkLEA}{Q^a!8rf?}y`)783A8MJiHff_re5AKcFr1lm zWj#)rS_e6zwu0I&U70hxf8vn&WEuX77ho#c@>mo|s#)gzb`QfK$aFbEt|$3*RAwLj zP_1aqhjXSU2NV7td|lF_8RS$nH8*r3>##hBt-Q-yR*%<99a5?CYvML_>f#m*FqM*y zNi1oTc(f+**R2)~Q?k>HXvDnY*E}pgze*5%(N%qhsB2|Ru3H)0c;VH3`o98*XD|Rm zd|L_|#gfvmRLpYw+67Mw5$I~AY7WhG?QazRrZ43d<)Lnhwydj;ktIyq6e0qA5&DXY zSsKQWS-LN!RYd5e9*R8&m&z3b!_oz%0Zjo*osy7}p{%e*k@wHLr}~e`%82pc3YgQ-)vCjKflt$gwjGq4ARy2^ zq;!cZOtg(p#Yi=ZSw6eM4|QC)W{+-7a&_m*k;VmKV;@yA&c`{B z?(LMZ`*tJle;q@nbc&;@6GSMO8)_yoGqm!s*qvkv+P1($e~%3%(4oj~>L8+8vlkVq z|JIlrZnm=(AFlXIFxw%hp2F&uQtCdR5Nq+x%12K{$D%OfO(wuW>D5bFh{&#sNf<-* zi!R;sMCz7Q9<_4#UMBp#*Kie~Sg%~I+RwN%_yPFVZdK3w3&K*n_5^=7@5c|^f|4H( z`~!Fx5UlZoU;#o91mD1Bewp%rhavz(K)b*3=@aw|6TtUB+?#%4wh}v5MO)tJX=HMs zN7SK3bIpXrH0mA1X<4GEiW2K=!q~XQ(BXlv>V$Olhg|OUKR54nuG`@T+UwG_RAK0F zfG=+jJl2#h&-?St`k$NhJ~r*VVzqQpRON_ueqwBV1Lv3-$TC)9obtyt?nP|c*`seE z#?bMHHSI-g-VxWdC#7#u!q_ke=NKBuvfdd=Z*joj9tPUW!!ykK%hc_}({rXk za`g5TrM9R>cvxU;P-Ez{`HeF<*n+26?A6hMOmSPnD5i{dIw%;1^S8*rQ>^wVfD0Lh zy>e{!^RgSDh~o@{-bq&bdfCkBo-E6~cPQJYuyGdq7YYXbouky2R;a3;0Z7CRUNnyF z9zc2v3Al#!o-~3^Ss2e`PmrumnjbBP0|2A;mwqpO!w!a)eGY5Gd+6C$A2kDvz**xLjKH}fL;@@8QYl>p2JEhNLuVnoD znsG$VfIx@U1mLH}pbnao?!@Cy4)tES41-5-do#cW^-a6cRamRW&R@0Op~;&a@R~9> zcG!0mL|;~ayGs8`FkjxI(bUVI(*wMiy*brGdQAI_YWs{Cx0{Qvdh-w6D81W%{F@;@ zqg&rS7oXou-}^1SsiBJ%3v_*~)xwkH^K&|foKc}{Xf~{SZY;CENV!wP zOvHX-GrN{^?!}+->JFx(hlXhbznw6W|vYgYfo-9AB+Rns~o1WSkC}C z%OjZis$Nq2zt~kb@QL;2M>zfoW%jqi`Z`M-u5lB6u!#R!9#9?~zsZt5rG+uF?VW2j z2;^V2-{4Be3YZ@#Kmof&EkBFddI{qwo>}_db%Q>WC%V}dndT%bR1;QgiKGIJaaJb; z*<)hq+3q;Ov2lsl%@1y&>bwIla^tcPj8kA%j z!y=dhNGD=xctx2-`1xND$-B2mi3HSkyCq)K}^q7lPUGNh274`pUi%0oGV zMc1$lbO#%hVeRAf+jIJl`kw7yb;N(P$Jvd(>){3v42^S)C6WF5K2t&O1NEC1jJ*yL z??5T{;OCApZK*MC1G*dT9R!F>LD=jL9YnsK$K#IU5pR~;+yfndOyqa*+u*<*OUR{< z>JBWDn6Z!3uYH7Jgosgu!X2`1)b=J;gE*uEDglx|q2v3@fn2J{mOt1X`vmE=AhA29 zG{i5VrylGBZ_Wg-Z)OR|2GlPwQ>31|!hU+<{C-xWB{i8|P#m$-29T@Jw4<0c(mPh8 z8a3Hoh`1vh_5!QOY6n2KSTE=dh_0mfZwd*7yIOZ>7eoU6@^|nZl0HExke^U5_)oC{ zJK&Dr_(^>Gh7TB@6WwxqP7&n z4$s4DES{XX1-ll_D9CPrJQD-v^EUv_Bw|Fs%@M-Uo)y<{qVjBJG}kbqN`?zW*O18P zpQyxkY}dXY&O}qCxCpD5o3Tc@2(g%J9H6=Vc995bfTk(tQ=;ZW2{LC?mG>+N0@D+I z%fB}l0DZrVNuK?FV#xhNS6V?>1LmEZ8)j1$xepB{wn5g9GMeuDK-*ppLWG&>H$Taz0uST05D6hfO_XNB#gyy;vB>MBH=S!RX2 zEGawTNe}kPEy>M+^!aV7FT1%S&Qcp-Y9L+zvjok-$!}Ph@k-Fio{}5ZHLtY=H!IR} zhPoxC2YSYW(@%c5{{(^8e`=uMgpN1(_2!>dE+uR~wayf~zY$H3>16#)Im_i1-eWck z#v20V@I5Q!c=n|w7Gn=pJ5U5nPgLe+wE>;6sATuv97a!Y{DxUOni1t$4fMS$j$wdf zR_xhSJ4|DC(2b1`f1BaP83bFEZ?*@0s`YH(!M-Is-5WDkg@YU~yiG?%?q2+E~Rl7BEQg6|YNWw_ygP&fIZTRAYlo(RzZHQ(?5^FRjywc+qcl>iZLL z>A0Tp6Opmg2Llt>&B9DE4%*`xiA1MUj6*O#J!wLfsv=<0At=KU+*?OWC`VC!jxtFN zOi!kn_U~Lt(%T8knD}eO-8XM}_s}avc6cw`%`#pYJw=xp%%rRb@i$2Q7PNqa)W#d5t*wo{6I^Cr8fVp1wps{ZKnn9oQX`3PPRRan6OZcmS zzR-7-=5)Jh{#2le{6TMB3&C0jvMbVHJxR7!chb7aDs8hVlgpZe$*^5&ryRR}bF$@< zU}?gIQN`wO?NL)yMbM>?pPfOawLb2?W)1!61H~9Su2Xpm@ zP_ofB*-a(g@+U%u^>%OZik`m8W%~;2n=Sk1XIsy<3Cks6z1Guo>U393mgQIY%jMgu z_1j;tucX8EFN5#UhE90w?8`!$egXBl1zh8<19dOaNEI`)X#lRaIztI$^}UlpX?$-; zf??t4-HM5y;YmD0HE_e6O+9fV7~DEw3T8=2jKGT#lMy7Bp;_0Qx;w`;@c5XuCebo0V$tI(gVD4r!^JVm-c<+rlniV_WoPO_5^(w%-VXkLTsRf z;VNGtJy2n--cw4V$q!`kH|`4Tx}QB>s3IJ}06Es+LWnt@PjsjzWb~iSYsGZWG$z)% zDadWLfGmYiytuB?IJn2Get4Ak34+>CAzt|jo!V%96zqw$4Er|^|Y`{>7o+THISLWAlA%2ixr9?t~c{w0_Vyr(iiFpLr^)-5_pg?gY}a{nXc1;d@B_n01R# z9&;{A(DxD$iW%tVF(|BO`jDnGkfS8!7UKbKEB@CYaMtSC0o2-~ai{6QV<&gLV{@Y0 zL9aU;Q*!Rk)^%f!{Wv~ zzRQq2PFX|E8zi@1W(}oa#P0{~#!b72T@l#6YQdY3bW5k+Tfa);mov(D0d{3F?uOK! zs$iIMr{ltvGf{>5{OCmk94x6_^x_8go7FUWQM4ya8=gb>2nZzE9QiZ_O`FEt@-{^s z*HgOvw!wV9_hML|gkQ1Z9ogEsUjcgYdxl`v@qvA%V%Ar?!M+8j)Y-jQTzC=~3fwV2 zMf7|f0CaZYTe27r0wb38lRB{VCV(&SEsMh)WBBDUpHe{U%Gbpptt@B#<(j6>qh15hSR<&?_XQE39AI(j#`FQ`@0~# zG%f;kuNH3xRW}%KBQeWBCFZ<_dGC_Cfd`KYuNBGwolo6$J)}}x&gXz_57`Xfr7}4u zbNsrm+9_T0MLD2T4&7Ikl+P$h$yxGznMvnUPF>3anM>!g1P15%qOGKs_vheB57Uie3|2uxtBIj9D{DL zjK=BQV;d-ep>nQ>tqs)7z*i^}b28_mJNE|vPw|jTdHD4Ir#zj_nYBF>F?{68cx(&$ zN|06jg_!`A6)~KCd~=;4?|iJ?dUeZXK%6bwZDZ9=89G&tXDB*RZeuVxjn_z_IG+RQ z-kmCEGo0E)M}SUQb?1PD=an&!OT!-LM*nfKrqxGO+$colZ!SZZmS3_I9D-Ipq@W|( zT;y)py%%Y$e!F1UcZ`vva($d`z}<@_)lqXVNf%V|-TJO_7e?|u&yKneWyQX0Z@|0l z%FuEzk`Hpn*m6IC52M!qi5!Wqo2=A3OnU@h6xRdB-Ctgq1Os|Q1<$mcY1cz(?`ph3-N9z}%MQf8 z;EX$Vd-X5CXTwkSuH^0jyWQ)(_GizQ@ax`~+rPK<@8IunUq8CX1^ROCI-h}`KR>g4 z^YuT=^6#b-o8Fy@Xtzrq_VuV>-(^hbzNDoN^=Jt`qnHD(HI8oVl9WHQ>Qa5HGlzW@ z8IA>LIBs$h*Po}yJU%1tn7-89{lAJY4!UWp?*$T(pT8f%f0o>le#zvl45Hhluaw6< z?v8rN9f0E_p!kkygmi9GyyyDBk#2$Q>Gpp?0$ECxU|rssw$QJjGWy90VSQgBz6Umk z<`B^L$Lv;q??4oY&Ve}>tU(nBYZiI?0{@rw$6F!?7)tu>n|s2)v;Ktr?^}QV(}Vv% z5+bU~qRPS&LSiaEnK}RIb9S@E6T=8R(hOT+$)k7!bJ-3eC%`zuTGPWtZ1 ze~wJe$w~^xSS#9)1F_ge1W&>tQM0br7@FLs-@}>Cj^uKzop!ib&_YBSXiMMB4l#x{ zpTZl6u8bMn)X{^0+;Qi6BN_6&%c&vG1enH&k7yLr>B+GD@s@S%b>97Pj7<2QGhB~) zWx!spnP$|zsy#Vt!AyD-l_Oz(YEin@5a7=17Ep0rLRx@|NI^mw zUVk|zhoq{1fX6Bm;$O}H#wE7F9YTr^Au6E@LqRMAB|wY;hsbcQ1Xe_4l#0it^0I1Z z%ilkWKM+XBC}PTCh^fSLG-?rZj8?cUQ+a{qvQ9kJaw#ULbh@+(7EQ!Qjz19ykzi@N zdTQ#E?%Mt^BwbvRVQy#zd|TDpv-PPRlS^BdFx0KAqYV|u{ib*%W;kq$^+^EC%Juj~ zGl*?hxTrHedqFm+%IGN39QDUa)08=3>K?M0LWf8TTo;#Q*5F}}8WM!3&iWw8!g2yl6 z3{8y_(y+wW3bTkW@(e51f&JlxzBamTnRFhf!|Ah?7=%UmS&G`DH9omC zW_ta_h|0Iz$j8c8B@ zsFvZh+(v&KckJK&@--<^{ZZOx#J>0n&{1y_unehW zeMdtfv^>gBgW}lv%RvG76prD)Yxt($S=ySoLPcA%>)q6Ycjk$y+Ss>d@Yiy2akr(1Z2FZ&gTrshty_*tMu*>L5m^Yh5mCKv!&k&VF#iR<%`8vl}6|;O~;X$Ql^!V#9|3fZZOwbf)S0TE49sCiWivnQq&lvbO$} zcm#!40c#uoyXwZi0MMConP*ttwEC31pR3&T{Jnv=W~q~ZFeC^)*ta6SNlClx5kK|K zXH!LSp+PEn6x$Vj!}!G0E$yLmk?c{F5ui!<0r`Uy1&|Z=ty5$#D)c$Iz!jaQvutA4 z4Xw%AQ`U<^*eeYx%#`PnSGXQiGWhxQjZ~Akt{-#t_MUItOp-1FwB#3w%&G%LW`<;5XxXl$yHb~V9NzZ-Jk7D4xI%;>D^_^nwTUti zrJrx9a2O}_3#oQ-qKx9`_b?u+ch#_0V(H*7P67iN&O6u@OW0`+DVTk%E-LbeeHqcm z$U^+s`0V?M(18>tw`>B+6#KKM7xK(bdZ!9yr22y%#|k;^%DFQR@rxkDaxz8K17K3X0K-BLZp!yc>NCHX)EJ**BbEUTKH-y zlbGco);ZK9%hPw2*KTpxH8MmP{}0@D^fSC5Snd8(3j?_G5+&%#W6fZbc7edDo5-9k zD1a1bHdh$l&wOV(wcXF07v~wm$#qxs!&iv&?CS?xFwk)BSZ+&%ZoVV!nKR>=)}Jr! zZw=S%JuUqKuoIldqTm3&TDeSqX{$*;?ia)_Xmir2jU3b5CN#k z=@)-d5Nq;yh{&=q z7@1hM>K?(;R4@GGV)rWR2uf$MGjmD@kQg|_@{US~c=JK-Ko3$?VpJKIkxic_|73W! zXyo)=n6f$zOrE;8zh9Vv3YCLA6>uT zm!~wy+uKpI%;fIN&(c@f!XAIbI-ju^Buy{U(H_uv$?&-i>`2tUD7&*vWpAEPREX)Y zvXE#WSfVuLDKwi*yBzLqin#i`DCGdDeasIwBiGGY?_~}tp9PP1Wp6I8KgEiJ_(Rp@K}1o`WSonraUAhbom&#frekaR)X^*aQLw`AEQ$e3X~T->_l z9#cUrd(rYR&WeMNoCErwt~L?P{Mgw_w-qyDor6xI`9Kp_{Sl_9_FyCpkhGTJ$gvHFTQ^)*W`JJgyLfp8BZB zS^n%ns{0H$nWEbAZ0SMh`w2BNVdjQ*H4b{jyJ#gh4V0HZpWnmawZ83OW zk^cqpI4yP{)ISg>!2Wj-xA?z@xR{8doPnE+iMxu0hspmq(*IB0|Ao?>nlBo-%Ye`9 z#z?YY@&T88PM7%s`5;XQtQ)W*3QY=T$r-r)P&yD6Utmq4-z-uFBwAv3$_FCU_C&ok%LZjYb)b^HC5&$hSS^Rn;P6Z>z54dt2$ zq2(wq6EET@^jz{h{%b zJ3$zCJfH>p?5IJEK7Jl9O|n68jP{24frn}tF+l^!gpM{o%&Ic(6p;Zv?#5ICh(KtU znpXANDJ$DGx1_<&h?IAJXkfXC!@v2ntn^VUPw8l8mO|RvJ{;!NQokAJwV)*F8d5NJ zHH8GFH$`QPip~{06!!>0M$ZBqi3RVvUC?Cx`6GsT0SPB4zX(tPORurVe_^n4e!(ds z$Lc`gV{fQ`Aj>++bpL=9w7y(&To+WaIK2bMCdbqQE!Bk_j{JuG<6A$aDzCo+v)kK6 zP~MDsw-HcE4$WuJM>Ys72ifO4fyOQ-5s_em^d9U2%uIg1_&2rRp>S%ywZC(#Ex;*K z3O0vxe?Nod{F6_>|C6W6kdZ*YlyDToEk7~m=%|G~D}kCBM9-0zrsYTe^Bd-CkU~x# zh_h9h-Ahmm{Hox$X1&%L1{=0*6yx;0|HS*1VuH%mV1AsmJ5>b9WdRF9bqIS&edeH- z$56Hf`8buOY2Z0I-(*BvT2^zNI5BEW)IE7Q**^#VPB|WBjPCiN05vwkI^<@}74jaCtuKDHQbP(O%MYSkH! zGxcT8pf*<@CG-94Gzx!nDI|L|$IghY}>1;>#jQr?gP>NljpZ_6q?{8l)}gT<=1Xzz(Gf0E@XW$y1O z@Jo3oZ}gqn)G_{sp9AT)Tk_Vf8yTqi+8PID?r)XlZOFQ_$5xuiLhIyY23ac`QkuJd~Bld*`7LAv0zxvf6ySG;+k|Qvt%b&qNCBtTARe(!TFDAh? zA_5Uyv4;7@$@mPTJkBW2yXl-EUv;Ol^xGGi6Kjsk@MKZ(W%nvtO0;j8fJRt`U=9w4 z>xIRm0>BM^_v)w=n>x`X>TSM1?!zkRn)&ptNct=c$4BM3x z8~-~6(ne1KDgkKyCN?nVZiR`=V8yE66cz};ZIW8Ksy7G;48dJeca_?huW5Rh47er~ zb*S8#H6H8q7a2`7gUmA?Yxh4gmevviG9LnkB$yWk3mI@iUC7+Qhqq#@9_LtOZNFEd zx4FQHKqKWQ%osf6!S|mGk$EtMkhX;Fi=yf5#dI}ZGVx07y3UsdXN>+)2m#vd4zxXR zd%z>~L{L(}1}OLaq81?!SAbIV=^GaRmcAj1S?SP!{V1I=cinz zC@M6wX2Iz%#}bf<8CBzT`naGet{!&;d@-dGLwlI)hQVly>XMzghp#CoC5r>ctyhCv zguP_(Zkr~_=cx1XtTED092f|?5DO03CuD9~s#~i@B_GFTBGSF%vN1=VQ)-|YRZR2} z#|Wt5%L>V<7L~2?>ooHrF5{t|dp-mH5o3vPXvwtl0*tZ-5*A0~9X)$=v+o#PJ@y-N z`x@8`d0`aWWd4*V?#P%7#8^lkTZ2LCZd@lmgnqei^j;~u>EE*0Tf!APUQNb%!jgUa zmT|hn*OHf(cdRTrqX?TiL>Strv~4)$#x_;UsBt_`)8aK-J~>Tbp8=JxY^@(OPx~C4 zf#U;CK}&kYY#RDAw+obi14o91$8*hJ$+rM4xIThf2GuSueEkWb0~gRr$f`W zoIZXL{!5o2b3b`L|D#KIF#eq`G5>$9Oa516$-h1xpo^h@axYu6iwJ}HEA@tgjoR+f zz)|5A5L+7(rL49H^6nWo)g!EuPE1k!2HR?O+oRtRG6*X|`GXomGpUel@vYz7fU(7mgMDs7k^#9pxEzx^qwr%!5Ny<0|L7e&_@&tL)MCl~i&Y^H8) z!j74#_MPExDL4u-I)72j#;C&%gVWgdUqY~CA>WVq$D4niMI2$VMa((Gu_9!^g$Q|8 zWEMb;)X-U5yqY(&Q*f|A0?V4i z*$QeU1)qG+mAfMpyx7{m&LYk`CdUX>18h*L zhW5m6vc-Hh?k^qxFh!vZgge2dk$ za7NW_t$nH^a5l)44+jc9Y#pQFEM=pq8+?k^;nGAx@N>KnjBF-4Z@qyXGy**0RdwA=ougj9;yo!|F>G2K6Ogfs-AM=fp1*=*UzwTehQAqh zyvB9v&J<<;Ja&;RN`{ZY)TDJ+u?!CjbZgRcl_jTi@qJs_{wyyfrvbQ-J z`cIgCn09+Mkaj4GTq-nMD6`6v-63Zo*}<2_W~H6R_*8B=7Za067c44hhQpZA-c;=Q zZv*qg`8>{HB?*S>of!uA!W@(&&bG$@S}z(8Z|EX<&ZM8tTehKghvzynAL`#Dtr-TC zKan}y1#)zfl2=d%-v zThsswlQd%#G#SUEhm%J(&K)b=aUcO;RY}FZ4UO!4_fJfoxoSX^6pU4Hj_0{0`vyC- zWQ2B=%eJh~HCjz<#xBz%=9{nGn=If^DU2gamIv;Y;04XwWnrDs%a_2_KoHlY1{}%@ z3L9{lwae;_*7-Qrd87`~eYno)J=6KvuXqPzH}OMr^iyk^8Ei=| zKt`6FZ_r(lseKD&hzrH^>Fe3D5N&&B^DJg+S!dkxR&jgqG@lP$yeR3V9ynB$V+I;p z!>M=uki)xM=8dEOC(Cu)Oc!$1a-z)f6$}ta9;`GZ}yfHVt ziZZNTNR5mpu|tza6Na}S$9~ucXA0~+KINJ4E8BxtGHra8xM!SftM8As;Nv= zax;6laB@F5I7gYH!KGFTmsPH-DzB#;^vR#FJe|exG$`;d8dt=TLR>?A`&Nbd?`SOh ze^2B89{<;Wf&ksUa2IcLv}ogF9c@OC-swPnf|wUbdP zCkf^Gw>DS3?Yda*k0vuX+Fu`cKLo!2rXk)20~0RbnE|%RxrBiCD!aNWSj1c~Uc%X2 zKR!V5)>SvmQ@5`NY;B#0C0wKg#49KOdjj>@b`FssOz1@pPaZ=KbGsWx*8p(P3QoYKno7Yzf{>s%7R}3~5w#PE@-8_H5Z_DLE(j<^t1Gc(q zICdy~l-L`e?hF4LE$g~yvEUyHJxb^s^gXgXa4Z=G7r_z@{RkW_`uGV&U%!`t8~F9 z(AHPe!BE%lqs>pXnGu(EuE)s({evN5t##YJkw*`A9q%IRYS}w;a@nT3aRaBoeTGlL zy#^M{w}B0V!~O{Pp##3E%A|<(EUdF`>3F2-SZ`;0`}owc+QI&+tOkbzV=5vluSUUA zGI(-Z57Vz^udaVxxwj<0dfdF#ZT<4VK6|Q~Q_A=SLosiZ!68YqtrBh)WE#k+%Ib&f zTGlfHi_;I)(TuW~-*~M~1u@(lO>P?^J$3reFM!tQSD|{>bc&y@TsU}c@*0_qUHfX7 zTLw2)*Lg-;d*Q9`B~F!;I{Y)9uC;=v@Hb@JccSr4zgP%hO%M9%^${``B!sgHlBVaZ zV?t814%ncklP6!s`c2WNeaIUWvRfrXq$%?dJ?2KE+%I@^#XF;1;47PjGi`*VO&Z<9 zrq@L-iYo2&Wqn-(hwGQ=?cf>0nw#^h#rH1i+_*CAW~?T~YwRSj<10Jl?p?iXD$au& z#Bhk4iVAYw5tpi5e`RLqzFO$6cr7;9@7!2qCT<6tjx+X)$EvGfv1;mx95~DBvpc8i z5wNdB6dP1AZofE!i#gK>xU2AT~^9HOtJGXpQQBBW51^HQ1=J{ zD0zW>5LOq={ORctV(Q9CQCa_pFZe~UE_YJUcnz z1>!gUKm(KWcjH-XsNN3JEF7q->Hyi7^EV&PXQizl`PF z2&GDLXhES*A{P_SK+!3dMnK$|mMorzOpG4W8qP#3VsGqR3H65TOq=A7Y#}Knm~;}w zL@AOZ2o5wr@;JzW!_?Ya;m z)Wu7y0=iTH!%UdOD+)crnduDNtNp;(#*zGawm*UlN|rK@mnt+j>&WcbL;2}gmdY~= z;?&nRV#X)K3TABQ@4v;`AZiNfuG*x^?B$nMxJ?Ve<0dV|xlpUvZU%I_hym=TPb49s zOe8EK7pv=##FO|w3nMfmQ(#ZCqx=0i+W5!{Zg=2g5 zZ-)lv?QK;3S>?DtmyzzBbN=9Ys6?7L5m$0#ZoXIYaSKjI2IvDE`Z%ShlnT-?OWDrv zHb>={buOK~O_#;e>SAPhsqMk`Lkiv|T|kTrSn1kZTcrGC@S6MZq0G;mMaL|NNohH8 zA3jJn!Jm?uI$FoBtDjJ^tNeAwqz!7r;MO;{Xc}Qu94R?_B>{wv50|s`d%XIAVZPFK9j;u>3x{w5k2F@HIJ}yK_J~K`f6_gN=5z{H-!Tp1o z*fl(ER#D(=G{=_Gw)0^0>CM3B)e`)_ukVfhpy>^lq#hqQIeEhiuIluZzL z#b5bP+!wO(V~>|9G`j~auB=?zvcy*H)@~&|CqNWc6f!8R@OLzT!XWiyHkDTe`xnrZ zOduS`PFkNr3ipY-5?X@AdpjdCd8LzBuEID>Gh9pCUa8+(z_GVMewSd}9l%IKxu9lK z)eH;@Ja$2m*RjDG{B*M_cY(kbEYUPDs1i*|}#nt8;47-CEe(k@nD;Ta~okqsiVeB2VPQ8Mhes zDZ#35-U^baIf{aoII)x2e;6Xu1g-}3wS3>6+U1IzMWP^s+PN)}rCgaJYY4ev%p2?k zf!I~XX;Mcmi-O)rX^4_IIR!z{?k&O#Sypi9#^)jx8REcVgdJ7rPr zlMRo)HUB^j5W>7UNJ~wLs|;ZRyg?M!FoxHYsfw3{s6!2twkT4?IJG8;X-#ioP`I;F zB|61vlVpwXJ9p2iX-UU65`$Vsd9pC>XHAHwKmf!^i=FQ>eE>2CY+Tmo!s(zhsCxDsX;QKU>^7w#5j}v?FC0=geN}8NN9cia$w)CZoef|DOrMPDVZtpUTfPzI!V_= z_BNAHxUNB)Q!tc6{ll~zQ+`L2V<83dpXnIasr`N4R$bbG&gf5I(%b^kWpQ2m9hw2j zMS_Hl)YC;-jJ>u-(IL2N+r1g^yKK~8{FhTS<|v;-=eTyByGP~-URx9=mW%GOIy(`* zeTI{8u9(iLs2dZcsJ16c@vQ#plX*1e=k2FI@r(4Od@fH8IF>e87tT%BkAq7I-DZmu zd9tG;LZOS>j2KpCOj%q|wDS#)mrDg2-EC*$x|OfS>XvH0nEHuq5E#-|{3bmbmjJmj zk4KZD2N$5@HuA~!3C(px=J5BbG~JGFq+b=xi^M$A2&E)e6ZL_n>yDwPo~(~(INcf$;k zSt#hBd7!myB#Pj3({3sC@ZwI*#mhUNGZSvD@X@rEABBJDa;KJsDpGX`+9{g8dSABy z<^I#Fm%qc}3griNG=pwpcs5mRWF_1wruZj{K@3xZ9!o*>*2PXn4Ck&qMi(-%;*R!E z?d~)bM)Cc2Nzo||(2@}Zg^`!Tk?<=`hy^J#FYDa}RN6FrFZI5H#9xQ}D_W;~lJPSV=`rc%4KXdU8Y8dSf5&@BVn(~j&_i6?-U{}O9BQ-18W8_| zp+N_zxCgB4sTO_QYObZ>~CQB!sauzs6M~9g11Z* zyMw3W$ZVazaK18ras~`zb%xyH+Hs3rVH@{I-23=CTLtnXt*-A_KGNv#k4gdG>nW)P?{3{jN8K ze7+>kiepH3(!Mk+bWmQe$=-~rLzZ_)TaAZ%#82B|$cBBGXE|wMjK_B$LTDx7ubO4Q zo1u~(Uj0&6FDcW1b;RK{K(QiWlpOkF7-I}jk7v#^u+L*n026}(!5CwFTLGwGl|jr< zvWxQ@BWC7iKciwJaJ*6G+HrW|PRDt?BV%(a@=KBV^+j{V9^v5mlTNj9-pvZ`-5zc6 z`6*)s(gXI9i($iaO7meOa%%H2k-C*c8A-hBLk&a%#FeV_Qu|bny5Lf1PgJN>XO7O> zMff#EemNTeFHLxnXH{hVF#6?OqyD>c>B0K^&6P`(I~Q7mXJvkMQJ7zPUTD$qbn2Ud z0BD1#3Lof$s0l%6gD8s~C|39s>*rH&oiWf10YDz~HbR)o5@-e=pos934eA>B7Ea^^ z=n*c+184>pYzOEOLBt5?9fG)xPy{Hr&QI|2@B#c|k3_(*i;&^y!Te*-S-`Mf7x{*U zr)545q>6mdfdcbxA>L3z^hKQI%VVra)T|D297{0?_>Zs+K`75uFuN91wH7$O7HsAn z+wCs)t|%>_o}fm9>tToe)>{4O$w)q6QSC4$Cx1wpbfj9F>yoI8F_>`;U{{EYMYhMjsr|4%z zQau)S5YHTL1y-Z-!tEHnfGmc#1fT@BAqAT;Q}F~j^(60-a@qSWtVJ`0xSPc?$Ma^6QK0v|0 zIOP`HNl%=*Rah{pvGv3tX?0>7y(4KPxDzg5<%L|&?-{#5xOtIPTw1VT$IauZuSpXA zv>qM?y*%jMf(+n-`h6KF=^<%;WM~fjC(_I>-pmim;$Scm&jb)bGkPWClO-<|CL!jn zApZUUWUCo(unPM7EP;TuXcYPkTI5~SxhVDTRc-P23n0BbqV5JrgJsgMi1-}xB2mDj zuXB;6q?ot7c!B3FBKTPh|7`}r8M(+iEpfMqR4s+1_Ybk6R`nuzoTAnzsan+eOu!=s z@fR)keDB{+Ns9AG20z9Uoau{r=f(>V6~!fzcJq?V`_RmPfI8L(J@ylLDu$5}rGcRy zLZKS97)i%I&V@^bkxD^I3o0Tk%td_bC1QYrja z^Q7{WMd<)B*{b+lJnFyS#CFMh8yF3}Xp=v!S~5dcDg?lm8;?ODnZZXgkA^;8Dx6Uu zNkdXp3}}jumq{X($3?d8h(wzul3yWJM^RxXt|lwWIFw?Q5X&eh0cV$DeUd6go=*pu zkr%z2Nm2X(sEV)4=ZwWHqu&hsnv>I0IQS$Z{=VBY7w8%ZYkj*#AlyC}H0H^RKwR@p z8wfk|O~clWyr7x`?N@Ma7D;jBkVD}ZP%}oILK6UX0Zc1VWr0S8xEPo3208B~DbY(Q z(Yp4h2jSWVK`z5=;qWh)dlU7lY786BTtH;YC&OMw?mO>8iqw|WTDLLwcB_5VsC+~g zc>~LLejpC?W5wATbOQVn{W3%2uzuwuomBeLs0pMGS@sL-Riz%F$bU~+eHWDBt^XNz zVi9{cv|A0pX3+d_Q2RJh`BpI?3#EZ*O90ZPdO-+24G6qp>4rZNi$ zvh1N;AZlYot?;oaM8Q-?$dFj?jZ8)km5tBgjL*G{y(o=_s^-{qoHmnZlrs+m(%H zH~?#7lSa;IFVM%LLELgogmEwr(4uM6T@Vx@%tyiFY>;9LdTCZPSm?)kqF9)WKgW${ zh_Gn;7g6N~%a~By%b94^)2jAn%cH(27?}kW2bpMb0=7<>jS9dd_>+DkCtbj&kFDDE zi9!2#Qv?qk8i-Qxw+;V{Kv{g0%ORss#Adm}VNn)I$r*#%I|Gia7d(Qa6&>^-cg|R5b1lckxx15~7-}^X>iKQ3tP#lLCu`sfj zHNdy3!WJio@}gPfhCs`>6;Y{7^kr8f?uOt#c*$Vgj79-J@0aSd3)S1E>QpOf&4h|z zDFne%bAvR-2;mY>Zh|#VPb&$Xh&X_>YY z_3RX8T~5jHH(Wr2c-h+;sXmZpU%Uy^3EvWJTaiNHxgk-{awPvE zPZ?|3T!+y-a5!do3_v`D?6Mew<+2!pXr?oU{FqMdcXRF8_T}C*>j4R!(zJo|5@I)_ zfZLC|9jzcP4Z3CSpCiDc_mnScO0qo4WhvioRC>yRCVNwK#b*2}|0Q^?5*`KDahhai zhbeOxU_X0=N$N3vd@lgEg2{@enAO&FNF-2qNhHvONVx1atRpY%Kq3$s2TY~eJG?_( zMM)zrAl$zHZU-UE7pq7X_}Wdd-$eS;6D3y$nwr+Z!jdr-6&}y zgL%=#Qh4IqObqk_7M$VG+h4@KZiCmJ&uBs@q*@SvL?iTT4+MX;n~iv!Zg;*4_~+^Q zg%d8+WYmD6$qj%VP0*P^uT7}OGD(lA*W3fj2iS}|P?(juq|>Og;2Qt@CsDUvdt?#D z1Olou{V#6%si+G7ubO`U-SPj_^!so@9mW5ydg78609A()14hAt`V|uW8H?J95Q`jJ zN8Xvhj9lb4Q`$@y@A`aZcKMhtKx8-XF`v?9C9V3NhkxF*+q6KIJ=4VcRUM$fn%%Oa zkKbU6FFNKqrPcbewQ=*&xbsEu{dtqS4LTdMLt|w!>sE-Rd)Q%~#_Y#|IeDjITjJZ3 zMvtRy5H4TbE?|5d)jSTx=%lLabEoD_RZbssf8_dyn;?ppf!2}Lmba4LrankxVtBt; zMmaFmcviUGKCNpzC;_l4ke{xTpu5SZRU8JZ(>~?Mc$Th!z|YT*^INVIwe(;i`)bP% z&es-p^W0;8XKs7#s%d-cj}_zKOz2Zitb!ynzkavEh5l9CtiNGD)sYGsQt0lgj^08_ zI^)q8-Hw?BNe+(82)0gWjLO=)%yP0unIqw~@#@hff~X6h8;h5tjn$tK(*Z7c-N_iQUYo9uhk7fN-i+qYfJ zAz^fXVKA^e>R&^sb9CY1kru*bK~}2yFa_dBS2Q}isErEfyiSaR&-K0$r8L9X_6jzv z;OS7JD=?}V>6lG=aD5>L#&4u(u9U%*$NUv0xGhN=%X&FXTUiIohxdGpFG`LI zN>gI_@!Nd$SyMByzq82i;4C?5#oW9Sj>>ukR7E(Cta+uYElsf2$gbdkc`ptgGSAf6 z@3;rY(7DhLOcGkAtjq~;Q#YDHte;CC+7m6*D)?tprJ?>x#+M7D=Z^`G2Dw-)D zGyNIaL3IF}1?t8J7KM+?SxMEO_pjqe#e-7{$g#Mk)0mXh4BncNSDjWL=XY+^1C23& zPb{*~(o$2h2J6Q^Ea!?N5AF7i7_h!m_4;AIdYA!KCN`;-lWTbj%c;k!E*|R)LXPa`3jS*EF!)o&*aVPMhFhZzEZ)Y zbgLfvS|TLVcXC0)HpO-TVxZ)hkpFQ25Fh5O&&(^tjAoJcL*CK2MH%G(QJ$T}8uPHP zRPl3nRW(PaG50JxdLlEZ*X5&%Aa1@Py zWUjIa+rnaso2h?#hE14vildeclpH-T+qmvhc*m`a6Jl@oo(?#?<&szgn`~q%`e&#>#I*s1U+HX0q7SC~Lgq*KJMJ0M zH^U!nI#js!pqHJYZI3#`M8tNx`=4Zl&#Q;T(xKfPYc%77k@6DcUPG2i_4wPpvq3+= zKNhfGU=WH}bI|c*EW2o}Unc5L&hoO=DcPZ>%WlJk9NTG@=TBaP8l=qO2c4i8T%s#dj zy;lBq$M);=+u$U^Es=$UKkbt9mZYI}xg?4Jl+w zk7kDu&U3h2KF|a&>?`cp-h&oBq9C; zlrI3(5Vrk0R%q;tp{L(b9x0o{34PD(Yx4A?{8VuFhpd6PY}1w9Yk?i-ZT0ELVL?=Z zn;6ak1ttsI^8zcW_1-)21j;SWm3Q{0Kj_CT1;L2p~n2bprT#2WYU5C$S}h1%#67B6T&G} zlnD^U2J~)NV}^#q5ONMnI5_7B?XQ**uJ^+RMvSioD)IovQBnB(=J&RyrWxhrAo%%a z6v7;Iq`%ClHn44O5Sv+T&nL9|m*-rwOBVvSN;o)13PHn88I7r&HES%NTg$mHT3CO=CM3bGDV8 z=PN;8wY~R6hWV)S;(+pH^~;ej&ji(;H0{hcO%fwn>_O9zZL~}~IX0@ucvX)JZr$_< zk6kF#+*o!&va^}FJ)L@0qFMbkQtb+DOrVtQruKU!{j3Xe_!&vfi85nc`Nf=3lNiQI z)!q<~4z6-c(wPVK#LRdo+}t8ArWNzL?$I_Z(r0#LwoB=^UR6>Yai~z>F*WE|dU&>Q zeE?x?i0#w-kplWvTkedqnTtIl+R19(7Cc#rK~kdrJWlYDKXYJ3r;RHovE(Xmt4@Y$&%dbiNhTu;%Fy0>(q z_viSin{Q^G2E(vHQ7}oR(kUBeU1D2wwElnh*H=&QT53->1NXJ)GOpN_D+Ia_>OT)K zQ-4Tq_vO2)cj*gwEMs@SS0SD~*OJu}UVoG?aaF2pJK z0d3D)vlP|$%Oei;!lVwR^a-R zhhn@n38edR3K_BUMD!XWFEY8`l4_hBOH~Z%5?5I@nl_ijs=+Edma+#BRS6?B^%$HJ zPqfOCN>PUkJezXyljRo6yzVndk18FUZ=Zt3qR8GE{$Zuo5VrT2b=?912W&X4sjmTH z=auxt2{FTE^yy?FCeWtUk6y{2F{0uiOH#-`nOQu45*3p-@!Eo-ARVe^A1d%c3kB6b ztwwKHPqS+&-2WI$r$=#|^HQT-^(I)MDe4zP;pyX?^yoXt9C^mxC!snL_-5BhP@iE-#027xJ%n_qC?T?csqNlJ#)<`~5 zVsr#MH$)sTjk*>j`Fqb=b8X?)ec{t3rZ=Lp_juU0I<@pR6c(aGF%h<#OXk~>wE|q- zm0vi^PeL(Q6(f7dj!Rs{Fk!HidaJjD{}dOmaM2H9MlA_pc=fzJFP0;Ig08(tY0y34+JNEl$Komio_s(Q|iJdo+qJqzQdh6zw z$Bv)J`^L`B7myLBfO=hc|7^92bJj(TIptG=NJHQBVVz4uGNZPafgHkd+qNZc@p@in z=H_w7HdE^Qh1<>gI1-(X1+gp#ip}yC)6h zT{m};2UD|{%4`M_ZDAMc7=O^cU7WK@{hum+s&6iuGE~bdJ12e_S-yOKdV^)ROxi z2d?`!dr9A(UV{zhd_!{oN|6RFoKKnDkU1@UhnMZtYG1%470xc0L+XzNy+xxK7;JwXgc&{O!S!6iV zR=CSHI8&J_O~~b@@^X_$b6VI71oBb1-wBuJA=QP9OsM!6D^kq4M1sROFn_cXfyf@N z*iST9m6!dC%_rV0JU4qM7+zfCjij=-zuC|vJInsoXCWp~mhDBquVXX*8-(MyX9(U< zsy(wvLXdxBEcQxE!fyoOeS4M8W0=s-#k=F0A``qAXQ$&DcN5Lw1E=1aTGkrVN)nc5 z?3%X-u=E$U+aBej0S*HX)l!}+8>jMyZMWhnIknI~5@bJ$k(xWMppAzd)7j7JA@&W4 zIWoD`NAYgcL<_K=(mYU`S7Ap`@mg6o!wwmf~K!~Vw8*z>CDmsMGNQYU8DDo~-v zw+;F>2C+(DBZ7LyT&7ywhDL45SQs2YYe|)$XCpMlPT6{=cMaY6dgQ=T$o~aFt^*|o zDrkC%R&ZyvOBt;XKz;fSa$NkTr-3^eGArfej?yaeXT3A!xT6iSOK;RlwEDp77uyi$ zOMFexdlW{i6D`_Qq<|lG$^gqEmbIx4(Jb%vW)^MA*$U~e&elC zs>1$29h?7DEX#g`3Hd`*f@IKNNs#9wRn=$m1is1Sx{CR2Tqc^e80~O{W*|GIAf>^Z zLXxm^XEwx0=?qZ5?%p6uD1GyN6^a#jtosZfQ2n}5`5E*mEqiMCZ?NNxxstH{#q2J$ z|F^+z|6efJ|2OCQ|5LJ4hez+MCVm0j1kJulQx28fq_!|v0#PQpWp6NFJYHhUfu`1_ zeAnY}H!!CxNjue4#yX)GdtkUrc#yaA;x4;j20N{E9?j(E({=OWC%E(b#na*8sUVYA64Nq2owY|1mu zgOaqp3IE7qf*`|5L>PTg1M!FV@_q<~B%ACcV4c)LKs3dc^aqRDO+?d^#5xv-Sd@mN z>wlB$J*F)D^)+n7j9EM9gEV{d4ect^GRQY2(8PHn7ZS%kFZtdQS= zDTea!!t}j_w>IgtWfi0FmFkX!&z3H|zasP279Z&F{2rVOUN@#sUY=5;vd|4pr_p|m z3}NaDK7DLHwH{=<#E1J8BkvSip~0dWEUr~x#5~x-GRGx$qDCjqJ~(}+Rpgde+FIyB zv^+sV!qyC-S00&}PA@l=+$8%EwbuTEo0bwaO38+DBl zdNA`!e%ut>fh2j2Mm^pNQ&uh}!d8Ln#jD_cd)~Uv0*>)jDzyV5Hg{<7gQgc8EURiX zv+J}SSefj^^{{kkzF+KENkgG}yS2~bl`OJiN5?RGX2$c#xAgdoVGG?54;!_WS(@sx z8W@sUnY>eHYAH2Ggj9y5nJ*!I#N4I!R^?IIn0P>mr9*~{*RQ$`NW?_FRmBhC##4D( zzyUEjZe7AZwGKh1I*q)c-wa;iNd0b|6n?1u(O_P-=8Q6{nHE|jyI-3sZo)=pkZ$?F zgnoie4#?U8#;JZxYIg3mi@&D;;JThTOn~scDUI z$E~ciseM_5>~^MFZYxc zlO_IQpds$Sbxq99_aEU=x+Pdk&$z;EXeiugBEtI+x>V*J-jXbk7a!h|t|#4@sdH=j zz)0X}rj9}vK*bf}Emok*Y<1nX2uHkFVpad32f-aIU&EsP8ZSKzOQl^U@Blc0wrfJq zYBBn2cPAhjnMV^`z* zp~t&}@(Au~hX58ZunyzO{*7Sxz+G2w*oOcXbU|6?@1uU}Q5N`4gVJ7%@}zEBq(p73 zN9jjE5wM_?AWYu?W(0sEAd%vRwu>?q0txE+5x*J13oOOd0+CslzN{BhOxBx`wMGN1 z`5B`FzVT;-CWI|*Oak+j;tlQ<1a;LP!6O=d&RcF>10OpTgMwvKG+>4Ml6qP2x?HjS zGQal)PXptkcfVZG?dW_*_%C>~2kwIL@MC!DGSm$qcOb3cJnj-$XFS7OQnw_XqC|Ke zV?N@i3Gv}nZ3xEx@e{to!x{~?%$Fxp_lP%$C8aMtpAv~ka9S-EVRK^Bda=siHMP7; zF1^&e^_c&>d+Lo~)_U>HUxq#KoCXEe9~}#^=acxRWVL}zne|NM`T$%D6w|%K;ofme z`$;1Nh@bsox0Be}b&}aCy~7_q)6MF8@q`zg<Pl|X<0(2F%})4yEo{WqW2kx$h>{(|=-=6`YCu4(LQYGvkNDQE8f_wC~U z%j5qExi4H$SJ1!p$-KzDh}EExfb+e$#8T|c`ijwb5k{aSiN@{C524%T8AA!)}Z}rlBt|nnJ@IJ&}cOhQc>UVR!VIP=dlC5dbGa*4(dZRR{R79C#IdI!S3vBo|=PjFk~muGT{{&apk>85GCjlv3$l8+6> zIM-CcjLVspw{c0IfBCxr4l39))0Cao~oBsRO`} zF@_3hA}9-Vk(kl9pdz*P#KB%zHj_Bya;nuW+WD)eQ_S1w^=VJoH;|h2;0D9|2716k zTC%m_NuMi~>eI7aPT+$yJt8_6o@hADF>a!sS|$sPWH?o;=_1h-W|%((S~%EaqSYc@ zw&g0@|I#>g&B`OmUm7p#_)Fs~<<|b=)zFwy%Z@jpMO@L0##;Tzp$B%;24zm2+i4dM zdcA#788t4W(q=>Ro~G7v4B7564Ux!v3Tb(}Sw(3PthC+S8o$v_C@g;`d4@h@!zjxd zn3-eQPbbgHdv$~rwb+}aoyNQKyc#T1R%Sm|B)le?|C-1;Hz^jOYs?r#O-j^9Jz+^^ zl_@!1w!J?w#4YhO6D8u7$&)h?>4y%@+0bG$ciCcz3ay(|z9UnCs{pfFc5ZBDQJ?Cr zKIsPTR)4)s5rgI}-bd=el7L8pX;4ePMuJ3FePtP>h?@DpT(4+Xg$Sw1inPuu87QCT z*(3wwN9lZ!0B42!SU=7*oNqUKK(M^WkT=Z8syxGF(OIJXMLamZL!(8>3z1tY&dgo8 zU-^nNNboN_S7uh!dagj^8BCw)ch~pAkpAj`ffrR<6vsvsh166sTkS~E9>$YN2JaC< zDSvnPkvdz74H6Y|@8p=hb@h>2QtA9Mv~`W6eX~R*eJ+7r5;WnBv?-he1FIgo^@$R) zaKswQD`@`@#tX-&Pps5UXnWTm-#axOPsw_FG?`4t={rCaz=Gf5)y-3NMf@c66WySy+t=2-7^#>#j4 zwxp-0=99$bzxTkwf3t3OCa#}(ZFEo}6h~s-{og`dfwHV!?*Lky%&EZw^o=P^!m|F( z{|IrZslxP7!AA+B$ghw1t~lYfLE z?d#IHiH3)sf$|*=gQ^MJ#`1ZGdbR4{W=T%*I$beX$+=y|VT_HKpQoyCSZ&o?2?tN7 zyG8ZI)4+dxxB%k1hRW^&KNHNsY4%Reism<0pq{I()GRes3hNX!546vey}qr@A?KYiyGILN zWkKTf{gX?>K9~gjp0O{^`Uk(ugu`I}IA5v6I555j$wZ${zI*1QTCtCmI!eu3#=U$! z;yOT%Uj7g0xT9^!8^R)RzsJo825*FT$Y8S-|I2>h0)&0Iy$VC;2*HjT?`3{zgAZ%9 z1HVoO6C#0IO1K)S4H1XHQR!oUC=v06UVFLh?Hqy2Nx;Vn(braeTU>JSf<=1O1(u=yy&33{+XD%I^X#LNd1IWM3u8LMgIJW_Ls@D~*Nflqq z@j%w*FV|Q~1{M5GTCWe27Ss@Qa(KfEgKse+0NfxJ0OA%Ms&u;3L=DK@J24PJOwdY* zx{^Jm&$=HLq>Bz;$h^DK8DV^10ZC+!D+ap1$ccWXCz8Z6zKP)wGFUqq)OCJtNu8`j z3mp+G0eOY@UqOHW&y)0>zz<~Zf2sW)?Y}r2|L?bg|DC1aFR!cO{^fPPJX#f8~lp6cA3m@@>kE3&o~^ zhz69eX-BcPG)p~UIJ~L(x+<{#C}qt+-}lx??K|*gTip5u`X8^&o=HmNL$p2i!9TCf zVcdo`J@!JPHbLz597U6o3M*{QU$^1$ICHz92F18FVjwzh^m02DL zt#Wl<{WO6;G7g43ckCEA#kV;IxWD~ zZIQ`Kk%N7pTG)*8D)$+ND%_e@F$KikJ_pddJQX#1B3GI4SO>HFm9%buW9x}4wmI-xMSuBP5E z6lL+s(3Ku$h~pt&i(i@If;zN#h~;h2oTyWB#8Y2UG6f-(jOnI}bQ*Hu|I%?jxOJ2N zq~pIpTS{)OmPd{(N_O2Vs!cSDY)XZm+l##%2771ZUij%+!s;S# zN9T=oiao=MEjQFQW86bihP{uCvwfqP0Fi8p*g`WyS#UC+ zAD;9Um8lFK<)?k!|HL*AK6zXtq1pe$Haf|dIvmpDk71VS^xQ2+|HL+ar{--v#9=_K zOt`RNSc`3gA-MECbW+s9mrX9$mRgNOTGuN-gCMb%j}RRuamKk?Ke2}5tqT1K-B~t! z-L<^6 zq=1iA@%brTp8&y5GDLaOV9onTMNddS@# zC+&fwGr};?(B}|qU&lKEI<*e~DIy^T_L#_AdImP~kKoT67rscODnL&n% z4AQc;@CP{e6=-=svR?y#Uc+?%>I?hzs0qC1Mjo>%^iOO9?}o#^Bb&eEN}r0VuSF_3 zM3~K{U##Dxg}qe?(!WqaT!>ytYZ!$UAGBXHe*cvJf@@(#vds`*SZ>(WE(`2nL20i? zb2C>hQlc@ojTgu~bikn*Q5L1Q;b$?MrI12JS+9--hK9N?H*o$Z!0lh9upOaqI`*z2 zd3!pX!hmi&R9vKLyHeDviHAUyJ_XsK+W|H-!qEM_TT{-blbg_@E;&*h5;62V>%bd) z_4Xdd|3n?a|LBp`-{Jek$@f&ArT5h-r2|$>f|MoRItp?#3BJrDa+{ zH+)UpAx5I`9o?VZ7%m>%j5uSoqNLOXX>mJ-_xCM6z?(XjH?(XhR zfZ!h7-QC@-vEc6R?rs}$X3k9Q?4I4XYTm8t;=@Dz>E_e@Tz&s!(j=yMP0*iF?01O< zqpHCVFqa&7X)c8FwIoWnO>nLQ@)zRQH71|pBUO9YdED_i4|6b4Zn{aYFs;LWpl9AB z`HJGg6EwgQy$6Skx)U(#4w1N*Fr1HcpnceVw(TWTXFvasU_mEdzYBZhq9b#T;Ck~v zkZ#`Y|2NoXj_fIIG(qm)f^Dvqt+x-)z)a$>7EwT6{a>@ITRtJZxrHL~<`1NgZ{|Ul zOdW&=7s%3-U#r(pI92|E^w)NZTURNas5b3Wz~6D~V2g!t`3KS~{w1V~{(m3G(x1n& z1{Qyw5Ogrs|MS@YoN1$B>7=EM@_sM9Y;IG8?EjeC@KY`Bmfju3mybDx3o}(*kVG0! zV#{RT$Yk0*-_>NgaMl2NNDvnlJ`6O#f}hXgH)DYY0ty1W5WhUUc6s2)cbX)cEZ!ey z+~OoD!$fgu5tZf9<_oKiopl#a<_FobnBVjRfmXRRYpW{hU>2We` zvigd8e^nmdN3$Ydm1gIyRd7+8;Kf@tgRIZa^_j9s8(*5U>>|mW(m%t9PC~q33;G8H z;$o-<@FFuC<6Q|!F(;B=;X(|?W4JJ}ko*#<<_}CDCxTqIh!PdfQ$DJL&AK?lwZXVj zBeF<_+Y9w z*Tw+>>T;+irp7_kFQ!ru!35e{%8q-iV3Ib4Vw3=tMu1DWXp;}+$!S+-`xi!L1x+3+ek$w*X}m^8 z;g|0Ka+V(wLE<4ui~oehHNZtnb`)E;rxHu{ z96Y^N7MiON*P`3IxrMjC%P7w4xAFpxJcnBW{=YFGUBQ3Yzc132*71C=GXx5Qpq)td z7_XijMd3{GRR$$PxKKr)X>hY}uIEKopl94HfqNz}!Q1~POo~&l51V7M{Nzwb@6QUS zctFevfLoV%XR$mLqnT)hOiVCZ_}$+Cm5v)mMNj|RU?tuT*16=7xGJPu+L(;9jC(t>w~d}Cs~ zBD@6G8^~_3`Q7|I{?|A%T4-ZN-I3|@2j7Z)N?mIfsxvLg>2CzlGK6~(0YTnlMl1D{ zU}v2H;_dDNp+LtaU-Oba8s|_+T!D^$XBcTjsf!b?9K?<`NZWDH4$`5xgqv^&px$+i z@k1-i3hN5<;!4M)gsgtG^o%ptK`E5`{#V8DT7AkK{pIU=^uiupncr5de)bLM+z?9$ zA^~!niuAbBS{HF+K0oEMs9ADpW8rFRI5Vc!B86gjL%g<*MV;-*)H>+R>`_tkg@rQ?Y6 zQdAw`ETUZf)@qToWDZleERNHuX$-+X&d%UYl~Uw0hVMf{JwsK-(%6)j7V|0l^UF+Z z6w2B-zG_01GA_*-Of%n*s7FUix5`L8bM^2FvZUB3x@t3_TS`#x-2!Eh+rpRG5K*Kx z{Z4hWT0{d>dofm(!V&IYc@lP#%oUOFIg_*rm$y21mQoE3kgSoAtjU|NA9LN|7z`&tbY(Cnj`D4kW7MU(hNZfychSb$pIe|fKTzzgt)>A@r<{xsTyP5! z*NLouT#&A}T3Ai-*BnyL({7j&IX=U_>*}PACkLI3dWem-Mio1(Q;j^=SnDFK;10rXUq2`DnG?*g1L6z2KZak!~Ikfj9 zB{lNSv%+2>D`Z@WGnmGkI(CmMEXP{8jbC&ceWq>*J^a0pk>YEIJeP8%X)tG>JMCUZ zWj^S_P3_`E>grNKNjbsC9(FwXs9kg7dE=r!_v_3<<@6ayKU`Si!Klf6FzQI^R?z;) zy;s*HQj#%x)!@DSHazz>s+@O~6=McOHnbxoN%-XZL`?8C6=k=@htTXhc@AT+7EK>x zV+G@|W$w)cgirbjN6{XQtjYu2#)XDk<}e|%|c8t>!}+~7vApRt1nrPxigNT z%_a=*%7jxZCn76%DG%O6UR5%iQw3LW1jD5RUKJN|wJ>yx?an&O`N567`Eco+zuIj3 zzB-i}Bj4B1?*3PuWOSX89=P))1IXX{rujyPOy^nA$u8s{oH3*c^PZ1XkrQeGahE!o z2Sy@jzVD&LEbZS~xjcD=vOXv#dT-2pblxC%E>U6BFGG%4lO zp_Irc2Nkm&K{#kZpZ||7ZSZCutZ8LE|d64xkS*(If8vi6p~pVr7Cusx^d$Owd*zzP_%XzAI&&g$TAvjsYk8!8lex z^EiQPQ6lAPJVrb1{2E2D!IT^K*za7i4FGoEg+UslqNG?0-9d-B@`3{sXU|=!&gL&0 zER>XZCyOxJ7UeDAVa(I@Fqq&gb{Gn_9=q0pIcQ}Y+J*Hy_e$M;Q0ax19inLii+UDj zf}%q0ynF+QC?p~>7E^K~12jof8R{ZvN2IzWF|NJ>7vW-j>RJ^T77~fWLZ&rA1*{bG zfxmTr#2LUFB2^adv>GZkfD(nok$NK)M>hijngxk`_IT#7!hIF%>w_%KLN_x?cy_5| zDFdk7vP$&4-jEv#Uh*WP&n%pgBd_a(SOL@FZakCnE*hgk7<5>)&*L zTU!#_DW?G=ZRxJ`c?z8z7z~+nl@^W_mRl}ri(z3DT|g2#oE&KMO@oK~KrL(fB@Ehf z@N(fcRqV4d3MN=_emDVc5L{(8U+~?2KgGUW{@-~21|QY30G=^;wQ}XCJZYCE8?)m| ziSwGaJxq&xi)13_To6V677P&A=%QX=W`vig&+WwltgH9zzJsAe{Vt4m;FeqY(PW9Z zM*c*ol9#c91ip@ij+Vqgc6GQD8y+_J0rMbb!z_bX9GbFL58|1;fN&qb-MPy#4;;jC z<(yvjCPt8v=I8Q48O1&NY-0NaD$@}Ckw{Rq5le?XN99-Y|=5Pf6tWNr_Yg zbQuY82Ft+*`ifb1nBDDRruNFq*BlJYCI zDmiVcwdF{wvU;ISi!i%nL$U;<7h5LYwh~7UEcy9D} zy4vx@etY7+))(hNyc_^gK(4={5yw5f92$)8fV|5qefovMmFNY& z)|G^MJL&kH<8Vn7_cl&D*#3)X2uB!nK#5L^#OoCET-~|&^|EXp=Ec$n&GWXGkI+YJ zJY0D&e+UZUGfrkHLCr#G_1N5OJ!1{wOKEK$*;N zL!QF4@aOUZwrFBz=M;0mHdD6`%|;>~BFk}?FACrvq8Dglo$5?xVdI||QnXi+3Tqzt zn9QcgomQ5wD8#-@$TYPhz|k3&vaUR;Bi!xN=PD>tDjKB2cO>l5DKyX}1@8&!d1+m8 znv)vsp^>XVt^C!mhbyH)8WSGmh4r3n78D98qID)Ifc%uL1M-oonrY;=J$M9$^p%N* zPD_}zL&=-~9`+SwL=_=Y^y_y6cNE>w=Z_$}*$>>#0Xso>QLb%kz;xtyPu`*1cbuNi z+m*%jl?PP64zDt|&WEoKQ=(HG0d@JSQAkFZbYc_j`GF_kUHp$;NKxCE zS6W4P3ubrD7N_3Cf(S`ZYQ@0@KpTLjA$^nsGPRAIs&A8>k2Ia4zOUZgvIcYC4$sIT zdpCW=t%89Iv-3AWpI*uZ(o$-oe!@(B=f}yxM}9`554^kQ)UubIHPbZ^xg{L2@Re`)PA{qMgV{2%WI{}dbQq!mJQ^Ho!5$Y)Cz%Y%GVn3@jK zI5JlB+mvrgORA0@87u5Z0+ns=N9u=;#+U$J&K)P?W&h<9m*>5)Vx2|;&BRzUz9{3u zdg0Y|@$%%|Ip~?j`~G}{_65scfgjYruqe*gzEabiF?(>^mrWLQpcZM^i~(mal#gii z4u3{$oCn5)iqM>^P+f$BnR9WtZVTpM3I`(zA56YfJnmrSw^?B#%x!=|3lVDp zP*CdmWaHK(OAyuzluETTllH-qm0nSaF#{LJHJNs+yH)a_A54QjVdivs`Y=XYhtM6I z>yr@^OI}LdwE7r~9e0uBraUh6?ZdwBcf`DUjq3P+@*}(M_w{2DIsN(JvY6WD6sX(#-))J9TjU7+^-HuSoW_aq)W4v= z%+0JM$f#pJS%R$)K+%|@Q#w`)_8aObZ9}0XZAk=mp$2jly{E^%ML~>HmRAOdsJV_1 zHQl4DgLxr@MdZ-1i=y=LxtA2lkZ~fDVgzL})JO%2lwHT~O{dZJvmG6iEKpgDc7BM* z&fKR4t`{BUP&g64f%Pvxp>!Gy^(-$n`c)uOCgokSh`076-zAF6I-p71JC zSP2V8pDi8>Kq@^n_)@T2J$;Y$rSIB3#$g>A`BYC$ovoeOlqh%g)&PW4So6-KI$VE8 z1xS`9I3QJ}gZ)LzU&%6f|Ql4BaK=24<@a70osO!dp=2D7QcTAv{@j zw0?f`5z>HyZuSA2d4Ho9$LoJ~{j?x!__j~+VJqh~rcC4@NSso` z*GxLH8iMZ^%rB(;H^gO;m7kyOeFQB?vcS=LR~-S6m5)e~P&Q9U zNtF3LLcko|tV0(+2U#P>4(tbwfGWTXtmhK#&GZRMv~M{l^4jD+s>^r^s>0vb4r*%U zK0?ZP5@Pdwz{SI}XP;kZ4qeqZi?#FushO}AG+?%L%u^eoJjq?q{(Ac+(3hAa#j?7N zI>}GhkI*)}6x|N7>&*da_tTrmhz_OX3A8aOe#%rrNKwyenL}tljbIaaz2vdavDojaP&-)5 zKAn9)Qrqw{JM67p0d;O)H+D2%qeYk1gPFb&KXJMxQH7>!1ch}CYk}^?33$?Iua}u0 zA|F_j(pjc=s~}x|gYxe+2}@8q?A|Y~AM1|=W)J*ETPR{nOOyCZTWc>)LHUsBEcf~d zRQd3xr5)F`burZE%jZ1Kf@lxC2K(}*>R+xe9R8c;v7nj$pBDq&eXJ+fX{7V7OF|_FF-Ai(oUE&tf{?}}zry6i8l%?jeid{w zAVmID9ukN{N>9iX)Dos3_f^V|IBAVJ-Ds5j7F_JR9CCTa;80vj8Qppv0!UE|>S?c< zKL`qX4Aa57CikFSj4?inipxVtKt$2u0SAdHpAG^AZALfIA6%$@ss7S-6EMyHDS1uMZx2YTS|h`srF zFl!Z5B}ZqfQ;-R-_GmB?4WG!a`Ulz3&m$ii1>~(#i@#P-L4F}Uz&Hmq^(qMFX(d0H zXv{TWkI6W6l%h4~t%wK{#EQ$_pfpiv;i>y~a6;RHOl&ej$N9&(%feXCMDf-sSrx-W6v|Q zu$d$Ad2cWb3wB{)4JPLlr7PWJF9lgiW-l;q^`G%Y(WV7NoxLlRHV5CikKhdssNav63gi z^XHW4{P~<4M(h6!)hyeg3Jav+cBRvsd6_ zl76DDs^~Ia3_~Rm@vPZWO|W7X>nsm0v+3^6Csv$rF@E2t-T%q#HRu;>TO{0mS(~O% z-mNXA6&y6QWsmIM{1E1i6&1%S#tHaSxzz=lR0YBg9n-l!>sPpQ!A*d%_Qt)$3TCg0 zQ%j4lgzRM&CqG8vmuBiRN)7#@w$4%CaV|W0bX;s-mZaWG&1ZHS^PBTFIr_T&NAf2! zz)DPITr>uHKq%`g-p@@11vmO?tqTlef``- z@x(`r59md!`W3V_SMZvLNy6d5H(YnQSXmIRYq`rRp%wDdZffk`9l?Y? z(Z4fuO`DKcWkqmB(PTF1e`nHLNNhUfDZokj&ff19K0|U%ie&pA4ZKN}hR6Ve zfQsWKE#eG<-!*vxNZd3=h)wo27c4p&g8zVYi?55SM^Dxa@5}}taQ9m;3QIky(HvCt zC5hua1$@3zN6}yb-S7ThPx^_kBbn%>xKXC6Igy2H$Yp6DW>kdSMu2lxWHSAYfV|z#{w<$5TmQSo4@OrMcrO|QKlz)>w$U?{g$61$1TNM)U z#gH5k5pMXM9F;<|4q>ozdeKj>r1ksBlt)}pnxEfi?Gf8_ik9l7dM7``tmJ?ctFt$a zpFEX&u=Gv|@g#3WoK+yl#bFakV&Pex2=<3D);A=|`E1Xd*U0v$Yx}{)!Bvz} z6Knp7>Un=qod^5yd=z+tRK&bN4_{K)U4u0;ez&E~@#psj1`Vp*eg>{ZXCbTwV0vnL zLRmljC)Vt&uy7CT~{sw1+pjee!r66ZA)#}WxR$!ndts-Tm?09`o zB5Vts)02x+T&uMW0v_o||E*5BV(Ux3jqD5vW4&U98j+zSR}9GYxX^F*j(k{Q_Nhk_ z$9^<3@EaLD(dWd0a5+J`TJJ?J@e6lyjy^q>7S12utfEDwzur=KC0qD&z^r z;C1J&4b`x+NF#Gh-TnF26kO;(OY}wntSH|rej_DHessb={G&wA{o*+b`Mi{5R6{G0 z1GE8VL?ZJuiYI|^_4t4uN|p(E#~x#Q$6a58qvoZ7DWTPD_I53!{d;;0kPD0ou5G_7%(Cwuc7srmv%ciaU~5DC z>H)Hrtgy;qn9}`c6pskFMG~oS9k{>22}Ef#(AaKmo9_)uB=B;}OClCZpU8Du$Pj>S z36n*H!I5;_68aO^W&6j>jLmdP{~g%*{vFt78T#!?NWUI=7KOR2N*vHK@N^l6)!9wj zpde~hi6>+m8^oLYw9Ie*_I>@vb|i0)<$+OII+hD4*=haTqF1*A!cfy1O&(gF|EAMp zH|591VT%O?M`!gLXFZADK;FiK{-=NLn+G==z;1^JNQosibybzX9#E_fGLVT`Gnqkg z-n-`X1>V*;l#Ka)`3Kt*1P+-4CAyM5ZSO1*`IA-9k+J@0IKB|dAq>jj8od&VTJ{Gx zT{fG~8a*X88#=91Fvjg3^shHiJ0o-B?Rzn6uJiAaE80U)m1lAA6e{1w~n*?kB zQKPr$qHm5O3d*~8F#1`e_oB@8h1Q>yTVL(j?6XFXORSc)8$DvG21ssjzT!)wC248H4?1j%Z|d?{q?f1Akg>(DCxX2iuM&fAZ zCAF+#jS-AW;;<^*WsGXw@=U6AN1mpA`!HdkSovO7`K+Y=>s|V@NN@jUB74Qy*L4>d z%R0x=o?7s`O;VxxL3NTr6TCJ7LXme*cMgV7>#MS>)XpV;*W-EG0JmxOm|p%d1gs1p zNl_`{5@LzD+LHj2{iv=pm*!;-quZ$RJ#zaR(}&TU?e=k%2Z`nhfJvrRFZ+e4WimYY z(3U3eJ~zEG3(+)dYUUtbSXYl!CT2Ei_i{lAePhz)76*5L2zT(oE%toE0E+bLYiECy zdcHJ!zB}2l?jV+t`0gwi@|)m(7+Dtbvft6QiMen%TN$VC(iVsdERYW;E16ZLnt0$Z z$6pd_Kd8u~XWSlsSlsUK7#zLbl>JaEhRW#DR^ri63gpQeIw_JtdpZ5<+85}TdVl{z z?1bq5YD%m8H%;mPeE7fU)YF_xc>h(Q*7zEcfnIyjW=#5Pp&Zs8o0Da+CKQQOKQyMm zR5X;DJvKeCIuH>mpDEspJf4OR8VC`C^Os-`AD(p~%p?pQh8}})(6|Vx^^p??H8uCc zk-A50rt$F5``)*~skRHPHP24Raqfpz#|ux6w}s3kAmnM;NHM%wjf{$xHlwn^qu&iI z%m*wZzg9&a&Q&zaW=NWL=NE?OHIh2!d=zK)Ynqm;>fBCcf^7;Azyw0!RLf?FE!8Pi z+xiIGuv;u8G1qXD`j5$-Ik-^U1YHnf=i?KqXemjlN};y)Pi$*6jGH)J<3^_ENmf`+ z_eL;V%sW==)1wtkZC%v3&S+B1WFpp751VWonD6ea9@y4URV%Hmn;O-%5>?Vx<2AL_ zDQ(o>NxI-hZQZFxt!h_}Yn#XmD=Kg6)O8xxYDZ#M4D6W><~h$A=`wZQM-!`z(xgkO zC@HOrwRP3kYb8L)%MM76STv$!o<5$QCNpOxy}+3JtQUD z%9)Ka28~^r1_$GbYuhTN6RojUoJx^bWMCH?D|3lxSDW9=*bG+ZTdfn@hrJ>_?}1uNt`0Xa{JlS!|?RZ4Bh6&(&8| zOPrcaR+UpyQ!}G>9!4D?RXPzzA_uQhYW;0VSte{Oz2kDOv3_1n0ZGtYg@-e-N^Ek z(EdemteY}Zr9q&}Lh?E_)kyOyuwt1HdVE(58m@-}rYD^-EF>o#@0;Wzu@n~GA>wHt zDxP5e6l9cryh*p5NHV=19$`J4<>VAcmCR6R(v1k*w;q82(BMZ%1aktUST@>399#i@ zCVn$(J^Wi3Felh>&^FM3)l8`5~MF zC3qvm`OiZR{3;S+H!%r*<+0J{gk>P=g!=VSYpw?5}!t0n~bP zape-p`#d*w+o^8Q`DMfreUJ1%n$)9V5lNsJdPG?ylBtG-zLQHPQ;7LTt&-@s;)y;D z;UJnoF${}x5RDGF33#AoT|H_9q2 zPrxw{+;<{hP9($XY)+3gol9E;!-eFWl40YaLM(kzzH1TuQ4haUt0_Q_dINH8RoAw3 zv+c7z;eUjbSxwWKNRY4gRn~qU&_@=as~rM|_8~9cKi1qI@`fF@T~ZlPwWHE|XtGqN zW3#1ZNNE|Pnb5HLOxGu33#Eg%cq1$ZUn`38;ODpMfYkPEZP42qu-zot{MEHK`P`1) zHpJr9zhzLGUT0WA^XoiO#4@qWPl%@)=zd3yQ8)pOj6s7nd24e;gEE8-5~{EStRA9( zTk4VCNb zj?b=b8c5^KE2#=gxlDL8XqJc?Qcg;=LZGOJ2f$UQj;=6W$d(Gkt0i?c-Pq^2gPa&6`MJBA34p_eCMLb8y-uWS} zwg@GmhM*0lvLxG@5V9f87BvAGI7P3}m;Jjtjsn3&z( z61Bg!Q$h#We{T{*2h~?Z+)X>g4oVl1B#;>vz(2(%+&dw(({zgk-WzL{PO@b^^%!Bs zMciyJ763mcD(NQ6#7mhPyhuZ5Ej%Jg^n*+zbH-Y|*qoiemsWU0_RpCc;0{dimsb$X zF=VeAtoP*c0yZfSn711pj~d7sK@*|3fY8+{o)G+*2dXH4uA32^JfYZP?OsG2*%UAJ z2C)XeE+Klt*9=T!?S(JJrYsyT@Yg!OOQ$Jt8M*0C;>?+S zrE<40Lu-f9rS{tCXBPoU1l8wMZh-+Gy*_D&45bXyd)r@3yH^ErEpjYcdC9N%NflvL z6V>{|C4eAIet=%=nsfKiJCS;OV8}68<3&uh3WWEcp%To^m=Ib+VIpVs5HII)$ry~q z4_Gzg=_*mULsS-4h_nVZz&=Ujg6U%rKIjg5N_Se`K0#FVBdiTlAVy69GN=^tHsHf@ zrTP6>^8NZ)>;-NyET;_2t?SiIXbChnqV{&~kn!D|g6`W%peSJmOKtK|1=O{44jB;- zETHogW~vBHf6bEY&&d$nfI14GzNQ*jVZx3S+eb8&yc91@o#jfsCVc4g3AY!D>ACD9 zSfi(8T*k4}IgS7l2Gd1!9)T$mjj{V3TBdla+!opt{pNZ_{wk6PD+Rm&wCwS4S z*8>O#TZLQoVm!CnO=*g1Il&)5d(mi!Io*YX!>vt)LYf}AY!$k~qx@<<(i_iw)@m>_ zDq;gMwIoT;YYXuAwlpe3ory8Z(nO7F-h;<(NxdXrBV4^+M`(&T%3oGGuyR%3b7*s` zGx5VM3*0V_imq8cx(#U(SuQo6U@022&J8|9Amo-x#$bb~=X7Cr9cobyt8x^SjC;m} z=9bt%xcC4qh2UMtd@SYm8l|Ly(+oe&)ZTMCH?y62i8SNI>9?ftf0+iyXt7m!Y$`}h zOyp=2)yd2h`i3}$p0fP4y(NV|D%^4HLfok6%&MN0!K_W=AzrA>jCFxKg}-gC)s%Qy zbir|r5yPoN!&N9Z&760kBbxtZu2m)!Zqi!o!2oQnaQ;rri4^T`R^OvE zD0AS}36|UcCN}@{lhB z4U0o=!(W;Yyz;n*Id^s0-%{B8$X7YO5tk{nwgucp-sXZooJ=!{BA4x{H5U9!u|b~A z-j=yx+(s|d#-NEunDT|molG6YMQycdHPl58@b_#~(;AHL4D*Alf_8{m8FnSdRssC> zQBIDHXk`w+daPwm0hM14g|{s+{gDm6XG;YRJL#gG_UQDZ9yPSlM5t!N!dr|!cZRkhCoybkQW+40f2k~@rCSbZdrI?s z?Q{P{o+H)K0{xJx3#b&88*BP@d7%H!<$}FINM@jFoYmW$eXPT^7WrK@rOxx}2kEb5 zSgYnDeZ;p8_NtH*c@gn`=83!l^Kfig1P2& z33)+FJJ2Mo60Iq>at4pP(j`+0%#D5sfi`=(AHK%rYe`&SM!OoFP9($*Nrv9WRVHzv z@~OELD_&4&X=6IKZuZKo-qYbo8HYT_Ny@LlkV=EK^L6EEbSaHw4q`kcrP#so_e?1< zIu~e1`C+$(XqqVbiWzJeVNS4w+9P79BDEqS&+1)bMaubEp8E39>&Jj2xqK6m<#91i z^b%%<>6JHvjy!_5Ug$JGr$VHQ0D?0kqHlx^jML{sVi$Mex1C|PQ94YNVy2u|-el7} zBCRnoHU{}`F)=)+Xh(!7M_C<YwKC#1Ou9}(TY z7RTF6VYm2+Yr0FycF5hwf1z$PtshZzKo^*Ku=EVPKZURxtx7lrtW1DN3sme!g$YNnYWD4su3MEE$Mg zA9WhhP!{ib00P(rN7@_>5+;D>KdWMKNeHVrZOTJ_$ z?PM4PlU6e+kmMKieV`!s5Pe)+coIdleFFr;Rx>M*WSt=QNPQWGQLL}M5i@}pw7^nm z(h*;7EQ8o5=(>!PH(((cLk%OonbbhVO&?6+*D=KS%WosY_QiLq^DCNJupwo&1u^JP zh-;ON7-32;=;yK-lEtx@)G8(o!=#q<3E4NukwnqOi8`l@ZUd;&L$}3pq+}T4Se;Tv zb6Pm0kXa#(uh|)&I%wkD(@}#M<#5m)0_p zH-%rb7>7eSqMwC5-v&e~pF3iqS6?{iTlt1)C;s+6G^gj}s=6ZDesS zZe{^RU_ zW9QI5sfleb@lWNDkE{3ns|(SA&0!&_By5wQTEf%hmo`_cs@#(%s%US!Cgjo}+nWQX zo=62#;Gug%G!cNRgcj87?1ssDbUmc&ZgFL;wIYuzBs{HoSa*ELJh)hOocQbK@cbgP z#R}DmZsJ@QtF_x|s3GoE8BcX(;V`dLicDz|lN9$ELPeD~oh&tvooApmgWXrog6fzO z*MfP_pQ6Dq*IL*;aoLSxEiakaU_qWzI!_7Z2h(TmbW+%#28%8mex{gOpxoS7AxOim zF>jToZ)!u4z~Sm{a(pdBk(Ju~BO-_G>ciEnTKVQ`z5od(r&gWXc-SH65Fql!;g_+J zBoQ%_cCv)ACEZWC|P{*Ii|hE*H#@2BNgV>jZ}G-#~SQa>Ot9i1|U2{0pg?-@&kzOHs?^<n;71YRhE9im6({m z_&7pzd;i?%54xC zk>~+X&;tzI4pH>Knh@h@bD!LbR8JtXznYMP5(SGomMR5coQRDyd7y-sJnOCfkxxxX zT}rFqOhc?A)0>4znR_6E)#4N9-tmvY+5-%E$k93MF@KVt=bg_}Imt!mo5`ljua z9ild97v#!R`-n=gZkltu&7}Q2hZOBmoG9+EjG>D9XfelMi~IL_;+JAs9})Xf+(rs^ zBsB6DhMf#eB_!~5j#aUN4doVWnB10>%6K zDF>x$x^ip%wZg*vyn=IWUdLg6X6*_GNrhDvJO3@f+erRJB1ws9lw!%vrzE6~{^|_$ z-z6a%B1{9-{vyvIMeb-GE<9A7eP3Em_)l|LzacaT)dD6SvwEPWbab5_I72!j-(r8v zUc`VCJ(c_v#f5nfG~2K~oj`eQvd2?}SRLqDU159mEIGCJxR>bpYP3s#yUB)|66gdUtwX#u4~`1cb(t7b0FH5;{J}+z%uZ)}oFz>L zNF~2V=-uueM3>JxCN#6T+~Or^joi#c^M#-Yfge&@DVbx=pP^Hn1WZ#q1|&5>l5du7 zHYh+J(i_qkC9rzB`3Fryk4YhKD~pjA;>O@w_^@gQ3e-3*621f})5Ne4zHeAGZN zknLNy>2!e^IqK1epo#iRgcrGh%lxbXs6L8kvsylAU$xDu;wpl~5KtaIFIY+Xj}7?H zrwvf$sWd;fEd*QqOmpw05AVj03kX=F_1<6az8eIyywyQf4_&e}&qg8{qRC3Ka1i{K$*+0F4 z*UyU>ue71GzHHcT61j9p)tRRR~W&;=M>Ga%OKcxDpb}t6=B_4ju`85d-_Yt1l z`-tzo3*?asfTHrS-Lc#9qrKA6|0@Z(;Lx!aH=k!qB#7}j9~N5`-zCdieGyI*THm~p zX9JwVej7P?L|OHr2fegx$AJ0xYuB*c1!K_x|MH~|`TvDo<3A1m|KsfcPj-zU&}E0& zQaxc`mK>25WCb}g^NRaga{kNWl`%>6p*@osC}3PSUAJ)XZFXF?-#OHS5%;8nTeg35 zrmSa-d`(E^F;<4p_dEWX4DI+-72XA`7FC53PjBWyfq=f%n!xbY!-|b=G|o3?)Qlii zOxT?Z9@4R6f(cRaTZj3G7&aQ^7-dd@v$q_Vpp~}kfA}?0r1X+X3TC)C?0(X4x|L@Q`oYZU8?u$CtH&`m zmWbV{xIPInv6Q4VC}4bwK+695HJn`ce_kMc`ZbaZa=G%-L^Ntw*4VqVs%tg4a{KGJ z78_)-rhx6K*|9%GAlNi&&9^nsHpIBx6&|Z%nDZ(@*M<8Kg2Gr8x{*(6#d<(}0|feu zFs4eg*n0h*r}*0IofIK)=HLKo6f`_4?V-|k?HeBm{4E%m2qh?$>5 zgt)C)MU>9?Ze~CF4sm{w?jAYy^)#eG05EGxhA_Tp{H=+}^|B8APZLwv!YwcPB)f2o zi*lGDxCAtDp141pCty(r*u(_>*2DyTl;yKFoIdJS2OU>u+;g>(mchpdT>tO@HZdJq zA*>h|S#xD>I4*ysWAvwk8>0v?EZ1b{D^!pV4@}ijR^x(R)Y!(Z;|1L7h)vx(nVB@j zkT=GNmdv9R&67uZNE*O0#gWk4LHO#Xd@OGKR0drCD2WROSxk8p4GY#Gzn2iu-%K^{ z30*(h!m!miClbbMC~3s9fG(@Kp6KCl!P5PRY?5B>lNvOyf*yO9=_)bkMU7SP)O@7sk_TWhdburZ#A|~tNw!^fqNr=K4*VLnD9)A@ zJPIx?3QK9w@t%$<9f5qe?MtU5;NfZgSmiVBc0L;DJn>@jobL+sVZ$fqYHy~Uj@Cd> zemw%8kucq`0C}!ZA!Aas3dsSo>w|ngBL6jP}gVz1uHkbIoMcW5fi053wnHGXQ*>!hPR8qHlHBxPuyH|)a^*U3>p7Z=!g=! zs4BHGZkkNw+@d9nxe%&vD4}$vjrFy`q+q+ zaVc zTCqCrhMtK)@3n-@@gT!1K(cV^H=k2OyZ(|*jvQ+ zB*|>yTOC~MbbpZNcjk)trZ}bXL~fLo&VP(SUK?1hV4DpWvK@Fg9yKMi$RDCG?%_S= zg<5B(dT>D5J3&`=7>CKPPeF0*QO{)A&0u2wK7Ny==>>!dahl=27Nh}w%d|KlE<8;R ztS$P4n&%a~l!9Ms==7{s{CiqESpCwj7GpSb3guG=|24CGWWU9>aUq)o)HY(T?Y>?7 z6OMPV%=E^)_iVx+GKho&h-qvXE$!h@wZkwK_QYVX`3gewh*Sr~@)C52 zJgH6i9%s#L+v&$9R^JY!IeVJWVaQ~?=@45jUDPzq!xBm5XRX)7Kj#{4NQGl_z$&J^ ztvxFO6NFgP3@_{znop^*pQ!5m^EXr_?k~PGNvQd^A-4no6QNHKKR8Bwp4_f*vxata zyzg;ZMaSiav%v0hcr><#wqaLD7>*N;=%hf-4g!5?=5O*58r@V;TCiF>&cENCdm<@+ zX-=@M)5PdXp+VpCOjh6PL3qd*E-X_Pp0f(7Io;cL8_bq#1m%sKmfAYQpa`vrRpZ?x zfAYz}SF`uR*gYqqSrbwpCOA&zPYzIYhC7WRj*<(JzF|$G%yE}B9?KhoP+(r_c3FZP z7A38W1AFRv`YRB+lAU5?3K$5zzFATmaiet(~=G4(H=QRn?`dp z^OiM*eO+2`_TL_B{LfLG>EBSC>HoLM3N`!Q=KhyI?TMqz)8*ET=50jOrV)ups7Rs> z>q;|ybsGIGSE^ld-s_Q9xy#nnF*r4?DC7u56d2``8ui9BZQY6U^6Nak zo{nqR>~xLD2_+YVGk}T3s|-gnLPwonC+ce~(S;DPvBhPG8-AM<0UYPV?>8pz@6^i1 zL7bBV+|-o2#*>D{3tDVHZ%z$Rfp%0f6MTf-C+=ce{%!G6&OV^Uzmk0wz<~eI^-OWI z`5q8XV5LJfdt_JaQp|})cmkn7_VEJ(BJe)rAIZ>i@boBYAA=hjgFl`aG#V|_x#X*+ zZ{NhSs6}T1&orihXBrI9c(9O41ME(}@VgyQn>g##*Yk(hJgQC< z*^xtf4^0$N1s_Ou&^^(XQj=8q2L0JjB}$s#qM?>7zFiERQK7&LX1d@v?ab-I=GGJLFg`?%4I{oQo4B*)M?wEM_+z(WnUiRxft z$+&9ud}3fQG?HzTBH>6@sSFcygK5lflr!}3t9ke9{M1L(gBqo?U+K*hNjZ#Hq4QH0 z>WLAiFGS417#fimBL?_}wX^|RVb0F-1>SQOY@qXCeZxe8VvvtMf&YLKbH~-i65{x1 zq*~l02jX8|8cZ%Ow=ivpV~O}3H)thErqcz$Pdzn~U{90a;>PF_lFvwTX!@{St9TA& z&~I(qFgUYNpS5cuBSuqvN7&wN{hi`_YQ@YDV|?4XpHbsD&om2)QPebT$vE8?Vh!YT zI(utyaE?+|T1EN*LIZEwNP*(#7FFUa6TlDMGFNPi>J|rnIj7$yU!k6pt^t}Hi8v8z za0I{6mkR~8Flc@(fh?7V*Q)U{ha~|^E}Pisj1sy}Pa;54Vv^89GWUQoMi%N^_Hsj( z;e)?MZrA&DHns|O&7!>cugR^28&L7a5r`C+us(JTafP#`nfqcTr*AKJnr%}tvxXtaC( zX%w8;Mbvj8N0AHd03n|Ir{6e-g4Mr#LE%arflwTe8*wUKt2*M`dugl93`l<*|2oEV zk(qJC5emx2H!Y)%FMd6!un|#SlMvK$0m_oqPrKL z=sdMSArULtb2RHWjFueqv)r2r;RM|~LQbn$e~11eIoUwf$0JCB(m53*Tr>O^h$|~Y zTr+K0=V5}08rNaaT2*&oixW&AFW3^5PX1TE#8y{6QMMoiRR_^>oVaKjS3`jfGd7QO zT%$QU&&wywc5At8fxFbt5UxbH0$`L(W>cm7GIm(C0$kKmGv>mS-F@9je_d@%;AREk zqD`JF3}2P&-cW$NV6|g0$Z|7Wfr!#hUJ^6B82HRn&ih)48Nki>O-~`lnHFKfL+=cf zT1HvsqbH1cZjLgd4*L#RI)Z4Y#(8Mo~Ae>15Y=~I=+=u$m!iuVgxr1 z_wjKff4U=S7lbWg6Y6|`_3-$9)8ll`4YhT9=z>_{`Nc{~1pdRTm@X$W9XK&KZU3qf z%HnXS2bg}~%g2L{Fj?arf#iO3XP;@a`h-jSdrna7cgOBGPIm*kPb3~sw7MePSV5y_ z8vbK0H0l@4-OF{fi{k`MnhH5|)7MC-wYfVBp}n{3jpHi$t^a$;3jgwP@ZWwLtSCSJ zraJPArCPIzGA=cgq9A2(JtXsY@HlxeQL>r*FbPPXh~|~$+)pk|3$+*U^6u+MtJxb% zHtv%CRSJnRp1RmCB;UAiPbTvRKt{w186EQ<8*fwH+Aq`k+EOmPGG0KxK(xz9cV+G` z*lWigD$YXh1?l4tFnX^)DRZQc_PS8OhuCuKV(u3OyrdfBhCL@6=rhXsPFM>u^|`nU zjT#7l#p&WeV|1O}>Z!L)F3JO4$r2|Rkudq5)=;3iaCzNoC^=$yoqTO zb_Co>&X8g{`dSb^KmW9_AybLAZSP5$bla2$4~~@jG?nr~tKo-6&2i#0HYu>5+=6SL zbz>DjDOSs;?mA5Mi#T?1`#zDEWajCr7XR>VbE}o1j+|r|_%h89CSGm6e$YqL80CCr ze?b0OPZRfKN9Ee107RQA}JBtH73R{C1E%_J83LQo8ZDqsm$1bXmvw;!xmS zW~0uPG@`Q7J#mw6v0v}T9(f5^%jh`dG5u^-BWYsR-NLwHCu0EI@0%2(KNO2`JMb-J zu?^7KD+L))Fsa5FQ6>CxC+-zdVr?>%(Ytw;3bu!x)aN<*lH#KXD3;Ct3Bk*+7p(@$ zCHOTcK$eRd)UA?=t){@PCBC2P`amfZ^M6t5F?m=i4-KS=cdp2*#=QkAgtEo4 z&#R_&Q{h4fTM!m*;MzwIoqV8CqJT2C3YW)1>5{!j2_(y9TM$Jb_}Rm_r4bi{@3EY{ z;b~8AKRPRfcDQ8`NFbf%G6-c$VrZn0ElS_|^oy4JM5YP`ZoDa2T+%9dLmaCX%g=Ax zO7_LfA9;JuWp1#9rI!7&L#oGjAjt{)hzFbK?q1_mqKsRM%*s&CNVbulv%Zo8wA z&39Io+B=JN3imYa_uxAQ*B@MKqw)8lz6C2xM!W?p2vueYmYxR&3!S4MZ*5GGBNb?_ zsD|fazXdB0ph)41{vE8~)`tE~-FvjMQCx01Hr86%6or6EY z3Nk%nJ|XucV=+_>18kxmrDT7C6;LWDoh`n-1uKABExrXS7|AC*+pP7dISX|z2{;VI z20IDXB2S*?Y-APaa4ujZ)2cu~@epxN)%bokbQA{$D@1g|){1a>5OT;>I6ufAwcaw6 zrW}_G-y6QB%J0?2N`~P3sxv`QE^FIC6}g8O$uj~UZRp#r5j}g05{W$h$UV|cq1><)i$f|sEuI%UVz|Q21@YL{0OV!fw zlTRKmF~;gMziLY@5l5z)HH)%h$Z7sa-PXjM!1Cva?X$lzK_T;n3AiP3Ka4yrB@QPq z{FRHn)$P4k-!b!^883v?qe|sDqjrn?i$aWYUDl` zz$$%U`b6L}*xEY`F5yU65o4S`QWyNE)HP~%Y^g}@x3`8lARBi;Fi}c7zW-C|oNMP2 zx?L*EteSj>L;oW6lrdeiq8EB44^b_&=VPO)Qu)`$KfwxkA|aVfcTX`NTd2;O)U}JK znNa3F2$1RdnJiKq<;|01ixF)UF`_Rs2Ps!{?5{%tgB4EOA-P_#YDI`rZpPQZWNnMd z<*1@kzAMlOAU!@wK!kw9Jp*>t4LbZ;#V=_~ALP`ZC1}yi+8Dg`eoLK4lIBV-9Xolj zFicrs?liFGbblXWFdMJx18>wc8@qcn)aLJhY87mukl39>nwgI>Pm<>xVHr00fwgk5 zCb+8G+^tga0+Q5UM|kzi0T&`!+zB*z)3m>+MwcYD6*;`qgnmRM{Qh93Qk2aCP05*L z!4ZSn0(&b>ZfjKLuyKhSqfp42stp<3O_0xerQN=!EC}&(Kx2R{!S@|LgLmbp!-Hkxh7&`Y0G0;&~goZ)_l9j+ANw-m@wd<=fyUO20HP#22rk z{H~roqx|A|818?H7fm7l)!l^mxXLtTVh8MQivQEyq*~)G4gVbm@pg1x#v`b_q)w%&w)m z?66%oNAe6VwvL9Tj)X~KlEXKQ!&2q|G5(Qeh~xrTW+@!QkMUGBi3CpQgh*yG1I_h1 zs3O+Z9K3PEq4_b;YJG1t$|ELu6mT1I(44ACK&%hvw%Fz%F%D4ipD!B<60nsfKu=i< zp}SX|VEcN7B7qJ*{Hv5}mWpYAcM>+{U=QVp?u;$w8~tfl7@wC86A zOOp{mDdf$GcbCC^wdYi}POfbIQy79cbyvzJ$xtPx8Ox}Gpe08cp9t#dS?gkBKVAMx zQFNddszFk(H~>G{tCxu~5h=*OH+V}`;9p6J*`!PFj`Y!kCRJN(Q{KL@J=V}#dl1wd zw@>4gB&5#oHI>V;HSJ{Lp7VDMP zEB3P#odzYUiwe?dl~~01skumgWpPy;fB%-M0A<)DE(T0hAlbGp6G-M)`8!pi%_KO0 z6(Z)d-yl&hN~-Q&bBKr>%N%u$_Q!$nV53M~X<|Oc_>`h}QD_KECwCaP!*?4JL4=Oq zdJx=cLYYWV^b4t0KEqSwpSb|2QIGG&>gDY!kfAhGP^J>ICW}Vcmx(@dqqeZ-_|!l{ zsF9><%{Hm;9FK0{B!?%Lmh7WVsrFFD6Lbx%kgF6d0Wx+4nAs~fLhcZ|c#7ZKwktA9 zsoXT@q_3+#S})0G3d&|EW$8o?Hj{1X?5#mT*&AA^m+ImQ4uWVA1K5c4(Ea8&-T1mL(OXLy1lKY7OT?K_yLDm7tYx-TYL#P7}JIZYdEI zpV~=Fj~&L0!^JEjcEui5Tp=z>-Yv!rEOA2otHjA?$GInd@q@`lbg)>XxLd6Bgf((% zQ%Z9Ls86#QGdfx0&q(u6xnSf#_mhgT z$3|8Mi}$f52#XLSJOzZ)9J3HOeY1LGd}Tkj?F36 z81!u$pmcOI4~7~pEmm79#1|P^%8biW=gWe~E2&-$q|AmqoB`N^Dy-NP%tkaQTap*s ztY?cCId}~|)(WTPdsnq~8kDu{uKjtnp*7SwIhY$v77^4*Lq&dQkfBf>YV zr@m7D#`+SP%O1{=3)Ul1)9Ptdgy==p8`i)4#(LIM*l(=g7yz-J{12=L9WCv>%hwewOF zA4N0BM`Oi$4h-dluINC!%03$BKGM5K9XA~OzFr#*&M&p|@dtZC)NNiLh-P zF)k2cw|{3beDkY!nHlVf)q~X_*HwQHJXSM*ms0;p!Dqf?KI}KvAI7S&Ux}>3Dz`mSn?6-zlxsuHb`oeVPM5V>g zgbU;TeS687;NTVFr_5{19aNXZSL}Q{P6 zL$?_3w$wBUcsS%!tR5t|)<}vm{NzG;a$cEu-a9mzgTr*lg(KKVdFracTt~zD$2QN^ z$6piNkGrcKFCVm#B+1Ei#;@fG>3%v;8hp5#m(~s>1@%pu5MYW5zHr7z+;OciA)?{F z%BB9SgFQ?2Ij)rn9d~v%U@BF}sbHlSIhKBTM^{)XiEB<(m9b7BlRI{pq>)^LF81_e z-L?NBy5;e(TIcM9eVP%2H+O!#2`Ec?KC5yK`KCeC zB2dH6Me}=C8ek4&`S@1|Uiqj6iAdGpvPS#JOwCJx@8_Qe3m{8 zlut6Fl?;fmb+A`A4)!p9PW7dDA8!GCoF5!-VdtwV-tmV8yYST(PYGX~nCnKSJTGde zPKg_dqCqDC?oOcNSvieg3!OH}c+ajENTuX~*3Cldr(b`XUA8Ac>fV zXf~0VnVwacTXfbrCe7Vl#)Df>DZp=&9+~A)iqFMJYF`kaHHiw7)ZW4XOnR-d%py2gx(bG@|(acop~ZR^rHSYcHNh^0Xv+d ziAhrid82QzSv{p}lN`QV+Tu|Kt)%G=?1vsj1bG|M@0-TxjKub@LweSXtj zj!Ovv_`yk)`qzZrI`Yqi9q-SCy;2WP+5hzSrzu@jm0LM*!oF3!GL=m9e)XY1XVb#|1oPc#$~=>#g4G3SJJHK}(4cI|7M2CcyM9r#0(gkz0iv^9>&ZMy3ndAU^g< z29_D8I6p`;6-b_6Rn7aHW)G(A-~4v_@lRcUDZv`6f@#Qt>ip3q=ySxj<-GAZNM&eJ zBi(|t-Bceug>nhrWz24gEqU@UbE@ZE?^jSB6hYv2rV2oQ?u%loh&i1XJiWW7DjpNg z5(JhxwNxsH2g2d-;^cV%%bd{eo_I5xtBMR&7Qjpk?Aw5y%b1Z5JZhM%+Wt)S?}ylkw9BB;ecatgf*`iTV?a^9Wi+M zB<)dWKvZ3hTxXyMEORQ2U@@Hb({Dw#kVp+-F<=K3P|(rxN5x@#@rMZCH0~FpO9RRvsZ0# zIWMlYY-b9f9Vb>@aEC6gBU%pRnAsoHfL%^McQd{u41thtfrwdTiP@BWp*@MqH)*I$ z&|M0oi3&6t%knw}BTRcqe(bHXiqLYu4cqL@$db@5+<6BR{+Xu0G`b0K-$vP=kLf(H zW2Z{Jlhm_UMrmQ{%yHtWCafc*q+`cly)2>EW*8iFrLW%~m+R|m3`QM_g8g$U+oMmq zqztM@&^4QctX5Rls#4NJ)#u$=63R!`MM(B*nJR6vN^06 zXkvI8D%)G;3VZ6u*%t!_3VWAHt)3_LRkSbQz;_v{lxF(wx7&OFOSfD8&%MhG%q;&- z?*IJpzsW*G>O*;jiEfQ<<)Q!);ELfZq|yh2h4+D}qWAeowGd=3!;jdk8TOalIZaID zL{n--E{!iUx6a8)weG$U5J*n`w);)$%ll`oJo@aF3&vq=mJPH zh>e3MVgSKF4v6#pGiI-ojf1F4*6}b?fKDqqQZ^Lw)HbGy(`&SLWN(AMc^k8ThHh6@ zO7G+q7WI+#ng8*f4n3QKMHh)*C_@N6gqbtLQuAOiAkZ!3t-wI{A~G1>NB4>!#q10e zFvAZRsF}F{YY?gniViLPZS__|EL|G3t}~s2$_*jp9>qbk;%52kh8T700%+09Q9>u7 zU5e${@7(Z*rr=5Vn8i88!yjt_q!^Yx@!8U!Je%nD!)lAo*pt(?Toq`og&M+w!SG{n zw`(jF8oyM#w#37Y(A{jvfOA9lsV?$pY~QF`luFq=gZ!DRCn1RW*5$o#V%otZjw>GU z1V|uf#UQg)G3SX1?K1cetOs2ZrPu4XY)rokr+U{GW(~OlHfsu;t6OISsg8Sv{KDd@ zz~5o4(t}uVp+ti;;J0(ORY~;LSityKV}aICexud>#l=U19UZQ$@1}j>Es4y!e<}-3 z3itZn`BKy{nKdn#7IjzF*zC?-Sjj{?i)HJ>6win0qm!pfTc_$QarhobijM3-VQsBN1fXN1~Kc2~-}`J-(^k@P2NuTouXNQ%?!%m5qI zF$!nE=zd-|MS2%IpSM(u00+cu9mo|lzjnSNKQ3^vULotGV4KmXRo-q`5gwTYu6=V7S%1KlBivLwe;E0%{acBMjP(gF=!Nsi~P2_M~ImA z6;#V;N#nakmrnALb0`{S$Vq)UfA9kh`N3eo=Gyeiv_}F_VT+;|D0r-VQGIT#FrHG6 zoO3f0W1_;BsD)dPpV_*wX5U>(Tg7p~ z5(N~rbX@a^VGbLb6Ru@jA*|Esk8k;hMi{W}yukcJv_JWWi>SBu)3GiNhsvBRQ9cPK z|Fk+;UvqpF8r-HrYyR482<2kx=0$bz-1&#BoP~Op0<}1HfOAN8yk%7^YLG*b;8<&^ zM-iMCGUzBb1QwwgOPyk^nl=5C0pxA9BgZOr#;NNuvD8eh ziLKgbW6l~T|Jd_TZis~M^h=xktNRt&mrP!Y6TNqB{2O6`jZ71qP;tNH{f%2eN@mTG z(U<}$wIhvZCleryZ?Fg8dAYTG!h~k;2@iR@d>blNBpV*u_UnIWnVhr)jWpT3N|+C= z{Ot0Iw`~v$^K^BL!Evih<_K-GpO`1;2 z#u1^%Dmk{f1rt;yif%aI?XR3ttC}@q5}dq}NxWf#QM3>#6BrSsH(App${`q=)8a?s zy2Wt5#Fo|=#;AmFrgf{45Vc6dPm8#jaMdc_`wDev4UTmdEq@~|A&e7WC@+?hy!HzD zzLpPINC3w|Ha!oCRNFj-^b^@J@*56Qh9O4$$~C(^fZx*<3tDMH(3gQ4EZe(7=Yb;o z+;|O3d=-Fn{fe_*_-ZGQQ63@^!FrEgCBE6$J-5)!3x71~9vT;P5&i9S9)Xj`YDd{u@=YWQN8 zR#~v)l*kXP^!{gRPotn$?}AX2OFM!B`lRkRw8CzK(vr_DlKUuw@*oEemSl-8Qqn{3 z(geck2HSXRg}1}zD^*e7g#3paV>cU^g~PQKhL zuYD}^fdV+t^j^gd*iq**%ZY)h@(-B%q)bBdZ`Y6Cq>noS6pmf~WF3l=R4z?Vn&2LL zgwibCeSyRK$RO_@rYu`iO=4s&7Ih$TauKxmqw!xQe*YyihZ@4Y0X=WVr-uq<8)JoO zGI}$-UemLG(DXbIb?id>(bGcsQ+J&{6@0z;XADZ^yKjPYjY;!YO#3#UO_WnG1`n|a zp;4&y^Pp}Ut9!2{37?G(clq$ z%?N{rDC#)*cT)>9k$*ru1mlAk-gV?*CEB)fw(fgN-8(l`GW)@aqP5q+om399px+R$ z7oNP=sip0yRp zgk~>qBvZyd-yhgapwO72Z3v~q!=5Le-0C`jol{S*C#(3>dn3(<{lu#i*-M#q9^Ac!B4vm;g2P-teOOKvmaKU>OG z;oMHSgg{G~$83ya)h_vg%^Jv}7%#9HENGQqJL$cXWJF7&aLf+Taq)mfkv#qj;wYrf zj|Ffv#9?vOTA1iNQo(7L6j|D6UD;3TWq(%P+vcek%jSH!p|R?rBCD&Ww>wS)HwDrt z1H&A2lYp!49z6Ib z%!g0`P@w6TJv~fN0>F6f$`h;3p*}{GID=?@uri#lyy^_>4B&Q-)=zP;8BPMb4Fs;b z=am_!Pk5hm=N_8|hVV#27K9f!B8|}#SuNZAOp^laDzxG^CYt=U>R#Bi-7VGr{v(fO zrx}!HTI^fSVIP*G5-{gb1l+KL-}xLhoYFa^a5P2sJUlR-?;%Z|_iEaTl#~Bh;qXf* zguan(z0Isq*UI^+8O*#)s%0(OWVScj?LJ`tqwetF>i3c@uho42I zMVH3_=N`=s)dNa!IzWtEmHb_fRHqazYdNhY>;{W%8Fr>w*`1B|36uw=FGS6r9QgW! zIA&AG$%YjBr)zAW#9i#mVv#uMwSW>A!^vx_RR&)%dVDgHY0IuMl<7e?B?U?xFXm6V-N@`yTDTid#==p%V?$ndJO!sc^*+L3kgzr=s*aUzBbTbQ3MEEVa zv@J<4$S*!s2FhW~wL7xI#P@k`1N0+?VwBR3&>kogx~L%7vzZIdwev8YO+jmkoowE*Xk0U?W&NM@DSzL3a@2_4Aa4hRe?!DG6kMjbPjb?HUczd z<4+nvW+=_)-wfl%8lxULzq*scQh$u%ui@=L_=llU7L6l}%9tbu z5`)_!<7tS6{jyf4^02jt8w*y*s;Lhd+*MM@8cVovo!r;edj14_ogrIGUmt!;{ObRf z#F^S)%3Yf1N(e}~y&h#JAU8cb4VaT&klxG#=RY5)^*Cw+lOWSZX zNkBv=*&E8LuFg3*Ie2(|bzG5hd-@6Cr%`(PAUL+btNogAeI%3N#+Yk@1iLX{BE@NU znzs9VyS&TO@Or<0S@Hg;bM@aVy#C)QJn?UZyScgAp^Sdgi_uhHlaFiQ1yOhaqe=RjsUR6cm zH=^K-Ur5J8#}wN}A5B%4r1gCUmJ!^(^QE1QGdhEdj>eD0XQ9J~1{4OXRYhgxtbPvd zNlueurFGcm?`~7^_tAzYpl^~8{P>mrAuX7>F-Ye+Qs=_Fj;r%n#v+^Ov)R5XdBp-C zaj1vReV(ASF(!Ln)I~xeLG;Ek`qN45SIB9Vt&=@<{}jZ^6g`bHd?W#W2l+S*@7Xh= zuI+hQWYbPsG?KQcw}E-gKL+OS^e1!NXMx-8idu6QSs35oPGrZ2tPAswrxYy5W_llx z=f=)_@(-77qA{wNl+`dJ#q`Q$WQ&rI4CaLqI7GdX)a07&Pu273*tu+yyQkvKl~OT( zM1f~kAkbu`{7{tu_6CO6ig5DJ`=p zC|v(9h2zQ7hl9mA$&7cg1qGmR3G80U>Y_xfA!q$45FtzhJyd<~>O(*$S3=;#ys*-& zRMbMz6tPUEusC1#D|LLQmEr!r_vmQBNR*}C9^1x-W2aC~d$7{gHn zGtL)g5ymU_q;k3ZT;z?s_8wxo2S1Ghh1B=Qt!uG6&fp2jU?$Z?KS8c(C=3Ly$j}GW{nbLS=`7oc1Z{?viIY}cR--Fd z>7-uU;oxwJ*O74p76asghhKRjr6~KL;#&sSmK!Wk;tAw9rv-Qi23u+f>U5`E6*|9Z0NKC=1`s-Yy?y6)HM~)Kl~!H zXIh%wu`glhgSV2Io}`YSB&mzl+z{||8rWAgyHZ`4oqq7QQ=FN-*WuS6 z>75OBgrot`CRo#&6_DqsPP$z+$m*xufT|Pp$e;{sB14Pq}TCY;b}r+ zYRUm`fr@PAZd4*;Bi#A613@jaI=CIgWA6*^f=5JbrRJbCLPB~_)R}~HI})UnDQnxl z;U_KqnV#lK*d}}FKfQpV=;hVG)`2IjKxzX?=05{*e(oJ^fwzG;OT@~m4|Uv`wXYxD z&HAnEPtPas!jt$~57|lnbd0Dwu7`-J&0j9q&Cc$)LbRfx3P0(@V5zznb7!E+B;}@$ zK2Re_4GE9DotIm^7&&yZHnI=9b1Zj1iccY}T1$=+?IrRyhX2EccLLZyFWM_DB zDed|+|2-kEddZaUpi&@Db#WT(H3w`Q3OEmcozIlkBNZP%kd*o;H}8q*Fz%jgpzOG7 zG>&m{Gqt467C?g;YeE1I;~ubY7ucKQZAI?^E;;?m{Zr=EsE|P&K1S2(f?hYNHzLTY zItcG?g?kYu?zQ{$A+AP-@C0r+#Kt}j$qIoP{Qox<{x9$R|H(7|9~4eT4J8jw z2~`Wp%q1w|5{oEWN1K8O*3-PQod3zCYN7T!ez4S;zg15|=IC8%c3H&V47VBoe`I)q z=RM314)@}}7_Re&;k`hHL+gJ-{0GCie>41PJnc8bZ3JpUT9cf7m;kbD-He5-j3K&;!(0EXu#+IoTbS-MMcm-z z4>|J84?*}sE9iWVpDryOz*v&a1y&9aa$N!#`kwjN`_<3D$^m*YL6>i=VYOS0 zHEj`i)qh``S7~9*g4j@FeDb5767GdUZP!GAwj^QU9(lVqHw0V&dOz|DQmPdF#FnQ_ z9I{r5(l$?Lq}a)d&f-CYt-HCss&~2xaH@~of3cP#t8MdAlIlo%ub^G1Kri-D$q8NL zSDXa2b&V8Opk4C5@V*b}+rjyuA;c*jjHUQ?LB?MP=WZ>nX6G#F$m`-sX}a}-`ChsH`&;%MU4oojOxh;DF#@9KmW>e&Y9YU2XUC^%H(NU0M59@M}7tg$y}Uh|UA zV~E8sD0_bchk+(0mINN0C!;sGx}@?U!SuNB0d9@I2Ifm0NK*3?(xOis^;?V#6%sdN$Aq0b`2`PQqm3zbFcNX}1Q zfu^ado>)M!NPDBS5XNzVSN9c-wF4$|jZUMomi(t#OYh{2=7t4ED zmiULKTO6CzLMQO5Dov`(%;12^h#K zR~1qH(+S{9A+CQ!V;=E|3|!^V5&4EN1OdDYTC9S)Y$I~5;Gr4=tKz%0Ku^vYgEQl2 zKpvbRG|xsSeYC|y54{o8@+JjtA5v_6w#zpN(woQ|N&=b(HsVxQ*&ZC{U;>xtaHJD= z2Cke9mChdX7$f2MCH>Ugop>bP`w#ec&bYJ`&N`xRd+d<3OByOra!&=wiO;a>J(SK8 zoh1SezhZ;u-uBqDAF>MGb1q;Ulq*9({UYIvsqx@9G!;mN_R}-!-leee-M(9vZM9kinTQfJXtod@Mf-1-Qq4D?OI8!%5DRQ66Wz!Ly7n)Ey9>7e1+} zTIzFR=kanXQ&U~!sMEuCK;rO+;R!&7H)vNev7m`rm#BNu96*{TxvK^*LE56Aj573% zCV+XM0tez5Rjtq(5@_ot&F@$qDCcoAytdgCElba|{0>S=@S`|~WR&Pdfec67w@ZHF z{y33is*UiS3Im%&IDn|u;m;ns=3jg445gi_s&@1{QBS(IhHYT#H>{?}%h#-^Cm?CD8{@!C>p?RQ2tK`;tjs3&$(ND^W6|c!9JTtL59YMK*(#7sC zHulX_*57Ciw4I*o38~hm z+w^v74SmD5m?eoa3fEVGOaLk1xlYIq9Pbg5RNa6#pdn@_L-W3+@xd%(XoiCsFa_LW z7p1Y^q<_fhFB~b%KUCQ`!shl6Rk^}Y+_Z~+@WFlwhT1e+3~cYQ3EdEJ4=C98MBKH( z(Z&7(LW47_diQ| z{BId<`2YTSmUFSNFtE2Z(fev{WMyk&Z){=r&ki6HYhwf3|Mb`Y{4OVba#vSK>+^aQ z$&cwXnPQ>#AZD_#5Q(XEkxI^wmn4aS7%34EhRn8Mup`Au7T*}oC8j!P&Zd+nFUfA9 zp(t<3rqqs!y&{Hp39hUz9ekMAP|po63H&&XBJ-5N$;#+-vYbQ&|8!*3v&^}h{(A56 zx@+_LYG>JT-B)u9QkdPh!Z|K$@|R`L z6vh>tke7V~9316(=ISOoCN|_lR{(&2f}_CeDiV{eRRMy&V#vP`Jys42-S zTU|e(shFQRHFcV9XvTb~3(5-Ro$8;B2!$p;`Ofjf%2Ir(4}gLTaVuTnW-LAdSK3R5 zqqaGyph0PoY@y4bT!+%z$)GGRzl20}p^GXpTJLw@!{+T-5ELYtuBF&)Q+>AsS|GgeP<+9qRcvqmYw?!(%GG|0M(q=uYW z4JY!aWIvb}=>m#z#Iu0s6N1;e;0D1F))N8{4Uzu&&2{K4xKrX>6wBX#aH>!s^~~$= zLw2_R_<{v#N8p{N%s2lTt-RUN$jkn=uCB?oSv56$Hb1;PK7FVD#B)V#W^&=^U{cYZ zn!3hJpDPJse=Sf1+KuQREBvp=3m2t=&k!)36P}!DY z$vSb_EBxZhKAWz=JQ%3BHR?yOyfh$>8iilG0pb^$%w?V1SC&g9W;v#hYRFui+^kS1 zt@D0-ZS}R@8QaK;=c-E^-ninE9N+}6*Tt$hJ0tK4q&u5EC2+R=oJLSfd(waYGK#cB z%0ktPUsaQyxdD3_-FoI_L)?Bn6&LpP&Vo%qdHUp&dRUhqimzy+7{78V;yZjfMtl2U6F?NIRdSyMQ+GsSYcDkY&4*<{^Qm z#{@?&JGmPhOETCYLX+J#SEY5q-F89+jE;%Z{4x9T4z7Z4CCr?4u}UE(ffxsdNTn^^ zE8iLi@&(O=o$xufWApvaN9%S2uV+o%aa64q!j?7IaIwo<$X2anBmeM+u5|u3&+S6@ zr}y3+KOrCwo!icAC#iFlcTT8M=iJ9$VdB={Al=cuB;cVfFCPp!7ZUqjKc8B$SpJ~L zvLu@BaAEe2*wDiUU6_)z@SVOeTn=4gF<57N=>?=fo~m|7>dBI>_4Gl~zIsK}lQ=lA zxJOI3uW^?RZ)PCQ`!o!oJT`!Mk*;PQWg_ar2)6UFJaH4SIu;+ZBV)5;E|^$c2|0DP z8Ilr{zp#6URFWVytmB#Aft+5TK46eqew)5*{)rN1Swu&3CiwJuJ^LX%TrnZ1ZFOPW z_R8M=+Nq(IwXQj_el2cIUd~Zn-4y$i^YnO8unZ4u!`hgji>+lf+e@a9%A^ zjkpQBdi6LhB;^q10dqZ4OA}7=O3B3?;>F(4Uz2B+-q!+IgG zM1ZQ8CZ<*;d@al!Qp}rfF;D(AU6UsAiAihKgjqN!^VnI=Vb{2;Wg0aeLg~ov>v>2` zOiwZG7^Y=i4(oFx7n4_7kd!=+aNcGVX;z2}RVN$`-p4|Et}p{^U1s*F~SOFzfafIedM@kmO3aMqj|+ zzpZ=R_|fK}hr_INmn4;?N1k)& zsg_(C^15Kp6=hD9AVTk6bN6%ZwSsWt4ZW(V4_71$3rC=YuSP(^XnH zqLwx8!>8DLG;Uzwi2ALUHLUBROfJT1K3Yp{WKE^cgjw#d$K<5JkUVP7=@d^Yn@;-H z^oR|u!EKiv-2Q43Ta}Fz6$~5~P#O-NvvNOvr|N80vt+oY%J^`njWYY5o8wgNgS;#C zYTTq7_on639E#FhX?JXtwd(egwH&g|4UeUSRE?`SSnstcA8)_=%!<6O=Ei&LFKcsG z)t~m~J)ALCxw1>6lWCXYiqlD1L8BCFN>a9x>m-_x3!ATM2>iuB_zWLjx57ukn-M^hdC66el+ zHi+bIeM9%kbL`vV#0pk)ZSiF+IB=WfO4EKDy;m|a<))9+#!cy7o+^{@E0Mi@E)O!;@*5PEimx(!PG50YhUTb%cnd~i zXLwRf?Vc4~+Bv19m+j68Q<&c8)n|K4Q=pd-C0$$;$}3OOTiaP2AajCrv}21+lxwZV zWq*PAf#IvYxxqNoH?N1ur8H}TWt(E(>Q#6z+x~#VTK-V;vv`t<`=g#$^`wJwil@GlRy25 ze9Vya#h#5XDzY;BWA1Cvry3a?-c52DQ+4;&k@EsU$)}&F#l$5mSm<;;DCS*i%9VwM z5?ezsy*emTcFi{e@3J;ERFph6+?5i%z^53)Rk}^A%1t?KIKV+?h;ej-J)bWFBd6#| z>i#VOsOk)%R`Y`3!G+jPw;-|>{WpHE*w*h`Nve2#E=qmRxiQnaX8bS?TTC?rL7?MfOY`bSYH^C*+yG`U`&j z%=vZ4?xk#NGo6d*HV28j9kO%1j=kS%qAwe)eLu=HqS^P6vr3%f*MXyBy`DilcZ(yx zCcTW6_I@Xy*7CkKoq{7wE~vqSqp(T%MS7CYd1qznfYoCI)Xz?8KY<rRQ`iAS+m7;=T{E~Wl3y$GWUL2jS8?CjDQ`0`pgauovDqWqHuOWRSZI^Cz`q86WJJU8vH>+_BFl+c7 zR-+IeIMSLnkd~&$G@#2e5Od@mLv(pV8h64wo1M*xX=(XPXU$cl9o7XLQhR9EOp)*| zwKXl5oAW{H5i{xLP0GzJ8h)W_o6*f5Thqpl9<>$I%|9q+z3y|e+Ett8VGX~v;samO z(n!Rb16c+Za13yA?XYZiNqkq*nih8SC~LdwOX=q8%FS$t8y9fgs~mGyH`&=N8GV$s zO_jtWO@(aTfhe`@8g;hK&8=xS!1EodfV@Y!nUpKXs(B|@jv8uf{E0-d=J-UuD5e8i zkC%&IrKM7l_Pwlb&ei)gtu*;)eEwV9q0;)=TZ`Vl%`27V6+CnU*JFP0QXWm7deRXr zPld=W@?H}!tDG}5ALB$E3uAg#sV~{OA$EO{eueW{<&^4!0dY*l8!kzYFpH0=}verXn} zw#WRL>3XLIZ1NgM?A~ysvXOYa6g~aYSJa{T%K)RSwc|s(t}ok@JGw@&FWrkjYh!AT z)wp}F)+kX7NN6D2O;sd){;9wY60|Q{oJn_XbYoKv`O>1UVwT6gdiA+BSGGo7juk#( zUGEh6u`)TqBFV};<}$B%pLtEaP+wq;tPpn}r(XRn5uGzN;|apIh5EMFB%h#mub>$= zO+2G()!cmexNV4PJ{oIMlbrA{(aJoQhgaN|&sqRo?^Q$75boPRGfa|rLf85jLrZ1C z=SXY{_3#zO&^6I|J0njBhcSxQCtNdQxR_woY-77MYGX~pA>lqLYv<$C*5cJ0Knjb8 zO8Q_etm_wBbM;r*Bv^@Hw6;e11_^76^vOhie3hKws26#7IgfZBs;0Cm!HB^ftyM2l z*CZs)#N{rL&bZM1)6%qz{(;4!c8fUpC24gy;&g1-4oGRB3=<+UhiccK&f9-m-{#EO z{Y*}g?2;F2h4qe@=~0QtF`%^aYWJP3kJVd9eE;>-GfoeY%k?E4DvyUV4{Z73jp6Tq*$Lwe>hocTA zMPvhthXSd!GzXH!XzyMd+i0-w*rnUF{f#<-4|%#eO_J4<(y_NHtUjK!KPIqIGut9g zJ$BsV*txbVX6KsjwQA|5geS^=$RChP;W@uq^L=0Y5J`Y@e>2Ci^s^21)a550o%iVR z`{Lqdm*vcnbDRCTAM350&8YDAc9|FD!kh;MUGIF7{geY7*zBt{VcCLDmJYhOM!vq0 zBiPf@ZY1PXc5+O@Rg3xJN(~))PmZ@vYv|)T7;lt#T+|8dy?zZBHcl_&w6k!ho;Bw7 zu9c=@Us}qU-J&zzC`NOYojv9sb6yDB9AB_pdqk#J@XB*-e0PQ5Nc`?qln_)S_P6c| z%h~O&&_rARem!9TVYv@;8`YN^tB!1Nd1AJ%mt9Lift|b7J6USqrwFGv1~O9X&Ukh- zcj;KED<7p+IJJdm$=1E*cN8x3ka<(fNQPV~;4FLHJXXG<47-A#KV^GPTH8+kdzPQx zJG}KZa`Eo_YS-70G-A7XB}=m|+_sHr+n%;v1-Tm!5apW-m51+ecEij`HKxem^8;VZut{n+=N-aL(vJV_G~{eXMbi#H#nXUU)RI z)oVV*;4>6tcJe-)t;1Ecrma{9W7_A!X(MzULLK!Rs+ zs9f-Ahy&8al0`pzM)d@M{8N%t&m0^^!>-`Uv&FmYyEYf8@ zVc)|TBIsG1;(Sh*K^H3-Ntlh}6}4ICvl&!Nx1)|wFF5lyu2GGi+OIwxgyadnE;9UScUEtK@TpA)oj>j%c9FZMm?si(BTbkVud zjcOu?*Xreq11z#+CqKUTFH2`i%Oo7#Hd?jMQ|8cjC06xG+BYYU4a?3Yr-D5b8ytzb zUh*8_C|dWCT&x!&+SlWAo_|n;z>Kw0cYD!GRv#j& zHH6f8Oos12XF^5xuGnM}THx5J?ky^j4#*2j^P3wQ$rMr@?G7c#eSRk^F6aL2nsunj z-&;Sep)D=nNbihs{*_y6kqsjrJMejE=?qGn&${w3 zuAd~vjo3H+>v^;HU%QhnG^dpZw?-Y2?fmsZqNa{|MD1vexUZOD5AarVgW4g7<`w5M z^(ZJ?>Xmjr^GwpkqiNFt)yt1Y@4i&n+=!`}5QGO)VF`MfftsID~k4iEUBYKeKH( zaNJG~DA#szUcYC|+v8d)-P>V4(r3--&ePbf3Df%gDA#xL61=ZqwZB_Gc?hFxgGaey zCOH;WV>_Yd&xF7_t}dtMR#shlJa&66tq91>IAp6{TcnFaI7MhrEN~gQ(vyKUlUytA zMQf%g`;eRd&3Xg%xR8zGP8UN~60Q+Z;%#q`P>OVzZ$;?i)>75ew44+7lPdqcpyAs? z!j*1+`ZalLd3YRZ=Dle6)AACb3#oWBWGgVZXm*j6@b%Pl8IX#kq*d3X#ss=jD=B!2zHoUNtbG2U4 zbL{54F9d5rp#q_=0S$V=oqDQe^zD-vP0rOGOtV;HEnh_%VVnpPI)6Zqtj-3s-s=8ASHdsCmZKZ za9iteVm;DovCgZPAf~QON^vqwNCS`BM^m27;-#(nMoP)W*C4nR&`V~dY!|SYS%Naz z2#Z2$`BTcZx3kZq6tYwOtsmosX!kI{nPR)@_&cd;Nvq|l=&d>Ejr`7aooI(9#LL)) zWA+anmE&d{iqn4R@)mUon_Y1=Z1bpF`x+l(Z2^0Enq2G7lLHvZ{G27U$uqzYLff-4)))hpgV1Lo&Q+u{QSV&c#GF8TU2JR4j|wzbTC0 zp#WcLD<>@4hd)V3J3Jih7M&ZSeoGFZB`bl>!sB=)x}0_w(U=u9&UnUeC`K*se+P zRzE{Oeu6zpp%AZfM!sZUHZHBe7)Z-?x;u{3qfR%=K6u-*l;p%>rkpT9&vaX{Y@!`E zdS;Z8xK~>&-(x-cqo4?arIoYojvY&!foIV)KNoggoNh%65o-5P=Z0s@_ui@&lKZ?r zhmB|^?Px`Rx3s!(bfC5=+5w=FMeEgnSNU9{xy1#Cb(FioyvEZEVIp!$&&D*ZXy@H(c7XAIUn zyHPSYBC6f^vF^AlBdJc&3+HRAVHM0sB1v-~nP#=6wL+5zZ{c@usl)?m->0SDzZ;RN zCE?O9X)qI)`*qRHmhpv3;tt1j(Vb>8vQrGWBW~7>+OpAs(3wKCZ8g$RP9F5shz!QF zZoW?s(UvGTEDQ?UtXKzuT`shB?9q!R=BlMzxt!0u%I65&SF(mwje`A(Vv5xY!$#-z zQY_lkIeG6IN93?S4X#isj^ZyKVoM4C-I1aeG9MD;kFBvUo_V!GmC&Y;$iyr3fxq~* zE9YdkY#)pE#!q$G69c!};>i<_CQfu--3U%Nu-MT!m-d~+pE1;Trx=uWq-G}7@$j>h z+~2C`$*98~Yf5kHVGk*nTOX#~Q8+Gt5tFT#6+Zp0t-ni~`+CMs7L>=u+D?44`TC`M z*fm>&fMT~ngzdPC60Y%1qZKVNK4`t0AvJR4{FCx(@1!_G<~Jwo1W?U3UUi7lnl)6a zQ|FeBmREF6NPk*tpIhzO@j6{A+`4-wY3F10aw4+L1gJ1moxs}8SqPTA{Z6mnIwDwk zwtTrqatmPsPvspAzQc{GuD6FF2KIxw*jEOn-$Pv8QPSs-H~Hcy?qhq%8X!QY zJK#*;v3OynM+*n%SNi%Hn4MqC?CDNLHrr0dozr>ipK4=jEd~5cvK4v?CmwL30w%C$ z(7Esri5pKWN1EpKjXe6bh}sQ}I5?d~;d<|YA-Pzv!tX)j7->?=gmKv*`f(*)oy7B~ ziK|;>h_vfS9;|cHs8vP}^W6!yf&DybtnP8&ayYF`9ha7!tPaf8>gtRroJI)+X&qKw z4jQ~IbKv6?!DJxGY9xroh)Ju^!nulO$&sw|iXZ83BvhL9c2#UBymC*p1kQZZ&I^rl z=+0-vZ-mt_a=>Mjk2EyIR}J3uk%oiR_pFkwzlVp})|bKZtZMDcYaAl}Dk7PiQT&t< z_owR3R3`6Uo=F?oyDtb;>WqQ^T4PPSc^J8QkK!^Pd4E-Y%BBMg7+2VI5BBo}((tnH zqFoOKqw0wLrN8zgew3(MR@2T!XdEs+BouCqN!f>-?i-)%D=j{Uc}(Q&|yuqXl1g|!2tNJw- zFp7zM@Ly~3KZ56KRISO{J+jd7Mcp5l!{+DTmoq^wc{ba-1kSV&ZwsTBb=ci%er)uW zpjaDP>7TY<<>mSv+J5W|>@ls{+L?BWe5)5_pNtFKX`T0e)oe*IVu$H7!uoE0#1g7C zGxZC_l-#~2!NE3sRA@d7w1AZ)&m$Gb!>e(5bBBH5R8?7EbK-6^d+C?&1bjz`U@I-9e!jpIB0@#nHUZrd{pAY*^Fdz9+~!8B}?j zOu1q=F&vbV=$v4WecgS&c}M%>*AB3V;D-uVNpvhSET#sh-VgYBgk+?dLJWVNG^ZOV%!!zxco&&)~$V=r0Cg?3rQL$M-HEp0Jeu1#tQRiaEwr_dub<-=(s(eg;h zvOxV1L6P>B%}>qLWve|TNFvjtjMRdk#4@bL`cfH~4&h*<)V0j?8ND|sJR=(Q4=U3x zxLZ$`VW&NER(#WHdg!C-zEzVp^87tw(dMXel)!B<;xYEA&6uaqtV^`tHM+}h45dms zaA7sD!hBjGqIRMf^Q|d=Vr(OR5gipBDQ~vwj9oqZ^(a~6a0is_q&9P&InOCR#YVl~ zKxWlie@Ab-uPwDRjQ!MWoHD4Zh%{wkmi-9Dqr7PYbv$)>Bh=#^bf+hnCKbs;v1=TPQHjwLJ3mPXJ~>)(w_F7az|R*fGopnDrwnYpxcYn8PY<9}90 zcsku4cTCa6tsRL`vN*WJ6^$w4<=${FJv1m%7KTakSicjB42%imiu*XODmH?;_&cFA z43ymS4*uMFQdxIqdri1INNG2b77Tc4;ym{H4kgT^2w`7h@mtx}c&yW{*Y!SGwB&dG z*Q6j!3gr*hd3)2e(G_cb*L%ms(c0!!9XP9@;p=dl2-ZjjMsmB*&H7un-c{mo3A`2I zkXH{iyI90+$RC_8dT}c0l8dg(gf#_}e6S>q>XI@d%V*)<1yn{w-rC5O$ApZX`hp>> z&lS!^D`n9Epl%kEhf0aGVXbaF*F{glehE+A=w+gmDr)Io{K#1zOu1gU`%bVcXxqRp z!L*eWx)NpvxQg1>Y~Dn4#WCKDk_kVmD^=_R;RM&UNy#7|yl4za+|ebNH|Zi^ZRL17 z8XQeqf2Ifv%%##rV@7#aZLy>;oQ35D9%R(>k6@TXEj+3x`OoMMJ44{ZK~? z%ZZ~pKF2n5M2Y{tV1(v?rKu?#Cr@C%7kkt})(8{6uB;U;RT}?Ws$S*%v?0Rwm!aX3 z4Hk_d=Gx)S-KlG4HrXPnD&(=WRjbBB(LV3xl6|vJZAkNr@I`CqHgtU zX14hi3TY8el6V=3D>kba2x98nx>GB=h)U>n#cd+KOdnF|jy=!`?~LnihvH{Y;O`r&i#Mv%WhzRG)Oy;^@8ZMh6+9}h zb3Z5Kk(8(5Y&O5~5+j=JNffqkIV3lp=FSgeMvtlfxY@kd&|0d>y)Cv&sM8(Y5k#tc z=Y})Zmudp;6)SHuJow zzr08i1b?{KY^Tt^n}@EgDiG6=U{kO!w*T&RUdl2;r&$yJ^Ea)b{tO;<#D)``!!LEA zR$E<5$qOUvb?Kj zbJ-I@64BYdLAII(Xjv7>aq8P^GTIvn_Vyf+c7dRDtgqv($-K{!cUo`okFaViUS-3CM@z(1 zrVW>#Wi#JVb*G!O^?Hsv*^+T9KIoUJ``9oGT6GZTU9UZP#(3O!Zv?$R6n%x`t-th0 zyPR<_qn1n}{+P}0Z|%FQoK>A z0WKBd9zUt|ctaDrknz4FW!mXO-X=KyWg>@?nNV+-$1M+AEsS@7xr{EqupHBeZ|9C5 z7N6VXLH8&pCC6vq7hns#T!cKwoVY%LL$VvUd0VGZ7CmzaLNmLFujp|MB3pT#t1%RU zyN~6nidL=Z)uJmHlvI8l4nA6m1zY{(a(0flqg|64{5+P^u@yQ_1=CYfk$2;W^QLM3 z##Lf#!uEQN4PI6T)JvhGDSh1*=T%JRQl0*L=1Al$jyacg&_6QgS9#J{3Am_H&jPz` z_40v3a9;BARAMmtbb_*r+wU~D9)DvP%&k@sc@!I1!)ngM)c_3-KZc#dl^|~nL%qt+R1b8{$?tJM~Lw0r)tjcn`U!OC)|%b zP~my;qVJsO8PSOjF&r7Tiy!?&v(S5qk`7eQYT!4I7G8QbxUJ-yKsb)2yW}{pBP$Nh zx9>kWQSGOi_wVCr+q}ol8eUJa@Rpj&3$xc*q+CMh!`_HE*?*bS|Ge0*Wr0i8B1Q$@ zy&!D*nM3o3AK92a#!@|c!9g8z!OnX z5g#WqqESyVDmcdDji5S(X2ktLz{_n|eX$I*Dhr)_k`^cU^?=h}nZoc>MR8qf+DglG z!J)z|5_Z&>iiI^!6r91lTSEsUO%0OMh?P#s=0#FjT(m%gAl8v^2s{N$F|_K{(;#ge zyIAwH!nj*pV`5aZ^-3qZs_HRYyHP<|T@{!`k{NhN3~lMiIDd(|3&VZASHv%iAHl>f zjEig=>Ed3FxNqD!pdU}76pG`BmeVSL0?rq;UCApO<}OvJ&Zf8G^!JsWV8q$#D7iB2`>~}q zw^wsep-v|0vHN!5g;TRt^8&@A4C*U~_vO%a$TEdr6t8k@h?+{A%G50Vmd1!oiGMPuN&;jwvQ$>rNG1$W-YvZR+%0`@zH!O}7*9+nXusHAzLdfU2C# z|pU3)K<(M7R+n$T}CUQ+xk zA9+-Jtc4G5(HkbCC#TRZ#;7Ctfuyr{d)nIs`q4fV2}gYsWhv`~a3G-^7!t zv*~CV^|dbphW&+Mb0y-Gv7dQ=FRe`g8tXsM2aUt5%MUH!U=G9eC++qQPc2my?YPdf9=h4zFssX018?DKI0BiORzDe< zot8K>N)T(Go4Wqav+JD4b2aCjtfD=-DQT79?1WgQex0|k3nytZ4(MZ2am}XCc<(KN zDE^HgY;jCGX(LSQS>NQ)7gD;`#J??%o-EG*#?r7YoL(_^0SDmiG$Qdzv9;)13j%>M0`B(u}DyIv-h2 zi*Zv!4HaFudZBpNvg4XMCMOHx!8EO42GM%$mYW^YH zrV~ZUqoVXQwqa8pF1--8q3JY+cu49?C9CYEv-iW@@R+b6N4-F+Os5_BTy~k4ifx*{ z?Mh@3aFO&LBwp7%u$fCut>}sKc)(FyrMcz`75HuaCVv|oOm(bIn-}s9nagP`zi6Z3 zb411O;>`gs$o<_SW6RXBL=h5eZ(`TWJhP|@j>HCyX zdRii_x9pU|pI8$Kj>cx*kZrPz|-f^8=6V;0+%UzA1 z?n>J|Re|v1&zO%o?Y2XMa`c<=(e8-5JLm!@vsnXrnWUqU3eCM;eTB3Oj(vh<GU5rm%0S?YBOVDCz~``={bmY!Bc))A`W_^)_V$i3XWS!j&-rQK*)jN&so zd<$+S7p4+h!a8M`x+kIl-x5j%5QrgCOgcXdeLH<@$|!a`=Pf%wC8sV3BZH`d%;h6@oQa=2HPpLu7au>+G-+7Wct#ew)+q&5dtecrc?GpxrX*vins3a#pq z-!fY;G;%~hs1Nq)*9v?K0%84$bye-YDRwFJEcrLBArj86ji=sOgM!H0A{BJ7f1(g7 zcC#7Snu;#L3XFMRPgIBmcrNY*;bW?fef{)=P|Gp!cnB&G8A5jqspR*jtQVM7UWFk` zF3U8KsrL4c1=!_wNn6*W4*``Qi0_8MSGj-!z=mWeqEP4S}kMPB`SbdM2yzUYj%@Cml!?n zE+!wjD-SmRC_mxG!1Q8%Bcr=^=*z{-x;ysi>r_a_^XEt`u@eNP2XQlQv;-g&6*z zD14!K^`13AO!-R+y7$E8)Ee-BW)+nCP89l6V0#7$fTL118MRw1a+faI)v zX`csJO1kbIgewUa@O0-n02M3?ptFGNPHzR+I55cRBOrp08UnE9(fME=LJspx2b`ZA zV=q0%jL)B}v%Y)3yqw`e4ARhaT_z4xUF_8ff9P8VpJ)LJYlpjCADdnp_ZpchDF#9o zaYBRb4*VN5=>01#28!0p8b3wrR@#&gBN0MoCn6m^$cP#t4#;zFXoSN-8U_oEA?-+` zG9EwSqpuKLFhMHn1WpYtnAL5&?gt5k-&=-zp(>Er8Lqm(WI~Ro_K^Inh>rO(W#DG$ z?QEb7L1{{}AS)0a))=0`dm}xFbF`v4?Kq5KDrMyU!mFAt|43C8)FFH;1^!VAHArzc_7yam z48zN2&WBSF^T)K8$D)Xwt~2l>C~SmIjJfj8AQ@0u{2M*K({d#Ni3RZTOb;NxhOQ>U zE=*HQ&91IVek!C`l(ihNmA`OlwY9{w_ic3i^piXFmy!q^KeQG^NLJE!Dej5l z$OxqnF|#%;&^e&RF@z20*kpw7NhQ7MqED|YIMufFR6 zkp7;!XU7M%lNEt>jRSgG*PWN}U)dT2OR;KG0V~*$^$dP2SwGn61!&S^E8wl?rw=>@ z3`=1`DBh=yo*7v8HgDmel+~_ho}$X?V&Rqe`reAFT%aN+?^Nc+{5ug2tsrv>SA0r4WQGFo)(DXS6F)xhQ~q#h}pQ$+p;ql#s@~+ z4YH@5j0YH=ae+%KBQ!wudH2nqkauxkUWcFLK~F%@zR11;b=xbs6O6EG^-yu7$(Iz2 z30qH*vDI38NuJ3UzPWmE0S+Y}M5HJ7b>iXKSCm$)st{q$({tNB0uU zz$(6*!jIAYLK+yEm6;wE*%&xjwMAdKZsbYl4JM)&6;`me1{}-m7KH@9e2hy5HD)o< zKv&&GG#1n)6322a0b9!9bLZ$PETxolHsl6?DZE&|=3^bwQ*Vg(KlgqQ2IX*GuP z#|h|nuf7@nDFa1_oq%gYT+ux{m!41I(CpZ38go!`uFGXe-h_)pQcPg)g(B3ImG1Y) z)Xhpn1aciMs#6f}0Ry-m76fQYV}IYfZYnsX3JSn$#xjy`rZdHv0&SazGaqdq=STz} z0^`uV()b^xe2>PeZ?QPD(RkwZ32UiLJKHSVVGgd z2vhc&$Pw6l(riOwY*gW9t7o~*?(T0YfIZf+DO5%MfGz-g;37TMfnvMM!60ZD`4~z^*~}+`2GtMwRD~-!*|?dnfX$MzQJ=ro zsYQ}*EnxHxhRqb>97fx0MhE(0#te{u6G3{qqLJhf!1KO;HrsupY~ZztNr@(nQd0-$ zP0z3e72M4?Gk80zc$y@70Trf(DE86apK=!WefnC|kLek%usntsmPJ5hwpl5U-c6Sb zBKC46;&NXX>&V5B(fPFmBf__aemi;AN^VsQ$V3JyIA@LC2_=sMR6)D*6v?!(P8_kL zsXP5wzIasDDeq$9W^cxAi9HYdW==ew&+wb$LI)S<%EKO2K3GaNcU~|Zj^epn4 zpF*(aBKEjC^7cI@GH^p_s!s)gK(};-hBo`OchXi~PxI-yyNeL2RKG~ow$PA}5 zk}A}LvN%S>nmw|$Zrc5xnN(MY^m&-Jo}w64e1p*H5FAjm*Gg_5PFV$Xf&TffrKm$N zl6XBLtnCk;5YN^^zA%$j(u1rB>PL|1K~?&Pz&DE~uKtLAn$H$0-$9008IdaPGF?jl>(9-#2esk=JJ6Mkqe+LTM}5? zZ_ap=oy#&N7Cn4fo>vmm!YyF>_ZHZf6uC)|%b}eVd+40w@+Xl`6wP(#36vVypJp$@t`M2qpLS!zi?K}v zHx|M_j7CjV=ld$U%!I!Qqn!){00D(eaVfnIYvH=9JX8ZTPeH2Cf{d9ZJ-LC1918&v zNDS$Utec%+uLoD}+Mfodjpp!V-aoB7@^M%oU2J9AQEtlw%ERjuOY){trcTH4*ExPj z#7#eT^0~t7R3y@Vk^nLoe9WeTd2^hr(`x%J#BXg#$lz&`RW-F}k z>XdK9i4&s6e^{-QUB#YsAKQLynziRLc86V$CD+>!n>YQ6X-)9@POjcppJ@-F0n}lqMWL_wr^p8pI4oMOzvjjWzG|Nj zvxj_6f+veq3V3ib>73VGwgz;2#bk{=Z;MF7e_JVc{MiIwbF`BdfPBr5fXlzK`6ldz zY=^fuzwf3JkW!r%!L{$9>KAValMUaa_(wTbV)Rn`9bkF9J^4dTzb~v}=P-J47>OdJ zd;SOB6mb1H=9pUX=S>P=yghcZZM4Yl$%3G=aOcL)OR^b5QpI20{rJskq=xh->yf)3 zzvZ4d^<}^rIA=Wb0{6t|04V!~lDZ8H9Hb*taP7MxWdJ>Oinjyj`%e?%#z=1PW-!7Y z_d70BE=D^mpMooCt%*_%wCC!4cab~{2Kia)afz$QJmT+H}hbmk#1lSzwpq=lp0KpXxu6-JhA751|r5Yp)t@K|m)fJLtP@lI#ow=st0~ zpA~#ll0js5TWXyEz8;Wh!njP^`=-P6oe#?xGQUy}y@m z9NtaDo4dF={2Ig=?By4OldnY? zQvy|e6O6-^d#~eSW4uq2^fU3)neb;8;soTDEPBv-5v#oN0V%O*vmVs`!~6$nne>-} zLp~q-Z`?L9bw%>T!w>%{~2Rh*9F9H+l+KYz(m`Fo`yph)~1S&FPr3i%HW5l?EC3(Df zWiDVRw9|m-Fa;IFyO|||s0BHwS_nd2gA(sO<7OzMn+g-4q-4 z20ZxNGKkY(USNT82ihrA#>>xovKDBLnFPaF^LO{F^q}u%9;}Z36oVFIFvhoq1$5^C zzH2!3SQ%KP87!0_!7H!cj4?t`YQ)aek1ZNRcp;9T+xoi=Pym-BF#I8Ul;#T-yu(s=O)Q|&pCopuj*0_!7=KxT=~g#ft=|k zkpcF#XLj-i);Tl?L6CS)4Z^ZPkm;4cEW8o@C{l~*Cyfwv@`Gmxq5)a%jW*EWZLA^P zKToU2-td2P<{!tVH=mmiHIa!kLCUFJ-{X@;2HV$2G+ zJS>FY1kFO-g7ZqbbPkw#Mx*?xIbmm=&X0KKgHp2TD=H#|JU8iBhN`|YYc9q65S{UY zU(j`nu?$x5m?7FW19>(@^~wfu-NLhE8xxOQ&mv%x4Utn$@eGAb@^XCI2qD_tkv#dZ9Gla|LDpp zg+XR-m9C=RmfjNySohJUU(Uer5r-#!9=@f!WOpbCI6# zO)iex4q#<=88{$Smv2Soe9R%Y-4LOV0FWP-9&4S|f$x^eEG#KDVdmI%b1?D5P_86b zugFj503KC4?-L;~D-T7Z3BB`oFM{bqUst>-t=0!!d{zNXP+ztY?+1v{n{vU`#SieC z=U+Fkl%hF+Vh(5aQFM&}mwUojGU{DQfiu#wpbHb2=YVY9l}4l(vF?&qla$-o$^l*b zqd~2rXAWZb8d%6+h!%PTJb_t^%p5LW$lgrQTf%$YN-x(RnMFe5{!&u2Ensh4xVu*KokUP@$LBuyiavv!Vb4^G)_L@U*wojU0D|{U|127z`njkZD&%y`%uS-Nm|Xo z6VZ%ox!r|fA$Z^wb%13$**y3ZV11=0a}dm7V9(md-x6s0bS^*djOC`#aS1T$B=fGs z8in*K!3O$-{qDEUz`>Bnmi1x|JWBdy$B>--&(<|4L&=2qabE$i8?V)|8i3>UG;&n=lFnyiiyRX&DR)$J#3KZ%uZLs?Vk;CNKu^xRX0CV$|zKSJr2)welf zSCsu{)HZUyS}UUMXNH@V+9BXpK|Um?6Kq#l?YaV|K=y`t{f8Lusg}wd4JW7O>x@i@AO}`X6IRm;z7L#f445mkcG#O4pJfqudK@5a16-McM8~ zS|l2)#BDr=i*GKXG7%_xLkp(hsb=J|p!f8+ll^!Kz?%miQveg+A^Ho@<*=GxpUq-FS|?YxJ5R|;T~pOE}w9>*+nIn^NNfwXEp$nlL26LN#H zz%$dR(I@cB0eNEv_-jbfKCZ?Pn=Pk@-`|6OMw`|ERvsq9Y+vuU7&rjHvl2=Vyv5Xs zLNpQhGY772#Fncvyjt>J+|fsEdY@JrrepZlwOYXGq{Em_&DRE0LcqKM&yRIM%7tpg zP8dMP$UOkJaXy2qN|YBdRvfQ|P4S z1mW8;gNS#l5(yRdaWp@;to=ebA&==is0$Q#kg}4Pes=+QdgK&FCsT=$QC1Z#3%QK; z>$52@?*t>NDp0X`zJYApImLiDG;cT>13ZaSVGi6cB9Nsem$; zSl;(7>YMJ#4|2h9^-)RWPxNEr3uOXaf-4}p^eZ42Rw+g>&?{~ixt=DC-KvTwvQH+8 zow82WI!G9?!FEbTyGMU?SJxhB&l;}DGAYkq# z08pO43V{ug(LOR5E7LFoNLMheLhO3jJh~j9twrs-sN9M+eWfC@$u!rshZ$NuXM0|& z+?!O-2bB<;7IS-9z1noZ5q%{LOCwNiQ5o1GYgrB|{UD08QQ|hhgyiLOm;~Odbr|fF zcD@SX@4Pga0Z;VYd*ton$0Fr?&QXNY9-_A)x~#{PdlH_^76I50I-sQN3c5B2ysH;{ z_&;Wm#UvM>@S-b0tX6^75Db9>zAI<))bU`Mgj_$N0SF3bUzhiN(jrWOyztJi0oiyV z6qNw$n(DwFB1l7@2TnH#XLoWlcKgnKDkR^4Wu~DwL9SQx-7cFb59oUH`E&~SdUOt2 zm~o3usdDrr53F$>B3*a@`Fr>izfbxz`}-L0qWNqQJckNS$vkyMubvqo*Al_97z?C4 z2?C&+L71qoEisAnZK-ksiXv$ax9WFJ!aQGi=aMGH1fMn*taWp;732Sc-D;(|%%m7o zQkw&xMZc=?ZR`%Wy#Vdqrl|Go6u>&Ulf9lH4Zw%S?Mb(Vwl6@*B^X#90BwZ*DahH3 z+(;O6l|E4$vF)F=0gONlL=;AuOgy~z62iglFXi8Dgks8P>F*-SoopziXsvy$z4A*P z7AlzwXB#cT1Dp(<%vL8&PP?n~B_Rm|9;O2iEw3)S0CYq^S`sfmr?jART|iA+8aV$B zoCzo|foGV()5!z|-;RE$yRjCaIJ>;iB)i-)J3@hRN+E7hVeMlO0Avb%pAeb~kQ@(3 z57gw@42{nTMh=V|+Db6Kq9(WjQJx4$*IxPJLjmCFcfyrv>?!n+F2+|-n^Qlp$Ap}EjW-q5BvC)~)o1b9!f zioGQh@S7ljLVHEkVAeO?GHqb~uN|a0?1*u#T(0nDq?jP<)nT`!&cMqdB$qCI8r&2* zbvEYbuSGexUU4ixP&P=2%!N6Q*m_I#A=n!7PYJ{TgPkOe+*Lo<353=(N}S8BAwk>} z_+t>L_3hrpg}It5$)TSgHlQQ$#hgg8OZ6=ni%knQgvEVEUpPX^9bok?HJaEJB3p1V z-gE*n40)J0M!}+P9n5-84%^;|4diSeKQ?|B9h_bG4YUqz{v^k<5S4W)Ll?m{{o!Em z^!5wq_>H|cVztr#ge)r97W;8>fo%!_&^#z(BfZ_rX%&L z$2HK=JrwvuF3?3W+p9b#`2A)@A=LwwDNk;Gb>(@jC&2(&(lW_a4*7YeBX+~BuN;0h zJa8884)am3I>507=lxNc2H^SU_krSsR`s>eg`rOMgIf^Rh(}4l6hvoe(S=)e_+x=?@dtjUITgPR!{wttLq|O-n-}9VsVJq{U z;{@bRv3i()dvTtob^b&^t|u&C=zJtD!``?~KR0R#eCEd- zdgKA@S%&|;x2I^N#Mg@4PgF&8{;@h!ASDQv=A{k67(!64&TS#KIT85s4rV3+_FX3d zYmV9AEb#V7!qph|O@@Yo2|NBQN-qvQU5u2pBFYkI~hz7ZUjN zeC)v!`%7J5>kznArhWY9`0|t5?a3+SF=f$E?p>g8UWe65(EZi?ZI@o!IoBDe{4aMH zzt16O$k}{e=k5@^pI%7ZgKxEdvIOsXi{xF2*+kz|2Xsv$qZQT)!X5zYvv3#SZ>gH~ zjPn!~qiw0ZVN>u9$zZ5`oKuZDj<@tKJCI|+O_vt}YqQ~>CNOO56|17|p_4cJY?6c} zlLA&mjU%&4$z-X)zW~xKOm^?|sU4)k;VPDcw~~u>C}8y%!2OmT$AHJ{Y@iug zpB4L+ey2jzwbKzNCUM~Ea{2BJ&c6xG~$Rw3gXii}@5F@G!sc-)o zkq$Nh-T5uH2-6I=0h$TbJ5FLEFm6eiYt(bL+v0bu2QDzJ8411^Xt0Tc)rhO2HK}`s zhdVEV;fB6?Pv3P5`~FhB7I&45DsPi0VYJ<%L%*&ijHZv#CLQ(+ZtbXq;D&$OXg--` zn=tD*$430|l#D_06Nxf)T_CX9Hy4u-nQ2_u4`jrY7=I8zh%BgiES;-CPg{C~hBXkp zN!X)1w&67=^hY`Vm>|e)U$52L$hKMAvrv5XXk2zEI+frM;_+^{(J-(#D7)8KX)0^Z3`!blC52hiPk=kglp9bQfn z7z7Fc00IJF&-%>s^_aDA7jP<}_0>!?n#D^46YVu_M?AQu-NN`aY8S4hBF@5)cRl z_}}PyzUcl41N}LD9gzR_=j)6J0O0%Q&3}^rpJLr#VzcU9&AEU80PkP2D1U1H>-Z}0 z<^KBbKgFc^WyD2<6~B^xd~Hwmzlr}K{1NyMVvv7H|2h33CjBZlu(6{1I|=B&NNE4N zgtL)>qmBLF3c~+IF#WHB2F50TD~$XX;jRB$*u=>CZvlw@0zd}*Z;Jl=W&dIS10ZDY zENJg$>u94RWu`Ca{I`HKe*yIVXMk2_CiZ%cW;TC+t#p5Z-u!3KHcpPVPL9TAmPQVL zd)*v=0T=i(fImI{-!#Pk32tuWXke-5;PBt@F#Lt5>YwpAIO)sT+ZY%*IM~?#y&ANC zfky@XM`}3hS(+LC_wE1vFW4^sW9%Nf`e^ zA_ew8Z6pgLx4*^z<8l7&_~Sil{>S)MPL_^lwtDuCX8-M&_^T>J;Qv!qteyYftug(F zCjWATVgF-%Cr7it@9@7G?A1RbaIvwsaIn?;8W8_iKRBzpCxL#As(T0k0RI2H_&;$# z;j82yjA?#L6B}`BV;ix5S&}{Rf4ryt*XaKLh5*MV_fU6O004b5006eX(2coYj}0Ib|6>|qOCu{IYe#Xz|A#Ji9eRsxUzo37`uw%EuBiVJiKvnF-?x?# zLmLpnSAY0^nX}MeS_|nb6#fHK{$luYxQ<4Kf=&*OHdab*wnh#@dX9PuMz;U81z>nE z&m4V4Le3fh0It61{h4rnMHX!>=Nv12=i$$?48 zLliJi6c8O|{e#Hwj>7x;LV05e3oT#n5sb{1z$PIF1l#{cN82Qg*mwony9zVK5okw> zy+Mz;IX3u;gZdAG{1<= zQms+1Q<;=pHEXvh9lqtmR-K~}2mXVa%27shN0K=u5PrNy70qT%WV3h@c;lx-S3bj& z^?*wtB;9|;BPi$YkCtlV=^`GfSkrPH+;uRTcT&Rx&kDwM>N+J^+3^{c9M8qt1lCB0 zzrV2fX(2?u1S3x-#7_9$8+fV)cv+;p`pezVac)N-P(%|flCF5ff^3N+B*97CH+UI%`Sp#NDyr}=Y_+ZX8rd|pF(;ZeDCtHms=2q#6R%iQ0>fU7dvq>4tj^w_a*FHNC6T)89C@j!WQ28etLB5x3CXgb9^ zB1t+G>oJW{XSYRHp`{EN&M;F68nqc>X`uE}z~?4njHW{{Q|DorX?AOw7L8y3dOMUc zyEns3BA7%Kh-bq2W3(w>qgEo^pdw`TtQJEgx^t*MUne_#3jJ&!R?FWC|B8{&ljA6@++?wD^$ARW>DA#vfc$y0Df_rV`hZE9dRJ)Ah@TMFEu zgwA1U`ijPLp@spt+9YkU^Bb`o5_Q__6jtx~*&ID^**EKuC5k|VR7B|ou_Th%yd*`w z9A^W)p}`R@`3hX4uIR^~pnE@Lssh3oXD<1igFGcUR;Opx*;;$d;IbN6ns|JrVCu&1 z#T_v1!4NftpqEzTYkG7~2{^I7vH%7$!&At_ns-ku15~3PCf2K?T8t>iWTYBpB1-T2 zAMUJVJ{F7aaln!VoNQbNtN}Qzr0A=gH1?zhH{0ta?%LaOSD6aetD$sM(5?%pA=V)lkmuk* zsMj3aDWL4l=T&QA1Ao|nEMSs{dkM}}l^!dh5qny-4Lp*;Lr$CseYj6}xKl)0+sl7H zjfB-5-asa-^%0^8MC(z;>c`KRiJWDSs@!pCyz;o}FW~S45*8Vh>PCs?V7;5RgX^?> z=~Di~?(lM;_rW|!OPJu<7$2f171|g{6dI*TW7#E<Q(IAN(P7#fb(P6UL?k=db z_-s z$^XEL#!fazX>`h5XU)^muROmOTLtvCKu;phLPm~gbQyQ`;x<6_Kd-%z0O%T|E3$6c znkyO_&6G1TpS%4YwR#b^w8*XIjgE)>Ms0S+;W=9dr?Wx%=jS&LsH(K0f ztS-`^Gpiwc8BQXZwgcyhVIbA2jleXqiL5r;(mmBL8}fODVsm;`GY}ZwfWY9leM^8R z4(&Enk39~ztb!d#4OG12TLL_HzHeRGqxuoj=OYl3SA8>yOY=H;?DnGh0cp`_N7EP+`3C7GIt;B4t7wWf8l;ae+lj#$mG-LV==G@{?Y6V zQ??|}ZSraT(L3$8K;oltbTZBktq=*#?QX*1+zDN{Z$^Tm9m5n4alL3ssT7Iq0cvb% z$%x4~Su>FEG6)L~suqgsvLzg&G%1nftUJS)S2+~Gcg)I^elc8+I2HyV$poH%ab$R6 zuEDRzuiZf=p@C)&eE;Ie@WkH<1zpvFAQRg_GfFHQ2}{DBn`sz59{r=TeZV2C!*FY* z(+HpOzxu++(5aMOY}JU{F<*fIMYfZvcfF)yT_4dTajWkRH#TXF>O5AG!zyzf{!Hig zD6*Y&CD*j|cO8*;edHxK9PC7t@whQ|N22}Cm+x|m-~Pd_iF;^^CITIYTg|U;AS?6ylniyMW`lh}>|d>L}NgtU-Q?CxAz!hyqTty~7gEYV!Ful&d}(xabs6 ze+OzDfqEd#BUGn1Wvugj`%VD=W#fjjz0!YU5OEH-8Dtsy7(KBEI(7neo|f7rrki$_ zY-RdE9HS68RTLqsEK4YCjP->VIjc9Tl{|NKA^WzT=N4YH2wIT@-keRTK^lkb=>x~c{H$7`~ zX+MNPJvukCo_{u1Fs>Dd>tN(MJvJwz3L_0z0Hh;_8-wRxLoMH^m|+wtPqT4KNXyybi5&>CxyO+dBg@-lysdZr-kB4tzjTWYs#a8 zwcfG%Hm*yVrSMfbp~zd`3I((4(fZC77jlB*q#Sk%wsCl*J$~r%ut40K{Y~N;^YrI@ zK!7fFQ2OG5!H~KH0fCHpO>PJUZE$7GwWM@d`PxNC7Q?FNP&1P2?jPP13Tt;HI#lcJ z6CP#{2F!Zb9ly1;qM@QpYK@APybim(P#xY-qOHn9H*HuJ{}FK2#imUz|lj{R;7nI}M&eu*tx#Su|@78yprE zYMgC!e(q;3X2BV+|Ka3n721@Usc?D2{PBd#sR#Q7MuenwU_Se)1JlR$35z&UwvR|K z*VAbcpfm7)mS#?^#4mhdKqwyR%po)7dE({+<Nv a!v574vT@B2F%Ycq&k CRYPTO_30_LIBCV_UINT16_MAX) +#define Crypto_30_LibCv_IsIOMask(value, mask) (((value) & (mask)) == (mask)) + +#define CRYPTO_30_LIBCV_IOMASK_EMPTY CRYPTO_30_LIBCV_REDIRECTION_MASK_NOT_USED + +#ifdef CRYPTO_REDIRECT_CONFIG_PRIMARY_INPUT /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT CRYPTO_REDIRECT_CONFIG_PRIMARY_INPUT +#else +# define CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT (0x01u) +#endif +#define CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT_INV (0xFEu) + +#ifdef CRYPTO_REDIRECT_CONFIG_SECONDARY_INPUT /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT CRYPTO_REDIRECT_CONFIG_SECONDARY_INPUT +#else +# define CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT (0x02u) +#endif + +#ifdef CRYPTO_REDIRECT_CONFIG_TERTIARY_INPUT /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_30_LIBCV_IOMASK_TERTIARY_INPUT CRYPTO_REDIRECT_CONFIG_TERTIARY_INPUT +#else +# define CRYPTO_30_LIBCV_IOMASK_TERTIARY_INPUT (0x04u) +#endif + +#ifdef CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT +#else +# define CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT (0x10u) +#endif + +#ifdef CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_30_LIBCV_IOMASK_SECONDARY_OUTPUT CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT +#else +# define CRYPTO_30_LIBCV_IOMASK_SECONDARY_OUTPUT (0x20u) +#endif + +#define CRYPTO_30_LIBCV_IOMASK_VERIFY_OUTPUT (0x40u) + +#define CRYPTO_30_LIBCV_OBJECTID_LENGTH (0x04u) +#define CRYPTO_30_LIBCV_ADDITIONAL_INFO_LENGTH (0x04u) +#define CRYPTO_30_LIBCV_WORKSPACE_SETTINGS_LENGTH (CRYPTO_30_LIBCV_OBJECTID_LENGTH + CRYPTO_30_LIBCV_ADDITIONAL_INFO_LENGTH) + +/* for each driver object --------------------------- */ + +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_VAR_ZERO_INIT_8BIT +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) +/*! Initialization state of the module */ +VAR(uint8, CRYPTO_30_LIBCV_VAR_ZERO_INIT) Crypto_30_LibCv_ModuleInitialized = CRYPTO_30_LIBCV_UNINIT; +#endif + +#define CRYPTO_30_LIBCV_STOP_SEC_VAR_ZERO_INIT_8BIT +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#define CRYPTO_30_LIBCV_START_SEC_CONST_8BIT +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) || (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_IOServiceMaskUpdate[CRYPTO_KEYUNWRAP + 1u] = { /* PRQA S 3218 */ /* MD_CRYPTO_30_LIBCV_8.7 */ + /* 0x00 CRYPTO_HASH */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x01 CRYPTO_MACGENERATE */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x02 CRYPTO_MACVERIFY */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x03 CRYPTO_ENCRYPT */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT | CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + /* 0x04 CRYPTO_DECRYPT */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT | CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + /* 0x05 CRYPTO_AEADENCRYPT */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT | CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT | CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + /* 0x06 CRYPTO_AEADDECRYPT */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT | CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT | CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + /* 0x07 CRYPTO_SIGNATUREGENERATE */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x08 CRYPTO_SIGNATUREVERIFY */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x09 CRYPTO_SECCOUNTERINCREMENT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0A CRYPTO_SECCOUNTERREAD */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0B CRYPTO_RANDOMGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0C CRYPTO_RANDOMSEED */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0D CRYPTO_KEYGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0E CRYPTO_KEYDERIVE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0F CRYPTO_KEYEXCHANGECALCPUBVAL */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x10 CRYPTO_KEYEXCHANGECALCSECRET */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x11 CRYPTO_CERTIFICATEPARSE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x12 CRYPTO_CERTIFICATEVERIFY */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x13 CRYPTO_KEYSETVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x14 CRYPTO_KEYSETINVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x15 CRYPTO_CUSTOM_SERVICE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x16 CRYPTO_KEYWRAP */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x17 CRYPTO_KEYUNWRAP */ CRYPTO_30_LIBCV_IOMASK_EMPTY +}; +#endif + +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) +/*! + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_IOServiceMaskUpdateOptional[CRYPTO_KEYUNWRAP + 1u] = { /* PRQA S 3218 */ /* MD_CRYPTO_30_LIBCV_8.7 */ + /* 0x00 CRYPTO_HASH */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x01 CRYPTO_MACGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x02 CRYPTO_MACVERIFY */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x03 CRYPTO_ENCRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x04 CRYPTO_DECRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x05 CRYPTO_AEADENCRYPT */ CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT, + /* 0x06 CRYPTO_AEADDECRYPT */ CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT, + /* 0x07 CRYPTO_SIGNATUREGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x08 CRYPTO_SIGNATUREVERIFY */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x09 CRYPTO_SECCOUNTERINCREMENT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0A CRYPTO_SECCOUNTERREAD */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0B CRYPTO_RANDOMGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0C CRYPTO_RANDOMSEED */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0D CRYPTO_KEYGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0E CRYPTO_KEYDERIVE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0F CRYPTO_KEYEXCHANGECALCPUBVAL */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x10 CRYPTO_KEYEXCHANGECALCSECRET */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x11 CRYPTO_CERTIFICATEPARSE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x12 CRYPTO_CERTIFICATEVERIFY */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x13 CRYPTO_KEYSETVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x14 CRYPTO_KEYSETINVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x15 CRYPTO_CUSTOM_SERVICE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x16 CRYPTO_KEYWRAP */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x17 CRYPTO_KEYUNWRAP */ CRYPTO_30_LIBCV_IOMASK_EMPTY +}; +#endif + +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) +/*! + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_IOServiceMaskUpdateOptionalKeepFromFinish[CRYPTO_KEYUNWRAP + 1u] = { /* PRQA S 3218 */ /* MD_CRYPTO_30_LIBCV_8.7 */ + /* 0x00 CRYPTO_HASH */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x01 CRYPTO_MACGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x02 CRYPTO_MACVERIFY */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x03 CRYPTO_ENCRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x04 CRYPTO_DECRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x05 CRYPTO_AEADENCRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x06 CRYPTO_AEADDECRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x07 CRYPTO_SIGNATUREGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x08 CRYPTO_SIGNATUREVERIFY */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x09 CRYPTO_SECCOUNTERINCREMENT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0A CRYPTO_SECCOUNTERREAD */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0B CRYPTO_RANDOMGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0C CRYPTO_RANDOMSEED */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0D CRYPTO_KEYGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0E CRYPTO_KEYDERIVE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0F CRYPTO_KEYEXCHANGECALCPUBVAL */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x10 CRYPTO_KEYEXCHANGECALCSECRET */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x11 CRYPTO_CERTIFICATEPARSE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x12 CRYPTO_CERTIFICATEVERIFY */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x13 CRYPTO_KEYSETVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x14 CRYPTO_KEYSETINVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x15 CRYPTO_CUSTOM_SERVICE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x16 CRYPTO_KEYWRAP */ CRYPTO_30_LIBCV_IOMASK_SECONDARY_OUTPUT, + /* 0x17 CRYPTO_KEYUNWRAP */ CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT +}; +#endif + +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_IOServiceMaskUpdateZeroLength[CRYPTO_KEYUNWRAP + 1u] = { /* PRQA S 3218 */ /* MD_CRYPTO_30_LIBCV_8.7 */ + /* 0x00 CRYPTO_HASH */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x01 CRYPTO_MACGENERATE */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x02 CRYPTO_MACVERIFY */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x03 CRYPTO_ENCRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x04 CRYPTO_DECRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x05 CRYPTO_AEADENCRYPT */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x06 CRYPTO_AEADDECRYPT */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x07 CRYPTO_SIGNATUREGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x08 CRYPTO_SIGNATUREVERIFY */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x09 CRYPTO_SECCOUNTERINCREMENT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0A CRYPTO_SECCOUNTERREAD */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0B CRYPTO_RANDOMGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0C CRYPTO_RANDOMSEED */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0D CRYPTO_KEYGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0E CRYPTO_KEYDERIVE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0F CRYPTO_KEYEXCHANGECALCPUBVAL */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x10 CRYPTO_KEYEXCHANGECALCSECRET */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x11 CRYPTO_CERTIFICATEPARSE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x12 CRYPTO_CERTIFICATEVERIFY */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x13 CRYPTO_KEYSETVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x14 CRYPTO_KEYSETINVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x15 CRYPTO_CUSTOM_SERVICE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x16 CRYPTO_KEYWRAP */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x17 CRYPTO_KEYUNWRAP */ CRYPTO_30_LIBCV_IOMASK_EMPTY +}; +#endif + +#if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) || (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) +/*! + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_IOServiceMaskFinish[CRYPTO_KEYUNWRAP + 1u] = { /* PRQA S 3218 */ /* MD_CRYPTO_30_LIBCV_8.7 */ + /* 0x00 CRYPTO_HASH */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + /* 0x01 CRYPTO_MACGENERATE */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + /* 0x02 CRYPTO_MACVERIFY */ CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT | CRYPTO_30_LIBCV_IOMASK_VERIFY_OUTPUT, + /* 0x03 CRYPTO_ENCRYPT */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + /* 0x04 CRYPTO_DECRYPT */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + /* 0x05 CRYPTO_AEADENCRYPT */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT | CRYPTO_30_LIBCV_IOMASK_SECONDARY_OUTPUT, + /* 0x06 CRYPTO_AEADDECRYPT */ CRYPTO_30_LIBCV_IOMASK_TERTIARY_INPUT | CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT | CRYPTO_30_LIBCV_IOMASK_VERIFY_OUTPUT, + /* 0x07 CRYPTO_SIGNATUREGENERATE */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT | CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + /* 0x08 CRYPTO_SIGNATUREVERIFY */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT | CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT | CRYPTO_30_LIBCV_IOMASK_VERIFY_OUTPUT, + /* 0x09 CRYPTO_SECCOUNTERINCREMENT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0A CRYPTO_SECCOUNTERREAD */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0B CRYPTO_RANDOMGENERATE */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + /* 0x0C CRYPTO_RANDOMSEED */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x0D CRYPTO_KEYGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0E CRYPTO_KEYDERIVE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0F CRYPTO_KEYEXCHANGECALCPUBVAL */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + /* 0x10 CRYPTO_KEYEXCHANGECALCSECRET */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x11 CRYPTO_CERTIFICATEPARSE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x12 CRYPTO_CERTIFICATEVERIFY */ CRYPTO_30_LIBCV_IOMASK_TERTIARY_INPUT | CRYPTO_30_LIBCV_IOMASK_SECONDARY_OUTPUT, + /* 0x13 CRYPTO_KEYSETVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x14 CRYPTO_KEYSETINVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x15 CRYPTO_CUSTOM_SERVICE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x16 CRYPTO_KEYWRAP */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT | CRYPTO_30_LIBCV_IOMASK_SECONDARY_OUTPUT, + /* 0x17 CRYPTO_KEYUNWRAP */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT | CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT +}; +#endif + +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) +/*! + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_IOServiceMaskFinishOptional[CRYPTO_KEYUNWRAP + 1u] = { /* PRQA S 3218 */ /* MD_CRYPTO_30_LIBCV_8.7 */ + /* 0x00 CRYPTO_HASH */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x01 CRYPTO_MACGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x02 CRYPTO_MACVERIFY */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x03 CRYPTO_ENCRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x04 CRYPTO_DECRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x05 CRYPTO_AEADENCRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x06 CRYPTO_AEADDECRYPT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x07 CRYPTO_SIGNATUREGENERATE */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x08 CRYPTO_SIGNATUREVERIFY */ CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT, + /* 0x09 CRYPTO_SECCOUNTERINCREMENT */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0A CRYPTO_SECCOUNTERREAD */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0B CRYPTO_RANDOMGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0C CRYPTO_RANDOMSEED */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0D CRYPTO_KEYGENERATE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0E CRYPTO_KEYDERIVE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x0F CRYPTO_KEYEXCHANGECALCPUBVAL */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x10 CRYPTO_KEYEXCHANGECALCSECRET */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x11 CRYPTO_CERTIFICATEPARSE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x12 CRYPTO_CERTIFICATEVERIFY */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x13 CRYPTO_KEYSETVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x14 CRYPTO_KEYSETINVALID */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x15 CRYPTO_CUSTOM_SERVICE */ CRYPTO_30_LIBCV_IOMASK_EMPTY, + /* 0x16 CRYPTO_KEYWRAP */ CRYPTO_30_LIBCV_IOMASK_SECONDARY_OUTPUT, + /* 0x17 CRYPTO_KEYUNWRAP */ CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT +}; +#endif + +#if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) +CRYPTO_30_LIBCV_LOCAL CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_RedirectReadAccessRight[CRYPTO_KEYUNWRAP + 1u] = { /* PRQA S 3218 */ /* MD_CRYPTO_30_LIBCV_8.7 */ + /* 0x00 CRYPTO_HASH */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x01 CRYPTO_MACGENERATE */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x02 CRYPTO_MACVERIFY */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x03 CRYPTO_ENCRYPT */ CRYPTO_30_LIBCV_RA_ALLOWED, + /* 0x04 CRYPTO_DECRYPT */ CRYPTO_30_LIBCV_RA_ALLOWED, + /* 0x05 CRYPTO_AEADENCRYPT */ CRYPTO_30_LIBCV_RA_ALLOWED, + /* 0x06 CRYPTO_AEADDECRYPT */ CRYPTO_30_LIBCV_RA_ALLOWED, + /* 0x07 CRYPTO_SIGNATUREGENERATE */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x08 CRYPTO_SIGNATUREVERIFY */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x09 CRYPTO_SECCOUNTERINCREMENT */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x0A CRYPTO_SECCOUNTERREAD */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x0B CRYPTO_RANDOMGENERATE */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x0C CRYPTO_RANDOMSEED */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x0D CRYPTO_KEYGENERATE */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x0E CRYPTO_KEYDERIVE */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x0F CRYPTO_KEYEXCHANGECALCPUBVAL */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x10 CRYPTO_KEYEXCHANGECALCSECRET */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x11 CRYPTO_CERTIFICATEPARSE */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x12 CRYPTO_CERTIFICATEVERIFY */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x13 CRYPTO_KEYSETVALID */ CRYPTO_30_LIBCV_RA_DENIED, + /* 0x14 CRYPTO_KEYSETINVALID */ CRYPTO_30_LIBCV_RA_DENIED, + /* 0x15 CRYPTO_CUSTOM_SERVICE */ CRYPTO_30_LIBCV_RA_DENIED, + /* 0x16 CRYPTO_KEYWRAP */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY, + /* 0x17 CRYPTO_KEYUNWRAP */ CRYPTO_30_LIBCV_RA_INTERNAL_COPY +}; +#endif +#define CRYPTO_30_LIBCV_STOP_SEC_CONST_8BIT +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_LIBCV_LONGTERMWS == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_LongWsIsLockNotProtected() + **********************************************************************************************************************/ +/*! \brief Check if long term workspace is locked. + * \details This function checks if the long term workspace is locked and provides the workspace idx. + * \param[in] cryptoKeyId Holds the key id which will lock the workspace + * \param[out] longWsIdxPtr Provided long term workspace idx. + * \return E_OK Lock is obtained or was already obtained. + * E_NOT_OK Request Failed + * \pre longWsIdxPtr has to be a valid pointer. + * Has to be called inside an exclusive area which protects the lock. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_LongWsIsLockNotProtected( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_SizeOfLongTermWsLockType, AUTOMATIC, AUTOMATIC) longWsIdxPtr); +#endif /* (CRYPTO_30_LIBCV_LONGTERMWS == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_IsKeyListValid() + **********************************************************************************************************************/ +/*! \brief Checks provided key list for validity of key Ids. + * \details - + * \param[in] keyList Holds the keylist which should be checked. Must not be NULL_PTR. + * \return TRUE Keys in keyList have valid Ids. + * FALSE At least one key in keyList has an invalid Id. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_IsKeyListValid( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); +#endif + +/********************************************************************************************************************** + * Crypto_30_LibCv_TryObtainingLockAndSetProcessing() + *********************************************************************************************************************/ +/*! \brief Try to obtain the workspace lock and set object state to processing. + * \details This function tries to lock the workspace with the job. + * If that succeeds, it sets the object state to processing. + * This access is not protected by a exclusive area. + * \param[in] objectId Holds the identifier of the object to lock. + * \param[in] job Pointer to the job. Must not be NULL_PTR. + * \param[out] keyListNeedsLock Pointer to a boolean where the information should be stored if the keys + * belonging to job must be locked. Must not be NULL_PTR. + * \return E_OK Lock is obtained or was already obtained. + * E_NOT_OK Request Failed + * CRYPTO_E_BUSY Lock is occupied by other job. + * \pre objectId has to be a valid object id. + * job has to be a valid job object. + * The caller must ensure that this call is protected by a exclusive area. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_TryObtainingLockAndSetProcessing( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(boolean, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyListNeedsLock); + +/********************************************************************************************************************** + * Crypto_30_LibCv_TryObtainingLockAndLockKeys() + *********************************************************************************************************************/ +/*! \brief Try to obtain lock workspace and set object state to processing. + * \details This function tries to lock the workspace and keys with the job. + * If that succeeds, it sets the object state to processing. + * \param[in] objectId Holds the identifier of the object to lock. + * \param[in] job Pointer to the job. Must not be NULL_PTR. + * \param[in] keyList Pointer to the key lock list. Must not be NULL_PTR. + * \return E_OK Lock is obtained or was already obtained. + * E_NOT_OK Request Failed + * CRYPTO_E_BUSY Lock is occupied by other job. + * \pre objectId has to be a valid object id. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_TryObtainingLockAndLockKeys( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +/********************************************************************************************************************** + * Crypto_30_LibCv_CheckQueueAndLockAndProcess() + *********************************************************************************************************************/ +/*! \brief If a job is in queue, try to obtain lock workspace and process the job. + * \details This function tries to lock the workspace and keys with the job next in the queue. + * If that succeeds, it sets the object state to processing and processes the job. + * \param[in] objectId Holds the identifier of the object queue to check. + * \pre objectId has to be a valid object id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_CheckQueueAndLockAndProcess( + uint32 objectId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_UpdateJobState() + *********************************************************************************************************************/ +/*! \brief Updates the state of the job according to retVal of dispatcher. + * \details This function updates the state of job according to retVal of dispatcher as long as dispatcher is not busy. + * \param[in] retVal Return value of the dispatcher + * \param[in,out] job Pointer to the job whose state shall be updated + * \pre job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_UpdateJobState( + Std_ReturnType retVal, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SearchService() + *********************************************************************************************************************/ +/*! \brief Search Service in List + * \details This function searches the provided job to the service as specified in the job configuration. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[out] primitiveInfoIdx Provide the primitive info index. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * primitiveInfoIdx has to be a valid Id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SearchService( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2VAR(Crypto_30_LibCv_SizeOfPrimitiveInfoType, AUTOMATIC, AUTOMATIC) primitiveInfoIdx); + +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_Verify() + **********************************************************************************************************************/ +/*! \brief Det Checks for the verify parameters. + * \details - + * \param[out] errorId Output pointer to the detected Error-Type-Id + * \param[in,out] dataPtr data pointer + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \note The verification pointer is set to CRYPTO_E_VER_NOT_OK by default, + * as it is required to hold the ECDSA safety requirement. + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_Verify( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_Input() + **********************************************************************************************************************/ +/*! \brief Det Checks for the input parameters. + * \details - + * \param[out] errorId Output pointer to the detected Error-Type-Id + * \param[in] dataPtr data pointer + * \param[in] dataLength data length + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_Input( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + uint32 dataLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_InputOptional() + **********************************************************************************************************************/ +/*! \brief Det Checks for the input parameters. + * \details DataLength 0 is a valid value. If dataLength is 0 the dataPtr can be a NULL_PTR. + * \param[out] errorId Output pointer to the detected Error-Type-Id + * \param[in] dataPtr data pointer + * \param[in] dataLength data length + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_InputOptional( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + uint32 dataLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_InputZeroLength() + **********************************************************************************************************************/ +/*! \brief Det Checks for the input parameters. + * \details DataLength 0 is a valid value. + * \param[out] errorId Output pointer to the detected Error-Type-Id + * \param[in] dataPtr data pointer + * \param[in] dataLength data length + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_InputZeroLength( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + uint32 dataLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_OutputMandatory() + **********************************************************************************************************************/ +/*! \brief Det Checks for the output parameters. + * \details - + * \param[out] errorId Output pointer to the detected Error-Type-Id + * \param[in] dataPtr data pointer + * \param[in] dataLengthPtr data length pointer + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_OutputMandatory( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + P2CONST(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataLengthPtr); + +# if((CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) || (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_OutputOptional() + **********************************************************************************************************************/ +/*! \brief Det Checks for the output parameters. + * \details DataLength 0 is a valid value. + * \param[out] errorId Output pointer to the detected Error-Type-Id + * \param[in] dataPtr data pointer + * \param[in] dataLengthPtr data length pointer + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \note Only SaveAndRestore and KeyWrap Aes have optional secondary output pointers + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_OutputOptional( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + P2CONST(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataLengthPtr); +# endif /* ((CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) || (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON)) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_PrimaryInput() + **********************************************************************************************************************/ +/*! \brief Dispatches Det checks for primary input. + * \details - + * \param[out] errorId Output pointer to the detected Error-Type-Id + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in] optionalMask Mask which optional parameter shall be checked. + * \param[in] zeroLengthMask Mask which zero-length-enabled parameter shall be checked. + * \pre job has to be a valid job object. errorId pointer has to be a valid pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_PrimaryInput( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint8 optionalMask, + uint8 zeroLengthMask); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_SecondaryInput() + **********************************************************************************************************************/ +/*! \brief Dispatches Det checks for secondary input. + * \details - + * \param[out] errorId Output pointer to the detected Error-Type-Id + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in] optionalMask Mask which optional parameter shall be checked. + * \pre job has to be a valid job object. errorId pointer has to be a valid pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_SecondaryInput( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint8 optionalMask); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_Output() + **********************************************************************************************************************/ +/*! \brief Dispatches Det checks for primary and secondary output. + * \details - + * \param[out] errorId Output pointer to the detected Error-Type-Id + * \param[in] optionalMask Mask which optional parameter shall be checked. + * \param[in] outputType Type of output, can be either: + * - CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT or + * - CRYPTO_30_LIBCV_IOMASK_SECONDARY_OUTPUT + * \param[in] dataPtr data pointer (e.g. jobs' outputPtr or secondaryOutputPtr) + * \param[in] dataLengthPtr data length pointer (e.g. jobs' outputLengthPtr or secondaryOutputLengthPtr) + * \pre errorId pointer has to be a valid pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_Output( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + uint8 optionalMask, + uint8 outputType, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + P2CONST(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataLengthPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_All() + **********************************************************************************************************************/ +/*! \brief Det Checks for the Service Parameters + * \details This function checks the Det-Checks for all required in- and output-values. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in] mask Mask which parameter shall be checked. + * \param[in] optionalMask Mask which optional parameter shall be checked. + * \param[in] zeroLengthMask Mask which zero-length-enabled parameter shall be checked. + * \return CRYPTO_E_NO_ERROR No Det error detected. + * CRYPTO_E_PARAM_POINTER Det error detected, invalid pointer. + * CRYPTO_E_PARAM_VALUE Det error detected, invalid value. + * \pre job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(uint8, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_All( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint8 mask, + uint8 optionalMask, + uint8 zeroLengthMask); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues() + *********************************************************************************************************************/ +/*! \brief Det Checks for the Service Parameters + * \details This function checks the Det-Checks for all required in- and output-values. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[out] errorId Output Pointer to the detected Error-Type-Id + * \return E_OK No Det error detected. + * E_NOT_OK Det error detected. + * \pre objectId has to be a valid driver object handle. + * errorId has to be a valid pointer. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) errorId); +#endif /* (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Process() + *********************************************************************************************************************/ +/*! \brief Processes the received job + * \details Performs the crypto primitive, that is configured in the job parameter. Takes care of jobs operation mode. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the configuration of the job. Contains structures with job and + * primitive relevant information but also pointer to result buffers. + * \param[in,out] keyList Pointer to the key lock list + * \param[in] primitiveInfoIdx Holds the identifier of the primitive. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * CRYPTO_E_QUEUE_FULL Request failed, the queue is full. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, the entropy is exhausted + * CRYPTO_E_JOB_CANCELED The service request failed because the synchronous Job has been canceled. + * \pre Lock has to be reserved for the job object. + * objectId has to be a valid driver object handle. + * job has to be a job object handle. + * primitiveInfoIdx has to be a valid Id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Process( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList, + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx); + +#if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_UpdateObjectWorkspace() + *********************************************************************************************************************/ +/*! \brief Save the last driver object workspace type. + * \details - + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * Has to be called inside an exclusive area which protects the consistency of the last job data. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_UpdateObjectWorkspace( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_ClearObjectWorkspace() + *********************************************************************************************************************/ +/*! \brief Clear the last driver object workspace type. + * \details - + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * Has to be called inside an exclusive area which protects the consistency of the last job data. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_ClearObjectWorkspace( + uint32 objectId); +#endif /* (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_IsRedirectUsed() + **********************************************************************************************************************/ +/*! \brief Is redirection used. + * \details Check if redirection is used in the current Job. + * \param[in] job Pointer to the job which shall checked. + * \return TRUE Job is redirected. + * FALSE Job is not redirected. + * \pre job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_IsRedirectUsed( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RedirectPreSetBufferForKey() + **********************************************************************************************************************/ +/*! \brief Check access rights for given key element. + * \details Check access rights according to their read/write access. + * \param[in] cryptoKeyId Holds the crypto key id. + * \param[in] keyElementId Holds the key element id. + * \param[out] elementPtr Pointer to the key element storage. + * \param[out] resultLengthPtr Pointer to the key element length. + * \param[in] readWrite Read or write access. + * \param[in] cryptoService Holds the crypto service. + * \return E_OK Request success. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_EMPTY Request failed, key is empty. + * \pre cryptoKeyId need to be valid. + * cryptoService need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RedirectPreSetBufferForKey( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) elementPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr, + uint8 readWrite, + Crypto_ServiceInfoType cryptoService); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RedirectPostSaveKeyResult() + **********************************************************************************************************************/ +/*! \brief Save result for output key elements. + * \details - + * \param[in] cryptoKeyId Holds the crypto key id. + * \param[in] keyElementId Holds the key element id. + * \param[in] resultLength Holds the result length. (current update length) + * \param[in,out] writtenLengthPtr Holds the a pointer to the already written length. (last update length) + * \param[in] result Current update result + * \pre cryptoKeyId need to be valid. + * cryptoService need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RedirectPostSaveKeyResult( + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 resultLength, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) writtenLengthPtr, + Std_ReturnType result); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_GetKeyListRedirection() + **********************************************************************************************************************/ +/*! \brief Create list of keys for redirection. + * \details A key is only referenced once in the list with the highest access. + * \param[in] job Pointer to the job which shall checked. + * \param[in,out] keyList Pointer to the keyList. + * \pre job has to be a valid job object. + * keyList has to be a valid keyList object with at least 6 elements if redirection is used, otherwise 1. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_GetKeyListRedirection( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RedirectPreRedirKeys() + **********************************************************************************************************************/ +/*! \brief Pre redirect keys and in- and out-buffer. + * \details Set the in- and out-buffer to the redirected keys. + * \param[in,out] redirectBuffer Pointer to the redirection buffer. + * \param[in,out] job Pointer to the configuration of the job. + * \return E_OK Request success. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_EMPTY Request failed, key is empty. + * \pre Lock has to be reserved for the job object. + * redirectBuffer has to be a valid pointer. + * job has to be a job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RedirectPreRedirKeys( + P2VAR(Crypto_30_LibCv_Redirect_Type, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) redirectBuffer, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RedirectPostRestoreBuffer() + **********************************************************************************************************************/ +/*! \brief Post redirect keys and in- and out-buffer. + * \details Save result and restore in- and out-buffer. + * \param[in,out] redirectBuffer Pointer to the redirection buffer. + * \param[in,out] job Pointer to the configuration of the job. + * \param[in] result Current update result + * \pre Lock has to be reserved for the job object. + * redirectBuffer has to be a valid pointer. + * job has to be a job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RedirectPostRestoreBuffer( + P2VAR(Crypto_30_LibCv_Redirect_Type, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) redirectBuffer, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Std_ReturnType result); +#endif /* (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SaveContextJob() + **********************************************************************************************************************/ +/*! \brief Save the context. + * \details Stores the current workspace context in the output buffer. + * If the output length pointer is set to 0, the expected buffer length is written to the output + * length pointer. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the configuration of the job. + * \param[in] primitiveInfoIdx Holds the identifier of the primitive. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * primitiveInfoIdx has to be a valid Id. + * length of the output buffer must be greater than or equal to the context length. + * Also refer to SMI-722498 + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SaveContextJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RestoreContextJob() + **********************************************************************************************************************/ +/*! \brief Restore the context. + * \details Restores the workspace context with the information from the job input pointer. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the configuration of the job. + * \param[in] primitiveInfoIdx Holds the identifier of the primitive. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * primitiveInfoIdx has to be a valid Id. + * length of the input buffer must be greater than or equal to the context length. + * Also refer to SMI-722498 + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RestoreContextJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx); +#endif /* (CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) */ + +#if((CRYPTO_30_LIBCV_SERVICE_SIGNATURE_GENERATE == STD_ON) || (CRYPTO_30_LIBCV_SERVICE_SIGNATURE_VERIFY == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_HandleOptionalInputDataInFinish() + **********************************************************************************************************************/ +/*! \brief This function calls the dispatch function in UPDATE mode to process optional input data in finish mode. + * \details This applies only for signature services. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the configuration of the job. + * \param[in] primitiveInfoIdx Holds the identifier of the primitive. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * primitiveInfoIdx has to be a valid Id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_HandleOptionalInputDataInFinish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx); +#endif /* (CRYPTO_30_LIBCV_SERVICE_SIGNATURE_GENERATE == STD_ON) || (CRYPTO_30_LIBCV_SERVICE_SIGNATURE_VERIFY == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchJob() + **********************************************************************************************************************/ +/*! \brief Dispatch the job. + * \details Forward the job to the correct primitive. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[out] unlockingNecessary Is set when unlocking is required + * \param[out] contextMode Is set when context mode is enabled + * \param[in,out] job Pointer to the configuration of the job. + * \param[in] primitiveInfoIdx Holds the identifier of the primitive. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_EMPTY Request failed, uninitialized source key element. + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, the entropy is exhausted + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * primitiveInfoIdx has to be a valid Id. + * length of the input buffer must be greater than or equal to the context length. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchJob( + uint32 objectId, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) unlockingNecessary, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) contextMode, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_TryToSetJobInQueue() + **********************************************************************************************************************/ +/*! \brief Handles an asynchronous job request and tries to push it into the queue for deferred processing. + * \details - + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the configuration of the job. + * \param[in] primitiveInfoIdx Holds the identifier of the primitive. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_QUEUE_FULL The queue for the async job is full. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * primitiveInfoIdx has to be a valid Id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_TryToSetJobInQueue( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_InitMainPartition() + *********************************************************************************************************************/ +/*! \brief Initializes the shared data of the Crypto Driver + * \details This function initializes all shared variables relevant for all + * partitions and sets the module state for this data to initialized. It has to be called once from + * the main partition. + * \param[out] errorIdPtr Pointer to where the errorId should be written. + * Must not be NULL_PTR and have enough space for a uint8. + * \pre Interrupts are disabled. + * Module is uninitialized. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_InitMainPartition( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) errorIdPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_InitPartitionSpecificData() + *********************************************************************************************************************/ +/*! \brief Initializes the partition specific data of the Crypto Driver + * \details This function initializes all partition specific variables relevant for the provided + * partitionIdx and sets the module state for the partition to initialized. It has to be called once from + * each partition where the module is used. + * \param[in] partitionIdx Holds the index of the partition which should be initialized. + * \param[out] errorIdPtr Pointer to where the errorId should be written. + * Must not be NULL_PTR and have enough space for a uint8. + * \pre Interrupts are disabled. + * Module is uninitialized. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_InitPartitionSpecificData(uint32 partitionIdx, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) errorIdPtr); + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#if (CRYPTO_30_LIBCV_LONGTERMWS == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_LongWsIsLockNotProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_LongWsIsLockNotProtected( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_SizeOfLongTermWsLockType, AUTOMATIC, AUTOMATIC) longWsIdxPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_LongTermWsLockIterType id; + + /* ----- Implementation ------------------------------------------------- */ + for (id = 0u; id < Crypto_30_LibCv_GetSizeOfLongTermWsLock(); id++) + { + if (Crypto_30_LibCv_IsLongTermWsLock(id, cryptoKeyId)) + { + *longWsIdxPtr = (Crypto_30_LibCv_SizeOfLongTermWsLockType)id; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_LongWsIsLockNotProtected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_LongWsLockGet() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_LongWsLockGet( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_SizeOfLongTermWsLockType, AUTOMATIC, AUTOMATIC) longWsIdxPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + Crypto_30_LibCv_LongTermWsLockIterType id; + + /* ----- Implementation ------------------------------------------------- */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_2(); + + /* Lock already occupied */ + retVal = Crypto_30_LibCv_Local_LongWsIsLockNotProtected(cryptoKeyId, longWsIdxPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + + /* Check if a lock is free and can be occupied. */ + if (retVal != E_OK) + { + for (id = 0u; id < Crypto_30_LibCv_GetSizeOfLongTermWsLock(); id++) + { + if (Crypto_30_LibCv_GetLongTermWsLock(id) == CRYPTO_30_LIBCV_LONG_TERM_WS_LOCK_FREE) + { + Crypto_30_LibCv_SetLongTermWsLock(id, cryptoKeyId);/* SBSW_CRYPTO_30_LIBCV_CSL01 */ + *longWsIdxPtr = (Crypto_30_LibCv_SizeOfLongTermWsLockType)id; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + break; + } + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_2(); + + return retVal; +} /* Crypto_30_LibCv_Local_LongWsLockGet() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_LongWsIsLock() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_LongWsIsLock( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_SizeOfLongTermWsLockType, AUTOMATIC, AUTOMATIC) longWsIdxPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_2(); + retVal = Crypto_30_LibCv_Local_LongWsIsLockNotProtected(cryptoKeyId, longWsIdxPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_2(); + + return retVal; +} /* Crypto_30_LibCv_Local_LongWsIsLock() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_LongWsLockRelease() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_LongWsLockRelease( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfLongTermWsLockType longWsIdx) +{ + /* ----- Local Variables ------------------------------------------------ */ + /* ----- Implementation ------------------------------------------------- */ + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_2(); + if (Crypto_30_LibCv_IsLongTermWsLock(longWsIdx, cryptoKeyId)) /* COV_CRYPTO_30_LIBCV_KEY_LOCKING_RELEASE */ + { + Crypto_30_LibCv_SetLongTermWsLock(longWsIdx, CRYPTO_30_LIBCV_LONG_TERM_WS_LOCK_FREE);/* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_2(); + +} /* Crypto_30_LibCv_Local_LongWsLockRelease() */ +#endif /* (CRYPTO_30_LIBCV_LONGTERMWS == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_TryObtainingLockAndSetProcessing() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_TryObtainingLockAndSetProcessing( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(boolean, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyListNeedsLock) +{ + Std_ReturnType retVal = E_NOT_OK; + + *keyListNeedsLock = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + + /* #5 Lock driver object for the given job if it is not already locked. */ + if (Crypto_30_LibCv_IsLockOccupiedByJob(objectId, job->CRYPTO_30_LIBCV_JOB_ID_MEMBER)) + { + Crypto_30_LibCv_SetDriverObjectState(objectId, CRYPTO_30_LIBCV_DRIVEROBJECTSTATE_PROCESSING); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + retVal = E_OK; + } +#if(CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) + else if ((Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_START)) || (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_RESTORE_CONTEXT))) +#else + else if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_START)) +#endif + { + if (Crypto_30_LibCv_IsLockFree(objectId)) + { + Crypto_30_LibCv_SetLock(objectId, job->CRYPTO_30_LIBCV_JOB_ID_MEMBER); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + /* #10 Set object state to processing */ + Crypto_30_LibCv_SetDriverObjectState(objectId, CRYPTO_30_LIBCV_DRIVEROBJECTSTATE_PROCESSING); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + *keyListNeedsLock = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ +#endif + retVal = E_OK; + } + else + { + retVal = CRYPTO_E_BUSY; + } + } + else + { + /* [SWS_Crypto_00118] No Start flag while in idle mode */ + retVal = E_NOT_OK; + } + + return retVal; +} /* Crypto_30_LibCv_TryObtainingLockAndSetProcessing() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_TryObtainingLockAndLockKeys() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_TryObtainingLockAndLockKeys( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + Std_ReturnType retVal = E_NOT_OK; + boolean keysNeedToBeLocked = FALSE; + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* #10 Try to lock driver object for the given job */ + retVal = Crypto_30_LibCv_TryObtainingLockAndSetProcessing(objectId, job, &keysNeedToBeLocked); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + if ((retVal == E_OK) && (keysNeedToBeLocked == TRUE)) + { + /* #20 Lock key if operation mode is start or restore */ + retVal = Crypto_30_LibCv_Local_KeyListPreLockKeysProtected(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + + if (retVal != E_OK) + { + /* #30 If any lock fails, revert all locks and processing states */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + Crypto_30_LibCv_FreeLock(objectId); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetDriverObjectState(objectId, CRYPTO_30_LIBCV_DRIVEROBJECTSTATE_IDLE); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + retVal = CRYPTO_E_BUSY; + } + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(keyList); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_LibCv_TryObtainingLockAndLockKeys() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_CheckQueueAndLockAndProcess() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_CheckQueueAndLockAndProcess( + uint32 objectId) +{ + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job; + Crypto_30_LibCv_KeyLockListType keyList = {0}; + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx = 0u; + Std_ReturnType localRetVal = E_NOT_OK; + boolean keysNeedToBeLocked = FALSE; + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + /* #1 Check if there is a job in the queue */ + job = Crypto_30_LibCv_GetQueue(Crypto_30_LibCv_GetQueueIdxOfObjectInfo(objectId)); + + if (job != NULL_PTR) + { + Crypto_30_LibCv_Local_GetKeyList(job, &keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + primitiveInfoIdx = Crypto_30_LibCv_GetDispatch_QueuePrimitiveInfoIdx(objectId); + +#if (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) + if (Crypto_30_LibCv_IsDefaultRandomSourceOfPrimitiveInfo(primitiveInfoIdx)) + { + uint32 defaultRandomKey = Crypto_30_LibCv_GetDefaultRandomKeyOfPartitionInfo(Crypto_30_LibCv_CurrentPartitionIdxViaObject(objectId)); + Crypto_30_LibCv_Local_KeyListAddKey(&keyList, defaultRandomKey, CRYPTO_30_LIBCV_KEY_ACCESS_READ); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + } +#endif + + /* #10 Try to lock driver object for the given job */ + localRetVal = Crypto_30_LibCv_TryObtainingLockAndSetProcessing(objectId, job, &keysNeedToBeLocked); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + if (localRetVal == E_OK) + { + if (keysNeedToBeLocked == TRUE) + { + /* #20 Lock key if operation mode is start or restore */ + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + localRetVal = Crypto_30_LibCv_Local_KeyListPreLockKeysProtected(&keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + if (localRetVal != E_OK) + { + /* #30 If any lock fails, revert all locks */ + Crypto_30_LibCv_FreeLock(objectId); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetDriverObjectState(objectId, CRYPTO_30_LIBCV_DRIVEROBJECTSTATE_IDLE); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + } + } +#endif + + if (localRetVal == E_OK) + { + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + localRetVal = Crypto_30_LibCv_Process((uint32)objectId, job, &keyList, primitiveInfoIdx); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ /* PRQA S 2973 */ /* MD_CRYPTO_30_LIBCV_2973 */ + + /* #40 Release Queue */ + Crypto_30_LibCv_SetQueue(Crypto_30_LibCv_GetQueueIdxOfObjectInfo(objectId), NULL_PTR); /* SBSW_CRYPTO_30_LIBCV_CSL02_QUEUE_VIA_DRIVEROBJECT */ + + /* #50 Notify CryIf about the result of the job */ + CryIf_CallbackNotification(job, localRetVal); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +} /* Crypto_30_LibCv_CheckQueueAndLockAndProcess() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_UpdateJobState() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_UpdateJobState( + Std_ReturnType retVal, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* #5 Set job state based on parameter return value. */ + if (retVal == E_OK) + { + job->CRYPTO_30_LIBCV_JOB_STATE_MEMBER = CRYPTO_JOBSTATE_ACTIVE; /* SBSW_CRYPTO_30_LIBCV_UPDATE_OF_JOB_STATE */ + } + else + { + /* [SWS_Crypto_00025] [SWS_Crypto_00119] Set job to IDLE if error occurred */ + job->CRYPTO_30_LIBCV_JOB_STATE_MEMBER = CRYPTO_JOBSTATE_IDLE; /* SBSW_CRYPTO_30_LIBCV_UPDATE_OF_JOB_STATE */ + } +} /* Crypto_30_LibCv_UpdateJobState() */ + +#if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_ObjectWorkspaceHasChanged() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_ObjectWorkspaceHasChanged( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + boolean retVal = TRUE; + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* Check if the cryptoKeyId is the same as in the last job. */ + if (job->cryptoKeyId == Crypto_30_LibCv_GetKeyIdOfLastJob(objectId)) + { + /* Check if the algorithm family and the algorithm mode is the same as in the last job. */ + if ((job->jobPrimitiveInfo->primitiveInfo->algorithm.family == Crypto_30_LibCv_GetFamilyOfLastJob(objectId))&& + (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode == Crypto_30_LibCv_GetModeOfLastJob(objectId))) + { + /* Return false - object workspace type has NOT changed. */ + retVal = FALSE; + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + return retVal; +} /* Crypto_30_LibCv_ObjectWorkspaceHasChanged() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_ClearObjectWorkspaceForChangedKey() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_ClearObjectWorkspaceForChangedKey( + uint32 cryptoKeyId) +{ + uint32 objectId; + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + /* #1 check if key is used in any object workspace type */ + for (objectId = 0; objectId < Crypto_30_LibCv_GetSizeOfObjectInfo(); objectId++) + { + if (Crypto_30_LibCv_GetKeyIdOfLastJob(objectId) == cryptoKeyId) + { + /* #2 clear the last object workspace type */ + Crypto_30_LibCv_SetKeyIdOfLastJob(objectId, CRYPTO_30_LIBCV_UINT32_MAX); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetFamilyOfLastJob(objectId, CRYPTO_ALGOFAM_NOT_SET); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetModeOfLastJob(objectId, CRYPTO_ALGOMODE_NOT_SET); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +} /* Crypto_30_LibCv_ClearObjectWorkspaceForChangedKey() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_UpdateObjectWorkspace() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_UpdateObjectWorkspace( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* #1 update the last object workspace type */ + Crypto_30_LibCv_SetKeyIdOfLastJob(objectId, job->cryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetFamilyOfLastJob(objectId, job->jobPrimitiveInfo->primitiveInfo->algorithm.family); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetModeOfLastJob(objectId, job->jobPrimitiveInfo->primitiveInfo->algorithm.mode); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ +} /* Crypto_30_LibCv_UpdateObjectWorkspace() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_ClearObjectWorkspace() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_ClearObjectWorkspace( + uint32 objectId) +{ + /* #1 clear the last object workspace type */ + Crypto_30_LibCv_SetKeyIdOfLastJob(objectId, CRYPTO_30_LIBCV_UINT32_MAX); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetFamilyOfLastJob(objectId, CRYPTO_ALGOFAM_NOT_SET); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetModeOfLastJob(objectId, CRYPTO_ALGOMODE_NOT_SET); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ +} /* Crypto_30_LibCv_ClearObjectWorkspace() */ +#endif /* (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_Verify() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_Verify( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr) +{ + + /* Check Pointer */ + if (dataPtr == NULL_PTR) + { + *errorId = CRYPTO_E_PARAM_POINTER; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } + else + { + /* In all primitives in which the verification pointer is usage, it is set to CRYPTO_E_VER_NOT_OK by default. + The verification pointer should be set to CRYPTO_E_VER_OK only in successful run. */ + *dataPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + +} /* Crypto_30_LibCv_Local_DetChecksServiceValues_Verify() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_Input() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_Input( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + uint32 dataLength) +{ + + /* Check Pointer */ + if (dataPtr == NULL_PTR) + { + *errorId = CRYPTO_E_PARAM_POINTER; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } + /* Check Length */ +# if(CRYPTO_30_LIBCV_VSEC_PRIM_ESLT_LENGTH_32 == STD_ON) + else if (dataLength == 0u) +# else + else if ((dataLength == 0u) || + Crypto_30_LibCv_IsIOLengthInvalid(dataLength)) +# endif + { + *errorId = CRYPTO_E_PARAM_VALUE; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } + else + { + /* Det Checks passed. Nothing has to be done. */ + } + +} /* Crypto_30_LibCv_Local_DetChecksServiceValues_Input() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_InputOptional() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_InputOptional( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + uint32 dataLength) +{ + /* Check Pointer */ + if ((dataPtr == NULL_PTR) && + (dataLength != 0u)) + { + *errorId = CRYPTO_E_PARAM_POINTER; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } +# if(CRYPTO_30_LIBCV_VSEC_PRIM_ESLT_LENGTH_32 == STD_OFF) + /* Check Length */ + else if (Crypto_30_LibCv_IsIOLengthInvalid(dataLength)) + { + *errorId = CRYPTO_E_PARAM_VALUE; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } +# endif + else + { + /* Det Checks passed. Nothing has to be done. */ + } +} /* Crypto_30_LibCv_Local_DetChecksServiceValues_InputOptional() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_InputZeroLength() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_InputZeroLength( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + uint32 dataLength) +{ + /* Check Pointer */ + if (dataPtr == NULL_PTR) + { + *errorId = CRYPTO_E_PARAM_POINTER; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } + /* Check Length */ +# if(CRYPTO_30_LIBCV_VSEC_PRIM_ESLT_LENGTH_32 == STD_OFF) + else if Crypto_30_LibCv_IsIOLengthInvalid(dataLength) + { + *errorId = CRYPTO_E_PARAM_VALUE; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } +# endif + else + { + /* Det Checks passed. Nothing has to be done. */ + } + +# if(CRYPTO_30_LIBCV_VSEC_PRIM_ESLT_LENGTH_32 == STD_ON) + CRYPTO_30_LIBCV_DUMMY_STATEMENT(dataLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} /* Crypto_30_LibCv_Local_DetChecksServiceValues_InputZeroLength() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_OutputMandatory() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_OutputMandatory( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + P2CONST(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataLengthPtr) +{ + + /* Check Pointer */ + if ((dataPtr == NULL_PTR) || + (dataLengthPtr == NULL_PTR)) + { + *errorId = CRYPTO_E_PARAM_POINTER; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } + /* Check Length */ +# if (CRYPTO_30_LIBCV_VSEC_PRIM_ESLT_LENGTH_32 == STD_ON) + else if (*dataLengthPtr == 0u) +# else + else if ((*dataLengthPtr == 0u) || + Crypto_30_LibCv_IsIOLengthInvalid(*dataLengthPtr)) +# endif + { + *errorId = CRYPTO_E_PARAM_VALUE; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } + else + { + /* Det Checks passed. Nothing has to be done. */ + } + +} /* Crypto_30_LibCv_Local_DetChecksServiceValues_OutputMandatory() */ + +# if((CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) || (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_OutputOptional() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_OutputOptional( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + P2CONST(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataLengthPtr) +{ + /* Check Pointer */ + if ((dataPtr == NULL_PTR) || (dataLengthPtr == NULL_PTR)) + { + *errorId = CRYPTO_E_PARAM_POINTER; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } +# if(CRYPTO_30_LIBCV_VSEC_PRIM_ESLT_LENGTH_32 == STD_OFF) + /* Check Length */ + else if (Crypto_30_LibCv_IsIOLengthInvalid(*dataLengthPtr)) + { + *errorId = CRYPTO_E_PARAM_VALUE; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } +# endif + else + { + /* Det Checks passed. Nothing has to be done. */ + } +} /* Crypto_30_LibCv_Local_DetChecksServiceValues_OutputOptional() */ +# endif /* ((CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) || (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON)) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_PrimaryInput() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_PrimaryInput( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint8 optionalMask, + uint8 zeroLengthMask) +{ + if (Crypto_30_LibCv_IsIOMask(optionalMask, CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT)) + { + Crypto_30_LibCv_Local_DetChecksServiceValues_InputOptional(errorId, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + } + else if (Crypto_30_LibCv_IsIOMask(zeroLengthMask, CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT)) + { + Crypto_30_LibCv_Local_DetChecksServiceValues_InputZeroLength(errorId, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + } + else + { + Crypto_30_LibCv_Local_DetChecksServiceValues_Input(errorId, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + } +} /* Crypto_30_LibCv_Local_DetChecksServiceValues_PrimaryInput() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_SecondaryInput() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_SecondaryInput( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint8 optionalMask) +{ + if (Crypto_30_LibCv_IsIOMask(optionalMask, CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT)) + { + Crypto_30_LibCv_Local_DetChecksServiceValues_InputOptional(errorId, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + } + else + { + Crypto_30_LibCv_Local_DetChecksServiceValues_Input(errorId, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + } +} /* Crypto_30_LibCv_Local_DetChecksServiceValues_SecondaryInput() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_Output() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_Output( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + uint8 optionalMask, + uint8 outputType, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + P2CONST(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataLengthPtr) +{ +# if((CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) || (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON)) + if (Crypto_30_LibCv_IsIOMask(optionalMask, outputType)) + { + Crypto_30_LibCv_Local_DetChecksServiceValues_OutputOptional(errorId, dataPtr, dataLengthPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + } + else +# endif /* ((CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) || (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON)) */ + { + Crypto_30_LibCv_Local_DetChecksServiceValues_OutputMandatory(errorId, dataPtr, dataLengthPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(optionalMask); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(outputType); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + } +} /* Crypto_30_LibCv_Local_DetChecksServiceValues_Output() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues_All() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +/* PRQA S 6010 4 */ /* MD_MSR_STPTH */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(uint8, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues_All( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint8 mask, + uint8 optionalMask, + uint8 zeroLengthMask + ) +{ + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* Dispatch Det checks. */ + if (Crypto_30_LibCv_IsIOMask(mask, CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT)) + { + Crypto_30_LibCv_Local_DetChecksServiceValues_PrimaryInput(&errorId, job, optionalMask, zeroLengthMask); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + } + + if (Crypto_30_LibCv_IsIOMask(mask, CRYPTO_30_LIBCV_IOMASK_SECONDARY_INPUT)) + { + Crypto_30_LibCv_Local_DetChecksServiceValues_SecondaryInput(&errorId, job, optionalMask); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + } + + if (Crypto_30_LibCv_IsIOMask(mask, CRYPTO_30_LIBCV_IOMASK_TERTIARY_INPUT)) + { + Crypto_30_LibCv_Local_DetChecksServiceValues_Input(&errorId, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.tertiaryInputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.tertiaryInputLength); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + } + + if (Crypto_30_LibCv_IsIOMask(mask, CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT)) + { + Crypto_30_LibCv_Local_DetChecksServiceValues_Output(&errorId, + optionalMask, CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + } + + if (Crypto_30_LibCv_IsIOMask(mask, CRYPTO_30_LIBCV_IOMASK_SECONDARY_OUTPUT)) + { + Crypto_30_LibCv_Local_DetChecksServiceValues_Output(&errorId, + optionalMask, CRYPTO_30_LIBCV_IOMASK_SECONDARY_OUTPUT, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + } + + if (Crypto_30_LibCv_IsIOMask(mask, CRYPTO_30_LIBCV_IOMASK_VERIFY_OUTPUT)) + { + Crypto_30_LibCv_Local_DetChecksServiceValues_Verify(&errorId, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + } + + return errorId; +} /* Crypto_30_LibCv_Local_DetChecksServiceValues_All() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_DetChecksServiceValues() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6010, 6030, 6050 3 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_DetChecksServiceValues( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) errorId) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + Crypto_ServiceInfoType cryptoService = job->jobPrimitiveInfo->primitiveInfo->service; + uint8 mask = CRYPTO_30_LIBCV_IOMASK_EMPTY; + uint8 optional = CRYPTO_30_LIBCV_IOMASK_EMPTY; + uint8 zeroLength = CRYPTO_30_LIBCV_IOMASK_EMPTY; + + /* ----- Development Error Checks --------------------------------------- */ + + /* #0 Check plausibility of parameters */ + if (cryptoService > CRYPTO_KEYUNWRAP) + { + /* #11 requested service is not valid (out of range of possible services) */ + /* [SWS_Crypto_00064] check if job->jobPrimitiveInfo->primitiveInfo->service is supported by Crypto Driver Object */ + *errorId = CRYPTO_E_PARAM_HANDLE; /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ + } + else + { + /* Check first FINISH then UPDATE this is required for optional special handling. */ + + if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_FINISH)) + { + mask = Crypto_30_LibCv_IOServiceMaskFinish[cryptoService]; + optional = Crypto_30_LibCv_IOServiceMaskFinishOptional[cryptoService]; + } + + if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_UPDATE)) + { + mask |= Crypto_30_LibCv_IOServiceMaskUpdate[cryptoService]; + + /* optional mask is reset since there might be optional parameters in update */ + optional &= Crypto_30_LibCv_IOServiceMaskUpdateOptionalKeepFromFinish[cryptoService]; + optional |= Crypto_30_LibCv_IOServiceMaskUpdateOptional[cryptoService]; + zeroLength = Crypto_30_LibCv_IOServiceMaskUpdateZeroLength[cryptoService]; + } + +# if(CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) + if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_SAVE_CONTEXT)) + { + mask |= CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT; + optional |= CRYPTO_30_LIBCV_IOMASK_PRIMARY_OUTPUT; + } + + if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_RESTORE_CONTEXT)) + { + mask |= CRYPTO_30_LIBCV_IOMASK_PRIMARY_INPUT; + } +# endif +# if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) + if (Crypto_30_LibCv_Local_IsRedirectUsed(job) == TRUE) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + { + mask &= (uint8)~(job->jobRedirectionInfoRef->redirectionConfig); + optional &= (uint8)~(job->jobRedirectionInfoRef->redirectionConfig); + } +# endif + + if (mask != CRYPTO_30_LIBCV_IOMASK_EMPTY) + { + *errorId = Crypto_30_LibCv_Local_DetChecksServiceValues_All(job, mask, optional, zeroLength); /* SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + } + } + + /* #12 Set return Value to E_NOT_OK if a failure was detected. */ + if ((*errorId == CRYPTO_E_PARAM_POINTER) || + (*errorId == CRYPTO_E_PARAM_VALUE) || (*errorId == CRYPTO_E_PARAM_HANDLE)) + { + retVal = E_NOT_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_DetChecksServiceValues() */ +#endif /* (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyListAddKey() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyListAddKey( + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList, + uint32 cryptoKeyId, + uint8 keyAccess) +{ + boolean found = FALSE; + uint8 i; + /* Check if key is already in key list. */ + for (i = 0; i < keyList->numKeys; i++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND_PTR */ + { + if (keyList->keyLockList[i].keyId == cryptoKeyId) + { + found = TRUE; + /* Add key access to found key. */ + /* 0 if read lock / >0 if write lock */ + keyList->keyLockList[i].keyAccess = (uint8)(keyList->keyLockList[i].keyAccess + keyAccess); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + break; + } + } + + /* Add new key to list. */ + if (found == FALSE) + { + keyList->keyLockList[keyList->numKeys].keyId = cryptoKeyId; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + keyList->keyLockList[keyList->numKeys].keyAccess = keyAccess; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + keyList->numKeys++; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } +} /* Crypto_30_LibCv_Local_KeyListAddKey() */ + +#if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_GetKeyListRedirection() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_GetKeyListRedirection( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + + /* # Check if redirection is used. */ + if (Crypto_30_LibCv_Local_IsRedirectUsed(job) == TRUE) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + { + P2CONST(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) redirInfoRef = job->jobRedirectionInfoRef; + Crypto_InputOutputRedirectionConfigType redirConfig = redirInfoRef->redirectionConfig; + + /* # Add redirected keys to key list. */ + if (Crypto_30_LibCv_IsRedirection(redirConfig, CRYPTO_REDIRECT_CONFIG_PRIMARY_INPUT)) + { + Crypto_30_LibCv_Local_KeyListAddKey(keyList, redirInfoRef->inputKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_READ); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + } + + if (Crypto_30_LibCv_IsRedirection(redirConfig, CRYPTO_REDIRECT_CONFIG_SECONDARY_INPUT)) + { + Crypto_30_LibCv_Local_KeyListAddKey(keyList, redirInfoRef->secondaryInputKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_READ); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + } + + if (Crypto_30_LibCv_IsRedirection(redirConfig, CRYPTO_REDIRECT_CONFIG_TERTIARY_INPUT)) + { + Crypto_30_LibCv_Local_KeyListAddKey(keyList, redirInfoRef->tertiaryInputKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_READ); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + } + + if (Crypto_30_LibCv_IsRedirection(redirConfig, CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT)) + { + Crypto_30_LibCv_Local_KeyListAddKey(keyList, redirInfoRef->outputKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_WRITE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + } + + if (Crypto_30_LibCv_IsRedirection(redirConfig, CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT)) + { + Crypto_30_LibCv_Local_KeyListAddKey(keyList, redirInfoRef->secondaryOutputKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_WRITE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + } + } +} /* Crypto_30_LibCv_Local_GetKeyListRedirection() */ +#endif + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_GetKeyList() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6030 3 */ /* MD_MSR_STCYC */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_GetKeyList( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + keyList->numKeys = 0u; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + +#if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) + Crypto_30_LibCv_Local_GetKeyListRedirection(job, keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ +#endif + + /* # Add Job key to key list. */ + switch (job->jobPrimitiveInfo->primitiveInfo->service) /* PRQA S 3315 */ /* MD_CRYPTO_30_LIBCV_3315 */ + { +#if (CRYPTO_30_LIBCV_SERVICE_RANDOM == STD_ON) + case CRYPTO_RANDOMGENERATE: + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->cryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_WRITE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + break; +#endif +#if (CRYPTO_30_LIBCV_SERVICE_KEY_SET_VALID == STD_ON) + case CRYPTO_KEYSETVALID: + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->cryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_WRITE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + break; +#endif +#if (CRYPTO_30_LIBCV_SERVICE_KEYSETINVALID == STD_ON) + case CRYPTO_KEYSETINVALID: + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->cryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_WRITE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + break; +#endif +#if (CRYPTO_30_LIBCV_SERVICE_RANDOM_SEED == STD_ON) + case CRYPTO_RANDOMSEED: + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->cryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_WRITE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + break; +#endif +#if (CRYPTO_30_LIBCV_SERVICE_KEY_DERIVE == STD_ON) + case CRYPTO_KEYDERIVE: + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->cryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_READ); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->targetCryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_WRITE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + break; +#endif +#if (CRYPTO_30_LIBCV_SERVICE_KEY_EXCHANGE_CALC_PUBVAL == STD_ON) + case CRYPTO_KEYEXCHANGECALCPUBVAL: + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->cryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_WRITE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + break; +#endif +#if (CRYPTO_30_LIBCV_SERVICE_KEY_EXCHANGE_CALC_SECRET == STD_ON) + case CRYPTO_KEYEXCHANGECALCSECRET: + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->cryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_WRITE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + break; +#endif +#if (CRYPTO_30_LIBCV_SERVICE_KEY_GENERATE == STD_ON) + case CRYPTO_KEYGENERATE: + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->cryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_WRITE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + break; +#endif +#if (CRYPTO_30_LIBCV_SERVICE_KEYUNWRAP == STD_ON) + case CRYPTO_KEYUNWRAP: + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->cryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_READ); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->targetCryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_WRITE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + break; +#endif +#if (CRYPTO_30_LIBCV_SERVICE_KEYWRAP == STD_ON) + case CRYPTO_KEYWRAP: + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->cryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_READ); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->targetCryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_READ); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + break; +#endif + default: + Crypto_30_LibCv_Local_KeyListAddKey(keyList, job->cryptoKeyId, CRYPTO_30_LIBCV_KEY_ACCESS_READ); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + break; + } +} /* Crypto_30_LibCv_Local_GetKeyList() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_GetKeyListAndDet() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6080 3 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_GetKeyListAndDet( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + Std_ReturnType retVal = E_OK; + uint8 i; + + /* Get key list */ + Crypto_30_LibCv_Local_GetKeyList(job, keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + + /* Check if the redirected keys have valid keyIds. */ + for (i = 0; i < keyList->numKeys; i++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND_PTR */ + { + if (keyList->keyLockList[i].keyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + retVal = E_NOT_OK; + break; + } + else + { + /* Check key list for other restrictions */ +#if ((CRYPTO_30_LIBCV_SERVICE_RANDOM == STD_ON) && (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON)) +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_OFF) + if (job->jobPrimitiveInfo->primitiveInfo->service == CRYPTO_RANDOMGENERATE) + { + Crypto_30_LibCv_PartitionInfoIterType partitionInfoIdx = 0u; + /* Check if default random key is used */ + for (partitionInfoIdx = 0u; partitionInfoIdx < Crypto_30_LibCv_GetSizeOfPartitionInfo(); partitionInfoIdx++) + { + if(Crypto_30_LibCv_GetDefaultRandomKeyOfPartitionInfo(partitionInfoIdx) == keyList->keyLockList[i].keyId) + { + retVal = E_NOT_OK; + break; + } + } + } +# endif +#endif + } + } + return retVal; +} /* Crypto_30_LibCv_Local_GetKeyListAndDet() */ + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyListPreLockKeys() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyListPreLockKeys( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + Std_ReturnType retVal = E_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + + uint8_least i; + uint8_least j; + + /* Try to obtain key locks for key list. */ + for (i = 0; i < keyList->numKeys; i++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND_PTR */ + { + if (keyList->keyLockList[i].keyAccess == CRYPTO_30_LIBCV_KEY_ACCESS_READ) /* 0 if read lock / >0 if write lock */ + { + retVal = Crypto_30_LibCv_Local_KeyReadLockGetNotProtected(keyList->keyLockList[i].keyId); + } + else + { + retVal = Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected(keyList->keyLockList[i].keyId); + } + + if (retVal != E_OK) + { + break; + } + } + + /* Locking failed, release already locked keys. */ + if (retVal != E_OK) + { + for (j = 0; j < i; j++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND_PTR */ + { + if (keyList->keyLockList[j].keyAccess == CRYPTO_30_LIBCV_KEY_ACCESS_READ) /* 0 if read lock / >0 if write lock */ + { + Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected(keyList->keyLockList[j].keyId); + } + else + { + Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected(keyList->keyLockList[j].keyId); + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyListPreLockKeys() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyListPostFreeKeys() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyListPostFreeKeys( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + uint8 i; + + /* Release already locked keys from key list. */ + for (i = 0; i < keyList->numKeys; i++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND_PTR */ + { + if (keyList->keyLockList[i].keyAccess == CRYPTO_30_LIBCV_KEY_ACCESS_READ) /* 0 if read lock / >0 if write lock */ + { + Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected(keyList->keyLockList[i].keyId); + } + else + { + Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected(keyList->keyLockList[i].keyId); + } + } +} /* Crypto_30_LibCv_Local_KeyListPostFreeKeys() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyListPreLockKeysProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyListPreLockKeysProtected( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + Std_ReturnType retVal = E_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + retVal = Crypto_30_LibCv_Local_KeyListPreLockKeys(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + + return retVal; +} /* Crypto_30_LibCv_Local_KeyListPreLockKeysProtected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyListPostFreeKeysProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyListPostFreeKeysProtected( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + Crypto_30_LibCv_Local_KeyListPostFreeKeys(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); +} /* Crypto_30_LibCv_Local_KeyListPostFreeKeysProtected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_IsKeyListValid() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_IsKeyListValid( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + boolean keysValid = TRUE; + uint8 currentKeyIdx = 0; + + /* Check if the keyList keys have valid keyIds. */ + for (currentKeyIdx = 0; currentKeyIdx < keyList->numKeys; currentKeyIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND_PTR */ + { + if (keyList->keyLockList[currentKeyIdx].keyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + keysValid = FALSE; + break; + } + } + + return keysValid; +} /* Crypto_30_LibCv_Local_IsKeyListValid() */ +#endif /* (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) */ + +#if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_IsRedirectUsed() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_IsRedirectUsed( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + boolean retVal = FALSE; + +# if(CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) + /* Check if save or restore mode is used and ignore redirection for these modes */ + if(Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_SAVE_CONTEXT) || Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_RESTORE_CONTEXT)) + { + retVal = FALSE; + } + else +# endif + /* # Check if redirection is used in the current Job. */ + if (job->jobRedirectionInfoRef != NULL_PTR) + { + retVal = TRUE; + } + else + { + /* retVal already set to FALSE */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_IsRedirectUsed() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RedirectPreSetBufferForKey() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RedirectPreSetBufferForKey( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) elementPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr, + uint8 readWrite, + Crypto_ServiceInfoType cryptoService) +{ + Std_ReturnType retVal = E_OK; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex; + + /* ----- Implementation ------------------------------------------------- */ + /* #20 Search Key Element */ + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, keyElementId, &elementIndex) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + } + else + { + /* #40 Check if read access is allowed */ + if (readWrite == CRYPTO_30_LIBCV_KEY_ACCESS_READ) + { + if (Crypto_30_LibCv_RedirectReadAccessRight[cryptoService] < (Crypto_30_LibCv_GetReadOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndex)))) + { + retVal = CRYPTO_E_KEY_READ_FAIL; + } + else if (!Crypto_30_LibCv_IsKeyElementValid(elementIndex)) + { + retVal = CRYPTO_E_KEY_NOT_VALID; + } + else + { + /* retVal is already set */ + } + } + else + { + if ((CRYPTO_30_LIBCV_WA_DENIED == (Crypto_30_LibCv_GetWriteOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndex))))|| + (!Crypto_30_LibCv_IsKeyElementPartial(elementIndex)) || Crypto_30_LibCv_IsKeyElementWriteOnce(elementIndex)) + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + } + } + + if (retVal == E_OK) + { + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic( elementIndex, elementPtr, resultLengthPtr, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE, CRYPTO_30_LIBCV_SHE_SERVICE_OTHER); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + + if (readWrite == CRYPTO_30_LIBCV_KEY_ACCESS_WRITE) + { + *resultLengthPtr = Crypto_30_LibCv_GetKeyElementLength(elementIndex); /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + else + { + if (*resultLengthPtr == 0u) + { + retVal = CRYPTO_E_KEY_EMPTY; + } + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_RedirectPreSetBufferForKey() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RedirectPreRedirKeys() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6010, 6030 3 */ /* MD_MSR_STPTH , MD_MSR_STCYC */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RedirectPreRedirKeys( + P2VAR(Crypto_30_LibCv_Redirect_Type, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) redirectBuffer, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_OK; + uint32 redirKeyLength = 0u; + Crypto_30_LibCv_SizeOfKeyStorageType elementStorageIndex = 0u; + P2CONST(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) redirInfoRef = job->jobRedirectionInfoRef; + P2VAR(Crypto_JobPrimitiveInputOutputType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) inOutRef = &job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER; + Crypto_ServiceInfoType cryptoService = job->jobPrimitiveInfo->primitiveInfo->service; + Crypto_InputOutputRedirectionConfigType redir; + + /* # Reset buffer length in start mode. */ + if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_START)) + { + redirectBuffer->firstOutputLengthWritten = 0u; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + redirectBuffer->secondaryOutputLengthWritten = 0u; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + + /* # If redirection is used. */ + if (Crypto_30_LibCv_Local_IsRedirectUsed(job) == TRUE) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + { + redir = job->jobRedirectionInfoRef->redirectionConfig; + redir &= (Crypto_30_LibCv_IOServiceMaskUpdate[cryptoService] | Crypto_30_LibCv_IOServiceMaskFinish[cryptoService]); + + redirectBuffer->jobPrimitiveInputOutput_Restore = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + + /* # Set redirection for primary input. */ + if (Crypto_30_LibCv_IsIOMask(redir, CRYPTO_REDIRECT_CONFIG_PRIMARY_INPUT)) + { + retVal = Crypto_30_LibCv_Local_RedirectPreSetBufferForKey(redirInfoRef->inputKeyId, /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + redirInfoRef->inputKeyElementId, + &elementStorageIndex, + &redirKeyLength, + CRYPTO_30_LIBCV_KEY_ACCESS_READ, + cryptoService); + inOutRef->inputPtr = Crypto_30_LibCv_GetAddrKeyStorage(elementStorageIndex); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + inOutRef->inputLength = redirKeyLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Set redirection for secondary input. */ + if ((retVal == E_OK) && + (Crypto_30_LibCv_IsIOMask(redir, CRYPTO_REDIRECT_CONFIG_SECONDARY_INPUT))) + { + retVal = Crypto_30_LibCv_Local_RedirectPreSetBufferForKey(redirInfoRef->secondaryInputKeyId, /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + redirInfoRef->secondaryInputKeyElementId, + &elementStorageIndex, + &redirKeyLength, + CRYPTO_30_LIBCV_KEY_ACCESS_READ, + cryptoService); + inOutRef->secondaryInputPtr = Crypto_30_LibCv_GetAddrKeyStorage(elementStorageIndex); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + inOutRef->secondaryInputLength = redirKeyLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Set redirection for tertiary input. */ + if ((retVal == E_OK) && + (Crypto_30_LibCv_IsIOMask(redir, CRYPTO_REDIRECT_CONFIG_TERTIARY_INPUT))) + { + retVal = Crypto_30_LibCv_Local_RedirectPreSetBufferForKey(redirInfoRef->tertiaryInputKeyId, /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + redirInfoRef->tertiaryInputKeyElementId, + &elementStorageIndex, + &redirKeyLength, + CRYPTO_30_LIBCV_KEY_ACCESS_READ, + cryptoService); + inOutRef->tertiaryInputPtr = Crypto_30_LibCv_GetAddrKeyStorage(elementStorageIndex); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + inOutRef->tertiaryInputLength = redirKeyLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Set redirection for primary output. */ + if ((retVal == E_OK) && + (Crypto_30_LibCv_IsIOMask(redir, CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT))) + { + retVal = Crypto_30_LibCv_Local_RedirectPreSetBufferForKey(redirInfoRef->outputKeyId, /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + redirInfoRef->outputKeyElementId, + &elementStorageIndex, + &redirKeyLength, + CRYPTO_30_LIBCV_KEY_ACCESS_WRITE, + cryptoService); + inOutRef->outputPtr = &Crypto_30_LibCv_GetAddrKeyStorage(elementStorageIndex)[redirectBuffer->firstOutputLengthWritten]; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + redirectBuffer->firstOutputLength = redirKeyLength - redirectBuffer->firstOutputLengthWritten; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + inOutRef->outputLengthPtr = &redirectBuffer->firstOutputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Set redirection for secondary output. */ + if ((retVal == E_OK) && + (Crypto_30_LibCv_IsIOMask(redir, CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT))) + { + retVal = Crypto_30_LibCv_Local_RedirectPreSetBufferForKey(redirInfoRef->secondaryOutputKeyId, /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + redirInfoRef->secondaryOutputKeyElementId, + &elementStorageIndex, + &redirKeyLength, + CRYPTO_30_LIBCV_KEY_ACCESS_WRITE, + cryptoService); + inOutRef->secondaryOutputPtr = &Crypto_30_LibCv_GetAddrKeyStorage(elementStorageIndex)[redirectBuffer->secondaryOutputLengthWritten]; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + redirectBuffer->secondaryOutputLength = redirKeyLength - redirectBuffer->secondaryOutputLengthWritten; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + inOutRef->secondaryOutputLengthPtr = &redirectBuffer->secondaryOutputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Restore buffer if there was a failure. */ + if (retVal != E_OK) + { + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER = redirectBuffer->jobPrimitiveInputOutput_Restore; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_RedirectPreRedirKeys() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RedirectPostSaveKeyResult() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RedirectPostSaveKeyResult( + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 resultLength, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) writtenLengthPtr, + Std_ReturnType result) +{ + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex; + + /* This can only work if the key was already redirected. */ + (void)Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, keyElementId, &elementIndex); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + Crypto_30_LibCv_ClearKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_CLEAR_NORMAL_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + + if (result == E_OK) + { + *writtenLengthPtr += resultLength; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(cryptoKeyId, elementIndex, *writtenLengthPtr); +} /* Crypto_30_LibCv_Local_RedirectPostSaveKeyResult() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RedirectPostRestoreBuffer() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RedirectPostRestoreBuffer( + P2VAR(Crypto_30_LibCv_Redirect_Type, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) redirectBuffer, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Std_ReturnType result) +{ + Crypto_InputOutputRedirectionConfigType redir; + Crypto_InputOutputRedirectionConfigType redirMask = 0; + P2CONST(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) redirInfoRef = job->jobRedirectionInfoRef; + + if (Crypto_30_LibCv_Local_IsRedirectUsed(job) == TRUE) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + { + redir = job->jobRedirectionInfoRef->redirectionConfig; + + if(Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_UPDATE)) + { + redirMask = Crypto_30_LibCv_IOServiceMaskUpdate[job->jobPrimitiveInfo->primitiveInfo->service]; + } + if(Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_FINISH)) + { + redirMask |= Crypto_30_LibCv_IOServiceMaskFinish[job->jobPrimitiveInfo->primitiveInfo->service]; + } + + redir &= redirMask; + + /* Restore IO buffer */ + if (Crypto_30_LibCv_IsIOMask(redir, CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT)) + { + Crypto_30_LibCv_Local_RedirectPostSaveKeyResult(redirInfoRef->outputKeyId, redirInfoRef->outputKeyElementId, + redirectBuffer->firstOutputLength, &(redirectBuffer->firstOutputLengthWritten), result); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + } + + if (Crypto_30_LibCv_IsIOMask(redir, CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT)) + { + Crypto_30_LibCv_Local_RedirectPostSaveKeyResult(redirInfoRef->secondaryOutputKeyId, redirInfoRef->secondaryOutputKeyElementId, + redirectBuffer->secondaryOutputLength, &(redirectBuffer->secondaryOutputLengthWritten), result); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + } + + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER = redirectBuffer->jobPrimitiveInputOutput_Restore; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } +} /* Crypto_30_LibCv_Local_RedirectPostRestoreBuffer() */ +#endif /* (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Process() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6010, 6030, 6050 5 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Process( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx) +{ + Std_ReturnType retVal; + boolean unlockingNecessary = FALSE; + boolean contextMode = FALSE; + Crypto_30_LibCv_SetProcessJob_Trigger_Write(objectId, FALSE); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + +#if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) + retVal = Crypto_30_LibCv_Local_RedirectPreRedirKeys(&Crypto_30_LibCv_GetRedirect_Buffer(objectId), job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_AND_GLOBAL_ARRAY_PTR */ + if (retVal == E_OK) +#endif + { + retVal = Crypto_30_LibCv_DispatchJob(objectId, &unlockingNecessary, &contextMode, job, primitiveInfoIdx); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + +#if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) + Crypto_30_LibCv_Local_RedirectPostRestoreBuffer(&Crypto_30_LibCv_GetRedirect_Buffer(objectId), job, retVal); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_AND_GLOBAL_ARRAY_PTR */ +#endif + } + + /* #14 Free keys in case of an error or if FINISH mode completed. */ +#if(CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) + if (((retVal != E_OK) && (contextMode == FALSE)) || (unlockingNecessary == TRUE)) +#else + if ((retVal != E_OK) || (unlockingNecessary == TRUE)) +#endif + { +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyListPostFreeKeysProtected(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ +#endif +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + if (Crypto_30_LibCv_IsProcessJob_Trigger_Write(objectId)) /* COV_CRYPTO_30_LIBCV_SERVICE_CONFIGURATION_2 */ + { + Crypto_30_LibCv_NvBlock_Write_Req(Crypto_30_LibCv_GetNvBlockIdxOfKey(job->cryptoKeyId)); + } +#endif + } + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +#if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) + if (retVal == E_OK) + { + Crypto_30_LibCv_UpdateObjectWorkspace(objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + } +# if(CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) + else if (contextMode == TRUE) + { + /* Workspace of the object should remain untouched for operation mode save or restore */ + } +# endif + else + { + Crypto_30_LibCv_ClearObjectWorkspace(objectId); + } +#endif + + /* Remove job from queue and release processing */ + Crypto_30_LibCv_SetDriverObjectState(objectId, CRYPTO_30_LIBCV_DRIVEROBJECTSTATE_IDLE); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + /* #15 Free workspace in case of an error or if FINISH mode completed. */ +#if(CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) + if (((retVal != E_OK) && (contextMode == FALSE)) || (unlockingNecessary == TRUE)) +#else + if ((retVal != E_OK) || (unlockingNecessary == TRUE)) +#endif + { + Crypto_30_LibCv_FreeLock(objectId); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_OFF) + CRYPTO_30_LIBCV_DUMMY_STATEMENT(keyList); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_LibCv_Process() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SearchService() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6080 4 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SearchService( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2VAR(Crypto_30_LibCv_SizeOfPrimitiveInfoType, AUTOMATIC, AUTOMATIC) primitiveInfoIdx) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + + Crypto_30_LibCv_PrimitiveInfoIterType primitiveInfoStartIdx, primitiveInfoEndIdx, primitiveInfoIteratorIdx; + + Crypto_30_LibCv_ObjectInfoIndIterType objectInfoIndStartIdx, objectInfoIndEndIdx, objectInfoIndIdx; + + Crypto_30_LibCv_PrimitiveFctIterType functionIdx; + + P2CONST(Crypto_PrimitiveInfoType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) primitive = job->jobPrimitiveInfo->primitiveInfo; + P2CONST(Crypto_AlgorithmInfoType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) algo = &primitive->algorithm; + + uint32 combi; + + /* ----- Implementation ----------------------------------------------- */ + /* # Check if primitive info is used */ + if (Crypto_30_LibCv_IsPrimitiveInfoUsedOfPrimitiveServiceInfo(primitive->service) == TRUE) /* COV_CRYPTO_30_LIBCV_SERVICE_CONFIGURATION */ + { + /* Get scope for iteration */ + primitiveInfoStartIdx = Crypto_30_LibCv_GetPrimitiveInfoStartIdxOfPrimitiveServiceInfo(primitive->service); + primitiveInfoEndIdx = Crypto_30_LibCv_GetPrimitiveInfoEndIdxOfPrimitiveServiceInfo(primitive->service); + + /* Generate combined value */ + combi = (((uint32)primitive->service << 24) | ((uint32)algo->family << 16) | ((uint32)algo->mode << 8) | ((uint32)algo->secondaryFamily)); + + /* # Iterate over primitive info elements */ + for (primitiveInfoIteratorIdx = primitiveInfoStartIdx; primitiveInfoIteratorIdx < primitiveInfoEndIdx; primitiveInfoIteratorIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + /* # Check for match with combined value */ + if (Crypto_30_LibCv_GetCombinedOfPrimitiveInfo(primitiveInfoIteratorIdx) == combi) + { + /* Get primitive function index */ + functionIdx = Crypto_30_LibCv_GetPrimitiveFctIdxOfPrimitiveInfo(primitiveInfoIteratorIdx); + + /* Get scope for iteration */ + objectInfoIndStartIdx = Crypto_30_LibCv_GetObjectInfoIndStartIdxOfPrimitiveFct(functionIdx); + objectInfoIndEndIdx = Crypto_30_LibCv_GetObjectInfoIndEndIdxOfPrimitiveFct(functionIdx); + + /* # Iterate over object info elements */ + for (objectInfoIndIdx = objectInfoIndStartIdx; objectInfoIndIdx < objectInfoIndEndIdx; objectInfoIndIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + /* # Check for match with object ID */ + if (Crypto_30_LibCv_GetObjectInfoInd(objectInfoIndIdx) == objectId) + { + /* Reference primitive function pointer */ + *primitiveInfoIdx = (Crypto_30_LibCv_SizeOfPrimitiveInfoType)primitiveInfoIteratorIdx; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + break; + } + } + } + + /* If found break loop */ + if (retVal == E_OK) + { + break; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_SearchService() */ + +#if(CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SaveContextJob() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SaveContextJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32 outputLength; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ----------------------------------------------- */ + outputLength = CRYPTO_30_LIBCV_WORKSPACE_SETTINGS_LENGTH + Crypto_30_LibCv_GetLengthOfSaveAndRestoreWorkspace(objectId); + + /* Check primitive context and output length */ + if ((job->jobPrimitiveInfo->primitiveInfo->service <= CRYPTO_SIGNATUREVERIFY) && (Crypto_30_LibCv_IsContextOfPrimitiveInfo(primitiveInfoIdx))) + { +# if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) + /* Check if output redirection was used in the previous calls of the current job */ + if(Crypto_30_LibCv_GetRedirect_Buffer(objectId).firstOutputLengthWritten != 0u) + { + /* No saving of output redirected job allowed. retVal already set to E_NOT_OK */ + } + else +# endif + if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr == 0u) + { + /* If the output buffer does not have the sufficient length, the expected length is written into the output buffer */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + else if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr >= outputLength) + { + /* Copy context to output [ 4 Byte ObjectId | 4 Byte Additional Info | x byte Workspace data ] */ + Crypto_30_LibCv_Local_Uint32ToUint8ArrayBigEndian(Crypto_30_LibCv_GetWorkspaceAddrOfObjectInfo(objectId), objectId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_OF_WORKSPACE */ + retVal = Appl_Crypto_30_LibCv_SaveContextCallout(objectId, + job->CRYPTO_30_LIBCV_JOB_ID_MEMBER, + (P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))Crypto_30_LibCv_GetWorkspaceAddrOfObjectInfo(objectId), + outputLength, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_OF_WORKSPACE */ + } + else + { + /* retval already set */ + } + } + + return retVal; +} /* Crypto_30_LibCv_SaveContextJob() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RestoreContextJob() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RestoreContextJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32 inputLength; + uint32 inputObjectId; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ----------------------------------------------- */ + /* Check if primitive context is set */ + if ((job->jobPrimitiveInfo->primitiveInfo->service <= CRYPTO_SIGNATUREVERIFY) && (Crypto_30_LibCv_IsContextOfPrimitiveInfo(primitiveInfoIdx))) + { + /* Get workspace address and length [ 4 byte ObjectId | 4 Byte Additional Info | x byte Workspace Data ] */ + (void) Crypto_30_LibCv_GetDispatchOfPrimitiveFct(Crypto_30_LibCv_GetPrimitiveFctIdxOfPrimitiveInfo(primitiveInfoIdx))(objectId, job, CRYPTO_OPERATIONMODE_RESTORE_CONTEXT); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + inputLength = CRYPTO_30_LIBCV_WORKSPACE_SETTINGS_LENGTH + Crypto_30_LibCv_GetLengthOfSaveAndRestoreWorkspace(objectId); + + /* Check if the input length is correct */ + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength >= inputLength) + { + /* Write Workspace data to the Workspace address */ + retVal = Appl_Crypto_30_LibCv_RestoreContextCallout(objectId, + job->CRYPTO_30_LIBCV_JOB_ID_MEMBER, + (P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))Crypto_30_LibCv_GetWorkspaceAddrOfObjectInfo(objectId), + inputLength, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_OF_WORKSPACE */ + + if (retVal == E_OK) + { + /* Get objectId */ + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&inputObjectId, Crypto_30_LibCv_GetWorkspaceAddrOfObjectInfo(objectId)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (inputObjectId == objectId) + { + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + } + } + + return retVal; +} /* Crypto_30_LibCv_RestoreContextJob() */ +#endif + +#if(CRYPTO_30_LIBCV_SERVICE_SIGNATURE_GENERATE == STD_ON || CRYPTO_30_LIBCV_SERVICE_SIGNATURE_VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_HandleOptionalInputDataInFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_HandleOptionalInputDataInFinish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx) +{ + Std_ReturnType retVal = E_NOT_OK; + Crypto_ServiceInfoType jobService = job->jobPrimitiveInfo->primitiveInfo->service; + + switch (jobService) + { +# if(CRYPTO_30_LIBCV_SERVICE_SIGNATURE_GENERATE == STD_ON) + case CRYPTO_SIGNATUREGENERATE: +# endif +# if(CRYPTO_30_LIBCV_SERVICE_SIGNATURE_VERIFY == STD_ON) + case CRYPTO_SIGNATUREVERIFY: +# endif + /* Check that the current job mode does not include UPDATE to omit that the input data is processed twice (in UPDATE and in FINISH) */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength > 0u) && (!Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_UPDATE))) + { + retVal = Crypto_30_LibCv_GetDispatchOfPrimitiveFct(Crypto_30_LibCv_GetPrimitiveFctIdxOfPrimitiveInfo(primitiveInfoIdx))(objectId, job, CRYPTO_OPERATIONMODE_UPDATE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + } + else + { + retVal = E_OK; + } + break; + + default: + /* Do not handle input data, retVal already E_OK */ + retVal = E_OK; + break; + } + return retVal; +} /* Crypto_30_LibCv_HandleOptionalInputDataInFinish() */ +#endif /* ((CRYPTO_30_LIBCV_SERVICE_SIGNATURE_GENERATE == STD_ON) || (CRYPTO_30_LIBCV_SERVICE_SIGNATURE_VERIFY == STD_ON)) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchJob() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchJob( + uint32 objectId, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) unlockingNecessary, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) contextMode, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx) +{ + Std_ReturnType retVal = E_NOT_OK; + + /* #10 Dispatch job according to job mode in START, UPDATE, FINISH, SAVE or Restore. */ + /* [SWS_Crypto_00017] [SWS_Crypto_00020] START while IDLE or ACTIVE */ + if (((job->CRYPTO_30_LIBCV_JOB_STATE_MEMBER == CRYPTO_JOBSTATE_IDLE) || + (job->CRYPTO_30_LIBCV_JOB_STATE_MEMBER == CRYPTO_JOBSTATE_ACTIVE)) && + Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_START)) + { + retVal = Crypto_30_LibCv_GetDispatchOfPrimitiveFct(Crypto_30_LibCv_GetPrimitiveFctIdxOfPrimitiveInfo(primitiveInfoIdx))(objectId, job, CRYPTO_OPERATIONMODE_START); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + Crypto_30_LibCv_UpdateJobState(retVal, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + } + + /* UPDATE while ACTIVE */ + if ((job->CRYPTO_30_LIBCV_JOB_STATE_MEMBER == CRYPTO_JOBSTATE_ACTIVE) && + Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_UPDATE)) /* [SWS_Crypto_00024] */ + { + retVal = Crypto_30_LibCv_GetDispatchOfPrimitiveFct(Crypto_30_LibCv_GetPrimitiveFctIdxOfPrimitiveInfo(primitiveInfoIdx))(objectId, job, CRYPTO_OPERATIONMODE_UPDATE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + Crypto_30_LibCv_UpdateJobState(retVal, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + } + + /* [SWS_Crypto_00023] FINISH while ACTIVE */ + if ((job->CRYPTO_30_LIBCV_JOB_STATE_MEMBER == CRYPTO_JOBSTATE_ACTIVE) && + Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_FINISH)) /* [SWS_Crypto_00024] */ + { +#if(CRYPTO_30_LIBCV_SERVICE_SIGNATURE_GENERATE == STD_ON || CRYPTO_30_LIBCV_SERVICE_SIGNATURE_VERIFY == STD_ON) + /* Enable signature services to process optional input data. */ + retVal = Crypto_30_LibCv_HandleOptionalInputDataInFinish(objectId, job, primitiveInfoIdx); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + + if(retVal == E_OK) +#endif + { + retVal = Crypto_30_LibCv_GetDispatchOfPrimitiveFct(Crypto_30_LibCv_GetPrimitiveFctIdxOfPrimitiveInfo(primitiveInfoIdx))(objectId, job, CRYPTO_OPERATIONMODE_FINISH); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + } + job->CRYPTO_30_LIBCV_JOB_STATE_MEMBER = CRYPTO_JOBSTATE_IDLE; /* SBSW_CRYPTO_30_LIBCV_DIRECT_ACCESS_TO_JOB_STATE */ + *unlockingNecessary = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } +#if(CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) + /* SAVE while ACTIVE */ + if ((job->CRYPTO_30_LIBCV_JOB_STATE_MEMBER == CRYPTO_JOBSTATE_ACTIVE) && + Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_SAVE_CONTEXT)) /* [SWS_Crypto_00024] */ + { + retVal = Crypto_30_LibCv_SaveContextJob(objectId, job, primitiveInfoIdx); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + job->CRYPTO_30_LIBCV_JOB_STATE_MEMBER = CRYPTO_JOBSTATE_ACTIVE; /* SBSW_CRYPTO_30_LIBCV_DIRECT_ACCESS_TO_JOB_STATE */ + *contextMode = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + /* RESTORE the workspace */ + if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_RESTORE_CONTEXT)) /* [SWS_Crypto_00024] */ + { + retVal = Crypto_30_LibCv_RestoreContextJob(objectId, job, primitiveInfoIdx); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + Crypto_30_LibCv_UpdateJobState(retVal, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + *contextMode = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(*contextMode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ +#endif + + return retVal; +} /* Crypto_30_LibCv_DispatchJob() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_TryToSetJobInQueue() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_TryToSetJobInQueue( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_LibCv_QueueIdxOfObjectInfoType queueIdx = Crypto_30_LibCv_GetQueueIdxOfObjectInfo(objectId); + boolean queueJob = FALSE; + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + /* #10 Check if queue is full */ + if (Crypto_30_LibCv_GetQueue(queueIdx) != NULL_PTR) + { + retVal = CRYPTO_E_QUEUE_FULL; + } + /* #20 Queue job if driver object lock is already set by the same job */ + else if ((Crypto_30_LibCv_IsLockOccupiedByJob(objectId, job->CRYPTO_30_LIBCV_JOB_ID_MEMBER)) == TRUE) + { + /* Previously already a start or restore job was processed, therefore the lock is set */ + queueJob = TRUE; + } + /* #30 Check if job is a start or restore job */ +#if (CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) + else if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_START) || Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_RESTORE_CONTEXT)) +#else + else if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_START)) +#endif + { + /* #35 Queue job if the driver object lock is not set */ + if (Crypto_30_LibCv_IsLockFree(objectId)) + { + /* Job is start or restore job */ + queueJob = TRUE; + } + else + { + /* Another job is currently processing */ + retVal = CRYPTO_E_QUEUE_FULL; + } + } + else + { + retVal = E_NOT_OK; + } + + if (queueJob) + { + Crypto_30_LibCv_SetQueue(queueIdx, job); /* SBSW_CRYPTO_30_LIBCV_CSL02_QUEUE_VIA_DRIVEROBJECT */ + Crypto_30_LibCv_SetDispatch_QueuePrimitiveInfoIdx(objectId, primitiveInfoIdx); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + retVal = E_OK; + } + + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + return retVal; +} /* Crypto_30_LibCv_TryToSetJobInQueue() */ + +#if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS > 1u) +/********************************************************************************************************************** + * Crypto_30_LibCv_GetPartitionIdx() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(uint32, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_GetPartitionIdx(void) +{ + uint32 partitionIdx = Crypto_30_LibCv_GetSizeOfPartitionIdentifiers(); + + Crypto_30_LibCv_PartitionIdentifiersIterType partitionIdentifierIdx = 0u; + ApplicationType applicationId = GetApplicationID(); + + for(partitionIdentifierIdx = 0u; partitionIdentifierIdx < Crypto_30_LibCv_GetSizeOfPartitionIdentifiers(); partitionIdentifierIdx++) + { + if(applicationId == Crypto_30_LibCv_GetPartitionSNVOfPartitionIdentifiers(partitionIdentifierIdx)) + { + partitionIdx = Crypto_30_LibCv_GetPCPartitionConfigIdxOfPartitionIdentifiers(partitionIdentifierIdx); + break; + } + } + return (uint32)partitionIdx; +} /* Crypto_30_LibCv_GetPartitionIdx() */ +#endif + +/********************************************************************************************************************** + * Crypto_30_LibCv_InitMainPartition() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + */ + /* PRQA S 6010 1 */ /* MD_MSR_STPTH */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_InitMainPartition( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) errorIdPtr) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_2 */ +{ + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #5 Check initialization state of the component. */ + if (Crypto_30_LibCv_IsModuleSharedInitialized()) + { + *errorIdPtr = CRYPTO_E_INIT_FAILED; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + else +#endif + { + Crypto_30_LibCv_KeyElementsIterType elementIndex; + Crypto_30_LibCv_SizeOfKeyType keyIndex; +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) + Crypto_30_LibCv_SheKeysIterType sheKeyIndex; +#endif + Crypto_30_LibCv_QueueIterType queueIdx; + Crypto_30_LibCv_LockIterType lockIdx; +#if (CRYPTO_30_LIBCV_LONGTERMWS == STD_ON) + Crypto_30_LibCv_LongTermWsLockIterType longWsLockIdx; +#endif +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + Crypto_30_LibCv_SizeOfNvBlockType blockIdx; +#endif + + /* #10 Initialize key elements which have a configured initial value. */ + for (elementIndex = 0u; elementIndex < Crypto_30_LibCv_GetSizeOfKeyElements(); elementIndex++) + { +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + if (Crypto_30_LibCv_IsKeyElementPersist(elementIndex)) + { + Crypto_30_LibCv_Init_KeySimple(elementIndex); + } + else +#endif + { + Crypto_30_LibCv_Init_Key(elementIndex, FALSE); + } + } + +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) + for (sheKeyIndex = 0u; sheKeyIndex < Crypto_30_LibCv_GetSizeOfSheKeys(); sheKeyIndex++) + { + + elementIndex = Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(sheKeyIndex); + Crypto_30_LibCv_Init_KeySheAdditional(elementIndex); + } +# if (CRYPTO_30_LIBCV_SHE_DEBUG_CMD == STD_ON) + /* It is only allowed to access this data if the SheInfoKey is locked */ + Crypto_30_LibCv_She_Debug_Cmd_ChallengeFlag = FALSE; +# endif +#endif +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + for (blockIdx = 0u; blockIdx < Crypto_30_LibCv_GetSizeOfNvBlock(); blockIdx++) + { + Crypto_30_LibCv_NvBlock_State_Init(blockIdx); + } +#endif + /* #15 Free all locks of workspaces. */ + for (lockIdx = 0u; lockIdx < Crypto_30_LibCv_GetSizeOfLock(); lockIdx++) + { + Crypto_30_LibCv_FreeLock(lockIdx); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } + +#if (CRYPTO_30_LIBCV_LONGTERMWS == STD_ON) + /* #17 Free all locks of long term workspaces. */ + for (longWsLockIdx = 0u; longWsLockIdx < Crypto_30_LibCv_GetSizeOfLongTermWsLock(); longWsLockIdx++) + { + Crypto_30_LibCv_SetLongTermWsLock(longWsLockIdx, CRYPTO_30_LIBCV_LONG_TERM_WS_LOCK_FREE); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } +#endif + + /* #20 Clear job queue. */ + for (queueIdx = 0u; queueIdx < Crypto_30_LibCv_GetSizeOfQueue(); queueIdx++) + { + Crypto_30_LibCv_SetQueue(queueIdx, NULL_PTR); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } + + for (keyIndex = 0u; keyIndex < Crypto_30_LibCv_GetSizeOfKey(); keyIndex++) + { + /* #21 Init key locks. */ + Crypto_30_LibCv_SetKeyLock(keyIndex, CRYPTO_30_LIBCV_KEY_LOCK_FREE); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + +#if(CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + /* #22 Init key Nv status */ + Crypto_30_LibCv_KeyNvStatus_InitKey(keyIndex); +#endif + } + + /* Set module partition state to initialized */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* Set shared data and general module state to initialized */ + Crypto_30_LibCv_ModuleInitialized = CRYPTO_30_LIBCV_INITIALIZED; +#endif + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_OFF) + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorIdPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif +} /* Crypto_30_LibCv_InitMainPartition() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_InitPartitionSpecificData() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_InitPartitionSpecificData(uint32 partitionIdx, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) errorIdPtr) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_2 */ +{ + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #5 Check initialization state of the partition. */ + if (Crypto_30_LibCv_IsModulePartitionInitialized(partitionIdx)) + { + *errorIdPtr = CRYPTO_E_INIT_FAILED; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + else +#endif + { + Crypto_30_LibCv_ObjectInfoIterType objectId; + +#if (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) + Crypto_30_LibCv_SetRandomSourceGenerateCount(0u, partitionIdx); /* SBSW_CRYPTO_30_LIBCV_WRITE_PARTITION_DATA */ +#endif + + /* #25 Init Driver Object State. */ + for (objectId = 0u; objectId < Crypto_30_LibCv_GetSizeOfObjectInfo(); objectId++) + { +#if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS > 1u) + if (partitionIdx == Crypto_30_LibCv_CurrentPartitionIdxViaObject(objectId)) +#endif + { + Crypto_30_LibCv_SetDriverObjectState(objectId, CRYPTO_30_LIBCV_DRIVEROBJECTSTATE_IDLE); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ +#if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) + /* clear the last object workspace type */ + Crypto_30_LibCv_SetKeyIdOfLastJob(objectId, CRYPTO_30_LIBCV_UINT32_MAX); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetFamilyOfLastJob(objectId, CRYPTO_ALGOFAM_NOT_SET); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetModeOfLastJob(objectId, CRYPTO_ALGOMODE_NOT_SET); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ +#endif + +#if (CRYPTO_30_LIBCV_FIPS186 == STD_ON) + if (Crypto_30_LibCv_GetRandomSeedBufferStartIdxOfObjectInfo(objectId) != CRYPTO_30_LIBCV_NO_RANDOMSEEDBUFFERENDIDXOFOBJECTINFO) + { + Crypto_30_LibCv_SetRandomSeedBuffer(Crypto_30_LibCv_GetRandomSeedBufferStartIdxOfObjectInfo(objectId), CRYPTO_30_LIBCV_KEYELEMENTSTATE_CLEAR_ALL_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } +#endif + +#if(CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) + Crypto_30_LibCv_ClearData(Crypto_30_LibCv_GetWorkspaceAddrOfObjectInfo(objectId), Crypto_30_LibCv_GetWorkspaceLengthOfObjectInfo(objectId)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_OF_WORKSPACE */ +#endif + } + } + + /* Set module partition state to initialized */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + Crypto_30_LibCv_SetPartitionInitialized(CRYPTO_30_LIBCV_INITIALIZED, partitionIdx); /* SBSW_CRYPTO_30_LIBCV_WRITE_PARTITION_DATA */ +#endif + } + +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_OFF) + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorIdPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + +#if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS < 2u) + CRYPTO_30_LIBCV_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif +} /* Crypto_30_LibCv_InitPartitionSpecificData() */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * Crypto_30_LibCv_InitMemoryHandler() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_InitMemoryHandler(uint32 partitionIdx) +{ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #5 Uninitialize module. */ +# if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS > 1u) + if (partitionIdx == Crypto_30_LibCv_MainPartitionIdx) +# endif + { + Crypto_30_LibCv_ModuleInitialized = (uint8)CRYPTO_30_LIBCV_UNINIT; + } + + Crypto_30_LibCv_SetPartitionInitialized(CRYPTO_30_LIBCV_UNINIT, partitionIdx); /* SBSW_CRYPTO_30_LIBCV_WRITE_PARTITION_DATA */ +#endif + + CRYPTO_30_LIBCV_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +} /* Crypto_30_LibCv_InitMemoryHandler() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Init_KeySimple() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Init_KeySimple( + Crypto_30_LibCv_KeyElementsIterType elementIndex) +{ + Crypto_30_LibCv_SizeOfKeyStorageType keyStorageIdx; + + /* clear extension */ + Crypto_30_LibCv_SetKeyElementExtension(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_CLEAR_ALL_MASK); /* SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_INIT */ + keyStorageIdx = Crypto_30_LibCv_GetKeyStorageWrittenLengthStartIdxOfKeyElements(elementIndex); + Crypto_30_LibCv_SetKeyStorage(keyStorageIdx, 0u); /* SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_INIT */ + Crypto_30_LibCv_SetKeyStorage(keyStorageIdx + 1u, 0u); /* SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_INIT */ + Crypto_30_LibCv_SetKeyElementState(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_CLEAR_ALL_MASK); /* SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_INIT */ + +} /* Crypto_30_LibCv_Init_KeySimple() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Init_Key() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Init_Key( + Crypto_30_LibCv_KeyElementsIterType elementIndex, + boolean initAllBytes) +{ +#if (CRYPTO_30_LIBCV_INITVALUE == STD_ON) + Crypto_30_LibCv_InitValueStartIdxOfKeyElementInfoType initValueIdx; + uint16 initValueLength; +#endif + Crypto_30_LibCv_SizeOfKeyStorageType keyStorageIdx; + uint32 keyElementLength; + + keyStorageIdx = Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(elementIndex); + keyElementLength = (uint32)Crypto_30_LibCv_GetLengthOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndex)); + +#if (CRYPTO_30_LIBCV_INITVALUE == STD_ON) + /* Fill elements with init values */ + if (Crypto_30_LibCv_HasKeyElementInitValue(elementIndex)) + { + initValueIdx = Crypto_30_LibCv_GetInitValueStartIdxOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndex)); + initValueLength = (uint16)Crypto_30_LibCv_GetKeyElementInitValueLength(elementIndex); + + /* Store the init value t the key element */ + Crypto_30_LibCv_CopyData(Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIdx), Crypto_30_LibCv_GetAddrInitValue(initValueIdx), (uint32)initValueLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + + if (initAllBytes) + { + /* Initialize remaining bytes with zeros. */ + Crypto_30_LibCv_ClearData(Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIdx + initValueLength), (uint32)(keyElementLength- initValueLength)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + } + /* clear extension */ + Crypto_30_LibCv_SetKeyElementExtension(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_CLEAR_ALL_MASK); /* SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_INIT */ + + /* Set the size of the init value written to the element */ + keyStorageIdx = Crypto_30_LibCv_GetKeyStorageWrittenLengthStartIdxOfKeyElements(elementIndex); + Crypto_30_LibCv_SetKeyStorage(keyStorageIdx, (uint8)(Crypto_30_LibCv_GetKeyElementInitValueLength(elementIndex) >> 8)); /* SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_INIT */ + Crypto_30_LibCv_SetKeyStorage(keyStorageIdx + 1u, (uint8)(Crypto_30_LibCv_GetKeyElementInitValueLength(elementIndex))); /* SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_INIT */ + Crypto_30_LibCv_SetKeyElementState(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_MASK); /* SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_INIT */ + } + else +#endif + { + Crypto_30_LibCv_Init_KeySimple(elementIndex); + if (initAllBytes) + { + /* Initialize data bytes with zeros. */ + Crypto_30_LibCv_ClearData(Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIdx), keyElementLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + } + } +} /* Crypto_30_LibCv_Init_Key() */ + +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Init_KeySheAdditional() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Init_KeySheAdditional( + Crypto_30_LibCv_KeyElementsIterType elementIndex) +{ + Crypto_30_LibCv_SetKeyElementExtension(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_SHE_KEY_MASK); /* SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_INIT */ + /* SHE keys are invalid also if they have an init value. */ + Crypto_30_LibCv_SetKeyElementState(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_CLEAR_ALL_MASK); /* SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_INIT */ +} /* Crypto_30_LibCv_Init_KeySheAdditional() */ +#endif + +/********************************************************************************************************************** + * Crypto_30_LibCv_Init() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Init(void) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + uint32 partitionIdx = Crypto_30_LibCv_CurrentPartitionIdx(); + +#if (CRYPTO_30_LIBCV_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + if (partitionIdx < Crypto_30_LibCv_GetSizeOfPartitionIdentifiers()) +#endif + { +#if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS > 1u) + if (partitionIdx == Crypto_30_LibCv_MainPartitionIdx) +#endif + { + /* #10 Initialize shared data */ + Crypto_30_LibCv_InitMainPartition(&errorId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + if(errorId == CRYPTO_E_NO_ERROR) +#endif + { + /* #20 Initialize partition specific data */ + Crypto_30_LibCv_InitPartitionSpecificData(partitionIdx, &errorId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + } +#if (CRYPTO_30_LIBCV_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + else + { + errorId = CRYPTO_E_INIT_FAILED; + } +#endif + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError(CRYPTO_30_LIBCV_MODULE_ID, CRYPTO_30_LIBCV_INSTANCE_ID, CRYPTO_30_LIBCV_SID_INIT, errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif +} /* Crypto_30_LibCv_Init() */ + +#if (CRYPTO_30_LIBCV_VERSION_INFO_API == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_GetVersionInfo() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_GetVersionInfo( + P2VAR(Std_VersionInfoType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) versioninfo) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #5 Check plausibility of parameters. */ + if (versioninfo == NULL_PTR) + { + /* [SWS_Crypto_00042] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #10 Write versionInfo pointer with modules versions. */ + versioninfo->vendorID = (uint16)CRYPTO_30_LIBCV_VENDOR_ID; /* SBSW_CRYPTO_30_LIBCV_GETVERSIONINFO */ + versioninfo->moduleID = (uint8)CRYPTO_30_LIBCV_MODULE_ID; /* SBSW_CRYPTO_30_LIBCV_GETVERSIONINFO */ + versioninfo->sw_major_version = (uint8)CRYPTO_30_LIBCV_SW_MAJOR_VERSION; /* SBSW_CRYPTO_30_LIBCV_GETVERSIONINFO */ + versioninfo->sw_minor_version = (uint8)CRYPTO_30_LIBCV_SW_MINOR_VERSION; /* SBSW_CRYPTO_30_LIBCV_GETVERSIONINFO */ + versioninfo->sw_patch_version = (uint8)CRYPTO_30_LIBCV_SW_PATCH_VERSION; /* SBSW_CRYPTO_30_LIBCV_GETVERSIONINFO */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + (uint8)CRYPTO_30_LIBCV_SID_GET_VERSION_INFO, + errorId); + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif +} /* Crypto_30_LibCv_GetVersionInfo() */ +#endif /* (CRYPTO_30_LIBCV_VERSION_INFO_API == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_MainFunctionHandler() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_MainFunctionHandler(uint32 partitionIdx) +{ + /* ----- Local Variables ---------------------------------------------- */ + Crypto_30_LibCv_ObjectInfoIterType objectId; + + /* ----- Implementation ----------------------------------------------- */ + +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #1 Check initialization state of the component. */ + if (Crypto_30_LibCv_IsModulePartitionInitialized(partitionIdx) && Crypto_30_LibCv_IsModuleSharedInitialized()) /* PRQA S 3415 */ /* MD_CRYPTO_30_LIBCV_3415_LOGICAL_OPERATOR */ +#endif + { + /* #2 Process NvM handling */ +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) +# if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS > 1u) + if (partitionIdx == Crypto_30_LibCv_MainPartitionIdx) +# endif + { + Crypto_30_LibCv_NvBlock_MainFunction(); + } +#endif + + /* #5 Process next enqueued job for all available queues. */ + for (objectId = 0u; objectId < Crypto_30_LibCv_GetSizeOfObjectInfo(); objectId++) + { +#if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS > 1u) + if (partitionIdx == Crypto_30_LibCv_CurrentPartitionIdxViaObject(objectId)) +#endif + { + Crypto_30_LibCv_CheckQueueAndLockAndProcess((uint32)objectId); + } + } + } + +#if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS < 2u) + CRYPTO_30_LIBCV_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif +} /* Crypto_30_LibCv_MainFunctionHandler() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_ProcessJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6030,6050,6080 3 */ /* MD_MSR_STCYC,MD_MSR_STCAL,MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_ProcessJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Crypto_30_LibCv_KeyLockListType keyList; + Crypto_30_LibCv_SizeOfPrimitiveInfoType primitiveInfoIdx = 0u; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* [SWS_Crypto_00057] */ + /* #5 Check initialization state of the component. */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + errorId = CRYPTO_E_UNINIT; + } + /* [SWS_Crypto_00058] */ + /* #10 Check plausibility of parameters. */ + + /* [SWS_Crypto_00059] Check if job is a null pointer */ + else if (job == NULL_PTR) + { + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (Crypto_30_LibCv_Local_DetChecksServiceValues(job, &errorId) != E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + { + /* Error Id is set by sub-function */ + } + else +#endif + if (objectId >= Crypto_30_LibCv_GetSizeOfObjectInfo()) + { + errorId = CRYPTO_E_PARAM_HANDLE; + } +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* [SWS_Crypto_00057] */ + /* #5 Check initialization state of the component. */ + else if (Crypto_30_LibCv_IsModulePartitionNotInitialized(Crypto_30_LibCv_CurrentPartitionIdxViaObject(objectId))) + { + errorId = CRYPTO_E_UNINIT; + } +#endif + else if (Crypto_30_LibCv_Local_GetKeyListAndDet(job, &keyList) != E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + { + errorId = CRYPTO_E_PARAM_HANDLE; + } + else if (Crypto_30_LibCv_SearchService(objectId, job, &primitiveInfoIdx) != E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + { + /* [SWS_Crypto_00064], [SWS_Crypto_00067] combination of service, (secondary) family and mode is not supported */ + errorId = CRYPTO_E_PARAM_HANDLE; + } +#if (CRYPTO_30_LIBCV_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + else if (Crypto_30_LibCv_CurrentPartitionIdx() != Crypto_30_LibCv_CurrentPartitionIdxViaObject(objectId)) + { + errorId = CRYPTO_E_PARAM_HANDLE; + } +#endif + else + { +#if (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) + if (Crypto_30_LibCv_IsDefaultRandomSourceOfPrimitiveInfo(primitiveInfoIdx)) + { + uint32 defaultRandomKey = Crypto_30_LibCv_GetDefaultRandomKeyOfPartitionInfo(Crypto_30_LibCv_CurrentPartitionIdxViaObject(objectId)); + Crypto_30_LibCv_Local_KeyListAddKey(&keyList, defaultRandomKey, CRYPTO_30_LIBCV_KEY_ACCESS_READ); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + } +#endif + + /* #15 Directly process job if it is synchronous. */ + if (job->jobPrimitiveInfo->processingType == CRYPTO_PROCESSING_SYNC) + { + retVal = Crypto_30_LibCv_TryObtainingLockAndLockKeys(objectId, job, &keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + retVal = Crypto_30_LibCv_Process(objectId, job, &keyList, primitiveInfoIdx); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + } + } + else + { + /* #20 Otherwise handle job asynchronously. */ + retVal = Crypto_30_LibCv_TryToSetJobInQueue(objectId, job, primitiveInfoIdx); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError(CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_PROCESS_JOB, + errorId); + } +# if (CRYPTO_30_LIBCV_SERVICE_RANDOM == STD_ON) + if (retVal == CRYPTO_E_ENTROPY_EXHAUSTION) + { + (void)Det_ReportRuntimeError(CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_PROCESS_JOB, + CRYPTO_E_RE_ENTROPY_EXHAUSTED); + } +# endif +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_ProcessJob() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_CancelJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + */ +/* PRQA S 6030, 6080 3 */ /* MD_MSR_STCYC, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_CancelJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* [SWS_Crypto_00123] */ + /* #5 Check initialization state of the component. */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + errorId = CRYPTO_E_UNINIT; + } + /* [SWS_Crypto_00124] */ + /* #10 Check plausibility of parameters. */ + /* [SWS_Crypto_00125] Check if job is a null pointer */ + else if (job == NULL_PTR) + { + errorId = CRYPTO_E_PARAM_POINTER; + } + else +#endif + if (objectId >= Crypto_30_LibCv_GetSizeOfObjectInfo()) + { + errorId = CRYPTO_E_PARAM_HANDLE; + } + else +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_LibCv_IsModulePartitionNotInitialized(Crypto_30_LibCv_CurrentPartitionIdxViaObject(objectId))) + { + errorId = CRYPTO_E_UNINIT; + } + else +#endif + { + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* Driver object is not processing anything at the moment */ + if (Crypto_30_LibCv_GetDriverObjectState(objectId) == CRYPTO_30_LIBCV_DRIVEROBJECTSTATE_IDLE) + { + Crypto_30_LibCv_QueueIdxOfObjectInfoType queueIdx = Crypto_30_LibCv_GetQueueIdxOfObjectInfo(objectId); + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) queuedJob = Crypto_30_LibCv_GetQueue(queueIdx); + + if ((queuedJob != NULL_PTR) && + (queuedJob->CRYPTO_30_LIBCV_JOB_ID_MEMBER == job->CRYPTO_30_LIBCV_JOB_ID_MEMBER)) + { + Crypto_30_LibCv_SetQueue(queueIdx, NULL_PTR); /* SBSW_CRYPTO_30_LIBCV_CSL02_QUEUE_VIA_DRIVEROBJECT */ +#if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) + Crypto_30_LibCv_ClearObjectWorkspace(objectId); +#endif + retVal = E_OK; + } + + if (Crypto_30_LibCv_IsLockOccupiedByJob(objectId, job->CRYPTO_30_LIBCV_JOB_ID_MEMBER)) + { + Crypto_30_LibCv_KeyLockListType keyList; + Crypto_30_LibCv_Local_GetKeyList(job, &keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + Crypto_30_LibCv_FreeLock(objectId); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + job->CRYPTO_30_LIBCV_JOB_STATE_MEMBER = CRYPTO_JOBSTATE_IDLE; /* SBSW_CRYPTO_30_LIBCV_ACCESS_OF_JOB_MEMBER_CANCEL_JOB */ +#if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) + Crypto_30_LibCv_ClearObjectWorkspace(objectId); +#endif +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + Crypto_30_LibCv_Local_KeyListPostFreeKeysProtected(&keyList); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +#endif + retVal = E_OK; + } + } + + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + if (retVal == E_OK) + { + if (job->jobPrimitiveInfo->processingType == CRYPTO_PROCESSING_ASYNC) + { + CryIf_CallbackNotification(job, CRYPTO_E_JOB_CANCELED); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + } + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError(CRYPTO_30_LIBCV_MODULE_ID, CRYPTO_30_LIBCV_INSTANCE_ID, CRYPTO_30_LIBCV_SID_CANCEL_JOB, errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_CancelJob() */ + +#if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_GetKeyListRedirection() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_GetKeyListRedirection( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + Crypto_30_LibCv_Local_GetKeyListRedirection(job, keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ +} /* Crypto_30_LibCv_Api_GetKeyListRedirection() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_RedirectPreRedirKeys() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_RedirectPreRedirKeys( + P2VAR(Crypto_30_LibCv_Redirect_Type, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) redirectBuffer, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_KeyLockListType keyList; + + if (Crypto_30_LibCv_Local_GetKeyListAndDet(job, &keyList) != E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + { + retVal = E_NOT_OK; + } + else + { + retVal = Crypto_30_LibCv_Local_RedirectPreRedirKeys(redirectBuffer, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } + + return retVal; +} /* Crypto_30_LibCv_Api_RedirectPreRedirKeys() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_RedirectPostRestoreBuffer() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_RedirectPostRestoreBuffer( + P2VAR(Crypto_30_LibCv_Redirect_Type, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) redirectBuffer, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Std_ReturnType result) +{ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_KeyLockListType keyList; + + if (Crypto_30_LibCv_Local_GetKeyListAndDet(job, &keyList) != E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + { + retVal = E_NOT_OK; + } + else + { + Crypto_30_LibCv_Local_RedirectPostRestoreBuffer(redirectBuffer, job, result); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Api_RedirectPostRestoreBuffer() */ +#endif /* (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyListAddKey() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyListAddKey( + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList, + uint32 cryptoKeyId, + uint8 keyAccess) +{ + Std_ReturnType retVal = E_NOT_OK; + + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + retVal = E_NOT_OK; + } + else + { + Crypto_30_LibCv_Local_KeyListAddKey(keyList, cryptoKeyId, keyAccess); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Api_KeyListAddKey() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyListPreLockKeys() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyListPreLockKeys( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + Std_ReturnType retVal = E_NOT_OK; + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + boolean keysValid = FALSE; + + /* Check if the keyList keys have valid keyIds. */ + keysValid = Crypto_30_LibCv_Local_IsKeyListValid(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + + if (keysValid) + { + retVal = Crypto_30_LibCv_Local_KeyListPreLockKeys(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } +#else + retVal = E_OK; + CRYPTO_30_LIBCV_DUMMY_STATEMENT(keyList); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_LibCv_Api_KeyListPreLockKeys() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyListPostFreeKeys() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyListPostFreeKeys( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + Std_ReturnType retVal = E_NOT_OK; + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + boolean keysValid = FALSE; + + /* Check if the keyList keys have valid keyIds. */ + keysValid = Crypto_30_LibCv_Local_IsKeyListValid(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + + if (keysValid) + { + Crypto_30_LibCv_Local_KeyListPostFreeKeys(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + retVal = E_OK; + } +#else + retVal = E_OK; + CRYPTO_30_LIBCV_DUMMY_STATEMENT(keyList); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_LibCv_Api_KeyListPostFreeKeys() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyListPreLockKeysProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyListPreLockKeysProtected( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + Std_ReturnType retVal = E_NOT_OK; + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + boolean keysValid = FALSE; + + /* Check if the keyList keys have valid keyIds. */ + keysValid = Crypto_30_LibCv_Local_IsKeyListValid(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + + if (keysValid) + { + retVal = Crypto_30_LibCv_Local_KeyListPreLockKeysProtected(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } +#else + retVal = E_OK; + CRYPTO_30_LIBCV_DUMMY_STATEMENT(keyList); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_LibCv_Api_KeyListPreLockKeysProtected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyListPostFreeKeysProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyListPostFreeKeysProtected( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList) +{ + Std_ReturnType retVal = E_NOT_OK; + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + boolean keysValid = FALSE; + + /* Check if the keyList keys have valid keyIds. */ + keysValid = Crypto_30_LibCv_Local_IsKeyListValid(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + + if (keysValid) + { + Crypto_30_LibCv_Local_KeyListPostFreeKeysProtected(keyList); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + retVal = E_OK; + } +#else + retVal = E_OK; + CRYPTO_30_LIBCV_DUMMY_STATEMENT(keyList); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_LibCv_Api_KeyListPostFreeKeysProtected() */ +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Module specific MISRA deviations + *********************************************************************************************************************/ +/* Module specific MISRA deviations: + +MD_CRYPTO_30_LIBCV_STPAR_ASR: +Reason: Internal forwarding of parameters of an AUTOSAR API. +Risk: Code is difficult to maintain. Poor readability of the code due to too many input parameters. +Prevention: Design and code review. Clearly structured and commented code. + +MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM: +Reason: Parameters are required by vSecPrim, due to code design and metrics code need to be split in subfunctions. +Risk: Code is difficult to maintain. Poor readability of the code due to too many input parameters. +Prevention: Design and code review. Clearly structured and commented code. + +MD_CRYPTO_30_LIBCV_STPAR: +Reason: Parameters are required by code design and to hold other code metrics. +Risk: Code is difficult to maintain. Poor readability of the code due to too many input parameters. +Prevention: Design and code review. Clearly structured and commented code. + +MD_CRYPTO_30_LIBCV_8.7: +Reason: The deceleration is on block. However the static source is only required by one function. +Risk: None +Prevention: Not necessary + +MD_CRYPTO_30_LIBCV_3.1: +Reason: Cast is needed since lower layer crypto library expects -1 as parameter value. +Risk: Cast from signed to unsigned results in an invalid value. +Prevention: Covered by code review. + +MD_CRYPTO_30_LIBCV_0310: +Reason: Cast is needed since lower layer crypto library expects super type as parameter. Internally it is casted back to concrete workspace type. +Risk: Wrong workspace type is casted or size does not match. +Prevention: Covered by code review. + +MD_CRYPTO_30_LIBCV_0311: +Reason: Parameter has to be casted to var since lower layer crypto library expects a var parameter even if it does not write to it. +Risk: Lower layer API could modify the given parameter. +Prevention: Covered by code review and component test. + +MD_CRYPTO_30_LIBCV_0316: +Reason: Cast is needed since upper layer NvM expects super type as parameter. +Risk: Wrong type is casted or size does not match. +Prevention: Covered by code review. + +MD_CRYPTO_30_LIBCV_2963: +Reason: The value does not need to be initialized because it was initialized in the previous steps or the value is not used. +Risk: None +Prevention: N/A + +MD_CRYPTO_30_LIBCV_2985: +Reason: The redundant operation is a side effect of a better readability of the code. +Risk: None +Prevention: N/A + +MD_CRYPTO_30_LIBCV_3219: +Reason: This function is inlined and therefore it has to be implemented here. The function is not used by all configurations of the implementation. +Risk: None. +Prevention: None. + +MD_CRYPTO_30_LIBCV_3219_1: +Reason: The function is not used by all configurations of the implementation. +Risk: None. +Prevention: None. + +MD_CRYPTO_30_LIBCV_2973: +Reason: Parameter is set in future code execution. The code section is only reachable if the value is already set before. +Risk: This function argument points to data that is possibly unset. +Prevention: Covered by code review and component test. + +MD_CRYPTO_30_LIBCV_3395: +Reason: Define is provided by header of lower layer crypto library. +Risk: Compiler wrongly calculates the value. +Prevention: Covered by component test. + +MD_CRYPTO_30_LIBCV_3315: +Reason: This 'switch' statement contains only a single path - it is redundant. +Risk: None. +Prevention: None. + +MD_CRYPTO_30_LIBCV_3673_1: +Reason: Parameter cannot be set to const since it is passed as var parameter to lower layer crypto library. +Risk: None +Prevention: None + +MD_CRYPTO_30_LIBCV_3673_2: +Reason: Pointer can only be const when method is empty and only Dummy statements are used. +Risk: None +Prevention: Covered by code review. + +MD_CRYPTO_30_LIBCV_3673_3: +Reason: Parameter cannot be set to const since it is used as var parameter. +Risk: None +Prevention: None + +MD_CRYPTO_30_LIBCV_3673_API_REQUIREMENT +Reason: Pointer cannot be const because of the Autosar API requirements. +Risk: None +Prevention: None + +MD_CRYPTO_30_LIBCV_3678: +Reason: Parameter cannot be set to const since it is passed as var parameter to lower layer crypto library. +Risk: None +Prevention: None + +MD_CRYPTO_30_LIBCV_4394: +Reason: Signed integer type is given as parameter to the lower layer crypto library, the cast has to be applied. +Risk: None +Prevention: None + +MD_CRYPTO_30_LIBCV_5013: +Reason: Signed integer type is given as return type by lower layer crypto library. Size does not matter since only -1 and 0 is returned. +Risk: None +Prevention: None + +MD_CRYPTO_30_LIBCV_0310_CRYPTOLIBRARY_CAST: +Reason: It is necessary to access inner members of the structure and therefore, the cast has to be applied. +Risk: None +Prevention: Covered by code review. + +MD_CRYPTO_30_LIBCV_3305_CRYPTOLIBRARY_CAST: +Reason: It is necessary to access inner members of the structure and therefore, the cast has to be applied. +Risk: None +Prevention: Covered by code review. + +MD_CRYPTO_30_LIBCV_3415_LOGICAL_OPERATOR: +Reason: Volatile reads could have side-effects. Ihe right side of the logical operator may not get evaluated and therefore doesn't produce the side-effect. +Risk: None, as no registers with side-effects are read. +Prevention: Covered by code review. + + */ + +/* +\CM CM_CRYPTO_30_LIBCV_STACK_ARRAY_WITH_SIZE The stack arrays are given with its size to the called API. +\CM CM_CRYPTO_30_LIBCV_STACK_ARRAY_WITHOUT_SIZE The stack array has the same length as expected by the called API. +\CM CM_CRYPTO_30_LIBCV_WORKSPACE_STACK The workspace is located on the stack and the pointer is valid throughout the call. +\CM CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME The workspace is received via ComStackLib access macros. As it is an 0:1 relation, a runtime check for availability is performed in the Dispatching function. +\CM CM_CRYPTO_30_LIBCV_JOB_INPUT_OUTPUT_BUFFERS_RUNTIME All job concerning in- and output buffer were checked in Crypto_30_LibCv_DetChecksServiceValues before based on service and mode and therefore are valid in this context. + */ + +/* SBSW_JUSTIFICATION_BEGIN + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR +\DESCRIPTION The caller forwards as parameter one or more pointer. +\COUNTERMEASURE \N The pointer is forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_OF_WORKSPACE +\DESCRIPTION The caller passes the address of the workspace of the respective object as a parameter. It is used to save and restore context. +\COUNTERMEASURE \N The pointer is forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH +\DESCRIPTION The caller provides the length of the workspace and the respective objectId as a parameter. +\COUNTERMEASURE \N The objectId is provided as a function parameter to the caller. The caller requires it to be within the array boundaries. + +\ID SBSW_CRYPTO_30_LIBCV_ACCESS_TO_WORKSPACE_RESTORE +\DESCRIPTION Write access to a pointer of the workspace object which is determined by primitive dispatcher. +\COUNTERMEASURE \R The pointer is forwarded and assumed to be valid and the length values which are set by dispatcher are correct. + According to SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_OF_WORKSPACE, SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH and [SMI-722498]. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR +\DESCRIPTION The caller forwards as parameters a pointer and a member of a job pointer. +\COUNTERMEASURE \N The pointers are forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA +\DESCRIPTION The caller forwards pointers from parameters and pointer from global Ecc curve data. +\COUNTERMEASURE \N The pointers are forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER +\DESCRIPTION The function is called with pointers pointing to stack buffers. +\COUNTERMEASURE \N Either the sizes of the buffers are given in the call or the sizes are according to the callee requirements. + +\ID SBSW_CRYPTO_30_LIBCV_CALL_WITH_STACK_WORKSPACE +\DESCRIPTION The function is called with a pointer pointing to a workspace located on the stack within the caller function. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_STACK] + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER +\DESCRIPTION The function is called with pointers pointing to stack buffers and pointer given as parameter to the caller. +\COUNTERMEASURE \N Either the sizes of the buffers are given in the call or the sizes are according to the callee requirements. + The caller requires the workspace to be valid, therefore it can be safely assumed that the workspace and its members is valid. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_WORKSPACE_MEMBER +\DESCRIPTION The function is called with pointers pointing to workspace members. The workspace itself is given as parameter to the caller. +\COUNTERMEASURE \N Either the sizes of the workspace members are given in the call or the sizes are according to the callee requirements. It is assumed that the workspace given as parameter to the caller are valid. + +\ID SBSW_CRYPTO_30_LIBCV_KEY_OUTPUT_BUFFER_PARAMETER_KEY_STACK +\DESCRIPTION Crypto_30_LibCv_SheKeyUpdateDecrypt is called and a pointer to a keybuffer and to an output buffer is passed as parameter. In addition to that, a pointer to a local key buffer located on the stack is passed as parameter. +\COUNTERMEASURE \N The output buffer and the keybuffer are passed as argument to the caller and are assumed to be valid and of the correct size as requested by the callee. +The size of the local key buffer is according to the requirements of the callee. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_KEY_PTR +\DESCRIPTION The esl library is called and a pointer to a workspace is forwarded which is located on the stack. A pointer to a key buffer is provided with a size which is smaller then the provided buffer. +\COUNTERMEASURE \R [CM_CRYPTO_30_LIBCV_WORKSPACE_STACK] +The key pointer is checked in function Crypto_30_LibCv_Local_KeyElementSet for size. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_KEY_PTR +\DESCRIPTION The esl library is called with a pointer to a workspace and one (or multiple) pointer to a key buffer is provided with a size which is equal or smaller than the provided buffer. +\COUNTERMEASURE \N The caller requires the workspace to be valid, therefore it can be safely assumed that the workspace is valid. +The pointers to the key buffers are ensured to be valid by the caller. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_DATA_PTR +\DESCRIPTION The esl library is called and a pointer to a workspace is forwarded which is located on the stack. A pointer to a data buffer is given with a size which is smaller then or equal to the provided buffer. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_STACK] +The data buffer is passed as argument to the caller and is assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_OUTPUT_PTR +\DESCRIPTION The esl library is called and a pointer to a workspace is forwarded which is located on the stack. A pointer to an output buffer is provided without a reference to the size of the buffer. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_STACK] +The output buffer is passed as argument to the caller and is assumed to be valid and of the correct size as requested by the callee. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_DATA_OUTPUT +\DESCRIPTION The esl library is called and a pointer to a workspace is forwarded which is located on the stack. A pointer to an output buffer is given without a reference to the size of the buffer. +In addition to that, a pointer to a data buffer is given with a size which is smaller or equal to the provided buffer. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_STACK] +The output buffer is passed as argument to the caller and is assumed to be valid and of the correct size as requested by the callee. +The data buffer is passed as argument to the caller and is assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE +\DESCRIPTION The esl library is called and a pointer to a workspace is forwarded which is located on the stack. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_STACK] + +\ID SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE +\DESCRIPTION The esl library is called with a pointer to the workspace, which is provided to the caller as parameter. +\COUNTERMEASURE \N The caller requires the workspace to be valid, therefore it can be safely assumed that the workspace and the workspace header are valid. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CONST_WORKSPACE +\DESCRIPTION The esl library is called and a pointer to a workspace is forwarded which is located on the const ram. +\COUNTERMEASURE \N The workspace is located on the const ram and the pointer is valid throughout the call. + +\ID SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM +\DESCRIPTION The function is called and one (or more) domain pointer to a const buffer provided as parameters is forwarded. +The const buffer provides domain parameters of a specific elliptic curve. +The domain parameters are provided in a known structure (ASN1 structure for EC domain parameters) where the size of the buffer +can be determined from a known field in the structure itself. +\COUNTERMEASURE \N The caller requires the provided domain pointer and the domain parameters to be valid. +Therefore it can be safely assumed that the domain pointer and the domain parameters are valid. +Thus, the length of the const buffer can be determined by the callee from a known field from the structure itself. + +\ID SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR +\DESCRIPTION The function is called and one (or more) domain pointer to a const buffer is forwarded. +The const buffer provides domain parameters of a specific elliptic curve. +The domain parameters are provided in a known structure (ASN1 structure for EC domain parameters) where the size of the buffer +can be determined from a known field in the structure itself. +\COUNTERMEASURE \N The function implementation itself guarantees that the domain pointer and the domain parameters are valid. +Thus, the length of the const buffer can be determined by the callee from a known field from the structure itself. + +\ID SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS +\DESCRIPTION The esl library is called and a pointer to a workspace is forwarded which is located on the stack. Other parameters are located on the stack and have the same size as expected from the called API. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_STACK_ARRAY_WITHOUT_SIZE] + +\ID SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS_AND_PTR_AS_PARAMETER +\DESCRIPTION The esl library is called and a pointer to a workspace is forwarded which is located on the stack. +Other parameters are located on the stack and have the same size as expected from the called API. +In addition, there is one pointer which is already given as parameter to the calling function. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_STACK] +[CM_CRYPTO_30_LIBCV_STACK_ARRAY_WITHOUT_SIZE] + +\ID SBSW_CRYPTO_30_LIBCV_CALL_WORKSPACE_STACK_WITH_STACK_BUFFERS_AND_PTR_AS_PARAMETER +\DESCRIPTION A function is called and a pointer to a workspace is forwarded which is located on the stack. +Other parameters are located on the stack and have the same size as expected from the called API. +In addition, there is one pointer which is already given as parameter to the calling function. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_STACK] +[CM_CRYPTO_30_LIBCV_STACK_ARRAY_WITHOUT_SIZE] + +\ID SBSW_CRYPTO_30_LIBCV_PTR_ACCESS +\DESCRIPTION Write access to a pointer which is passed to the function. +\COUNTERMEASURE \N The pointer is assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_INLINE_STACK +\DESCRIPTION Write access to a pointer which is passed to the inlined function. The memory pointed to by the pointer is located in the stack of the calling function. +\COUNTERMEASURE \N The pointer points to memory located on the stack. The call context is synchronous and therefore, the memory stays valid throughout the call. + +\ID SBSW_CRYPTO_30_LIBCV_CALL_WITH_KEYPTR_AND_LENGTH +\DESCRIPTION A pointer to a key buffer is given to the callee with its actual length. +\COUNTERMEASURE \R The key pointer points to a valid key buffer and the length was determined and +checked by Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR +\DESCRIPTION A pointer to a key buffer is forwarded to the callee without a size. +\COUNTERMEASURE \R The key pointer is checked in function Crypto_30_LibCv_Local_KeyElementSet for size and matches the requirements of the callee. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR_KEY_OUTPUT +\DESCRIPTION A pointer to a key buffer is provided with its size and a pointer to another key array located on the stack is provided without size. In addition to that, an output buffer is forwarded to the callee. +\COUNTERMEASURE \R The key pointer is checked in function Crypto_30_LibCv_Local_KeyElementSet for size. +The array located on the stack is sufficiently large and the call context is synchronous. The output buffer is only forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_AND_KEY +\DESCRIPTION The KDFbuffer is forwarded to the callee with its size. The key ptr is pointing to a stack array which corresponds to the API requirements. +\COUNTERMEASURE \N KDFbuffer is only forwarded and assumed to be valid. The buffer is located on the stack and the call is synchronous. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_KEY_OUTPUTBUFFER +\DESCRIPTION The KDFbuffer is located on the stack and given with its size to the callee. The outputbuffer is also located on the stack and matches the callees requirements in terms of size. The pointer to the key is given as parameter to the caller and only forwarded to the callee. +\COUNTERMEASURE \N The call is synchronous and the stack arrays stay valid throughout the call. The key pointer is assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS +\DESCRIPTION Write access to array given by pointer through a parameter. The API requires the array to have a certain size and it is assumed that the size is available in the given pointer. +\COUNTERMEASURE \R The caller has to assure that the API requirements are matched and the size of the buffer is according to these requirements. + +\ID SBSW_CRYPTO_30_LIBCV_CSL01 +\DESCRIPTION Access of Queue, KeyElementWrittenLength, KeyElement, RandomSeedBuffer, KeyNvStatus and Lock using ComStackLib. +\COUNTERMEASURE \N Qualified use-case CSL01 of ComStackLib. + +\ID SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID +\DESCRIPTION Access of WrittenLength, BufferLength, DriverObjectState, QueuePrimitiveInfoIdx, ProcessJob_Trigger_Write, Redirect_Buffer and Lock using ComStackLib. The GetSizeOf-check is performed in one of the global APIs Crypto_30_LibCv_CancelJob, Crypto_30_LibCv_ProcessJob or Crypto_30_LibCv_MainFunction. +\COUNTERMEASURE \N Qualified use case CSL01 of ComStackLib. + +\ID SBSW_CRYPTO_30_LIBCV_CSL02_QUEUE_VIA_DRIVEROBJECT +\DESCRIPTION Access of Queue (via indirection over DriverObject) with same index using ComStackLib. +\COUNTERMEASURE \N Qualified use case CSL02 of ComStackLib. + +\ID SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT +\DESCRIPTION Access of KeyStorage (via indirection over keyElement) with same index using ComStackLib. +\COUNTERMEASURE \N Qualified use case CSL02 of ComStackLib. + +\ID SBSW_CRYPTO_30_LIBCV_VOLATILE_KEY_STORAGE_VIA_KEY_ELEMENT +\DESCRIPTION Access of KeyStorage via volatile pointer. Pointer is set using ComStackLib (via indirection over keyElement). +\COUNTERMEASURE \N Setting of pointer is done via indirection using ComStackLib. Access of data is done through unmodified pointer. + +\ID SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY +\DESCRIPTION Access of KeyElement (via indirection over Key) with same index using ComStackLib. +\COUNTERMEASURE \N Qualified use case CSL02 of ComStackLib. + +\ID SBSW_CRYPTO_30_LIBCV_CSL02_NV_BLOCK +\DESCRIPTION Access of NvBlock (via indirection NvBlockId) with same index using ComStackLib. +\COUNTERMEASURE \N Qualified use case CSL02 of ComStackLib. + +\ID SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE +\DESCRIPTION Access of array located on stack. +\COUNTERMEASURE \N The static size of the array is used as upper bound and therefore no illegal write access is done. + +\ID SBSW_CRYPTO_30_LIBCV_GLOBAL_ARRAY_ACCESS_WITH_SIZE +\DESCRIPTION Access of global array located in data segment. +\COUNTERMEASURE \N The static size of the array is used as upper bound and therefore no illegal write access is done. + +\ID SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR +\DESCRIPTION One or more variables located on the stack are given as parameter pointer to a function. +\COUNTERMEASURE \N The pointer is forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR +\DESCRIPTION One or more variables located on the stack and one or more members of job pointer are given as parameter pointer to a function. +\COUNTERMEASURE \N The pointer is forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR +\DESCRIPTION A pointer to an array located on the stack is given as parameter to a function including its size. +\COUNTERMEASURE \N The function call is synchronous and the size of the array is given, therefore the stack array is valid for the function call. + +\ID SBSW_CRYPTO_30_LIBCV_ACCESS_TO_ERRORID_PTR +\DESCRIPTION Access of errorId pointer to set the errorId. The context is an inlined function which is always called synchronously from Crypto_30_LibCv_Process, +where the variable is located on the stack. +\COUNTERMEASURE \N The function call is synchronous and the variable errorId has to be located on the stack. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR +\DESCRIPTION The call is only forwarded and has as parameter a job pointer. +\COUNTERMEASURE \N The pointer is forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_UPDATE_OF_JOB_STATE +\DESCRIPTION Direct write access to state member of job ptr. The context is the inlined function Crypto_30_LibCv_UpdateJobState, +which is always called synchronously from Crypto_30_LibCv_Process. +\COUNTERMEASURE \R The ptr is checked in the global API Crypto_ProcessJob or Crypto_MainFunction. + +\ID SBSW_CRYPTO_30_LIBCV_DIRECT_ACCESS_TO_JOB_STATE +\DESCRIPTION Direct write access to state member of job ptr. The context is the inlined function Crypto_30_LibCv_Process, +which is always called synchronously from Crypto_30_LibCv_ProcessJob or Crypto_30_LibCv_MainFunction. +\COUNTERMEASURE \R The job object is already checked in global API. + +\ID SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR +\DESCRIPTION Write access to a pointer of the jobs primitive input output object. +\COUNTERMEASURE \R [CM_CRYPTO_30_LIBCV_JOB_INPUT_OUTPUT_BUFFERS_RUNTIME] + +\ID SBSW_CRYPTO_30_LIBCV_ACCESS_OF_JOB_MEMBER_CANCEL_JOB +\DESCRIPTION Write access to the state member of job pointer. +\COUNTERMEASURE \N The pointer is checked for validity in the beginning of the Crypto_30_LibCv_CancelJob function. + +\ID SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_INIT +\DESCRIPTION Direct array access to key storage array generated by ComStackLib. +The access is in bounds since it is iterated over all key elements and the access is either direct or via indirection (KeyElement to KeyStorage). +\COUNTERMEASURE \N Qualified use case CSL02 of ComStackLib. + +\ID SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_NV +\DESCRIPTION Direct array access to key storage array generated by ComStackLib. +The access is in bounds since it is iterated over all key elements and the access is either direct or via indirection (KeyElement to KeyStorage). +\COUNTERMEASURE \N Qualified use case CSL02 of ComStackLib. + +\ID SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE +\DESCRIPTION The function esl_initWorkSpaceHeader is called with a pointer to the workspace header and a size. +The workspace pointer was received by calling Crypto_30_LibCv_GetWorkspaceOf which is provided by the ComStackLib. +\COUNTERMEASURE \R CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME + +\ID SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE +\DESCRIPTION The function esl_initWorkSpaceHeader is called with a pointer to the workspace header and a size. The workspace is located on the stack. +\COUNTERMEASURE \N The call to esl_initWorkSpaceHeader is synchronous and therefore, the workspace stays valid during the lifetime of the call. + +\ID SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE_PARAMETER +\DESCRIPTION The function esl_initWorkSpaceHeader is called with a pointer to the workspace header, a size and a function pointer. The workspace is provided to the caller as parameter. +\COUNTERMEASURE \N The caller requires the workspace to be valid, therefore it can be safely assumed that the workspace and the workspace header are valid. + The function pointer is a static generated value and therefore it can be assumed that it is valid. + +\ID SBSW_CRYPTO_30_LIBCV_ACT_RANDOM_WORKSPACE_ARRAY_ACCESS +\DESCRIPTION Array access to X_KEY member of random workspace pointer of type ActFIPS186STRUCT. +\COUNTERMEASURE \N The validity of the pointer to the random workspace is given since the workspace is provided by the ComStackLib and the access is in bounds. +Since the accessing index is limited by the static size of the X_KEY array, it is ensured that is in range. + +\ID SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS +\DESCRIPTION Access to member of workspace pointer. +\COUNTERMEASURE \N The validity of the pointer to the workspace is given since the workspace is provided by the ComStackLib. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE +\DESCRIPTION The esl library is called and a pointer to a workspace is forwarded. The workspace pointer points to a workspace provided by ComStackLibrary via Indirection over ObjectId. +\COUNTERMEASURE \R [CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME] + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS +\DESCRIPTION The esl library is called and a pointer to a workspace as well as in - and output buffers are forwarded. +The pointer to the workspace is already initialized before and therefore valid. All other buffers are checked before in local function Crypto_30_LibCv_Local_DetChecksServiceValues, +which is called in the context of the global API Crypto_30_LibCv_Process. +\COUNTERMEASURE \R [CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME] +\R [CM_CRYPTO_30_LIBCV_JOB_INPUT_OUTPUT_BUFFERS_RUNTIME] + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS_AND_NULL_PTR +\DESCRIPTION The esl library is called and a pointer to a workspace as well as in - and output buffers are forwarded. +The pointer to the workspace is already initialized before and therefore valid. All other buffers are checked before in local function Crypto_30_LibCv_Local_DetChecksServiceValues, +which is called in the context of the global API Crypto_30_LibCv_Process. +There is a optional pointer which is allowed to be a NULL_PTR. +\COUNTERMEASURE \R [CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME] +\R [CM_CRYPTO_30_LIBCV_JOB_INPUT_OUTPUT_BUFFERS_RUNTIME] +\R The called function allows that the param pointer is a NULL_PTR. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER +\DESCRIPTION The esl library is called and a pointer to a workspace as well as buffer and lengths of stack variables are given as parameter to the function call. +The pointer to the workspace is already initialized before and therefore valid. All other buffers are located on the stack and the function call is synchronous. Therefore, the memory +stays valid throughout the call. +\COUNTERMEASURE \N All pointers point to stack variables and the length is also provided to the called function. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER +\DESCRIPTION The esl library is called with a pointer to a workspace, +a pointer located at the job object (pointing to a buffer) with an length denoting the length of the buffer +and a pointer to an buffer which is located on the stack and without size. +\COUNTERMEASURE \R [CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME] +[CM_CRYPTO_30_LIBCV_JOB_INPUT_OUTPUT_BUFFERS_RUNTIME] +[CM_CRYPTO_30_LIBCV_STACK_ARRAY_WITHOUT_SIZE] + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_PARAMETER_BUFFER +\DESCRIPTION The esl library is called with a pointer to a workspace, +a pointer to a buffer provided to the caller via parameter and a length denoting the length of the buffer. +\COUNTERMEASURE \N The caller requires the workspace to be valid, therefore it can be safely assumed that the workspace is valid. + The caller requires the buffer to be valid, therefore it can be safely assumed that the buffer is valid during the call. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER +\DESCRIPTION The esl library is called with a pointer to a workspace, +a pointer to one or multiple const buffers and a length denoting the length of the buffers. +\COUNTERMEASURE \N The caller requires the workspace to be valid, therefore it can be safely assumed that the workspace is valid. + As the const buffers are constant, they cannot be written to, making them irrelevant for this analysis. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER_AND_PARAMETER_BUFFER +\DESCRIPTION The esl library is called with a pointer to a workspace, +a pointer to one or multiple const buffer, a length denoting the length of the const buffers, +a pointer to one or multiple buffers provided to the caller via parameter and a length denoting the length of the buffers. +\COUNTERMEASURE \N The caller requires the workspace to be valid, therefore it can be safely assumed that the workspace is valid. + As the const buffers are constant, they cannot be written to, making them irrelevant for this analysis. + The caller requires the parameter buffers to be valid, therefore it can be safely assumed that they are valid during the call. + The caller also provides the length of the parameter buffers as required by the API of the callee. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER_AND_STACK_BUFFER +\DESCRIPTION The esl library is called with a pointer to a workspace, +a pointer to one or multiple const buffer, a length denoting the length of the const buffers, +a pointer to one or multiple stack buffers provided located on the stack and a length denoting the length of the buffers. +\COUNTERMEASURE \N The caller requires the workspace to be valid, therefore it can be safely assumed that the workspace is valid. + As the const buffers are constant, they cannot be written to, making them irrelevant for this analysis. + The caller creates the stack buffers before and ensures their validity. + The caller also provides the length of the stack buffers as required by the API of the callee. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR +\DESCRIPTION The esl library is called with a pointer to a workspace and a null pointer is given to the library as parameter. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME] +The null pointer is a valid input to the calling function. + +\ID SBSW_CRYPTO_30_LIBCV_CALL_WITH_NULL_PTR +\DESCRIPTION The NvM is called with a null pointer is given as parameter. +\COUNTERMEASURE \N The null pointer is a valid input to the calling function. + +\ID SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN +\DESCRIPTION The esl library is called and a pointer to a workspace as well as pointer to stack arrays are given without an information how large the arrays are. +This is due to the fact that these esl library functions do not provide a parameter for the length of the buffer. +\COUNTERMEASURE \N The stack arrays have the same length as the esl library expects. + +\ID SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE +\DESCRIPTION The service is called and a pointer to a workspace is forwarded. The workspace pointer points to a workspace provided by ComStackLibrary via Indirection over ObjectId. +\COUNTERMEASURE \R [CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME] + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR_AND_CONST_BUFFER +\DESCRIPTION The pointers of workspace and job are forwarded. +The workspace pointer points to a workspace provided by ComStackLibrary via Indirection over ObjectId. +A pointer to a const buffer is passed to the called function. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME] +The job pointer is forwarded and assumed to be valid. +As the const buffer is constant, it cannot be written to, making them irrelevant for this analysis. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR +\DESCRIPTION The call is only forwarded and has as parameter a pointer to a workspace a job pointer. +The workspace pointer points to a workspace provided by ComStackLibrary via Indirection over ObjectId. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME] +The job pointer is forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR +\DESCRIPTION The call is only forwarded and has as parameter a pointer to a workspace a job pointer. +The workspace pointer points to a workspace provided by ComStackLibrary via Indirection over ObjectId. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME] +The job pointer is forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_AND_GLOBAL_ARRAY_PTR +\DESCRIPTION The call is only forwarded and has as parameter a pointer to a job and a pointer to a global +array located in data segment. +\COUNTERMEASURE \N The job pointer is forwarded and assumed to be valid. For the pointer to a global array +the static size of the array is used as upper bound and therefore no illegal access is done. + +\ID SBSW_CRYPTO_30_LIBCV_CALL_WITH_GLOBAL_WORKSPACE_AND_CONST_BUFFER +\DESCRIPTION A function is called with a pointer to a workspace, which is provided by ComStackLibrary via Indirection over ObjectId, +and a pointer to one or multiple const buffers. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME] +As the const buffers are constant, they cannot be written to, making them irrelevant for this analysis. + +\ID SBSW_CRYPTO_30_LIBCV_CALL_WITH_GLOBAL_WORKSPACE_AND_JOB_BUFFER +\DESCRIPTION A function is called with a pointer to a workspace, which is provided by ComStackLibrary via Indirection over ObjectId, +and pointers pointing to workspace members. +\COUNTERMEASURE \N [CM_CRYPTO_30_LIBCV_WORKSPACE_VIA_COMSTACKLIB_RUNTIME] +[CM_CRYPTO_30_LIBCV_JOB_INPUT_OUTPUT_BUFFERS_RUNTIME] + +\ID SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK +\DESCRIPTION The value of a pointer to a variable located on the stack is written. +\COUNTERMEASURE \N The function call is synchronous and there is no array access. + +\ID SBSW_CRYPTO_30_LIBCV_ARRAY_ACCESS_WITH_SIZE_CHECK +\DESCRIPTION The array is written with an index, the size of the array is known in this context. +\COUNTERMEASURE \R It is checked that there is no out of bounds via the provided length. + +\ID SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_WITH_DET_CHECK +\DESCRIPTION Write access to a pointer. +\COUNTERMEASURE \R The pointer is checked for validity before. + +\ID SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK +\DESCRIPTION One or more pointer are forwarded as parameter to the caller. +\COUNTERMEASURE \R The pointer are checked for validity before. + +\ID SBSW_CRYPTO_30_LIBCV_RNG_SEED +\DESCRIPTION Access to KeyElementState via indirection over Key. +\COUNTERMEASURE \N The index is not explicitly checked. Since the code is only executed if the Crypto_30_LibCv_KeyElementSet has successfully written the same KeyElement, it is guaranteed that the key element exist and therefore the index is also valid. + +\ID SBSW_CRYPTO_30_LIBCV_GETVERSIONINFO +\DESCRIPTION The function Crypto_30_LibCv_GetVersionInfo writes to the object referenced by parameter VersionInfo +\COUNTERMEASURE \N The caller ensures that the pointers passed to the parameter VersionInfo is valid. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER +\DESCRIPTION The NvBuffer is forwarded and accessed without a length given to the service. +\COUNTERMEASURE \S SMI-863486 ensures, that the NvM block length is as expected from the component. Therefore read and write access is within correct boundaries. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_AND_ACCESS_TO_NVBUFFER +\DESCRIPTION A pointer to a stack variable is forwarded and a NvBuffer is forwarded and accessed without a length given to the service. +\COUNTERMEASURE \S SMI-863486 ensures, that the NvM block length is as expected from the component. Therefore read and write access is within correct boundaries. + Stack pointer assumed to be valid, pointer to NvM block is forwarded by the caller and assumed to be valid. + +\ID SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_AND_KEYSTORE_BUFFER +\DESCRIPTION The function is called with pointers pointing to stack and keystorage buffers. +\COUNTERMEASURE \N Either the sizes of the buffers are given in the call or the the caller ensures that the sizes are according to the callee requirements. + +\ID SBSW_CRYPTO_30_LIBCV_WRITE_PARTITION_DATA +\DESCRIPTION Write of Partition specific data using ComStackLib. +\COUNTERMEASURE \N The index for the Partition specific data is either fixed (for single partition usecase) or provided by searching the current application id + in the PartitionIdentifiers and using its corresponding partitionIdx (Qualified use-case CSL05 of ComStackLib). + If no partitionIdx can be found, usage of an invalid index is prevented by checking the index to be in acceptable range. + Therefore it is always guaranteed to be in the acceptable range. + +SBSW_JUSTIFICATION_END */ + +/* COV_JUSTIFICATION_BEGIN + + \ID COV_CRYPTO_30_LIBCV_LOCAL_DEFINE + \ACCEPT XF + \ACCEPT TX + \REASON CRYPTO_30_LIBCV_LOCAL is always defined externally. + + \ID COV_CRYPTO_30_LIBCV_COMPATIBILITY_DEFINE + \ACCEPT TX + \REASON Define is always defined internally but cane be overwritten for compatibility. + + \ID COV_CRYPTO_30_LIBCV_CSM_DEFINES + \ACCEPT XF + \ACCEPT TX + \REASON This defines could be defined in other crypto drivers as well. In order to increase flexibility, defines are defined in crypto driver if not provided yet. + + \ID COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT + \ACCEPT X + \REASON This else/default statements are required by misra but cannot be reached in code. The statement is captured by upper Api. + + \ID COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE + \ACCEPT XF + \ACCEPT TX + \REASON This encapsulation is for different platform types. Not all platform types can be covered by development test. Covered by code review and integration test. + + \ID COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS + \ACCEPT TX + \REASON The Crypto needs custom key elements, which could be defined in other modules as well. + + \ID COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM + \ACCEPT TX + \REASON The Crypto needs custom algorithm and algorithm mode defines, which could be defined in other modules as well. + + \ID COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM + \ACCEPT TX + \REASON The Crypto needs custom key algorithm, which could be defined in other modules as well. + + \ID COV_CRYPTO_30_LIBCV_KEY_LOCKING_RELEASE + \ACCEPT TX + \REASON This check can only be false if there is a implementation mistake. + + \ID COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT + \ACCEPT TX + \REASON This check can only be false if the parameter is defined externally. + + \ID COV_CRYPTO_30_LIBCV_SHE_ECU_MASTER_KEY + \ACCEPT TX + \ACCEPT XF + \REASON The result of the check depends of the SHE configuration. If the ECU_MASTER_KEY is configured the result can be TX otherwise XF. + + \ID COV_CRYPTO_30_LIBCV_SHE_KEY_CONFIGURATION + \ACCEPT TF + \ACCEPT XF + \REASON The result of the check depends of the SHE configuration. If the required key is not configured the result can be XF. + + \ID COV_CRYPTO_30_LIBCV_SHE_KEY_CONFIGURATION_2 + \ACCEPT TF + \ACCEPT TX + \REASON The result of the check depends of the SHE configuration. If the required key is not configured the result can be TX. + + \ID COV_CRYPTO_30_LIBCV_SERVICE_CONFIGURATION + \ACCEPT TX + \ACCEPT TF + \REASON The result of the check depends of the service configuration. If all services are enabled the result can be TX. + + \ID COV_CRYPTO_30_LIBCV_SERVICE_CONFIGURATION_2 + \ACCEPT XF + \ACCEPT TF + \REASON The result of the check depends of the service configuration. If no service with key write access is enabled the result can be XX. + + \ID COV_CRYPTO_30_LIBCV_ECDSA_CONFIGURATION + \ACCEPT TF + \ACCEPT TX + \ACCEPT XF + \REASON The result of the check depends of the ECDSA configuration. If pre hash length is longer than the curve length the result is always TX. If pre hash length is shorter than the curve length the result is always TX. + + \ID COV_CRYPTO_30_LIBCV_ECDSA_PREHASHING_ENABLED + \ACCEPT TF + \ACCEPT TX + \ACCEPT XF + \REASON The result of the check depends of the ECDSA configuration. In a configuration where only curve SECp521r1 is supported, the ECDSA is always used together with SHA512 prehashing and thus, + the algorithm secondary family is always set. + + \ID COV_CRYPTO_30_LIBCV_ASR_COMPATIBILITY + \ACCEPT XF + \ACCEPT TX + \REASON The Crypto_JobType differs between the different ASR version to support ASR 4.3.0 the defines ca be overwritten. Standard is ASR 4.3.1. + + \ID COV_CRYPTO_30_LIBCV_BINARYSEARCH + \ACCEPT TX + \REASON This check can never be false, as the searched list is generated as an ordered list without gaps. + Consequently, the used binary search algorithm will always find the searched entry if the list was generated correctly, + and the check will never be false. + +\ID COV_CRYPTO_30_LIBCV_USER_DEFINES + \ACCEPT TX + \ACCEPT XF + \REASON Ifndef is present for redefinition prevention. This allows the user or CSM to override this value + while also ensuring that the constant is present if the user or CSM does not override it. + +COV_JUSTIFICATION_END */ + +/********************************************************************************************************************** + * FETA JUSTIFICATIONS + *********************************************************************************************************************/ + + /* FETA_JUSTIFICATION_BEGIN + + \ID FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA + \DESCRIPTION Loop bounds are determined by static GenData which is accessed via ComStackLib. + \COUNTERMEASURE \N The here applied loop uses variables as lower and upper bound which are set via a ComStackLib macro + and remain unchanged during loop execution. The lower bound variable is guaranteed to be less + than or equal to the upper bound variable. The loop's type of the counter variable is appropriate + for the loop's type of lower and upper bound determining variables as it is an iteration type suitable for the + used CSL indirection. The counter variable is increased once within each single loop iteration (strictly monotonically increasing) + until it reaches a value that makes the loop stop without any occurrences of overflows. This + is done by a comparison used as loop termination condition that considers the amount of the + increment that is applied within each single loop. + + \ID FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND_STATIC_GENDATA + \DESCRIPTION Loop upper bound is determined by static GenData which is accessed via ComStackLib. + \COUNTERMEASURE \N The here applied loop uses a variables as upper bound which is set via a ComStackLib macro + and remains unchanged during loop execution. The loop's type of the counter variable is appropriate + for the loop's type of lower and upper bound determining variables as it is an iteration type suitable for the + used CSL indirection. The counter variable is increased once within each single loop iteration (strictly monotonically increasing) + until it reaches a value that makes the loop stop without any occurrences of overflows. This + is done by a comparison used as loop termination condition that considers the amount of the + increment that is applied within each single loop. + + \ID FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND_WITH_CHECK + \DESCRIPTION Loop upper bound is determined by a constant parameter which is passed to the function. + \COUNTERMEASURE \R The caller ensures correctness of the parameter by checking it for boundary conditions + described in the function doxygen comment. + [CM_CRYPTO_LIBCV_FOR_LOOP_WITH_NON_CHANGING_UPPER_BOUND] + + \ID FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND_PTR + \DESCRIPTION Loop upper bound is determined by a pointer parameter which is passed to the function. + \COUNTERMEASURE \N [CM_CRYPTO_LIBCV_FOR_LOOP_WITH_NON_CHANGING_UPPER_BOUND] + + \ID FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND + \DESCRIPTION Loop upper bound is determined by a constant parameter which is passed to the function. + \COUNTERMEASURE \N [CM_CRYPTO_LIBCV_FOR_LOOP_WITH_NON_CHANGING_UPPER_BOUND] + + \ID FETA_CRYPTO_30_LIBCV_BINARY_SEARCH + \DESCRIPTION While loop which is used for a binary search of a cryptoKeyId via its elementIndex. + \COUNTERMEASURE \N The here applied while loop is controlled by a comparison of the variables minKey and maxKey, + which are of the same type. + Within each single loop execution: + - the value of variable middleKey, which is of an appropriate type, is calculated and then it is: minKey <= middleKey < maxKey, + - Then + - either maxKey becomes middleKey, so right decreases + - or minKey becomes (middleKey + 1), so left increases + - or keyFound becomes TRUE which makes the loop stop by a call of break + So with each single loop the difference (maxKey - minKey) becomes smaller (strictly monotonically decreasing) and + the loop will finally stop after a maximum of (maxKey - minKey) loop executions. + + \CM CM_CRYPTO_LIBCV_FOR_LOOP_WITH_NON_CHANGING_UPPER_BOUND + The loop's type of the counter variable is appropriate for the loop's type of upper bound + variable as it is the same type as the bound determining variables. The upper bound remains unchanged during loop execution. + The counter variable is increased once within each single loop iteration (strictly monotonically increasing) + until it reaches a value that makes the loop stop without any occurrences of overflows. This + is done by a comparison used as loop termination condition that considers the amount of the + increment that is applied within each single loop. + + FETA_JUSTIFICATION_END */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv.h new file mode 100644 index 0000000..033463c --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv.h @@ -0,0 +1,600 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------ + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------ + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Implementation of the MICROSAR Crypto Driver (Crypto) + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2016-10-31 vismss Initial creation for ASR 4.3 + * 01.00.01 2016-12-06 vismss Minor adaptions to the specification + * 01.00.02 2016-12-07 vismss Fixed rng and key storage init + * 01.00.03 2016-12-14 vismss ESCAN00093302 Fixed AES enc/dec and EdDSA + * 01.00.04 2017-01-24 vismss ESCAN00093690 Support of simplified SHE Key Update Protocol + * ESCAN00093350 Fixed workspace casts + * ESCAN00093365 DET encapsulation + * Adaptions to ASR spec and coding style patterns + * 01.01.00 visros Fixed DET ServiceIds + * Added DET for process job + * visgut Fixed processing of asynchronous jobs in mainfunction. + * Include SchM_Crypto_30_LibCv.h + * Support multiple driver objects and locking of workspaces. + * ESCAN00094360 Compiler warning: GetVersionInfo API missing return statement at end of non-void function + * vistof Moved Crypto_30_LibCv_QueueStateType from Csm_types.h to Crypto + * Added Cancel API + * vismss Added SipHash + * Adapted EDDSA + * 01.01.01 vismaw ESCAN00094769 Calling of services always returns false + * 01.02.00 2017-05-05 vismaw FEATC-1229 Release of component + * ESCAN00093105 Release of component + * ESCAN00095032 AEAD Encrypt does not check if output buffer for authentication tag has a wrong size + * ESCAN00095030 Crypto_30_LibCv_KeyElementIdsGet always returns E_NOT_OK + * ESCAN00095028 Wrong output length returned for AEAD Encrypt + * ESCAN00095033 KeyElementSet with SHE Key update mechanism does not set the new key + * 02.00.00 2017-08-06 vismwe ESCAN00095629 Crypto_30_LibCv_KeyElementIdsGet returns E_NOT_OK instead of CRYPTO_E_SMALL_BUFFER + * ESCAN00096063 Crypto_30_LibCv_KeyElementSet calculates wrong values for M4 proof if a SHE update key flags is set. + * ESCAN00096032 Crypto_30_LibCv_KeyDerive returns suspect values, if the calculation failed. + * ESCAN00095987 Crypto_30_LibCv_KeyElementSet returns always E_NOT_OK for SHE key update without the key element "proof" + * ESCAN00095985 Compiler error: undeclared identifier for virtual key usage + * ESCAN00095928 Crypto_30_LibCv_KeyExchangeCalcSecret does not reject calls with invalid length of public key + * ESCAN00096031 Crypto_30_LibCv_KeyCopy copies key elements with different lengths without enabled partial access. + * ESCAN00096176 Crypto_30_LibCv_KeyElementGet returns CRYPTO_E_KEY_NOT_VALID instead of CRYPTO_E_KEY_NOT_AVAILABLE + * 02.01.00 2017-08-15 vistof ESCAN00096308 MAC verification only done for complete bytes. + * vismaw STORYC-934 Optimize AES runtime through keeping the SubKey and Roundkeys of former used Keys + * vismwe ESCAN00096452 Error is returned when IV key element is missing during AES-ECB. + * STORYC-281 Safe BSW Release + * 03.00.00 2017-09-11 vismwe STORYC-1851 Support of RSA + * STORYC-2438 SHE Key Update Protocol - Use and check key slot mentioned in M1 + * STORYC-2485 Support Access Rights of Key Elements + * 03.01.00 2017-09-11 vismwe STORYC-2700 Support Key Locking + * ESCAN00096711 The key element is set valid if Crypto_30_LibCv_KeyElementSet failed + * ESCAN00096872 Crypto_30_LibCv_ProcessJob: Missing Det report if the Crypro is not supported on the driver object + * STORYC-2159 Support ECC with NIST P-256 (ECDSA) + * STORYC-2600 Support ECDSA for SECGp256r1 + * ESCAN00097178 ProcessJob returned with E_NOT_OK if the RSA signature verification failed + * 03.02.00 2017-11-06 vismwe STORYC-2606 Support ECDHE for ANSIp256r1 + * STORYC-2599 Support RSA Encrypt/Decrypt + * STORYC-2604 Support HMAC with SHA1 and SHA256 + * ESCAN00097356 Compiler error: C2065: 'actX25519Struct' : undeclared identifier + * ESCAN00097524 Crypto_30_LibCv_ProcessJob returns CRYPTO_E_KEY_NOT_VALID, if RSA signature is generated. + * 03.03.00 2017-11-29 vismwe STORYC-2601 Support concatenation KDF + * STORYC-2603 Support certificate installation and update according to ISO15118 + * ESCAN00097542 Compiler error: unresolved external Crypto_30_LibCv_Local_ReadTwoKeyElements + * 03.04.00 2018-01-08 vismwe STORYC-2605 Support ECDSA for ANSIp256r1 with SHA-1 + * ESCAN00097921 Compiler error: 'CRYPTO_RANDOM' : undeclared identifier + * 03.05.00 2018-01-22 vismwe STORYC-3392 Support CTR-DRBG using AES-128 according to NIST SP 800-90A + * STORYC-2607 Support RSA CRT DSA SHA-1 and SHA-256 and PKCS1_V15 + * ESCAN00098171 Compiler warning: uninitialized variable retVal. + * ESCAN00098173 Compiler warning: incompatible types uint8* and uint8_least* + * STORYC-2602 Support ECDHE for SECp256r1 + * STORYC-4075 Support delete key element + * ESCAN00098280 Compiler error: Crypto_30_LibCv.c undefined identifier "Crypto_30_LibCv_QueueElementType" + * ESCAN00098328 AES encryption/decryption does not fail if the key is too short. + * ESCAN00098330 EDDSA 25519 generate/verify does not fail if the key is too short. + * ESCAN00098322 AES CMAC Round-key Reuse does not reduce the runtime. + * ESCAN00098354 Crypto_ProcessJob returned CRYPTO_E_BUSY for async job update in streaming mode. + * 03.06.00 2018-02-19 vismwe STORYC-4373 Support AES 128 encryption and decryption without padding + * ESCAN00098488 Crypto_30_LibCv_ProcessJob return CRYPTO_E_KEY_NOT_VALID instead of E_NOT_OK if AES key length is not correct. + * ESCAN00098501 Compiler error: undeclared identifiers for Ecc Curve Parameters. + * ESCAN00098502 Crypto_30_LibCv_RandomSeed returns always E_NOT_OK if DRBG is used. + * ESCAN00098593 Crypto_30_LibCv_ProcessJob returns E_OK instead of E_NOT_OK if key element seed state is missing for FIPS186. + * 03.06.01 2018-04-09 vismwe ESCAN00098720 Compiler warning: incompatible types - from 'eslt_WorkSpace *' to 'eslt_WorkSpaceEd25519 *' relevant if SysService_CryptoCv is greater 3.02.00 + * 04.00.00 2018-05-23 vismwe STORYC-5043 Support for ECDSA 384 + * STORYC-5044 Support for AES 256 + * 04.01.00 2018-05-23 vismwe STORYC-5529 SHE Key Update Protocol - Support UID, Fid and counter + * ESCAN00098947 No error generated when length greater than 65535 (0xFFFF) bytes is passed to an algorithm + * 04.02.00 2018-08-20 vismwe ESCAN00100198 Compiler error: function Crypto_30_LibCv_CompareMac undefined + * ESCAN00099294 Keys will not be persist in NVM + * ESCAN00100597 AES-GCM output size check is not sufficient in streaming mode. + * 05.00.00 2018-09-20 vismwe STORYC-6301 Support RSAES-OAEP with SHA-1 and SHA-256 + * ESCAN00100617 A SHE key with debugger/boot-protection will not be provided + * 05.01.00 2018-11-05 vismwe STORYC-6543 Support redirection of input/output buffers from/to key elements + * STORYC-6544 Support partial key element copy + * STORYC-7031 Support vSecPrim watchdog trigger function + * ESCAN00101150 AES 256 CBC: Crypto_ProcessJob returns CRYPTO_E_KEY_SIZE_MISMATCH in case of IV != 32Bytes + * ESCAN00101246 Memory Corruption if ProcessJob is called with an invalid cryptoKeyId + * ESCAN00101340 HMAC returns CRYPTO_E_KEY_NOT_VALID if key length is longer than Hash length + * 05.02.00 2018-11-21 visivg STORYC-7065 Support of SHA384 and SHA512 pre-hashing for ECDSA + * STORYC-5518 Support of SHA384 hashing + * STORYC-5520 Support of ECDHE for SECp384r1 + * vismwe ESCAN00101561 Compiler warning: Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected is undefined + * ESCAN00101562 Compiler warning: Incompatible types - of "Crypto_30_LibCv_SizeOfKeyStorageType *" and "Crypto_30_LibCv_SizeOfKeyElementsType *" + * 05.03.00 2019-01-02 visivg STORYC-5807 Support GMAC AES-256, AES-192 and AES-128 + * 05.04.00 2019-01-25 visivg STORYC-7447 Support HMAC SHA-384 + * 05.05.00 2019-02-26 visivg STORYC-7655 Prepare Release of Crypto 5.x + * ESCAN00102255 Compiler warning: 'Crypto_30_LibCv_Dispatch_RsaOaepSha1Decrypt' and 'Crypto_30_LibCv_Dispatch_RsaOaepSha256Decrypt' : undeclared identifier in Crypto_30_LibCv_cfg.c + * ESCAN00099936 ProcessJob returns different values for different primitives if the key size is not matching. + * vismwe ESCAN00101248 CMAC wrong calculation for updated CMAC key, if CMAC key reuse is enabled. + * ESCAN00100548 Random Number Generator FIPS186 will provide the same random numbers after restart + * ESCAN00102474 Key Derivation according to ISO15118 returns always E_NOT_OK + * ESCAN00102491 Unexpected behavior if a job is executed which configuration is not supported in the crypto configuration. + * 05.06.00 2019-05-11 vismwe STORYC-7979 Support RSAES PKCS#1 v1.5 public key decryption + * STORYC-5721 MISRA-C:2012 Compliance + * STORYC-7161 Support KDF X9.63 with Sha256 in Crypto Driver + * ESCAN00102689 Primitive execution always fails with an error for a specific primitive. + * 06.00.00 2019-07-08 vismwe SEC-62 Support Export of She RAM Keys + * SEC-27 Support of She DEBUG_CMD + * SEC-61 Introduce multiple NvM Blocks + * 06.01.00 2019-08-05 vismwe SEC-667 Introduce Immediate write of NvM Blocks + * 06.01.01 2019-08-20 vismaw ESCAN00104069 LibCv causes endless loop in NvM_Readall + * 07.00.00 2019-12-03 vismwe SEC-934 Trigger Persist only if effected persist keys are changed + * ESCAN00102474 Key Derivation according to ISO15118 returns always E_NOT_OK + * ESCAN00105277 Crypto_30_LibCv_ProcessJob provides wrong Det errorId if KeyId is wrong + * visenc SEC-54 Support Asynchronous Key Handling + * 07.00.01 2020-01-20 vismwe ESCAN00105402 Compiler error: Crypto_30_LibCv_KeyManagement.c(8760): 'writeBlock' : undeclared identifier + * 07.01.00 2020-01-20 vismwe SEC-10 Add callout implementation for esl_getBytesRNG + * ESCAN00105358 Memory Corruption if a DRBG Random Generate job is called with less than 16 Bytes of output. + * ESCAN00093129 esl_getBytesRNG is missing + * 07.02.00 2020-03-09 vismwe SEC-881 Remove 64k single call limitation for all security algorithms + * SEC-1005 Remove limitation for signature input data pointers + * ESCAN00105884 Exception caused by access to uninitialized memory. + * ESCAN00105886 She Debug Command corrupts key storage data. + * visenc SEC-885 Support AES Padding One with Zeros + * 07.03.00 2020-03-23 visenc SEC-902 Support CryptoStack KeyGenerate Interfaces + * 08.00.00 2020-04-17 visenc SEC-1280 Support HMAC RIPEMD-160 + * ESCAN00106153 Crypto_30_LibCv_ProcessJob for RSA PKCS1 CRT returns always E_NOT_OK. + * 08.00.01 2020-04-20 vismwe ESCAN00106180 Primitive execution fails or provides wrong calculation for asynchronous jobs + * 08.01.00 2020-04-29 visenc SEC-1276 Support of ECDSA with SECP160R1 + * ESCAN00106259 Compiler error: Missing functions for key generation + * 08.02.00 2020-05-25 visenc SEC-1278 Support of HASH with RIPEMD-160 + * SEC-796 Support of AES CTR-Mode + * SEC-954 Support of PBKDF2 HMAC SHA-1 and SHA-256 + * 08.03.00 2020-06-12 visenc SEC-1534 Support KDF963 in combination with SHA512 + * ESCAN00106613 Useless access of uninitialized stack variable reseedCnt. + * 08.04.00 2020-06-29 visenc SEC-1250 Support ChaCha20 with Poly1305 as authenticator for AEAD + * ESCAN00106735 Access of uninitialized stack variable while ProcessJob redirection and negative error code + * 08.05.00 2020-07-20 visenc SEC-1164 Support CTR_DRBG based on AES-128 from vSecPrim + * SEC-1375 Harmonize Crypto_JobType according to different ASR version + * SEC-1215 Support PRNG based on SHA512 according to SP800-90A + * SEC-1472 Support SHA-3-256 + * ESCAN00106930 Key Init Value is not Correct or leads to compile Error + * ESCAN00106936 She key update fails or compile Error + * ESCAN00106783 Memory Corruption: Crypto_KeyElementCopyPartial with invalid values. + * ESCAN00106807 Changed keys are not persisted with KeySetValid after WriteAll + * vismwe SEC-1687 Support Write Once Keys + * 09.00.00 2020-08-31 visenc SEC-1691 Support CTR-DRBG using AES-256 according to NIST SP 800-90A + * SEC-1665 Support SHE command CMD_GET_ID + * ESCAN00107335 MacVerify fails on Big-Endian Platforms for truncated MACs when length in bits is not divisible by 8 + * ESCAN00107666 Primitive execution fails or provides wrong calculation + * 09.01.00 2020-10-27 visenc SEC-1801 Support CMAC AES-256 + * SEC-1805 Support HKDF HMAC SHA256 + * SEC-1809 Support AES-CCM + * ESCAN00107841 Access of uninitialized memory, RandomSeedBuffer in Crypto_30_LibCv_Init + * vismwe SEC-1812 Support SPAKE2+ + * 09.02.00 2020-11-20 visenc SEC-2080 Support Hash MD5 + * SEC-1677 Support Key Generation for Ed25519 Keys + * 09.03.00 2021-01-12 vismxe SEC-1887 Support Custom Mode Synchronization according to AUTOSAR R20-11 + * vismwe SEC-2263 Support Runtime DET for CRYPTO_E_ENTROPY_EXHAUSTION + * 10.00.00 2021-05-11 visenc SEC-2714 Support save and restore context for running crypto operations + * ESCAN00109421 Crypto_30_LibCv_Local_KeyElementGet_Standard access to uninitialized memory + * ESCAN00109433 Crypto_30_LibCv_Local_KeyGenerate_Ed25519_With_Ws forwards uninitialized key length variable + * ESCAN00108731 SHE DEBUG Command Due to Write Lock bit Enabled Crypto Driver won't provide data to NVM during Zero Value write in to D flash + * 10.01.00 2021-08-31 vismwe SEC-3114 Support Elliptic Curve Burmester Desmedt (ECBD) + * ESCAN00109930 SHE DEBUG Command: Key access issues after DEBUG_CMD execution. + * 11.00.00 2021-11-29 visenc SEC-3388 Support Key Derivation NIST SP 800-56C Option 1 + * 11.01.00 2021-12-20 visenc SEC-3570 Support key value changed callouts + * visenc ESCAN00111088 Persistency fails or unexpected behaviour when calling KeyDerive API + * viseag SEC-3640 Usage of _MemMap.h + * 12.00.00 2022-05-16 visenc SEC-4482 Support of ECDSA secp521r1 with SHA2-512 + * 2022-09-01 viseag SEC-4863 Support of AES-192 + * 2022-10-24 viskju ESCAN00111536 Missing validation can lead to undefined behavior + * ESCAN00111597 Missing Partial Access Limitation + * ESCAN00111639 Algorithm message length limitation too strict + * 12.01.00 2022-11-11 viskju HSM-3249 Support of ECDHE secp521r1 + * HSM-3317 Provide APIs for redirection for Hwa Use-Case + * HSM-3096 Support SHA-3 and SHAKE according to FIPS 202 + * ESCAN00113238 Redirection will provide wrong data in output key element for Encrypt, Decrypt, Aead Encrypt and Aead Decrypt + * ESCAN00113241 Undefined behavior after restoring context of job with configured redirection + * ESCAN00113214 RSA PKCS1 decryption fails after restore + * ESCAN00113213 RSA PSS signature verification fails after restore + * 12.02.00 2023-01-24 viskju HSM-3086 Support of HKDF HMAC SHA384 + * HSM-3703 FETA Analysis + * 12.03.00 2023-03-15 viskju HSM-3819 Support HKDF HASH Option 1 Sha-512 + * ESCAN00114135 RSA signature verification job with invalid input data returns unexpectedly with E_NOT_OK + * 12.04.00 2023-04-03 viskju HSM-3826 Support ISO-15118-20 Key Derivation for P521 + * ESCAN00114495 CMAC generation or verification produces the wrong output + * ESCAN00114531 CMAC generation or verification fails unexpectedly + * 13.00.00 2023-04-13 viskju HSM-3728 Support multicore with shared memory + * ESCAN00114693 Invalid sequence of asynchronous jobs leads to blockage of queue + * 13.01.00 2023-06-06 viskju HSM-4098 Support X448/ECDH based on curve Edwards448 + * HSM-3956 Harmonize Crypto_JobType usage to ASR 21-11 + * HSM-4090 Support ISO-15118-20 Key Derivation for ED448 + * HSM-4390 Rework InitMemory for LibCv + * coechsler SEC-6446 Support Ed448 Signature generation and verification, support Ed25519 context mode + * SEC-6572 Use NvM defines for service identification + * 13.02.00 2023-07-31 coechsler SEC-6310 Support HMAC with SHA2-512 generation and verification + * SEC-6306 Support HKDF Expand SHA2-256 and SHA2-384 + * SEC-6683 Support IsKeyOnCurve for P160R1, P256R1, P384R1, P521R1 + * 13.03.00 2023-08-21 coechsler SEC-6734 Support IsKeyOnCurve for Ed25519 and Ed448 + * SEC-6768 Support ECBD KeyExchange based on P256R1 + * ESCAN00115701 Missing length check for AES GCM Decrypt Authentication Tag + * 13.04.00 2023-10-04 viskju HSM-4583 Support for secp521r1 Key Generation + * 13.04.01 2023-10-16 viskju ESCAN00115928 For ChaCha20-Poly1305-Crypto jobs in finish mode the outputLength is not updated + * 13.05.00 2023-10-27 coechsler CRY-418 Support ECDHE with x-coordinate shared secret only + * 13.05.01 2024-01-05 coechsler ESCAN00116209 Added length check of CRYPTO_KE_RANDOM_SEED_STATE in DRBG + * ESCAN00116431 Support ECBD with x-coordinate shared secret only + * 13.06.00 2024-01-16 coechsler CRY-58 Support SLH-DSA SHA2-128s Verify + * CRY-391 Support SM4 Cipher Encrypt/Decrypt + * CRY-389 Support SM3 Hash + * CRY-395 Support SM2 Signature Generate/Verify + * 14.00.00 2024-03-15 coechsler CRY-759 Support AES GCM variable tag length + * main-1 2024-03-25 coechsler CRY-462 Change history is maintained in the global ChangeHistory.txt file starting with this release. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_H) +# define CRYPTO_30_LIBCV_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +# include "Csm_Types.h" +# include "Crypto_30_LibCv_Cfg.h" +# include "Crypto_30_LibCv_KeyManagement.h" +# include "SchM_Crypto_30_LibCv.h" + +# include "Crypto_30_LibCv_Custom.h" + +# if (CRYPTO_30_LIBCV_USE_VSTD_LIB == STD_ON) +# include "vstdlib.h" +# endif + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* Vendor and module identification */ +# define CRYPTO_30_LIBCV_VENDOR_ID (30u) +# define CRYPTO_30_LIBCV_MODULE_ID (114u) +# define CRYPTO_30_LIBCV_INSTANCE_ID (0u) + +/* AUTOSAR Software specification version information */ +# define CRYPTO_30_LIBCV_AR_RELEASE_MAJOR_VERSION (0x04u) +# define CRYPTO_30_LIBCV_AR_RELEASE_MINOR_VERSION (0x03u) +# define CRYPTO_30_LIBCV_AR_RELEASE_REVISION_VERSION (0x00u) + +/* Component version information (decimal version of ALM implementation package) */ +# define CRYPTO_30_LIBCV_SW_MAJOR_VERSION (14u) +# define CRYPTO_30_LIBCV_SW_MINOR_VERSION (9u) +# define CRYPTO_30_LIBCV_SW_PATCH_VERSION (4u) + +/* API service IDs */ +/* these Ids are used for DET, therefore only "services" which are not handled by ProcessJob (thus, are provided as APIs) + * have a define here. */ +# define CRYPTO_30_LIBCV_SID_INIT (0x00u) /*!< Service ID: Crypto_30_LibCv_Init() */ +# define CRYPTO_30_LIBCV_SID_GET_VERSION_INFO (0x01u) /*!< Service ID: Crypto_30_LibCv_GetVersionInfo() */ +# define CRYPTO_30_LIBCV_SID_PROCESS_JOB (0x03u) /*!< Service ID: Crypto_30_LibCv_ProcessJob() */ +# define CRYPTO_30_LIBCV_SID_KEY_ELEMENT_SET (0x04u) /*!< Service ID: Crypto_30_LibCv_KeyElementSet() */ +# define CRYPTO_30_LIBCV_SID_KEY_SET_VALID (0x05u) /*!< Service ID: Crypto_30_LibCv_KeySetValid() */ +# define CRYPTO_30_LIBCV_SID_KEY_ELEMENT_GET (0x06u) /*!< Service ID: Crypto_30_LibCv_KeyElementGet() */ +# define CRYPTO_30_LIBCV_SID_KEY_GENERATE (0x07u) /*!< Service ID: Crypto_30_LibCv_KeyGenerate() */ +# define CRYPTO_30_LIBCV_SID_KEY_DERIVE (0x08u) /*!< Service ID: Crypto_30_LibCv_KeyDerive() */ +# define CRYPTO_30_LIBCV_SID_KEY_EXCHANGE_CALC_PUB_VAL (0x09u) /*!< Service ID: Crypto_30_LibCv_KeyExchangeCalcPubVal() */ +# define CRYPTO_30_LIBCV_SID_KEY_EXCHANGE_CALC_SECRET (0x0Au) /*!< Service ID: Crypto_30_LibCv_KeyExchangeCalcSecret() */ +# define CRYPTO_30_LIBCV_SID_CERTIFICATE_PARSE (0x0Bu) /*!< Service ID: Crypto_30_LibCv_CertificateParse() */ /* not supported */ +# define CRYPTO_30_LIBCV_SID_MAIN_FUNCTION (0x0Cu) /*!< Service ID: Crypto_30_LibCv_MainFunction() */ +# define CRYPTO_30_LIBCV_SID_RANDOM_SEED (0x0Du) /*!< Service ID: Crypto_30_LibCv_RandomSeed() */ +# define CRYPTO_30_LIBCV_SID_CANCEL_JOB (0x0Eu) /*!< Service ID: Crypto_30_LibCv_CancelJob() */ +# define CRYPTO_30_LIBCV_SID_KEY_ELEMENT_COPY (0x0Fu) /*!< Service ID: Crypto_30_LibCv_KeyElementCopy() */ +# define CRYPTO_30_LIBCV_SID_KEY_COPY (0x10u) /*!< Service ID: Crypto_30_LibCv_KeyCopy() */ +# define CRYPTO_30_LIBCV_SID_KEY_ELEMENT_IDS_GET (0x11u) /*!< Service ID: Crypto_30_LibCv_KeyElementIdsGet() */ +# define CRYPTO_30_LIBCV_SID_CERTIFICATE_VERIFY (0x12u) /*!< Service ID: Crypto_30_LibCv_CertificateVerify() */ /* not supported */ +# define CRYPTO_30_LIBCV_SID_KEY_ELEMENT_COPY_PARTIAL (0x13u) /*!< Service ID: Crypto_30_LibCv_KeyElementCopyPartial() */ +# define CRYPTO_30_LIBCV_SID_KEY_GET_STATUS (0x14u) /*!< Service ID: Crypto_30_LibCv_KeyGetStatus() */ +# define CRYPTO_30_LIBCV_SID_KEY_SET_INVALID (0x15u) /*!< Service ID: Crypto_30_LibCv_KeySetInvalid() */ +# define CRYPTO_30_LIBCV_SID_NVBLOCK_READFROMBLOCK (0x80u) /*!< Service ID: Crypto_30_LibCv_NvBlock_ReadFromBlock() */ +# define CRYPTO_30_LIBCV_SID_NVBLOCK_WRITETOBLOCK (0x81u) /*!< Service ID: Crypto_30_LibCv_NvBlock_WriteToBlock() */ +# define CRYPTO_30_LIBCV_SID_NVBLOCK_INIT (0x82u) /*!< Service ID: Crypto_30_LibCv_NvBlock_Init() */ +# define CRYPTO_30_LIBCV_SID_NVBLOCK_CALLBACK (0x83u) /*!< Service ID: Crypto_30_LibCv_NvBlock_Callback() */ +# define CRYPTO_30_LIBCV_SID_ESL_GETBYTESRNG (0x84u) /*!< Service ID: esl_getBytesRNG() */ +# define CRYPTO_30_LIBCV_SID_KEY_VALID_SET (CRYPTO_30_LIBCV_SID_KEY_SET_VALID) /*!< Service ID: Crypto_30_LibCv_KeyValidSet() */ + +/* Modes */ +/* State: Uninitialized */ +# define CRYPTO_30_LIBCV_UNINIT (0x00u) +/* State: Initialized */ +# define CRYPTO_30_LIBCV_INITIALIZED (0x01u) + +/* Development Error Types [SWS_Crypto_00040] */ +# ifndef CRYPTO_E_NO_ERROR /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_E_NO_ERROR (255u) +# endif +# ifndef CRYPTO_E_UNINIT /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_E_UNINIT (0u) +# endif +# ifndef CRYPTO_E_INIT_FAILED /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_E_INIT_FAILED (1u) +# endif +# ifndef CRYPTO_E_PARAM_POINTER /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_E_PARAM_POINTER (2u) +# endif +# ifndef CRYPTO_E_PARAM_HANDLE /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_E_PARAM_HANDLE (4u) +# endif +# ifndef CRYPTO_E_PARAM_VALUE /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_E_PARAM_VALUE (5u) +# endif + +/* Crypto Stack Error Codes used from Autosar 4.4 */ +# ifndef CRYPTO_E_KEY_EMPTY /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_E_KEY_EMPTY (13u) +# endif + +/* Runtime Error Types [SWS_Crypto_00194] */ +# ifndef CRYPTO_E_RE_ENTROPY_EXHAUSTED /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_E_RE_ENTROPY_EXHAUSTED (3u) +# endif +# ifndef CRYPTO_E_RE_GET_BYTES_RNG_ERROR /* COV_CRYPTO_30_LIBCV_CSM_DEFINES */ +# define CRYPTO_E_RE_GET_BYTES_RNG_ERROR (30u) +# endif + +/* Data Services */ +# if (CRYPTO_30_LIBCV_USE_VSTD_LIB == STD_ON) +/* Use VStdLib */ +# define Crypto_30_LibCv_CopyData(destinationPtr, sourcePtr, length) (VStdLib_MemCpy((P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))(destinationPtr), (P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))(sourcePtr), (VStdLib_CntType)(length))) +# define Crypto_30_LibCv_ClearData(dataPtr, length) (VStdLib_MemClr((P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))(dataPtr), (VStdLib_CntType)(length))) +# define Crypto_30_LibCv_SetData(dataPtr, pattern, length) (VStdLib_MemSet((P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))(dataPtr), (pattern), (VStdLib_CntType)(length))) +# else +/* Use internal implementation */ +# define Crypto_30_LibCv_CopyData(destinationPtr, sourcePtr, length) (Crypto_30_LibCv_Local_CopyData_Implementation((P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))(destinationPtr), (P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))(sourcePtr), (length))) +# define Crypto_30_LibCv_ClearData(dataPtr, length) (Crypto_30_LibCv_Local_ClearData_Implementation((P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))(dataPtr), (length))) +# define Crypto_30_LibCv_SetData(dataPtr, pattern, length) (Crypto_30_LibCv_Local_SetData_Implementation((P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))(dataPtr), (pattern), (length))) +# endif + +/* Watchdog Trigger Function */ +# if (CRYPTO_30_LIBCV_WATCHDOGTRIGGERFUNCTIONOFGENERAL == STD_ON) +# define CRYPTO_30_LIBCV_WATCHDOG_PTR Crypto_30_LibCv_GetWatchdogTriggerFunctionOfGeneral() +# else +# define CRYPTO_30_LIBCV_WATCHDOG_PTR (NULL_PTR) +# endif + +/* Macros for Job access */ +# ifndef CRYPTO_30_LIBCV_JOB_STATE_MEMBER /* COV_CRYPTO_30_LIBCV_ASR_COMPATIBILITY */ +# define CRYPTO_30_LIBCV_JOB_STATE_MEMBER jobState +# endif + +# ifndef CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER /* COV_CRYPTO_30_LIBCV_ASR_COMPATIBILITY */ +# define CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER jobPrimitiveInputOutput +# endif + +# ifndef CRYPTO_30_LIBCV_JOB_ID_MEMBER /* COV_CRYPTO_30_LIBCV_ASR_COMPATIBILITY */ +# define CRYPTO_30_LIBCV_JOB_ID_MEMBER jobId +# endif + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Init() + *********************************************************************************************************************/ +/*! \brief Initializes the Crypto Driver + * \details This function initializes the module Crypto_30_LibCv. It initializes all variables relevant for the + * partition and sets the module state for the partition to initialized. It has to be called once from + * the main partition and also from each other partition where the module is used. + * \pre Interrupts are disabled. + * Module is uninitialized. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + * \note Specification of module initialization + * \trace DSGN-DrvCrypto_Libcv_Initialization + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Init(void); + +# if (CRYPTO_30_LIBCV_VERSION_INFO_API == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_GetVersionInfo() + *********************************************************************************************************************/ +/*! \brief Returns the version information + * \details Crypto_30_LibCv_GetVersionInfo() returns version information, vendor ID and AUTOSAR module ID of the component. + * \param[out] versioninfo Pointer to where to store the version information. Parameter must not be NULL. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \config CRYPTO_30_LIBCV_VERSION_INFO_API == STD_ON + * \trace CREQ-131329 + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_GetVersionInfo( + P2VAR(Std_VersionInfoType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) versioninfo); +# endif /* (CRYPTO_30_LIBCV_VERSION_INFO_API == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_ProcessJob() + *********************************************************************************************************************/ +/*! \brief Processes the received job + * \details Performs the crypto primitive, that is configured in the job parameter. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * If multi-partition support is enabled, only the objectId which belongs to + * the calling partition is allowed to be used. + * \param[in,out] job Pointer to the configuration of the job. Contains structures with job and + * primitive relevant information but also pointer to result buffers. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * CRYPTO_E_QUEUE_FULL Request failed, the queue is full. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_EMPTY Request failed, uninitialized source key element. + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, the entropy is exhausted. + * CRYPTO_E_JOB_CANCELED The service request failed because the synchronous Job has been canceled. + * \pre - + * \context TASK + * \reentrant TRUE, for jobs with different job ids + * \synchronous TRUE|FALSE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_ProcessJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_CancelJob() + *********************************************************************************************************************/ +/*! \brief Cancels the received job + * \details This interface removes the provided job from the queue and cancels the processing of the job if possible. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the configuration of the job. Contains structures with user and + * primitive relevant information. + * \return E_OK Request successful, job has been removed. + * E_NOT_OK Request failed, job could not be removed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_CancelJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +# if(CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON) +/********************************************************************************************************************** + * Appl_Crypto_30_LibCv_SaveContextCallout() + *********************************************************************************************************************/ +/*! \brief Saves the context to the output buffer. + * \details The customer can choose whether the context data is to be written encrypted or in plain text + * to the output buffer. The outputLengthPtr must be set to the written length. + * The JobId and ObjectId can be used to check whether the data originates + * from the correct job and object. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in] jobId Holds the identifier of the Job. + * \param[in] context Holds the Address of the source context data. + * \param[in] contextLength Holds the length of the source context. + * \param[out] outputPtr Pointer to output buffer + * \param[in,out] outputLengthPtr Pointer to output length buffer + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \config CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CRYPTO_30_LIBCV_APPL_CODE) Appl_Crypto_30_LibCv_SaveContextCallout( + uint32 objectId, + uint32 jobId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) context, + uint32 contextLength, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) outputPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) outputLengthPtr); + +/********************************************************************************************************************** + * Appl_Crypto_30_LibCv_RestoreContextCallout() + *********************************************************************************************************************/ +/*! \brief Restores the context from the output buffer. + * \details The customer can choose to write the data encrypted or in plain text to the destination context address. + * The data shall only be copied if the plain context matches the contextLength. + * If the context data is encrypted, it must be decrypted first and then written to the workspace address. + * The JobId and ObjectId can be used to check whether the data originates from the correct job and object. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in] jobId Holds the identifier of the Job. + * \param[out] context Holds the Address of the destination context data. + * \param[in] contextLength Holds the length of the destination context. + * \param[in] inputPtr Pointer to source input buffer. + * \param[in] inputLength Holds the input buffer length. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \config CRYPTO_30_LIBCV_SAVEANDRESTOREWORKSPACE == STD_ON + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CRYPTO_30_LIBCV_APPL_CODE) Appl_Crypto_30_LibCv_RestoreContextCallout( + uint32 objectId, + uint32 jobId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) context, + uint32 contextLength, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) inputPtr, + uint32 inputLength); +# endif + +/********************************************************************************************************************** + * Crypto_30_LibCv_MainFunction<_OS_APPLICATION>() + *********************************************************************************************************************/ +/*! \fn FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_MainFunction(void) + * \brief Main function of the module. Is called cyclically and handles asynchronous jobs. + * \details This interface process the provided asynchronous jobs from the queue. + * <_OS_APPLICATION> is only used if module is used by multiple partitions. + * \pre - + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + * \note Declared and called by SchM. Due to long runtimes, it is advisable to map function to a preemptive task. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * esl_getBytesRNG() + *********************************************************************************************************************/ +/*! \fn VSECPRIM_FUNC(eslt_ErrorCode) esl_getBytesRNG( const eslt_Length targetLength, VSECPRIM_P2VAR_PARA(eslt_Byte) target); + * \brief Get random byte + * \details This function generates random numbers for primitives which requires random numbers for algorithm execution. + * \param[in] targetLength the number of bytes that shall be generated + * \param[in,out] target (in) pointer to output buffer + * (out) pointer to generated random bytes + * \return ESL_ERC_ERROR input generation failed + * ESL_ERC_NO_ERROR else + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \config CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*! + * \exclusivearea CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0 + * Ensures consistency of common global RAM variables. + * \protects Crypto_30_LibCv_Lock, Crypto_30_LibCv_LastJob, Crypto_30_LibCv_Queue, Crypto_30_LibCv_NvBlock_State, Crypto_30_LibCv_RandomSourceGenerateCount, Crypto_30_LibCv_KeyNvStatus + * \usedin Crypto_30_LibCv_MainFunction, Crypto_30_LibCv_ProcessJob, Crypto_30_LibCv_CancelJob, Crypto_30_LibCv_KeyValidSet, Crypto_30_LibCv_KeyElementSet, Crypto_30_LibCv_KeyElementCopy, Crypto_30_LibCv_KeyCopy, Crypto_30_LibCv_KeyExchangeCalcSecret, Crypto_30_LibCv_KeyExchangeCalcPub, Crypto_30_LibCv_KeyGenerate, Crypto_30_LibCv_KeyDerive, Crypto_30_LibCv_RandomGenerate, Crypto_30_LibCv_RandomSeed, esl_getBytesRNG, Crypto_30_LibCv_KeyGetStatus, Crypto_30_LibCv_NvBlock_Callback and Crypto_30_LibCv_NvBlock_WriteToBlock. + * \exclude All functions in which this exclusive area is used in. + * \length LONG in esl_getBytesRNG, SHORT in rest. + * \endexclusivearea + + * \exclusivearea CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1 + * Ensures consistency of global RAM variables used for key locking. + * \protects Crypto_30_LibCv_KeyLock + * \usedin Crypto_30_LibCv_MainFunction, Crypto_30_LibCv_ProcessJob, Crypto_30_LibCv_CancelJob, Crypto_30_LibCv_KeyExchangeCalcPubVal, Crypto_30_LibCv_KeyExchangeCalcSecret, Crypto_30_LibCv_KeyGenerate, Crypto_30_LibCv_KeyElementSet, Crypto_30_LibCv_KeyValidSet, Crypto_30_LibCv_KeyElementGet, Crypto_30_LibCv_KeyCopy, Crypto_30_LibCv_KeyElementCopy, Crypto_30_LibCv_KeyElementCopyPartial, Crypto_30_LibCv_KeyDerive, Crypto_30_LibCv_RandomSeed + * \exclude All functions in which this exclusive area is used in. + * \length MEDIUM as runtime depends on number of to be locked keys. + * \endexclusivearea + + * \exclusivearea CRYPTO_30_LIBCV_EXCLUSIVE_AREA_2 + * Ensures consistency of global RAM variables used for the primitives Spake2+ and ECBD. + * \protects Crypto_30_LibCv_LongTermWsLock + * \usedin Crypto_30_LibCv_MainFunction, Crypto_30_LibCv_ProcessJob, Crypto_30_LibCv_KeyExchangeCalcPubVal, Crypto_30_LibCv_KeyExchangeCalcSecret + * \exclude All functions in which this exclusive area is used in. + * \length SHORT as only one operation is secured. + * \endexclusivearea + */ + +#endif /* CRYPTO_30_LIBCV_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Aead.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Aead.c new file mode 100644 index 0000000..e29067f --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Aead.c @@ -0,0 +1,1695 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Aead.c + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Implementation for AEAD Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_AEAD_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Crypto_30_LibCv.h" +#include "Crypto_30_LibCv_Services.h" +#include "Crypto_30_LibCv_AeadEncrypt.h" +#include "Crypto_30_LibCv_AeadDecrypt.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_AESGCM_MAX_OUT_SIZE (16u) +#define CRYPTO_30_LIBCV_AESCCM_MAX_OUT_SIZE (16u) + +#define CRYPTO_30_LIBCV_AES128CCM_KEY_SIZE (ESL_SIZEOF_AES128_KEY) +#define CRYPTO_30_LIBCV_AES256CCM_KEY_SIZE (ESL_SIZEOF_AES256_KEY) + +#define CRYPTO_30_LIBCV_CHACHA20POLY1305_KEY_LENGTH ESL_SIZEOF_ChaCha20_KEY +#define CRYPTO_30_LIBCV_CHACHA20POLY1305_NONCE_LENGTH ESL_SIZEOF_ChaCha20_NONCE +#define CRYPTO_30_LIBCV_POLY1305_OUT_SIZE ESL_SIZEOF_Poly1305_TAG + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_LIBCV_AESGCMENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Start() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesGcmEncrypt start job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Start( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Update() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesGcmEncrypt update job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Update( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Finish() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesGcmEncrypt finish job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Finish( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +#endif /* (CRYPTO_30_LIBCV_AESGCMENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AESGCMDECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Start() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesGcmDecrypt start job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Start( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Update() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesGcmDecrypt update job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Update( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Finish() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesGcmDecrypt finish job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Finish( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_AESGCMDECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Start() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesCcmEncrypt start job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service + * by passing the workspace to Crypto_30_LibCv_Dispatch_AesCcm_Start. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Start( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Update() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesCcmEncrypt update job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Update( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Finish() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesCcmEncrypt finish job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Finish( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +#endif /* (CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Start() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesCcmDecrypt start job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * By passing a suitable workspace to Crypto_30_LibCv_Dispatch_AesCcm_Start + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Start( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Update() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesCcmDecrypt update job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Update( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Finish() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesCcmDecrypt finish job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Finish( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) || (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcm_Start() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesCcm start job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in] authenticationFieldSize Holds the length of authentication field size. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcm_Start( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint8 authenticationFieldSize); +#endif /* ((CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) || (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON)) */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#if (CRYPTO_30_LIBCV_AESGCMENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Start() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Start( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Handle operationmode START. */ + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CIPHER_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CIPHER_IV); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_GCM, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initEncryptGCM(workspace, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1u].keyElementIndex), + (eslt_Length)keyElements[1u].keyElementLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Start() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Update() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Update( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Handle operationmode UPDATE. */ + + /* Update GCM Calculation */ + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + /* # Check if output size is sufficient otherwise return error. */ + if (((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength + (CRYPTO_30_LIBCV_AESGCM_MAX_OUT_SIZE - 1u)) & 0xFFFFFFF0u) > (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)) + { + retValCv = ESL_ERC_OUTPUT_SIZE_TOO_SHORT; + } + else + { + retValCv = ESL_ERC_NO_ERROR; + } + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = 0u; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + if ((retValCv == ESL_ERC_NO_ERROR) && (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength != 0u)) + { + /* # Process authentic data. */ + retValCv = esl_updateAuthDataEncryptGCM(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Process plaintext data. */ + retValCv = esl_updatePlaintextEncryptGCM(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + (P2VAR(eslt_Size32, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + } + + /* # Store current written length and remaining buffer length for operationmode FINISH. */ + Crypto_30_LibCv_SetWrittenLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, Crypto_30_LibCv_GetBufferLength(objectId) - Crypto_30_LibCv_GetWrittenLength(objectId)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Update() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Finish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Finish( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + /* Get outputLength in local variable to omit type mismatches */ + eslt_Length secondaryOutputLength = (eslt_Length)*(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr); + + /* ----- Implementation ------------------------------------------------- */ + + /* # Handle operationmode FINISH. */ + /* # Reinitialize written length and remaining buffer if UPDATE was not part of this job. */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode & CRYPTO_OPERATIONMODE_UPDATE) != CRYPTO_OPERATIONMODE_UPDATE) + { + Crypto_30_LibCv_SetWrittenLength(objectId, 0u); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + + /* # Check if output size is sufficient otherwise return error. */ + if (Crypto_30_LibCv_GetBufferLength(objectId) < CRYPTO_30_LIBCV_AESGCM_MAX_OUT_SIZE) + { + retValCv = ESL_ERC_OUTPUT_SIZE_TOO_SHORT; + } + else + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = Crypto_30_LibCv_GetWrittenLength(objectId); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Write results in output buffers. */ + retValCv = esl_finalizeEncryptGCMVariableTagLength(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)], + (P2VAR(eslt_Size32, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&secondaryOutputLength); + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr = secondaryOutputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Finish() */ +#endif /* (CRYPTO_30_LIBCV_AESGCMENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AESGCMDECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Start() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Start( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Handle operationmode START. */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CIPHER_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CIPHER_IV); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_GCM, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initDecryptGCM(workspace, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1u].keyElementIndex), + (eslt_Length)keyElements[1u].keyElementLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Start() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Update() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Update( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Handle operationmode UPDATE. */ + /* Update GCM Calculation */ + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + /* # Check if output size is sufficient otherwise return error. */ + if (((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength + (CRYPTO_30_LIBCV_AESGCM_MAX_OUT_SIZE - 1u)) & 0xFFFFFFF0u) > (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)) + { + retValCv = ESL_ERC_OUTPUT_SIZE_TOO_SHORT; + } + else + { + retValCv = ESL_ERC_NO_ERROR; + } + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = 0u; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Process authentic data. */ + if ((retValCv == ESL_ERC_NO_ERROR) && (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength != 0u)) + { + retValCv = esl_updateAuthDataDecryptGCM(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); + } + + /* # Process plaintext data. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + retValCv = esl_updateCiphertextDecryptGCM(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + (P2VAR(eslt_Size32, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + } + + /* # Store current written length and remaining buffer length for operationmode FINISH. */ + Crypto_30_LibCv_SetWrittenLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, Crypto_30_LibCv_GetBufferLength(objectId) - Crypto_30_LibCv_GetWrittenLength(objectId)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Update() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Finish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Finish( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Init verify result to CRYPTO_E_VER_NOT_OK */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Handle operationmode FINISH. */ + /* # Reinitialize written length and remaining buffer if UPDATE was not part of this job. */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode & CRYPTO_OPERATIONMODE_UPDATE) != CRYPTO_OPERATIONMODE_UPDATE) + { + Crypto_30_LibCv_SetWrittenLength(objectId, 0u); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + + /* # Check if output size is sufficient otherwise return error. */ + if (Crypto_30_LibCv_GetBufferLength(objectId) < CRYPTO_30_LIBCV_AESGCM_MAX_OUT_SIZE) + { + retValCv = ESL_ERC_OUTPUT_SIZE_TOO_SHORT; + } + else + { + retValCv = ESL_ERC_NO_ERROR; + } + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = Crypto_30_LibCv_GetWrittenLength(objectId); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Write results in output buffers. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + retValCv = esl_finalizeDecryptGCMVariableTagLength(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)], + (P2VAR(eslt_Size32, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.tertiaryInputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.tertiaryInputLength); + } + + /* # Check if verification was successful. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + else if (retValCv == ESL_ERC_GCM_TAG_VERIFICATION_FAILED) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + /* For all other errors do nothing */ + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Finish() */ +#endif /* (CRYPTO_30_LIBCV_AESGCMDECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Start() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Start( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Call Crypto_30_LibCv_Dispatch_AesCcm_Start */ + retVal = Crypto_30_LibCv_Dispatch_AesCcm_Start( + workspace, + job, + (uint8)*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Start() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Update() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Update( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_ErrorCode retValCv; + eslt_Length outlength; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Handle operationmode UPDATE. */ + + /* Update CCM Calculation */ + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + outlength = (eslt_Length)*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr; + + /* # Process plaintext data. */ + retValCv = esl_updateAESCCMEncrypt(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outlength); + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = outlength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Store current written length and remaining buffer length for operationmode FINISH. */ + Crypto_30_LibCv_SetWrittenLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, Crypto_30_LibCv_GetBufferLength(objectId) - Crypto_30_LibCv_GetWrittenLength(objectId)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Update() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Finish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Finish( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + /* buffer holding Auth Tag */ + eslt_Length outlength, secOutlength; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Handle operationmode FINISH. */ + outlength = (eslt_Length)Crypto_30_LibCv_GetBufferLength(objectId); + secOutlength = (eslt_Length)*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr; + + /* # Write results in output buffers. */ + retValCv = esl_finalizeAESCCMEncrypt(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)], + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outlength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&secOutlength); + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr += outlength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Finish() */ +#endif /* (CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Start() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Start( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Call Crypto_30_LibCv_Dispatch_AesCcm_Start */ + retVal = Crypto_30_LibCv_Dispatch_AesCcm_Start( + workspace, + job, + (uint8)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.tertiaryInputLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Start() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Update() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Update( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_ErrorCode retValCv; + eslt_Length outlength; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Handle operationmode UPDATE. */ + /* Update CCM Calculation */ + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + outlength = (eslt_Length)*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr; + /* # Process plaintext data. */ + retValCv = esl_updateAESCCMDecrypt(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outlength); + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = outlength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Store current written length and remaining buffer length for operationmode FINISH. */ + Crypto_30_LibCv_SetWrittenLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, Crypto_30_LibCv_GetBufferLength(objectId) - Crypto_30_LibCv_GetWrittenLength(objectId)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Update() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Finish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Finish( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_ErrorCode retValCv; + eslt_Length outlength; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Handle operationmode FINISH. */ + outlength = (eslt_Length)Crypto_30_LibCv_GetBufferLength(objectId); + + /* # Write results in output buffers. */ + retValCv = esl_finalizeAESCCMDecrypt(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)], + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outlength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.tertiaryInputPtr); + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr += outlength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Check if verification was successful. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + else if (retValCv == ESL_ERC_INCORRECT_TAG) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + /* For all other errors do nothing */ + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Finish() */ +#endif /* (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) || (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcm_Start() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcm_Start( + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint8 authenticationFieldSize) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Handle operationmode START. */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CIPHER_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CIPHER_IV); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_AESCCM, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + eslt_Byte lengthFieldSize = (eslt_Byte)(CRYPTO_30_LIBCV_AESCCM_SUM_OF_NONCE_LENGTH_AND_L - keyElements[1u].keyElementLength); + eslt_Length keyLength = (eslt_Length) keyElements[0u].keyElementLength; + retVal = E_NOT_OK; + + /* # Check key length */ + if ((keyLength == CRYPTO_30_LIBCV_AES128CCM_KEY_SIZE) || (keyLength == CRYPTO_30_LIBCV_AES256CCM_KEY_SIZE)) + { + /* # Initialize algorithm. */ + retValCv = esl_initAESCCM(workspace, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + keyLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1u].keyElementIndex), + (eslt_Length)keyElements[1u].keyElementLength, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (eslt_Byte)authenticationFieldSize, + lengthFieldSize); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + } + else + { + /* retVal has already been set before */ + } + + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesCcm_Start() */ +#endif /* ((CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) || (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON)) */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ +#if (CRYPTO_30_LIBCV_AESGCMENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmEncrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmEncrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfAesGcmEncrypt(Crypto_30_LibCv_GetAesGcmEncryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceGCM)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Start(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Update(workspace, objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_AesGcmEncrypt_Finish(workspace, objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesGcmEncrypt() */ +#endif /* (CRYPTO_30_LIBCV_AESGCMENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AESGCMDECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmDecrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmDecrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfAesGcmDecrypt(Crypto_30_LibCv_GetAesGcmDecryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceGCM)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Start(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Update(workspace, objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_AesGcmDecrypt_Finish(workspace, objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesGcmDecrypt() */ +#endif /* (CRYPTO_30_LIBCV_AESGCMDECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmEncrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmEncrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfAesCcmEncrypt(Crypto_30_LibCv_GetAesCcmEncryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceAESCCM)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_SINGLECALL)) + { + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Start(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Update(workspace, objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_AesCcmEncrypt_Finish(workspace, objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesCcmEncrypt() */ +#endif /* (CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmDecrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmDecrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceAESCCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfAesCcmDecrypt(Crypto_30_LibCv_GetAesCcmDecryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceAESCCM)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_SINGLECALL)) + { + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Start(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Update(workspace, objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_AesCcmDecrypt_Finish(workspace, objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesCcmDecrypt() */ +#endif /* (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AEADCHACHAPOLY1305ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AEADChaChaPoly1305Encrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6030, 6050 4 */ /* MD_MSR_STCYC, MD_MSR_STCAL */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AEADChaChaPoly1305Encrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceChaChaPoly, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfAEADChaChaPoly1305Encrypt(Crypto_30_LibCv_GetAEADChaChaPoly1305EncryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceChaChaPoly)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_CIPHER_KEY, CRYPTO_30_LIBCV_CHACHA20POLY1305_KEY_LENGTH); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 1u, CRYPTO_KE_CIPHER_IV, CRYPTO_30_LIBCV_CHACHA20POLY1305_NONCE_LENGTH); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_AEAD_ChaCha_Poly, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initEncryptChaChaPoly(workspace, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1u].keyElementIndex)); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + } + } + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + /* Get output length in local variable to omit type mismatches */ + eslt_Length outputLength; + outputLength = (eslt_Length)*(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* # Check if output size is sufficient otherwise return error. */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength) > (outputLength)) + { + retValCv = ESL_ERC_OUTPUT_SIZE_TOO_SHORT; + } + else + { + retValCv = ESL_ERC_NO_ERROR; + } + + if ((retValCv == ESL_ERC_NO_ERROR) && (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength != 0u)) + { + /* # Process authentic data. */ + retValCv = esl_updateAADChaChaPoly(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Process plaintext data. */ + retValCv = esl_updateDataChaChaPoly(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength); + + /* copy back written output length */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) = outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + /* buffer holding Auth Tag */ + uint8 authTagTempBuffer[CRYPTO_30_LIBCV_POLY1305_OUT_SIZE] = { 0u }; + + /* # For finish only mode, adapt output length */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode & CRYPTO_OPERATIONMODE_UPDATE) != CRYPTO_OPERATIONMODE_UPDATE) + { + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) = 0u; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Write results in output buffers. */ + retValCv = esl_finalizeChaChaPoly(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))authTagTempBuffer); + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Adapt output size of auth tag. */ + if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr > CRYPTO_30_LIBCV_POLY1305_OUT_SIZE) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr = CRYPTO_30_LIBCV_POLY1305_OUT_SIZE; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Copy auth tag to output buffer. */ + Crypto_30_LibCv_CopyData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputPtr, authTagTempBuffer, *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AEADChaChaPoly1305Encrypt() */ +#endif /* (CRYPTO_30_LIBCV_AEADCHACHAPOLY1305ENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AEADCHACHAPOLY1305DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AEADChaChaPoly1305Decrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6030 4 */ /* MD_MSR_STCYC */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AEADChaChaPoly1305Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceChaChaPoly, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfAEADChaChaPoly1305Decrypt(Crypto_30_LibCv_GetAEADChaChaPoly1305DecryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceChaChaPoly)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_CIPHER_KEY, CRYPTO_30_LIBCV_CHACHA20POLY1305_KEY_LENGTH); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 1u, CRYPTO_KE_CIPHER_IV, CRYPTO_30_LIBCV_CHACHA20POLY1305_NONCE_LENGTH); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_AEAD_ChaCha_Poly, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initDecryptChaChaPoly(workspace, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1u].keyElementIndex)); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + } + } + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + /* Get output length in local variable to omit type mismatches */ + eslt_Length outputLength; + outputLength = (eslt_Length)*(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* # Check if output size is sufficient otherwise return error. */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength) > (outputLength)) + { + retValCv = ESL_ERC_OUTPUT_SIZE_TOO_SHORT; + } + else + { + retValCv = ESL_ERC_NO_ERROR; + } + + /* # Process authentic data. */ + if ((retValCv == ESL_ERC_NO_ERROR) && (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength != 0u)) + { + retValCv = esl_updateAADChaChaPoly(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); + } + + /* # Process plaintext data. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + retValCv = esl_updateDataChaChaPoly(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength); + + /* copy back written output length */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) = outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + /* # For finish only mode, adapt output length */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode & CRYPTO_OPERATIONMODE_UPDATE) != CRYPTO_OPERATIONMODE_UPDATE) + { + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) = 0u; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Check if output size is sufficient otherwise return error. */ + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.tertiaryInputLength == CRYPTO_30_LIBCV_POLY1305_OUT_SIZE) + { + /* # Verify tag. */ + retValCv = esl_verifyChaChaPoly(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.tertiaryInputPtr); + } + else + { + retValCv = ESL_ERC_INCORRECT_TAG; + } + + /* # Check if verification was successful. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + else if (retValCv == ESL_ERC_INCORRECT_TAG) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + /* For all other errors do nothing */ + } + + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AEADChaChaPoly1305Decrypt() */ +#endif /* (CRYPTO_30_LIBCV_AEADCHACHAPOLY1305DECRYPT == STD_ON) */ + +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Aead.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AeadDecrypt.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AeadDecrypt.h new file mode 100644 index 0000000..e1c34d1 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AeadDecrypt.h @@ -0,0 +1,132 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_AeadDecrypt.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for AEAD Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_AEADDECRYPT_H) +# define CRYPTO_30_LIBCV_AEADDECRYPT_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_AESGCMDECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmDecrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesGcmDecrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-139103 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmDecrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_AESGCMDECRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmDecrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesCcmDecrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-266237 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmDecrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_AESCCMDECRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_AEADCHACHAPOLY1305DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AEADChaChaPoly1305Decrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the AEAD ChaCha Poly1305 Decrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-251277 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AEADChaChaPoly1305Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_AEADCHACHAPOLY1305DECRYPT == STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_AEADDECRYPT_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_AeadDecrypt.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AeadEncrypt.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AeadEncrypt.h new file mode 100644 index 0000000..3194f34 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AeadEncrypt.h @@ -0,0 +1,132 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_AeadEncrypt.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for AEAD Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_AEADENCRYPT_H) +# define CRYPTO_30_LIBCV_AEADENCRYPT_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_AESGCMENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesGcmEncrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesGcmEncrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-139104 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesGcmEncrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_AESGCMENCRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesCcmEncrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesCcmEncrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-266236 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesCcmEncrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_AESCCMENCRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_AEADCHACHAPOLY1305ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AEADChaChaPoly1305Encrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the AEAD ChaCha Poly1305 Encrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-251276 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AEADChaChaPoly1305Encrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_AEADCHACHAPOLY1305ENCRYPT == STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_AEADENCRYPT_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_AeadEncrypt.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AutosarDefines.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AutosarDefines.h new file mode 100644 index 0000000..3d3161a --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_AutosarDefines.h @@ -0,0 +1,390 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file Crypto_30_LibCv_AutosarDefines.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Internal header file for fallback AUTOSAR definitions and necessary AUTOSAR definition checks. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_AUTOSARDEFINES_H) +# define CRYPTO_30_LIBCV_AUTOSARDEFINES_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Csm_Types.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* Algorithm type definitions are normally provided by Csm, here only as fallback */ +# ifndef CRYPTO_ALGOFAM_NOT_SET /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_NOT_SET 0x00u +# endif +# ifndef CRYPTO_ALGOFAM_SHA1 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA1 0x01u +# endif +# ifndef CRYPTO_ALGOFAM_SHA2_224 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_224 0x02u +# endif +# ifndef CRYPTO_ALGOFAM_SHA2_256 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_256 0x03u +# endif +# ifndef CRYPTO_ALGOFAM_SHA2_384 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_384 0x04u +# endif +# ifndef CRYPTO_ALGOFAM_SHA2_512 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_512 0x05u +# endif +# ifndef CRYPTO_ALGOFAM_SHA2_512_224 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_512_224 0x06u +# endif +# ifndef CRYPTO_ALGOFAM_SHA2_512_256 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_512_256 0x07u +# endif +# ifndef CRYPTO_ALGOFAM_SHA3_224 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA3_224 0x08u +# endif +# ifndef CRYPTO_ALGOFAM_SHA3_256 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA3_256 0x09u +# endif +# ifndef CRYPTO_ALGOFAM_SHA3_384 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA3_384 0x0Au +# endif +# ifndef CRYPTO_ALGOFAM_SHA3_512 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA3_512 0x0Bu +# endif +# ifndef CRYPTO_ALGOFAM_SHAKE128 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHAKE128 0x0Cu +# endif +# ifndef CRYPTO_ALGOFAM_SHAKE256 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHAKE256 0x0Du +# endif +# ifndef CRYPTO_ALGOFAM_RIPEMD160 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_RIPEMD160 0x0Eu +# endif +# ifndef CRYPTO_ALGOFAM_BLAKE_1_256 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_BLAKE_1_256 0x0Fu +# endif +# ifndef CRYPTO_ALGOFAM_BLAKE_1_512 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_BLAKE_1_512 0x10u +# endif +# ifndef CRYPTO_ALGOFAM_BLAKE_2s_256 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_BLAKE_2s_256 0x11u +# endif +# ifndef CRYPTO_ALGOFAM_BLAKE_2s_512 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_BLAKE_2s_512 0x12u +# endif +# ifndef CRYPTO_ALGOFAM_3DES /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_3DES 0x13u +# endif +# ifndef CRYPTO_ALGOFAM_AES /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_AES 0x14u +# endif +# ifndef CRYPTO_ALGOFAM_CHACHA /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_CHACHA 0x15u +# endif +# ifndef CRYPTO_ALGOFAM_RSA /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_RSA 0x16u +# endif +# ifndef CRYPTO_ALGOFAM_ED25519 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ED25519 0x17u +# endif +# ifndef CRYPTO_ALGOFAM_BRAINPOOL /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_BRAINPOOL 0x18u +# endif +# ifndef CRYPTO_ALGOFAM_ECCNIST /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECCNIST 0x19u +# endif +# ifndef CRYPTO_ALGOFAM_SECURECOUNTER /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SECURECOUNTER 0x1Au +# endif +# ifndef CRYPTO_ALGOFAM_RNG /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_RNG 0x1Bu +# endif +# ifndef CRYPTO_ALGOFAM_SIPHASH /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SIPHASH 0x1Cu +# endif +# ifndef CRYPTO_ALGOFAM_ECIES /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECIES 0x1Du +# endif +# ifndef CRYPTO_ALGOFAM_ECCANSI /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECCANSI 0x1Eu +# endif +# ifndef CRYPTO_ALGOFAM_ECCSEC /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECCSEC 0x1Fu +# endif +# ifndef CRYPTO_ALGOFAM_DRBG /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_DRBG 0x20u +# endif +# ifndef CRYPTO_ALGOFAM_FIPS186 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_FIPS186 0x21u +# endif +# ifndef CRYPTO_ALGOFAM_PADDING_PKCS7 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_PADDING_PKCS7 0x22u +# endif +# ifndef CRYPTO_ALGOFAM_PADDING_ONEWITHZEROS /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_PADDING_ONEWITHZEROS 0x23u +# endif +# ifndef CRYPTO_ALGOFAM_PBKDF2 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_PBKDF2 0x24u +# endif +# ifndef CRYPTO_ALGOFAM_KDFX963 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_KDFX963 0x25u +# endif +# ifndef CRYPTO_ALGOFAM_DH /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_DH 0x26u +# endif +# ifndef CRYPTO_ALGOFAM_SM2 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SM2 0x27u +# endif +# ifndef CRYPTO_ALGOFAM_EEA3 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_EEA3 0x28u +# endif +# ifndef CRYPTO_ALGOFAM_SM3 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SM3 0x29u +# endif +# ifndef CRYPTO_ALGOFAM_EIA3 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_EIA3 0x2Au +# endif +# ifndef CRYPTO_ALGOFAM_HKDF /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_HKDF 0x2Bu +# endif +# ifndef CRYPTO_ALGOFAM_ECDSA /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECDSA 0x2Cu +# endif +# ifndef CRYPTO_ALGOFAM_POLY1305 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_POLY1305 0x2Du +# endif +# ifndef CRYPTO_ALGOFAM_X25519 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_X25519 0x2Eu +# endif +# ifndef CRYPTO_ALGOFAM_ECDH /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECDH 0x2Fu +# endif +# ifndef CRYPTO_ALGOFAM_CUSTOM /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOFAM_CUSTOM 0xFFu +# endif + +# ifndef CRYPTO_ALGOMODE_NOT_SET /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_NOT_SET 0x00u +# endif +# ifndef CRYPTO_ALGOMODE_ECB /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_ECB 0x01u +# endif +# ifndef CRYPTO_ALGOMODE_CBC /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CBC 0x02u +# endif +# ifndef CRYPTO_ALGOMODE_CFB /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CFB 0x03u +# endif +# ifndef CRYPTO_ALGOMODE_OFB /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_OFB 0x04u +# endif +# ifndef CRYPTO_ALGOMODE_CTR /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CTR 0x05u +# endif +# ifndef CRYPTO_ALGOMODE_XTS /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_XTS 0x06u +# endif +# ifndef CRYPTO_ALGOMODE_GCM /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_GCM 0x07u +# endif +# ifndef CRYPTO_ALGOMODE_RSAES_OAEP /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_RSAES_OAEP 0x08u +# endif +# ifndef CRYPTO_ALGOMODE_RSAES_PKCS1_v1_5 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_RSAES_PKCS1_v1_5 0x09u +# endif +# ifndef CRYPTO_ALGOMODE_RSASSA_PSS /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_RSASSA_PSS 0x0Au +# endif +# ifndef CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 0x0Bu +# endif +# ifndef CRYPTO_ALGOMODE_8ROUNDS /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_8ROUNDS 0x0Cu +# endif +# ifndef CRYPTO_ALGOMODE_12ROUNDS /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_12ROUNDS 0x0Du +# endif +# ifndef CRYPTO_ALGOMODE_20ROUNDS /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_20ROUNDS 0x0Eu +# endif +# ifndef CRYPTO_ALGOMODE_HMAC /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_HMAC 0x0Fu +# endif +# ifndef CRYPTO_ALGOMODE_CMAC /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CMAC 0x10u +# endif +# ifndef CRYPTO_ALGOMODE_GMAC /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_GMAC 0x11u +# endif +# ifndef CRYPTO_ALGOMODE_CTRDRBG /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CTRDRBG 0x12u +# endif +# ifndef CRYPTO_ALGOMODE_SIPHASH_2_4 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_SIPHASH_2_4 0x13u +# endif +# ifndef CRYPTO_ALGOMODE_SIPHASH_4_8 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_SIPHASH_4_8 0x14u +# endif +# ifndef CRYPTO_ALGOMODE_PXXXR1 /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_PXXXR1 0x15u +# endif +# ifndef CRYPTO_ALGOMODE_CUSTOM /* COV_CRYPTO_30_LIBCV_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CUSTOM 0xFFu +# endif + +/* Check Autosar defines for array access */ +/*! + * + * Internal comment removed. + * + * + */ +# if (CRYPTO_HASH != 0x00u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_MACGENERATE != 0x01u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_MACVERIFY != 0x02u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ENCRYPT != 0x03u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_DECRYPT != 0x04u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_AEADENCRYPT != 0x05u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_AEADDECRYPT != 0x06u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_SIGNATUREGENERATE != 0x07u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_SIGNATUREVERIFY != 0x08u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_RANDOMGENERATE != 0x0Bu) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_RANDOMSEED != 0x0Cu) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_KEYGENERATE != 0x0Du) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_KEYDERIVE != 0x0Eu) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_KEYEXCHANGECALCPUBVAL != 0x0Fu) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_KEYEXCHANGECALCSECRET != 0x10u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_KEYSETVALID != 0x13u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_KEYSETINVALID != 0x14u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_KEYWRAP != 0x16u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_KEYUNWRAP != 0x17u) +# error "Define is not Autosar conform." +# endif + +/*! + * + * Internal comment removed. + * + * + */ +# if (CRYPTO_ALGOFAM_NOT_SET != 0u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHA1 != 1u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHA2_224 != 2u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHA2_256 != 3u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHA2_384 != 4u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHA2_512 != 5u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHA2_512_224 != 6u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHA2_512_256 != 7u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHA3_224 != 8u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHA3_256 != 9u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHA3_384 != 10u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHA3_512 != 11u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHAKE128 != 12u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_SHAKE256 != 13u) +# error "Define is not Autosar conform." +# endif +# if (CRYPTO_ALGOFAM_RIPEMD160 != 14u) +# error "Define is not Autosar conform." +# endif + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#endif /* CRYPTO_30_LIBCV_AUTOSARDEFINES_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_AutosarDefines.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Cipher.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Cipher.c new file mode 100644 index 0000000..49322ec --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Cipher.c @@ -0,0 +1,3018 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Cipher.c + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Implementation for CIPHER Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_CIPHER_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Crypto_30_LibCv.h" +#include "Crypto_30_LibCv_Services.h" +#include "Crypto_30_LibCv_Encrypt.h" +#include "Crypto_30_LibCv_Decrypt.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_AES128_KEY_LENGTH CRYPTO_30_LIBCV_AES_BLOCK_SIZE +#define CRYPTO_30_LIBCV_AES128_IV_LENGTH CRYPTO_30_LIBCV_AES_BLOCK_SIZE +#define CRYPTO_30_LIBCV_AES192_KEY_LENGTH (24u) +#define CRYPTO_30_LIBCV_AES192_IV_LENGTH CRYPTO_30_LIBCV_AES_BLOCK_SIZE +#define CRYPTO_30_LIBCV_AES256_KEY_LENGTH (32u) +#define CRYPTO_30_LIBCV_AES256_IV_LENGTH CRYPTO_30_LIBCV_AES_BLOCK_SIZE +#define CRYPTO_30_LIBCV_AES_MODE_128 (0u) +#define CRYPTO_30_LIBCV_AES_MODE_192 (1u) +#define CRYPTO_30_LIBCV_AES_MODE_256 (2u) + +/* SM4 defines */ +#define CRYPTO_30_LIBCV_SM4_KEY_LENGTH ESL_SIZEOF_SM4_BLOCK +#define CRYPTO_30_LIBCV_SM4_IV_LENGTH ESL_SIZEOF_SM4_BLOCK + +/* RSA decryption mode */ +/* normal mode */ +#define CRYPTO_30_LIBCV_RSA_DECRYPT_MODE_PRIVATE (0u) +/* inverse mode */ +#define CRYPTO_30_LIBCV_RSA_DECRYPT_MODE_PUBLIC (1u) + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if ((CRYPTO_30_LIBCV_AESENCRYPT == STD_ON) || (CRYPTO_30_LIBCV_AESDECRYPT == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesKey() + *********************************************************************************************************************/ +/*! \brief Load AES key and iv. + * \details This function loads the AES key and iv and checks the AES key length. + * The iv is used as counter in CTR mode. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the workspace. + * \param[out] keyIndexPtr Pointer to the key storage index which holds the key. + * \param[out] ivIndexPtr Pointer to the key storage index which holds the iv or counter, according to the aes-mode. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre all pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesKey( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) keyIndexPtr, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) ivIndexPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesPaddingMode() + *********************************************************************************************************************/ +/*! \brief Load AES padding mode. + * \details This function loads the AES padding mode. + * \param[in] secondaryAlgorithmFamilyOfJob secondary algorithm family of the job which shall be dispatched. + * \return AES paddingMode + * \pre all pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_PaddingMode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesPaddingMode( + Crypto_AlgorithmSecondaryFamilyType secondaryAlgorithmFamilyOfJob); +#endif + +#if (CRYPTO_30_LIBCV_AESENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesEncryptStart() + *********************************************************************************************************************/ +/*! \brief Dispatches the CipherAesEncrypt job for key sizes 128, 192 and 256 bit in operation mode start + * to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the workspace. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * workspace has to be a valid Crypto_30_LibCv_WorkSpaceAES workspace. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesEncryptStart( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesEncryptUpdate() + *********************************************************************************************************************/ +/*! \brief Dispatches the CipherAesEncrypt job for key sizes 128, 192 and 256 bit in operation mode update + * to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the workspace. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * workspace has to be a valid Crypto_30_LibCv_WorkSpaceAES workspace. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesEncryptUpdate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesEncryptFinish() + *********************************************************************************************************************/ +/*! \brief Dispatches the CipherAesEncrypt job for key sizes 128, 192 and 256 bit in operation mode finish + * to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the workspace. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * workspace has to be a valid Crypto_30_LibCv_WorkSpaceAES workspace. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesEncryptFinish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); +#endif /* (CRYPTO_30_LIBCV_AESENCRYPT == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_SM4ENCRYPT == STD_ON) || (CRYPTO_30_LIBCV_SM4DECRYPT == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherSm4Start_InitAlgorithm() + *********************************************************************************************************************/ +/*! \brief Inits the SM4 algorithm. + * \details Inits either encryption or decryption based on the job service. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the workspace. + * \param[in] keyLength Length of the cipher key. + * \param[in] keyPtr Pointer to the cipher key. + * \param[in] blockMode Block mode of cipher algorithm, ESL_BM_CBC or ESL_BM_ECB. + * \param[in] ivLength Length of the initialization vector (IV) + * \param[in] ivPtr Pointer to the initialization vector + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * workspace has to be a valid eslt_WorkSpaceSM4 workspace. + * keyPtr has to be valid. + * ivPtr has to be valid if blockMode is ESL_BM_CBC. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherSm4Start_InitAlgorithm( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(eslt_WorkSpaceSM4, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 keyLength, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) keyPtr, + eslt_BlockMode blockMode, + uint32 ivLength, + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ivPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherSm4Start() + *********************************************************************************************************************/ +/*! \brief Dispatches the CipherSm4 job in operation mode start to the lower layer. + * \details Loads necessary key elements and inits the SM4 algorithm. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the workspace. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key size is not correct. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * workspace has to be a valid eslt_WorkSpaceSM4 workspace. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherSm4Start( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(eslt_WorkSpaceSM4, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherSm4Update() + *********************************************************************************************************************/ +/*! \brief Dispatches the CipherSm4 job in operation mode update to the lower layer. + * \details Encrypts/Decrypts the provided data using the SM4 algorithm. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the workspace. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * workspace has to be a valid eslt_WorkSpaceSM4 workspace. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherSm4Update( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(eslt_WorkSpaceSM4, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherSm4Finish() + *********************************************************************************************************************/ +/*! \brief Dispatches the CipherSm4 job in operation mode finish to the lower layer. + * \details Finalizes the SM4 encryption or decryption based on the job service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the workspace. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * workspace has to be a valid eslt_WorkSpaceSM4 workspace. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherSm4Finish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(eslt_WorkSpaceSM4, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); +#endif /* (CRYPTO_30_LIBCV_SM4ENCRYPT == STD_ON || CRYPTO_30_LIBCV_SM4DECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AESDECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesDecryptStart() + *********************************************************************************************************************/ +/*! \brief Dispatches the CipherAesDecrypt job for key sizes 128, 192 and 256 bit in operation mode start + * to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the workspace. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * workspace has to be a valid Crypto_30_LibCv_WorkSpaceAES workspace. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesDecryptStart( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesDecryptUpdate() + *********************************************************************************************************************/ +/*! \brief Dispatches the CipherAesDecrypt job for key sizes 128, 192 and 256 bit in operation mode update + * to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the workspace. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * workspace has to be a valid Crypto_30_LibCv_WorkSpaceAES workspace. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesDecryptUpdate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesDecryptFinish() + *********************************************************************************************************************/ +/*! \brief Dispatches the CipherAesDecrypt job for key sizes 128, 192 and 256 bit in operation mode finish + * to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the workspace. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * workspace has to be a valid Crypto_30_LibCv_WorkSpaceAES workspace. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesDecryptFinish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); +#endif /* (CRYPTO_30_LIBCV_AESDECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ENCRYPT_RSA == STD_ON) || (CRYPTO_30_LIBCV_DECRYPT_RSA == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsa_Finish() + *********************************************************************************************************************/ +/*! \brief Handle operation mode finish for Rsa cipher. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \pre job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsa_Finish( + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_ENCRYPT_RSA == STD_ON) || (CRYPTO_30_LIBCV_DECRYPT_RSA == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Start() + *********************************************************************************************************************/ +/*! \brief Dispatches the RsaPkcs1Decrypt job to the lower layer for operation mode start. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation start, it triggers different stages of the service. + * \param[in,out] workspace Holds the workspace of the Crypto Driver Object. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre workspace has to be a valid esLib workspace. + * objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Start( + P2VAR(Crypto_30_LibCv_WorkSpaceRsaDecrypt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Update() + *********************************************************************************************************************/ +/*! \brief Dispatches the RsaPkcs1Decrypt job to the lower layer for operation mode start. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation start, it triggers different stages of the service. + * \param[in,out] workspace Holds the workspace of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid esLib workspace. + * objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Update( + P2VAR(Crypto_30_LibCv_WorkSpaceRsaDecrypt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1DECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPSHA1ENCRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPSHA256ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Start() + *********************************************************************************************************************/ +/*! \brief Handle operation mode start for RsaOaep Encrypt Sha1 and Sha256. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Holds the workspace of the Crypto Driver Object. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in] secondaryFamily Holds the secondary algorithm family. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre workspace has to be a valid esLib workspace. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Start( + P2VAR(eslt_WorkSpaceRSAOAEPenc, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_AlgorithmSecondaryFamilyType secondaryFamily); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Update() + *********************************************************************************************************************/ +/*! \brief Handle operation mode update for RsaOaep Encrypt Sha1 and Sha256. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Holds the workspace of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] secondaryFamily Holds the secondary algorithm family. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre workspace has to be a valid esLib workspace. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Update( + P2VAR(eslt_WorkSpaceRSAOAEPenc, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_AlgorithmSecondaryFamilyType secondaryFamily); +#endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA1ENCRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPSHA256ENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPSHA1DECRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPSHA256DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Start() + *********************************************************************************************************************/ +/*! \brief Handle operation mode start for RsaOaep Decrypt Sha1 and Sha256. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Holds the workspace of the Crypto Driver Object. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in] secondaryFamily Holds the secondary algorithm family. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre workspace has to be a valid esLib workspace. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Start( + P2VAR(eslt_WorkSpaceRSAOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_AlgorithmSecondaryFamilyType secondaryFamily); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Update() + *********************************************************************************************************************/ +/*! \brief Handle operation mode update for RsaOaep Decrypt Sha1 and Sha256. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Holds the workspace of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] secondaryFamily Holds the secondary algorithm family. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre workspace has to be a valid esLib workspace. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Update( + P2VAR(eslt_WorkSpaceRSAOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_AlgorithmSecondaryFamilyType secondaryFamily); +#endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA1DECRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPSHA256DECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPCRTSHA1DECRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPCRTSHA256DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Start() + *********************************************************************************************************************/ +/*! \brief Handle operation mode start for RsaOaep Crt Decrypt Sha1 and Sha256. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Holds the workspace of the Crypto Driver Object. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in] secondaryFamily Holds the secondary algorithm family. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre workspace has to be a valid esLib workspace. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Start( + P2VAR(eslt_WorkSpaceRSACRTOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_AlgorithmSecondaryFamilyType secondaryFamily); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Update() + *********************************************************************************************************************/ +/*! \brief Handle operation mode update for RsaOaep Crt Decrypt Sha1 and Sha256. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in,out] workspace Holds the workspace of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] secondaryFamily Holds the secondary algorithm family. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre workspace has to be a valid esLib workspace. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Update( + P2VAR(eslt_WorkSpaceRSACRTOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_AlgorithmSecondaryFamilyType secondaryFamily); +#endif /* (CRYPTO_30_LIBCV_RSAOAEPCRTSHA1DECRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPCRTSHA256DECRYPT == STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#if ((CRYPTO_30_LIBCV_AESDECRYPT == STD_ON) || (CRYPTO_30_LIBCV_AESENCRYPT == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesKey() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 5 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesKey( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) keyIndexPtr, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) ivIndexPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + uint32 aesKeyLength, aesIvLength; + Std_ReturnType retVal = E_NOT_OK, localRetVal; +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 != STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 != STD_ON)) + uint8 errorId = CRYPTO_E_NO_ERROR; +# endif + + /* ----- Implementation ------------------------------------------------- */ + /* Load key element from storage. */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended(job->cryptoKeyId, CRYPTO_KE_CIPHER_KEY, keyIndexPtr, &aesKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE, CRYPTO_30_LIBCV_SHE_SERVICE_ENCRYPT_DECRYPT); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* check the key length and differ algorithm */ + if (localRetVal == E_OK) + { + if (aesKeyLength == CRYPTO_30_LIBCV_AES128_KEY_LENGTH) + { + workspace->mode = CRYPTO_30_LIBCV_AES_MODE_128; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + aesIvLength = CRYPTO_30_LIBCV_AES128_IV_LENGTH; + } + else if (aesKeyLength == CRYPTO_30_LIBCV_AES192_KEY_LENGTH) + { +# if (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) + workspace->mode = CRYPTO_30_LIBCV_AES_MODE_192; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + aesIvLength = CRYPTO_30_LIBCV_AES192_IV_LENGTH; +# else + errorId = CRYPTO_E_PARAM_HANDLE; + localRetVal = E_NOT_OK; +# endif + } + else if (aesKeyLength == CRYPTO_30_LIBCV_AES256_KEY_LENGTH) + { +# if (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) + workspace->mode = CRYPTO_30_LIBCV_AES_MODE_256; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + aesIvLength = CRYPTO_30_LIBCV_AES256_IV_LENGTH; +# else + errorId = CRYPTO_E_PARAM_HANDLE; + localRetVal = E_NOT_OK; +# endif + + } + else + { + localRetVal = E_NOT_OK; + } + + if (localRetVal == E_OK) + { + /* Load iv for CBC or CTR mode, iv is used as counter in CTR mode */ + if ((job->jobPrimitiveInfo->primitiveInfo->algorithm.mode == CRYPTO_ALGOMODE_CBC) + || (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode == CRYPTO_ALGOMODE_CTR)) + { + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(job->cryptoKeyId, CRYPTO_KE_CIPHER_IV, ivIndexPtr, &aesIvLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + } + else + { + retVal = E_OK; + } + } + } + else if (localRetVal == CRYPTO_E_KEY_NOT_VALID) + { + retVal = CRYPTO_E_KEY_NOT_VALID; + } + else + { + /* retVal is already set */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (((CRYPTO_30_LIBCV_ENABLE_AES192 != STD_ON)) || (CRYPTO_30_LIBCV_ENABLE_AES256 != STD_ON)) +# if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError(CRYPTO_30_LIBCV_MODULE_ID, CRYPTO_30_LIBCV_INSTANCE_ID, CRYPTO_30_LIBCV_SID_PROCESS_JOB, errorId); + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif +# endif + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherAesKey() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesPaddingMode() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_PaddingMode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesPaddingMode( + Crypto_AlgorithmSecondaryFamilyType secondaryAlgorithmFamilyOfJob) +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_PaddingMode paddingMode = ESL_PM_OFF; + + /* ----- Implementation ------------------------------------------------- */ + /* #10 Set AES padding mode from the primitive's secondary family. */ + if (secondaryAlgorithmFamilyOfJob == CRYPTO_ALGOFAM_CUSTOM_CRYPTO_30_LIBCV_PADDING_PKCS7) + { + /* esLib uses PKCS5 define for PKCS7 padding */ + paddingMode = ESL_PM_PKCS5; + } + else if (secondaryAlgorithmFamilyOfJob == CRYPTO_ALGOFAM_PADDING_PKCS7) + { + /* esLib uses PKCS5 define for PKCS7 padding */ + paddingMode = ESL_PM_PKCS5; + } + else if (secondaryAlgorithmFamilyOfJob == CRYPTO_ALGOFAM_PADDING_ONEWITHZEROS) + { + /* esLib uses zero padding */ + paddingMode = ESL_PM_ONEWITHZEROES; + } + else /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Additional misra statement */ + } + + return paddingMode; +} /* Crypto_30_LibCv_DispatchCipherAesPaddingMode() */ +#endif /* AES decrypt and encrypt */ + +#if (CRYPTO_30_LIBCV_AESENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesEncryptStart() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesEncryptStart( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + Crypto_30_LibCv_SizeOfKeyStorageType aesEncryptKeyIndex; + Crypto_30_LibCv_SizeOfKeyStorageType aesEncryptIvIndex; + + eslt_BlockMode blockMode; + eslt_PaddingMode paddingMode = ESL_PM_OFF; + + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) aesEncryptIvPtr = NULL_PTR; + + /* ----- Implementation ------------------------------------------------- */ + + /* Init workspace variables */ + Crypto_30_LibCv_SetBufferLength(objectId, 0u); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetWrittenLength(objectId, 0u); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + /* #15 Load key element from storage. */ + retVal = Crypto_30_LibCv_DispatchCipherAesKey(job, workspace, &aesEncryptKeyIndex, &aesEncryptIvIndex); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + /* #20 Set AES mode and padding mode. */ + if (retVal == E_OK) + { + retVal = E_NOT_OK; + + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode == CRYPTO_ALGOMODE_CBC) + { + blockMode = ESL_BM_CBC; + aesEncryptIvPtr = (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(aesEncryptIvIndex); + } + else if (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode == CRYPTO_ALGOMODE_CTR) + { + blockMode = ESL_BM_CTR; + aesEncryptIvPtr = (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(aesEncryptIvIndex); + } + else + { + blockMode = ESL_BM_ECB; + } + + paddingMode = Crypto_30_LibCv_DispatchCipherAesPaddingMode(job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily); + + /* #25 Initialize algorithm with keys depending on the key size: 256, 192 or 128 (default) bit. */ +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + switch (workspace->mode) + { +# if (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_256: + if (esl_initWorkSpaceHeader(&workspace->wsAES.wsAES256.header, ESL_MAXSIZEOF_WS_AES256, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + retValCv = esl_initEncryptAES256(&workspace->wsAES.wsAES256, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(aesEncryptKeyIndex), + blockMode, + paddingMode, + aesEncryptIvPtr); + } + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_192: + if (esl_initWorkSpaceHeader(&workspace->wsAES.wsAES192.header, ESL_MAXSIZEOF_WS_AES192, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + retValCv = esl_initEncryptAES192(&workspace->wsAES.wsAES192, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(aesEncryptKeyIndex), + blockMode, + paddingMode, + aesEncryptIvPtr); + } + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) */ + + default: + /* case CRYPTO_30_LIBCV_AES_MODE_128 */ +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + if (esl_initWorkSpaceHeader(&workspace->wsAES.wsAES128.header, ESL_MAXSIZEOF_WS_AES128, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + retValCv = esl_initEncryptAES128(&workspace->wsAES.wsAES128, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(aesEncryptKeyIndex), + blockMode, + paddingMode, + aesEncryptIvPtr); + } + +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + break; + } +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherAesEncryptStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesEncryptUpdate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesEncryptUpdate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_Length outputLength; + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + + /* ----- Implementation ------------------------------------------------- */ + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + /* Get output length in local variable to omit type mismatches */ + outputLength = (eslt_Length)*(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* #45 Process input data depending on the key size: 256, 192 or 128 (default) bit. */ +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + switch (workspace->mode) + { +# if (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_256: + retValCv = esl_encryptAES256(&workspace->wsAES.wsAES256, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_192: + retValCv = esl_encryptAES192(&workspace->wsAES.wsAES192, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) */ + + default: + /* case CRYPTO_30_LIBCV_AES_MODE_128 */ +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + retValCv = esl_encryptAES128(&workspace->wsAES.wsAES128, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + break; + } +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + + /* copy back written output length */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) = outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + Crypto_30_LibCv_SetWrittenLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, Crypto_30_LibCv_GetBufferLength(objectId) - Crypto_30_LibCv_GetWrittenLength(objectId)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherAesEncryptUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesEncryptFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesEncryptFinish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_Length outputLength; + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + + /* ----- Implementation ------------------------------------------------- */ + /* #75 Reinitialize written length and remaining buffer if UPDATE was not part of this job. */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode & CRYPTO_OPERATIONMODE_UPDATE) != CRYPTO_OPERATIONMODE_UPDATE) + { + Crypto_30_LibCv_SetWrittenLength(objectId, 0u); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + + /* Get output length in local variable to omit type mismatches */ + outputLength = (eslt_Length)(Crypto_30_LibCv_GetBufferLength(objectId)); + + /* #80 Write results in output buffers depending on the key size: 256, 192 or 128 (default) bit. */ +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + switch (workspace->mode) + { +# if (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_256: + retValCv = esl_finalizeEncryptAES256(&workspace->wsAES.wsAES256, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)]); + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_192: + retValCv = esl_finalizeEncryptAES192(&workspace->wsAES.wsAES192, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)]); + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) */ + + default: + /* case CRYPTO_30_LIBCV_AES_MODE_128 */ +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + retValCv = esl_finalizeEncryptAES128(&workspace->wsAES.wsAES128, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)]); + +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + break; + } +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* copy back written output length and add writtenLength */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = outputLength + Crypto_30_LibCv_GetWrittenLength(objectId); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherAesEncryptFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesEncrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesEncrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfAesEncrypt(Crypto_30_LibCv_GetAesEncryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(Crypto_30_LibCv_WorkSpaceAES)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* #5 Distinguish modes. */ + switch (mode) + { + /* #10 Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + retVal = Crypto_30_LibCv_DispatchCipherAesEncryptStart(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* #40 Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + retVal = Crypto_30_LibCv_DispatchCipherAesEncryptUpdate(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* #70 Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + retVal = Crypto_30_LibCv_DispatchCipherAesEncryptFinish(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported State */ + break; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesEncrypt() */ +#endif /* (CRYPTO_30_LIBCV_AESENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_AESDECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesDecryptStart() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6010, 6030 4 */ /* MD_MSR_STPTH, MD_MSR_STCYC */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesDecryptStart( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + Crypto_30_LibCv_SizeOfKeyStorageType aesDecryptKeyIndex; + Crypto_30_LibCv_SizeOfKeyStorageType aesDecryptIvIndex; + + eslt_BlockMode blockMode; + eslt_PaddingMode paddingMode = ESL_PM_OFF; + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) aesDecryptIvPtr = NULL_PTR; + + /* ----- Implementation ------------------------------------------------- */ + /* Init workspace variables */ + Crypto_30_LibCv_SetWrittenLength(objectId, 0u); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, 0u); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + /* #15 Load key element from storage. */ + retVal = Crypto_30_LibCv_DispatchCipherAesKey(job, workspace, &aesDecryptKeyIndex, &aesDecryptIvIndex); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + /* #20 Set AES mode and padding mode. */ + if (retVal == E_OK) + { + retVal = E_NOT_OK; + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode == CRYPTO_ALGOMODE_CBC) + { + blockMode = ESL_BM_CBC; + aesDecryptIvPtr = (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(aesDecryptIvIndex); + } + else if (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode == CRYPTO_ALGOMODE_CTR) + { + blockMode = ESL_BM_CTR; + aesDecryptIvPtr = (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(aesDecryptIvIndex); + } + else + { + blockMode = ESL_BM_ECB; + } + + paddingMode = Crypto_30_LibCv_DispatchCipherAesPaddingMode(job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily); + + /* #25 Initialize algorithm with keys depending on the key size: 256, 192 or 128 (default) bit. */ +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + switch (workspace->mode) + { +# if (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_256: + if (esl_initWorkSpaceHeader(&(workspace->wsAES.wsAES256.header), ESL_MAXSIZEOF_WS_AES256, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + retValCv = esl_initDecryptAES256(&workspace->wsAES.wsAES256, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(aesDecryptKeyIndex), + blockMode, + paddingMode, + aesDecryptIvPtr); + } + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_192: + if (esl_initWorkSpaceHeader(&(workspace->wsAES.wsAES192.header), ESL_MAXSIZEOF_WS_AES192, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + retValCv = esl_initDecryptAES192(&workspace->wsAES.wsAES192, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(aesDecryptKeyIndex), + blockMode, + paddingMode, + aesDecryptIvPtr); + } + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) */ + + default: + /* case CRYPTO_30_LIBCV_AES_MODE_128 */ +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + if (esl_initWorkSpaceHeader(&(workspace->wsAES.wsAES128.header), ESL_MAXSIZEOF_WS_AES128, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + retValCv = esl_initDecryptAES128(&workspace->wsAES.wsAES128, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(aesDecryptKeyIndex), + blockMode, + paddingMode, + aesDecryptIvPtr); + } + +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + break; + } +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherAesDecryptStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesDecryptUpdate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesDecryptUpdate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_Length outputLength; + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + + /* ----- Implementation ------------------------------------------------- */ + /* Get output length in local variable to omit type mismatches */ + outputLength = (eslt_Length)*(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* #45 Process input data depending on the key size: 256, 192 or 128 (default) bit. */ +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + switch (workspace->mode) + { +# if (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_256: + retValCv = esl_decryptAES256(&workspace->wsAES.wsAES256, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_192: + retValCv = esl_decryptAES192(&workspace->wsAES.wsAES192, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) */ + + default: + /* case CRYPTO_30_LIBCV_AES_MODE_128 */ +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + retValCv = esl_decryptAES128(&workspace->wsAES.wsAES128, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + break; + } +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) - outputLength); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetWrittenLength(objectId, outputLength); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + /* copy back written output length */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) = outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherAesDecryptUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherAesDecryptFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherAesDecryptFinish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_Length outputLength; + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + + /* ----- Implementation ------------------------------------------------- */ + /* #75 Reinitialize written length and remaining buffer if UPDATE was not part of this job. */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode & CRYPTO_OPERATIONMODE_UPDATE) != CRYPTO_OPERATIONMODE_UPDATE) + { + Crypto_30_LibCv_SetWrittenLength(objectId, 0u); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + + /* Get output length in local variable to omit type mismatches */ + outputLength = (eslt_Length)Crypto_30_LibCv_GetBufferLength(objectId); + + /* #80 Write results in output buffers depending on the key size: 256, 192 or 128 (default) bit. */ +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + switch (workspace->mode) + { +# if (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_256: + retValCv = esl_finalizeDecryptAES256(&workspace->wsAES.wsAES256, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)]); + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) + case CRYPTO_30_LIBCV_AES_MODE_192: + retValCv = esl_finalizeDecryptAES192(&workspace->wsAES.wsAES192, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)]); + break; +# endif /* (CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) */ + + default: + /* case CRYPTO_30_LIBCV_AES_MODE_128 */ +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + retValCv = esl_finalizeDecryptAES128(&workspace->wsAES.wsAES128, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)]); + +# if ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) + break; + } +# endif /* ((CRYPTO_30_LIBCV_ENABLE_AES192 == STD_ON) || (CRYPTO_30_LIBCV_ENABLE_AES256 == STD_ON)) */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = outputLength + Crypto_30_LibCv_GetWrittenLength(objectId); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherAesDecryptFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesDecrypt() + **********************************************************************************************************************/ +/*! + * # + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesDecrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(Crypto_30_LibCv_WorkSpaceAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfAesDecrypt(Crypto_30_LibCv_GetAesDecryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(Crypto_30_LibCv_WorkSpaceAES)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* ----- Implementation ------------------------------------------------- */ + /* #5 Distinguish modes. */ + switch (mode) + { + /* #10 Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + retVal = Crypto_30_LibCv_DispatchCipherAesDecryptStart(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* #40 Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + retVal = Crypto_30_LibCv_DispatchCipherAesDecryptUpdate(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* #70 Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + retVal = Crypto_30_LibCv_DispatchCipherAesDecryptFinish(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported State */ + break; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_AesDecrypt() */ +#endif /* (CRYPTO_30_LIBCV_AESDECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SM4ENCRYPT == STD_ON || CRYPTO_30_LIBCV_SM4DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherSm4Start_InitAlgorithm() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherSm4Start_InitAlgorithm( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(eslt_WorkSpaceSM4, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 keyLength, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) keyPtr, + eslt_BlockMode blockMode, + uint32 ivLength, + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ivPtr) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Init workspace header. */ + if ((esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_SM4, CRYPTO_30_LIBCV_WATCHDOG_PTR)) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* # Distinguish between ENCRYPT and DECRYPT based on job primitive service. */ + switch (job->jobPrimitiveInfo->primitiveInfo->service) + { +# if (CRYPTO_30_LIBCV_SM4ENCRYPT == STD_ON) + case CRYPTO_ENCRYPT: + /* # Init SM4 Encrypt algorithm. */ + retValCv = esl_initEncryptSM4(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_PARAMETER_BUFFER */ + (eslt_Length)keyLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr, + blockMode, + (eslt_Length)ivLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))ivPtr); + break; +# endif +# if (CRYPTO_30_LIBCV_SM4DECRYPT == STD_ON) + case CRYPTO_DECRYPT: + /* # Init SM4 Decrypt algorithm. */ + retValCv = esl_initDecryptSM4(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_PARAMETER_BUFFER */ + (eslt_Length)keyLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr, + blockMode, + (eslt_Length)ivLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))ivPtr); + break; +# endif + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Only ENCRYPT and DECRYPT supported */ + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherSm4Start_InitAlgorithm() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherSm4Start() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherSm4Start( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(eslt_WorkSpaceSM4, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_BlockMode blockMode = 0xFF; + + /* # Init stack variables for cipher key and initialization vector. */ + Crypto_30_LibCv_SizeOfKeyStorageType keyIndex = 0u; + uint32 keyLength = CRYPTO_30_LIBCV_SM4_KEY_LENGTH; + + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ivPtr = NULL_PTR; + Crypto_30_LibCv_SizeOfKeyStorageType ivIndex = 0u; + uint32 ivLength = 0u; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Set workspace lengths to zero. */ + Crypto_30_LibCv_SetBufferLength(objectId, 0u); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetWrittenLength(objectId, 0u); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + /* # Load cipher key element from storage. */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(job->cryptoKeyId, CRYPTO_KE_CIPHER_KEY, &keyIndex, &keyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + retVal = E_NOT_OK; + + /* # Set SM4 mode and load IV key element if necessary. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_CBC: + blockMode = ESL_BM_CBC; + + /* # If block mode CBC is used, load IV key element from storage. */ + ivLength = CRYPTO_30_LIBCV_SM4_IV_LENGTH; /* IV has to be as long as the cipher block size */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(job->cryptoKeyId, CRYPTO_KE_CIPHER_IV, &ivIndex, &ivLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + ivPtr = Crypto_30_LibCv_GetAddrKeyStorage(ivIndex); + } + break; + + case CRYPTO_ALGOMODE_ECB: + blockMode = ESL_BM_ECB; + + /* # If block mode ECB is used, ivPtr remains NULL_PTR and ivLength remains 0u. */ + retVal = E_OK; + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Unsupported mode */ + } + + if (retVal == E_OK) + { + /* # Init the SM4 algorithm with determined parameters. */ + retVal = Crypto_30_LibCv_DispatchCipherSm4Start_InitAlgorithm( /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_KEYPTR_AND_LENGTH */ + job, workspace, + keyLength, Crypto_30_LibCv_GetAddrKeyStorage(keyIndex), + blockMode, + ivLength, ivPtr); + } + } + return retVal; +} /* Crypto_30_LibCv_DispatchCipherSm4Start() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherSm4Update() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherSm4Update( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2VAR(eslt_WorkSpaceSM4, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_Length outputLength; + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + /* Copy output length in local variable to omit type mismatches. */ + outputLength = (eslt_Length)*(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* # Distinguish between ENCRYPT and DECRYPT based on job primitive service. */ + switch (job->jobPrimitiveInfo->primitiveInfo->service) + { +# if (CRYPTO_30_LIBCV_SM4ENCRYPT == STD_ON) + case CRYPTO_ENCRYPT: + /* # Encrypt provided input data via SM4 Encrypt algorithm. */ + retValCv = esl_encryptSM4(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; +# endif +# if (CRYPTO_30_LIBCV_SM4DECRYPT == STD_ON) + case CRYPTO_DECRYPT: + /* # Decrypt provided input data via SM4 Encrypt algorithm. */ + retValCv = esl_decryptSM4(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; +# endif + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Only ENCRYPT and DECRYPT supported */ + } + + /* Copy back written output length. */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) = outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Update the workspace lengths based on the actual output data. */ + Crypto_30_LibCv_SetWrittenLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, Crypto_30_LibCv_GetBufferLength(objectId) - Crypto_30_LibCv_GetWrittenLength(objectId)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + else if (retValCv == ESL_ERC_OUTPUT_SIZE_TOO_SHORT) + { + retVal = CRYPTO_E_SMALL_BUFFER; + } + else + { + /* retVal remains E_NOT_OK */ + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherSm4Update() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherSm4Finish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherSm4Finish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2VAR(eslt_WorkSpaceSM4, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_Length outputLength = 0u; + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + /* # Reinitialize written length and remaining buffer if UPDATE was not part of this job. */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode & CRYPTO_OPERATIONMODE_UPDATE) != CRYPTO_OPERATIONMODE_UPDATE) + { + Crypto_30_LibCv_SetWrittenLength(objectId, 0u); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + Crypto_30_LibCv_SetBufferLength(objectId, *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + + /* Copy output length in local variable to omit type mismatches. */ + outputLength = (eslt_Length)(Crypto_30_LibCv_GetBufferLength(objectId)); + + /* # Distinguish between ENCRYPT and DECRYPT based on job primitive service. */ + switch (job->jobPrimitiveInfo->primitiveInfo->service) + { +# if (CRYPTO_30_LIBCV_SM4ENCRYPT == STD_ON) + case CRYPTO_ENCRYPT: + /* # Finalize SM4 Encrypt algorithm. */ + retValCv = esl_finalizeEncryptSM4(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)]); + break; +# endif +# if (CRYPTO_30_LIBCV_SM4DECRYPT == STD_ON) + case CRYPTO_DECRYPT: + /* # Finalize SM4 Decrypt algorithm. */ + retValCv = esl_finalizeDecryptSM4(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[Crypto_30_LibCv_GetWrittenLength(objectId)]); + break; +# endif + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Only ENCRYPT and DECRYPT supported */ + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* Copy back written output length and add writtenLength */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = outputLength + Crypto_30_LibCv_GetWrittenLength(objectId); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else if (retValCv == ESL_ERC_OUTPUT_SIZE_TOO_SHORT) + { + retVal = CRYPTO_E_SMALL_BUFFER; + } + else + { + /* retVal remains E_NOT_OK */ + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherSm4Finish() */ +#endif /*(CRYPTO_30_LIBCV_SM4ENCRYPT == STD_ON || CRYPTO_30_LIBCV_SM4DECRYPT == STD_ON)*/ + +#if (CRYPTO_30_LIBCV_SM4ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm4Encrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm4Encrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceSM4, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfSm4Encrypt(Crypto_30_LibCv_GetSm4EncryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceSM4)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + retVal = Crypto_30_LibCv_DispatchCipherSm4Start(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + retVal = Crypto_30_LibCv_DispatchCipherSm4Update(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + retVal = Crypto_30_LibCv_DispatchCipherSm4Finish(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported State */ + break; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Sm4Encrypt() */ +#endif /* (CRYPTO_30_LIBCV_SM4ENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SM4DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm4Decrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm4Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceSM4, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfSm4Decrypt(Crypto_30_LibCv_GetSm4DecryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceSM4)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + retVal = Crypto_30_LibCv_DispatchCipherSm4Start(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + retVal = Crypto_30_LibCv_DispatchCipherSm4Update(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + retVal = Crypto_30_LibCv_DispatchCipherSm4Finish(objectId, job, workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported State */ + break; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Sm4Decrypt() */ +#endif /* (CRYPTO_30_LIBCV_SM4DECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Encrypt() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + */ + +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Encrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceRSAenc, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfRsaPkcs1Encrypt(Crypto_30_LibCv_GetRsaPkcs1EncryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceRSAenc)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* #5 Distinguish modes. */ + switch (mode) + { + /* #10 Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CUSTOM_RSA_MODULUS); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CUSTOM_RSA_PUBLIC_EXPONENT); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* #15 Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_RSA_ENC, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* #20 Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* #25 Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initEncryptRSA_V15(workspace, + /* Modulus */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + /* Public Exponent */ + (eslt_Length)keyElements[1u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1u].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + } + } + break; + } + + /* #40 Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + /* #45 Update algorithm and save result. */ + eslt_Length outputLength; + outputLength = (eslt_Length)(*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + /* #75 Copy Result to output PTR. */ + + retValCv = esl_encryptRSA_V15(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = (uint32)outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + break; + } + + /* #70 Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = E_OK; + Crypto_30_LibCv_DispatchCipherRsa_Finish(job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaPkcs1Encrypt() */ +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1ENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Start() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Start( + P2VAR(Crypto_30_LibCv_WorkSpaceRsaDecrypt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Std_ReturnType retValKey; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + /* ----- Implementation ------------------------------------------------ */ + + /* # Handle operationmode START. */ + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CUSTOM_RSA_MODULUS); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CUSTOM_RSA_PRIVATE_EXPONENT); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Check if key element is accessible */ + /* # Read key elements. */ + retValKey = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retValKey == E_OK) + { + retValKey = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(job->cryptoKeyId, CRYPTO_KE_CUSTOM_RSA_PRIVATE_EXPONENT, &keyElements[1u].keyElementIndex, &keyElements[1u].keyElementLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # If private exponent is not available use check if decryption with public exponent is used. */ + if (retValKey == CRYPTO_E_KEY_NOT_AVAILABLE) + { + workspace->decryptionMode = CRYPTO_30_LIBCV_RSA_DECRYPT_MODE_PUBLIC; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + retValKey = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(job->cryptoKeyId, CRYPTO_KE_CUSTOM_RSA_PUBLIC_EXPONENT, &keyElements[1u].keyElementIndex, &keyElements[1u].keyElementLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + } + else + { + workspace->decryptionMode = CRYPTO_30_LIBCV_RSA_DECRYPT_MODE_PRIVATE; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + } + + if (retValKey == CRYPTO_E_KEY_NOT_AVAILABLE) + { + retValKey = E_NOT_OK; + } + } + + if (retValKey == E_OK) + { + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->wsRsa.header), ESL_MAXSIZEOF_WS_RSA_DEC, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + + /* # Initialize algorithm. */ + retValCv = esl_initDecryptRSA_V15(&(workspace->wsRsa), + /* Modulus */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + /* Private/Public Exponent */ + (eslt_Length)keyElements[1u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1u].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + } + } + else + { + retVal = retValKey; + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Start() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Update() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Update( + P2VAR(Crypto_30_LibCv_WorkSpaceRsaDecrypt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_ErrorCode retValCv; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------ */ + /* # Handle operationmode UPDATE. */ + + /* # Update algorithm and save result. */ + eslt_Length outputLength; + outputLength = (eslt_Length)(*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + /* # Copy Result to output PTR. */ + /* # If private exponent is not available use check if decryption with public exponent is used. */ + if(workspace->decryptionMode == CRYPTO_30_LIBCV_RSA_DECRYPT_MODE_PRIVATE) + { + retValCv = esl_decryptRSA_V15(&(workspace->wsRsa), + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else + { + retValCv = esl_decryptPubRSA_V15(&(workspace->wsRsa), + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = (uint32)outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Update() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ + +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceRsaDecrypt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfRsaPkcs1Decrypt(Crypto_30_LibCv_GetRsaPkcs1DecryptIdxOfObjectInfo(objectId)); + + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(Crypto_30_LibCv_WorkSpaceRsaDecrypt)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Start(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt_Update(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = E_OK; + Crypto_30_LibCv_DispatchCipherRsa_Finish(job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt() */ +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1DECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ENCRYPT_RSA == STD_ON) || (CRYPTO_30_LIBCV_DECRYPT_RSA == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsa_Finish() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ + +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsa_Finish( + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode == CRYPTO_OPERATIONMODE_FINISH) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = 0u; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } +} /* Crypto_30_LibCv_DispatchCipherRsa_Finish() */ +#endif /* (CRYPTO_30_LIBCV_ENCRYPT_RSA == STD_ON) || (CRYPTO_30_LIBCV_DECRYPT_RSA == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPSHA1ENCRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPSHA256ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Start() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Start( + P2VAR(eslt_WorkSpaceRSAOAEPenc, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_AlgorithmSecondaryFamilyType secondaryFamily) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_RSA_OAEP_ENC, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CUSTOM_RSA_MODULUS); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CUSTOM_RSA_PUBLIC_EXPONENT); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + switch (secondaryFamily) + { +# if (CRYPTO_30_LIBCV_RSAOAEPSHA1ENCRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_initEncryptRSASHA1_OAEP(workspace, + /* Modulus */ + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), + /* Public Exponent */ + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif +# if (CRYPTO_30_LIBCV_RSAOAEPSHA256ENCRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_initEncryptRSASHA256_OAEP(workspace, + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; + } + + if (retValCv != ESL_ERC_NO_ERROR) + { + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Start() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Update() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Update( + P2VAR(eslt_WorkSpaceRSAOAEPenc, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_AlgorithmSecondaryFamilyType secondaryFamily) +{ + Std_ReturnType retVal = E_NOT_OK, localRetVal; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + uint32 labelLength = 0; + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) labelPtr = NULL_PTR; + Crypto_30_LibCv_SizeOfKeyStorageType labelIndex; + boolean process = FALSE; + + /* # Update algorithm and save result. */ + eslt_Length outputLength; + outputLength = (eslt_Length)(*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* # Check if label is available. */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(job->cryptoKeyId, CRYPTO_KE_CUSTOM_LABEL, &labelIndex, &labelLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (localRetVal == E_OK) + { + labelPtr = (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(labelIndex); + process = TRUE; + } + else if (localRetVal == CRYPTO_E_KEY_NOT_AVAILABLE) + { + process = TRUE; + } + else + { + retVal = localRetVal; + } + + if (process == TRUE) + { + + /* # Execute algorithm calculation. */ + switch (secondaryFamily) + { +# if (CRYPTO_30_LIBCV_RSAOAEPSHA1ENCRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_encryptRSASHA1_OAEP_Label(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)labelLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) labelPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif +# if (CRYPTO_30_LIBCV_RSAOAEPSHA256ENCRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_encryptRSASHA256_OAEP_Label(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)labelLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) labelPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; + } + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = (uint32)outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Update() */ +#endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA1ENCRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPSHA256ENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPSHA1ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepSha1Encrypt() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ + +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepSha1Encrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + Crypto_AlgorithmSecondaryFamilyType secAlgoFam = job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily; + + P2VAR(eslt_WorkSpaceRSAOAEPenc, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + workspace = Crypto_30_LibCv_GetWorkspaceOfRsaOaepSha1Encrypt(Crypto_30_LibCv_GetRsaOaepSha1EncryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceRSAOAEPenc)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* #5 Distinguish modes. */ + switch (mode) + { + /* #10 Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Start(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* #40 Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Update(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* #70 Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + Crypto_30_LibCv_DispatchCipherRsa_Finish(job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + retVal = E_OK; + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaOaepSha1Encrypt() */ +#endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA1ENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPSHA256ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepSha256Encrypt() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ + +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepSha256Encrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + Crypto_AlgorithmSecondaryFamilyType secAlgoFam = job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily; + + P2VAR(eslt_WorkSpaceRSAOAEPenc, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + workspace = Crypto_30_LibCv_GetWorkspaceOfRsaOaepSha256Encrypt(Crypto_30_LibCv_GetRsaOaepSha256EncryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceRSAOAEPenc)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* #5 Distinguish modes. */ + switch (mode) + { + /* #10 Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Start(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* #40 Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepEncrypt_Update(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* #70 Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + Crypto_30_LibCv_DispatchCipherRsa_Finish(job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + retVal = E_OK; + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaOaepSha256Encrypt() */ +#endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA256ENCRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPSHA1DECRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPSHA256DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Start() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Start( + P2VAR(eslt_WorkSpaceRSAOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_AlgorithmSecondaryFamilyType secondaryFamily) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_RSA_OAEP_DEC, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CUSTOM_RSA_MODULUS); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CUSTOM_RSA_PRIVATE_EXPONENT); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* # Initialize algorithm according to secondaryFamily. */ + switch (secondaryFamily) + { +# if (CRYPTO_30_LIBCV_RSAOAEPSHA1DECRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_initDecryptRSASHA1_OAEP(workspace, + /* Modulus */ + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), + /* Private Exponent */ + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif +# if (CRYPTO_30_LIBCV_RSAOAEPSHA256DECRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_initDecryptRSASHA256_OAEP(workspace, + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; + } + + if (retValCv != ESL_ERC_NO_ERROR) + { + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Start() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Update() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Update( + P2VAR(eslt_WorkSpaceRSAOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_AlgorithmSecondaryFamilyType secondaryFamily) +{ + Std_ReturnType retVal = E_NOT_OK, localRetVal; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + uint32 labelLength = 0; + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) labelPtr = NULL_PTR; + Crypto_30_LibCv_SizeOfKeyStorageType labelIndex; + boolean process = FALSE; + + /* # Update algorithm and save result. */ + eslt_Length outputLength; + outputLength = (eslt_Length)(*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* # Check if label is available. */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(job->cryptoKeyId, CRYPTO_KE_CUSTOM_LABEL, &labelIndex, &labelLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (localRetVal == E_OK) + { + labelPtr = (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(labelIndex); + process = TRUE; + } + else if (localRetVal == CRYPTO_E_KEY_NOT_AVAILABLE) + { + process = TRUE; + } + else + { + retVal = localRetVal; + } + + if (process == TRUE) + { + /* # Execute algorithm calculation. */ + switch (secondaryFamily) + { +# if (CRYPTO_30_LIBCV_RSAOAEPSHA1DECRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_decryptRSASHA1_OAEP_Label(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)labelLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) labelPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS_AND_NULL_PTR */ + break; + } +# endif +# if (CRYPTO_30_LIBCV_RSAOAEPSHA256DECRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_decryptRSASHA256_OAEP_Label(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)labelLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) labelPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS_AND_NULL_PTR */ + break; + } +# endif + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; + } + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = (uint32)outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Update() */ +#endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA1DECRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPSHA256DECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPSHA1DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepSha1Decrypt() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ + +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepSha1Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + Crypto_AlgorithmSecondaryFamilyType secAlgoFam = job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily; + + P2VAR(eslt_WorkSpaceRSAOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + workspace = Crypto_30_LibCv_GetWorkspaceOfRsaOaepSha1Decrypt(Crypto_30_LibCv_GetRsaOaepSha1DecryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceRSAOAEPdec)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Start(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Update(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + Crypto_30_LibCv_DispatchCipherRsa_Finish(job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + retVal = E_OK; + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaOaepSha1Decrypt() */ +#endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA1DECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPSHA256DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepSha256Decrypt() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ + +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepSha256Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + Crypto_AlgorithmSecondaryFamilyType secAlgoFam = job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily; + + P2VAR(eslt_WorkSpaceRSAOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + workspace = Crypto_30_LibCv_GetWorkspaceOfRsaOaepSha256Decrypt(Crypto_30_LibCv_GetRsaOaepSha256DecryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceRSAOAEPdec)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Start(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepDecrypt_Update(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + Crypto_30_LibCv_DispatchCipherRsa_Finish(job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + retVal = E_OK; + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaOaepSha256Decrypt() */ +#endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA256DECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPCRTSHA1DECRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPCRTSHA256DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Start() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Start( + P2VAR(eslt_WorkSpaceRSACRTOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_AlgorithmSecondaryFamilyType secondaryFamily) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_KeyElementGetType keyElements[5]; + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_RSA_CRT_OAEP_DEC, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CUSTOM_RSA_PRIME_P); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CUSTOM_RSA_PRIME_Q); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 2u, CRYPTO_KE_CUSTOM_RSA_EXPONENT_DP); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 3u, CRYPTO_KE_CUSTOM_RSA_EXPONENT_DQ); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 4u, CRYPTO_KE_CUSTOM_RSA_INVERSE_QI); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 5u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + switch (secondaryFamily) + { +# if (CRYPTO_30_LIBCV_RSAOAEPCRTSHA1DECRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_initDecryptRSACRTSHA1_OAEP( + workspace, + /* Prime p */ + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), + /* Prime q */ + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex), + /* Exponent dP */ + (eslt_Length)keyElements[2].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[2].keyElementIndex), + /* Exponent dQ */ + (eslt_Length)keyElements[3].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[3].keyElementIndex), + /* Inverse qInv */ + (eslt_Length)keyElements[4].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[4].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif +# if (CRYPTO_30_LIBCV_RSAOAEPCRTSHA256DECRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_initDecryptRSACRTSHA256_OAEP( + workspace, + /* Prime p */ + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), + /* Prime q */ + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex), + /* Exponent dP */ + (eslt_Length)keyElements[2].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[2].keyElementIndex), + /* Exponent dQ */ + (eslt_Length)keyElements[3].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[3].keyElementIndex), + /* Inverse qInv */ + (eslt_Length)keyElements[4].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[4].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; + } + + if (retValCv != ESL_ERC_NO_ERROR) + { + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Start() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Update() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Update( + P2VAR(eslt_WorkSpaceRSACRTOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_AlgorithmSecondaryFamilyType secondaryFamily) +{ + Std_ReturnType retVal = E_NOT_OK, localRetVal; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + uint32 labelLength = 0; + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) labelPtr = NULL_PTR; + Crypto_30_LibCv_SizeOfKeyStorageType labelIndex; + boolean process = FALSE; + + /* # Update algorithm and save result. */ + eslt_Length outputLength; + outputLength = (eslt_Length)(*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* # Check if label is available. */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(job->cryptoKeyId, CRYPTO_KE_CUSTOM_LABEL, &labelIndex, &labelLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (localRetVal == E_OK) + { + labelPtr = (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(labelIndex); + process = TRUE; + } + else if (localRetVal == CRYPTO_E_KEY_NOT_AVAILABLE) + { + process = TRUE; + } + else + { + retVal = localRetVal; + } + + if (process == TRUE) + { + /* # Execute algorithm calculation. */ + switch (secondaryFamily) + { +# if (CRYPTO_30_LIBCV_RSAOAEPCRTSHA1DECRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_decryptRSACRTSHA1_OAEP_Label(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)labelLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) labelPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS_AND_NULL_PTR */ + break; + } +# endif +# if (CRYPTO_30_LIBCV_RSAOAEPCRTSHA256DECRYPT == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_decryptRSACRTSHA256_OAEP_Label(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)labelLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) labelPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS_AND_NULL_PTR */ + break; + } +# endif + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; + } + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = (uint32)outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Update() */ +#endif /* (CRYPTO_30_LIBCV_RSAOAEPCRTSHA1DECRYPT == STD_ON) || (CRYPTO_30_LIBCV_RSAOAEPCRTSHA256DECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPCRTSHA1DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepCrtSha1Decrypt() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ + +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepCrtSha1Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + Crypto_AlgorithmSecondaryFamilyType secAlgoFam = job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily; + + P2VAR(eslt_WorkSpaceRSACRTOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + workspace = Crypto_30_LibCv_GetWorkspaceOfRsaOaepCrtSha1Decrypt(Crypto_30_LibCv_GetRsaOaepCrtSha1DecryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceRSACRTOAEPdec)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Start(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Update(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + Crypto_30_LibCv_DispatchCipherRsa_Finish(job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + retVal = E_OK; + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaOaepCrtSha1Decrypt() */ +#endif /* (CRYPTO_30_LIBCV_RSAOAEPCRTSHA1DECRYPT == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAOAEPCRTSHA256DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepCrtSha256Decrypt() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ + +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepCrtSha256Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + Crypto_AlgorithmSecondaryFamilyType secAlgoFam = job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily; + + P2VAR(eslt_WorkSpaceRSACRTOAEPdec, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + workspace = Crypto_30_LibCv_GetWorkspaceOfRsaOaepCrtSha256Decrypt(Crypto_30_LibCv_GetRsaOaepCrtSha256DecryptIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceRSACRTOAEPdec)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Start(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchCipherRsaOaepCrtDecrypt_Update(workspace, job, secAlgoFam); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + Crypto_30_LibCv_DispatchCipherRsa_Finish(job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + retVal = E_OK; + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaOaepCrtSha256Decrypt() */ +#endif /* (CRYPTO_30_LIBCV_RSAOAEPCRTSHA256DECRYPT == STD_ON) */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Cipher.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Curve.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Curve.c new file mode 100644 index 0000000..9d346d6 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Curve.c @@ -0,0 +1,1474 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Curve.c + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Internal implementation file for curve parameters + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_CURVE_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +#include "Crypto_30_LibCv_Curve.h" + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION MACROS + *********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CONST_8BIT +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/**************************************************************************** + * + * This file contains: CURVE PARAMETER and additional informations + * generated by ECC_CreateGFPCurveInfos_ASN1 + * + * data objects: + * esl_EccDomain, esl_EccDomainExt, esl_EccSpeedUpExt + * + ***************************************************************************/ + +/* Empty curve vector START *********************************************************************************************/ +/* This vector is used to initialize pointers which shall point to the EC domain, the EC domain extension and + * the EC SpeedUp extension. If one of the regular curve parameters were used for this purpose, the corresponding + * arrays will always be used and therefore never be removed by the linker. + * Since this array does not start with the ASN1 sequence tag '0x30', the parser of the underlying crypto + * library will recognize these domains as invalid. + * Also, the length value (the second byte) is set to zero. + * Together, these two bytes form a valid ASN1 structure of tag and length 0 (and thus no content bytes). */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveEmptyDomain[2] = { 0u, 0u }; +/* Empty curve vector END ***********************************************************************************************/ + +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* SEC_p160r1 START *************************************************************************************************/ +/* The curve params in shorthand notation: + * Name: "SECGp160r1", + * p: "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + * a: "0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + * b: "0X1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + * Gx: "0X4A96B5688EF573284664698968C38BB913CBFC82", + * Gy: "0X23A628553168947D59DCC912042351377AC5FB32", + * n: "0X100000000000000000001F4C8F927AED3CA752257", + * h: "0x1", + */ +#if (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1Domain[155] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0x98u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x20u, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x15u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x7fu, 0xffu, 0xffu, 0xffu, + /* SEQUENCE */ + 0x30u, 0x2cu, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x14u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x7fu, 0xffu, 0xffu, 0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x14u, 0x1cu, 0x97u, 0xbeu, 0xfcu, 0x54u, 0xbdu, 0x7au, 0x8bu, 0x65u, 0xacu, 0xf8u, 0x9fu, 0x81u, 0xd4u, 0xd4u, 0xadu, 0xc5u, 0x65u, 0xfau, 0x45u, + /* G (basepoint of the curve) */ + 0x04u, 0x29u, 0x04u, 0x4au, 0x96u, 0xb5u, 0x68u, 0x8eu, 0xf5u, 0x73u, 0x28u, 0x46u, 0x64u, 0x69u, 0x89u, 0x68u, 0xc3u, 0x8bu, 0xb9u, 0x13u, 0xcbu, 0xfcu, 0x82u, 0x23u, 0xa6u, 0x28u, 0x55u, 0x31u, 0x68u, 0x94u, 0x7du, 0x59u, 0xdcu, 0xc9u, 0x12u, 0x04u, 0x23u, 0x51u, 0x37u, 0x7au, 0xc5u, 0xfbu, 0x32u, + /* n (order of G) */ + 0x02u, 0x15u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0xf4u, 0xc8u, 0xf9u, 0x27u, 0xaeu, 0xd3u, 0xcau, 0x75u, 0x22u, 0x57u, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1DomainExt[147] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0x90u, + /* SEQUENCE */ + 0x30u, 0x72u, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x14u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x40u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x01u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x2cu, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x14u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfdu, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x14u, 0x46u, 0xf6u, 0x7cu, 0x42u, 0x07u, 0x93u, 0xf6u, 0xdbu, 0x26u, 0x97u, 0x62u, 0xf6u, 0x6bu, 0xadu, 0xc1u, 0x8fu, 0x53u, 0xb1u, 0xd9u, 0xc3u, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x29u, 0x04u, 0x92u, 0x11u, 0x6eu, 0xfcu, 0xb2u, 0x27u, 0xa7u, 0xecu, 0xfau, 0xc6u, 0x2fu, 0x66u, 0x05u, 0x4fu, 0x37u, 0x54u, 0x39u, 0x17u, 0x57u, 0x36u, 0xbcu, 0x5au, 0x72u, 0x93u, 0xdeu, 0x56u, 0xf9u, 0x06u, 0x5bu, 0xeeu, 0x71u, 0xadu, 0xcau, 0x6fu, 0xd8u, 0xe5u, 0x8cu, 0x99u, 0x0fu, 0x5cu, + /* SEQUENCE */ + 0x30u, 0x1au, + /* n_RR (R^2 in order field) */ + 0x04u, 0x15u, 0x00u, 0xabu, 0x09u, 0x43u, 0x6au, 0xb2u, 0x04u, 0xa0u, 0xe6u, 0x26u, 0x84u, 0xc9u, 0x2cu, 0x7bu, 0xaau, 0xd1u, 0xb0u, 0xf3u, 0x93u, 0xb2u, 0x49u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x01u, 0x99u, +}; + +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1SpeedUpExt[355] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x5fu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x58u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0xa1u, 0x29u, 0x00u, 0x19u, 0x67u, 0x48u, 0xc7u, 0x48u, 0x89u, 0x82u, 0x8du, 0x41u, 0xdcu, 0x95u, 0xd7u, 0xd2u, 0x6au, 0x71u, 0x32u, 0x7fu, 0x94u, 0x98u, 0x6du, 0x17u, 0xeau, 0x30u, 0xd4u, 0xa8u, 0x54u, 0xf6u, 0x5du, 0x38u, 0x1cu, 0xecu, 0xdcu, 0xfau, 0x76u, 0x3au, 0x4bu, 0x0du, + /* (2^54 + 1) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x25u, 0xfcu, 0x2fu, 0x27u, 0xf5u, 0x1cu, 0x2au, 0xadu, 0xa3u, 0xceu, 0x1fu, 0x41u, 0xefu, 0x06u, 0x99u, 0xd7u, 0x69u, 0x03u, 0xeeu, 0xd9u, 0x79u, 0x51u, 0xdeu, 0xfcu, 0x19u, 0xaeu, 0xe1u, 0xd9u, 0xc9u, 0xf0u, 0x18u, 0xc4u, 0x02u, 0x2eu, 0xbbu, 0x4eu, 0x0eu, 0x9eu, 0xaeu, 0x84u, + /* (2^54 + 2) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0xe7u, 0xbfu, 0x07u, 0x2du, 0xb4u, 0x5du, 0x88u, 0x4au, 0x29u, 0x69u, 0x97u, 0x77u, 0xb1u, 0xceu, 0xbau, 0xe2u, 0xb8u, 0x76u, 0xaeu, 0x32u, 0x22u, 0x34u, 0x45u, 0x0au, 0x8au, 0x69u, 0x30u, 0xcbu, 0xcfu, 0xa6u, 0x7cu, 0xe6u, 0x50u, 0xb3u, 0x3cu, 0xadu, 0x43u, 0x1du, 0xb1u, 0x4fu, + /* (2^108 + 1) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x35u, 0x63u, 0x29u, 0xc6u, 0xa6u, 0xe7u, 0xb3u, 0x6eu, 0x51u, 0xefu, 0xe3u, 0x5du, 0xe5u, 0x2bu, 0x0du, 0x03u, 0x0bu, 0x1bu, 0x53u, 0x67u, 0x13u, 0xe0u, 0xbau, 0x88u, 0x37u, 0xffu, 0xc0u, 0x5du, 0x06u, 0xfeu, 0x3du, 0x1du, 0xa4u, 0x83u, 0x9au, 0x6au, 0x04u, 0xa3u, 0xe6u, 0x85u, + /* (2^108 + 2) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0xd4u, 0xd8u, 0x7cu, 0x90u, 0xc7u, 0x2bu, 0x0eu, 0x2eu, 0x56u, 0x73u, 0xc8u, 0x69u, 0x67u, 0xa2u, 0x28u, 0x2bu, 0x20u, 0x3fu, 0x96u, 0x30u, 0x8eu, 0xa8u, 0x06u, 0xb8u, 0xc8u, 0xecu, 0xbau, 0x42u, 0xa1u, 0xacu, 0x51u, 0x03u, 0xf0u, 0x59u, 0xc2u, 0xcfu, 0xddu, 0xdfu, 0xdeu, 0x40u, + /* (2^108 + 2^54 + 1) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x8eu, 0x62u, 0x41u, 0x4bu, 0x47u, 0x53u, 0x93u, 0xbbu, 0x20u, 0x70u, 0x01u, 0x8du, 0x63u, 0xedu, 0x63u, 0x7fu, 0x40u, 0xd1u, 0xecu, 0xf6u, 0x34u, 0x85u, 0xb9u, 0x62u, 0xfdu, 0x6au, 0x93u, 0x29u, 0x29u, 0xfeu, 0x95u, 0x42u, 0x85u, 0x1bu, 0x65u, 0xd9u, 0x42u, 0x0au, 0xc0u, 0x41u, + /* (2^108 + 2^54 + 2) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x8au, 0x73u, 0xfeu, 0x9fu, 0x5cu, 0x23u, 0xdcu, 0xf4u, 0x52u, 0x78u, 0x77u, 0x72u, 0x81u, 0xa7u, 0x55u, 0xdbu, 0xbfu, 0x77u, 0xc3u, 0x17u, 0x5cu, 0x80u, 0xf5u, 0x5du, 0x1cu, 0xbeu, 0xb3u, 0x42u, 0x3au, 0x1fu, 0x42u, 0xc4u, 0x96u, 0xd5u, 0xdbu, 0xc3u, 0x03u, 0x7du, 0x17u, 0x43u, + /* correction point D = - ((2^54 - 1) * G) in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x19u, 0x86u, 0x73u, 0x2eu, 0x8eu, 0x3eu, 0x13u, 0x39u, 0x81u, 0x01u, 0x3bu, 0xbcu, 0xd7u, 0x52u, 0x20u, 0x46u, 0x64u, 0xb8u, 0xa9u, 0xb3u, 0x96u, 0x28u, 0x5eu, 0xf2u, 0x3au, 0xa0u, 0xd2u, 0xebu, 0xe2u, 0x17u, 0x6fu, 0xcbu, 0xabu, 0x60u, 0xc1u, 0xdbu, 0xe0u, 0x59u, 0xe5u, 0x5cu, +}; + +#elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1Domain[155] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0x98u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x20u, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x15u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x7fu, 0xffu, 0xffu, 0xffu, + /* SEQUENCE */ + 0x30u, 0x2cu, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x14u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x7fu, 0xffu, 0xffu, 0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x14u, 0x1cu, 0x97u, 0xbeu, 0xfcu, 0x54u, 0xbdu, 0x7au, 0x8bu, 0x65u, 0xacu, 0xf8u, 0x9fu, 0x81u, 0xd4u, 0xd4u, 0xadu, 0xc5u, 0x65u, 0xfau, 0x45u, + /* G (basepoint of the curve) */ + 0x04u, 0x29u, 0x04u, 0x4au, 0x96u, 0xb5u, 0x68u, 0x8eu, 0xf5u, 0x73u, 0x28u, 0x46u, 0x64u, 0x69u, 0x89u, 0x68u, 0xc3u, 0x8bu, 0xb9u, 0x13u, 0xcbu, 0xfcu, 0x82u, 0x23u, 0xa6u, 0x28u, 0x55u, 0x31u, 0x68u, 0x94u, 0x7du, 0x59u, 0xdcu, 0xc9u, 0x12u, 0x04u, 0x23u, 0x51u, 0x37u, 0x7au, 0xc5u, 0xfbu, 0x32u, + /* n (order of G) */ + 0x02u, 0x15u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0xf4u, 0xc8u, 0xf9u, 0x27u, 0xaeu, 0xd3u, 0xcau, 0x75u, 0x22u, 0x57u, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1DomainExt[149] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0x92u, + /* SEQUENCE */ + 0x30u, 0x73u, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x14u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x40u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x01u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x02u, 0x00u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x2cu, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x14u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfdu, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x14u, 0x46u, 0xf6u, 0x7cu, 0x42u, 0x07u, 0x93u, 0xf6u, 0xdbu, 0x26u, 0x97u, 0x62u, 0xf6u, 0x6bu, 0xadu, 0xc1u, 0x8fu, 0x53u, 0xb1u, 0xd9u, 0xc3u, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x29u, 0x04u, 0x92u, 0x11u, 0x6eu, 0xfcu, 0xb2u, 0x27u, 0xa7u, 0xecu, 0xfau, 0xc6u, 0x2fu, 0x66u, 0x05u, 0x4fu, 0x37u, 0x54u, 0x39u, 0x17u, 0x57u, 0x36u, 0xbcu, 0x5au, 0x72u, 0x93u, 0xdeu, 0x56u, 0xf9u, 0x06u, 0x5bu, 0xeeu, 0x71u, 0xadu, 0xcau, 0x6fu, 0xd8u, 0xe5u, 0x8cu, 0x99u, 0x0fu, 0x5cu, + /* SEQUENCE */ + 0x30u, 0x1bu, + /* n_RR (R^2 in order field) */ + 0x04u, 0x15u, 0x00u, 0x43u, 0x6au, 0xb2u, 0x04u, 0xa0u, 0xe6u, 0x26u, 0x83u, 0x7au, 0x98u, 0xa2u, 0x2cu, 0x8du, 0x84u, 0x55u, 0xe5u, 0x56u, 0x3au, 0xadu, 0xf1u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x02u, 0x16u, 0x99u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1SpeedUpExt[355] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x5fu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x58u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0xa1u, 0x29u, 0x00u, 0x19u, 0x67u, 0x48u, 0xc7u, 0x48u, 0x89u, 0x82u, 0x8du, 0x41u, 0xdcu, 0x95u, 0xd7u, 0xd2u, 0x6au, 0x71u, 0x32u, 0x7fu, 0x94u, 0x98u, 0x6du, 0x17u, 0xeau, 0x30u, 0xd4u, 0xa8u, 0x54u, 0xf6u, 0x5du, 0x38u, 0x1cu, 0xecu, 0xdcu, 0xfau, 0x76u, 0x3au, 0x4bu, 0x0du, + /* (2^54 + 1) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x25u, 0xfcu, 0x2fu, 0x27u, 0xf5u, 0x1cu, 0x2au, 0xadu, 0xa3u, 0xceu, 0x1fu, 0x41u, 0xefu, 0x06u, 0x99u, 0xd7u, 0x69u, 0x03u, 0xeeu, 0xd9u, 0x79u, 0x51u, 0xdeu, 0xfcu, 0x19u, 0xaeu, 0xe1u, 0xd9u, 0xc9u, 0xf0u, 0x18u, 0xc4u, 0x02u, 0x2eu, 0xbbu, 0x4eu, 0x0eu, 0x9eu, 0xaeu, 0x84u, + /* (2^54 + 2) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0xe7u, 0xbfu, 0x07u, 0x2du, 0xb4u, 0x5du, 0x88u, 0x4au, 0x29u, 0x69u, 0x97u, 0x77u, 0xb1u, 0xceu, 0xbau, 0xe2u, 0xb8u, 0x76u, 0xaeu, 0x32u, 0x22u, 0x34u, 0x45u, 0x0au, 0x8au, 0x69u, 0x30u, 0xcbu, 0xcfu, 0xa6u, 0x7cu, 0xe6u, 0x50u, 0xb3u, 0x3cu, 0xadu, 0x43u, 0x1du, 0xb1u, 0x4fu, + /* (2^108 + 1) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x35u, 0x63u, 0x29u, 0xc6u, 0xa6u, 0xe7u, 0xb3u, 0x6eu, 0x51u, 0xefu, 0xe3u, 0x5du, 0xe5u, 0x2bu, 0x0du, 0x03u, 0x0bu, 0x1bu, 0x53u, 0x67u, 0x13u, 0xe0u, 0xbau, 0x88u, 0x37u, 0xffu, 0xc0u, 0x5du, 0x06u, 0xfeu, 0x3du, 0x1du, 0xa4u, 0x83u, 0x9au, 0x6au, 0x04u, 0xa3u, 0xe6u, 0x85u, + /* (2^108 + 2) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0xd4u, 0xd8u, 0x7cu, 0x90u, 0xc7u, 0x2bu, 0x0eu, 0x2eu, 0x56u, 0x73u, 0xc8u, 0x69u, 0x67u, 0xa2u, 0x28u, 0x2bu, 0x20u, 0x3fu, 0x96u, 0x30u, 0x8eu, 0xa8u, 0x06u, 0xb8u, 0xc8u, 0xecu, 0xbau, 0x42u, 0xa1u, 0xacu, 0x51u, 0x03u, 0xf0u, 0x59u, 0xc2u, 0xcfu, 0xddu, 0xdfu, 0xdeu, 0x40u, + /* (2^108 + 2^54 + 1) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x8eu, 0x62u, 0x41u, 0x4bu, 0x47u, 0x53u, 0x93u, 0xbbu, 0x20u, 0x70u, 0x01u, 0x8du, 0x63u, 0xedu, 0x63u, 0x7fu, 0x40u, 0xd1u, 0xecu, 0xf6u, 0x34u, 0x85u, 0xb9u, 0x62u, 0xfdu, 0x6au, 0x93u, 0x29u, 0x29u, 0xfeu, 0x95u, 0x42u, 0x85u, 0x1bu, 0x65u, 0xd9u, 0x42u, 0x0au, 0xc0u, 0x41u, + /* (2^108 + 2^54 + 2) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x8au, 0x73u, 0xfeu, 0x9fu, 0x5cu, 0x23u, 0xdcu, 0xf4u, 0x52u, 0x78u, 0x77u, 0x72u, 0x81u, 0xa7u, 0x55u, 0xdbu, 0xbfu, 0x77u, 0xc3u, 0x17u, 0x5cu, 0x80u, 0xf5u, 0x5du, 0x1cu, 0xbeu, 0xb3u, 0x42u, 0x3au, 0x1fu, 0x42u, 0xc4u, 0x96u, 0xd5u, 0xdbu, 0xc3u, 0x03u, 0x7du, 0x17u, 0x43u, + /* correction point D = - ((2^54 - 1) * G) in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x19u, 0x86u, 0x73u, 0x2eu, 0x8eu, 0x3eu, 0x13u, 0x39u, 0x81u, 0x01u, 0x3bu, 0xbcu, 0xd7u, 0x52u, 0x20u, 0x46u, 0x64u, 0xb8u, 0xa9u, 0xb3u, 0x96u, 0x28u, 0x5eu, 0xf2u, 0x3au, 0xa0u, 0xd2u, 0xebu, 0xe2u, 0x17u, 0x6fu, 0xcbu, 0xabu, 0x60u, 0xc1u, 0xdbu, 0xe0u, 0x59u, 0xe5u, 0x5cu, +}; + +#elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1Domain[155] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0x98u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x20u, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x15u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x7fu, 0xffu, 0xffu, 0xffu, + /* SEQUENCE */ + 0x30u, 0x2cu, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x14u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x7fu, 0xffu, 0xffu, 0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x14u, 0x1cu, 0x97u, 0xbeu, 0xfcu, 0x54u, 0xbdu, 0x7au, 0x8bu, 0x65u, 0xacu, 0xf8u, 0x9fu, 0x81u, 0xd4u, 0xd4u, 0xadu, 0xc5u, 0x65u, 0xfau, 0x45u, + /* G (basepoint of the curve) */ + 0x04u, 0x29u, 0x04u, 0x4au, 0x96u, 0xb5u, 0x68u, 0x8eu, 0xf5u, 0x73u, 0x28u, 0x46u, 0x64u, 0x69u, 0x89u, 0x68u, 0xc3u, 0x8bu, 0xb9u, 0x13u, 0xcbu, 0xfcu, 0x82u, 0x23u, 0xa6u, 0x28u, 0x55u, 0x31u, 0x68u, 0x94u, 0x7du, 0x59u, 0xdcu, 0xc9u, 0x12u, 0x04u, 0x23u, 0x51u, 0x37u, 0x7au, 0xc5u, 0xfbu, 0x32u, + /* n (order of G) */ + 0x02u, 0x15u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0xf4u, 0xc8u, 0xf9u, 0x27u, 0xaeu, 0xd3u, 0xcau, 0x75u, 0x22u, 0x57u, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1DomainExt[153] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0x96u, + /* SEQUENCE */ + 0x30u, 0x75u, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x14u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x40u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x01u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x04u, 0x80u, 0x00u, 0x00u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x2cu, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x14u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfdu, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x14u, 0x46u, 0xf6u, 0x7cu, 0x42u, 0x07u, 0x93u, 0xf6u, 0xdbu, 0x26u, 0x97u, 0x62u, 0xf6u, 0x6bu, 0xadu, 0xc1u, 0x8fu, 0x53u, 0xb1u, 0xd9u, 0xc3u, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x29u, 0x04u, 0x92u, 0x11u, 0x6eu, 0xfcu, 0xb2u, 0x27u, 0xa7u, 0xecu, 0xfau, 0xc6u, 0x2fu, 0x66u, 0x05u, 0x4fu, 0x37u, 0x54u, 0x39u, 0x17u, 0x57u, 0x36u, 0xbcu, 0x5au, 0x72u, 0x93u, 0xdeu, 0x56u, 0xf9u, 0x06u, 0x5bu, 0xeeu, 0x71u, 0xadu, 0xcau, 0x6fu, 0xd8u, 0xe5u, 0x8cu, 0x99u, 0x0fu, 0x5cu, + /* SEQUENCE */ + 0x30u, 0x1du, + /* n_RR (R^2 in order field) */ + 0x04u, 0x15u, 0x00u, 0xa0u, 0xe6u, 0x26u, 0x83u, 0x7au, 0x98u, 0x1eu, 0x4bu, 0x3cu, 0xdcu, 0x38u, 0x54u, 0x08u, 0x5eu, 0x33u, 0x5fu, 0x67u, 0x44u, 0xf8u, 0xa4u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x04u, 0x30u, 0x6du, 0x16u, 0x99u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1SpeedUpExt[355] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x5fu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x58u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0xa1u, 0x29u, 0x00u, 0x19u, 0x67u, 0x48u, 0xc7u, 0x48u, 0x89u, 0x82u, 0x8du, 0x41u, 0xdcu, 0x95u, 0xd7u, 0xd2u, 0x6au, 0x71u, 0x32u, 0x7fu, 0x94u, 0x98u, 0x6du, 0x17u, 0xeau, 0x30u, 0xd4u, 0xa8u, 0x54u, 0xf6u, 0x5du, 0x38u, 0x1cu, 0xecu, 0xdcu, 0xfau, 0x76u, 0x3au, 0x4bu, 0x0du, + /* (2^54 + 1) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x25u, 0xfcu, 0x2fu, 0x27u, 0xf5u, 0x1cu, 0x2au, 0xadu, 0xa3u, 0xceu, 0x1fu, 0x41u, 0xefu, 0x06u, 0x99u, 0xd7u, 0x69u, 0x03u, 0xeeu, 0xd9u, 0x79u, 0x51u, 0xdeu, 0xfcu, 0x19u, 0xaeu, 0xe1u, 0xd9u, 0xc9u, 0xf0u, 0x18u, 0xc4u, 0x02u, 0x2eu, 0xbbu, 0x4eu, 0x0eu, 0x9eu, 0xaeu, 0x84u, + /* (2^54 + 2) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0xe7u, 0xbfu, 0x07u, 0x2du, 0xb4u, 0x5du, 0x88u, 0x4au, 0x29u, 0x69u, 0x97u, 0x77u, 0xb1u, 0xceu, 0xbau, 0xe2u, 0xb8u, 0x76u, 0xaeu, 0x32u, 0x22u, 0x34u, 0x45u, 0x0au, 0x8au, 0x69u, 0x30u, 0xcbu, 0xcfu, 0xa6u, 0x7cu, 0xe6u, 0x50u, 0xb3u, 0x3cu, 0xadu, 0x43u, 0x1du, 0xb1u, 0x4fu, + /* (2^108 + 1) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x35u, 0x63u, 0x29u, 0xc6u, 0xa6u, 0xe7u, 0xb3u, 0x6eu, 0x51u, 0xefu, 0xe3u, 0x5du, 0xe5u, 0x2bu, 0x0du, 0x03u, 0x0bu, 0x1bu, 0x53u, 0x67u, 0x13u, 0xe0u, 0xbau, 0x88u, 0x37u, 0xffu, 0xc0u, 0x5du, 0x06u, 0xfeu, 0x3du, 0x1du, 0xa4u, 0x83u, 0x9au, 0x6au, 0x04u, 0xa3u, 0xe6u, 0x85u, + /* (2^108 + 2) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0xd4u, 0xd8u, 0x7cu, 0x90u, 0xc7u, 0x2bu, 0x0eu, 0x2eu, 0x56u, 0x73u, 0xc8u, 0x69u, 0x67u, 0xa2u, 0x28u, 0x2bu, 0x20u, 0x3fu, 0x96u, 0x30u, 0x8eu, 0xa8u, 0x06u, 0xb8u, 0xc8u, 0xecu, 0xbau, 0x42u, 0xa1u, 0xacu, 0x51u, 0x03u, 0xf0u, 0x59u, 0xc2u, 0xcfu, 0xddu, 0xdfu, 0xdeu, 0x40u, + /* (2^108 + 2^54 + 1) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x8eu, 0x62u, 0x41u, 0x4bu, 0x47u, 0x53u, 0x93u, 0xbbu, 0x20u, 0x70u, 0x01u, 0x8du, 0x63u, 0xedu, 0x63u, 0x7fu, 0x40u, 0xd1u, 0xecu, 0xf6u, 0x34u, 0x85u, 0xb9u, 0x62u, 0xfdu, 0x6au, 0x93u, 0x29u, 0x29u, 0xfeu, 0x95u, 0x42u, 0x85u, 0x1bu, 0x65u, 0xd9u, 0x42u, 0x0au, 0xc0u, 0x41u, + /* (2^108 + 2^54 + 2) * G in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x8au, 0x73u, 0xfeu, 0x9fu, 0x5cu, 0x23u, 0xdcu, 0xf4u, 0x52u, 0x78u, 0x77u, 0x72u, 0x81u, 0xa7u, 0x55u, 0xdbu, 0xbfu, 0x77u, 0xc3u, 0x17u, 0x5cu, 0x80u, 0xf5u, 0x5du, 0x1cu, 0xbeu, 0xb3u, 0x42u, 0x3au, 0x1fu, 0x42u, 0xc4u, 0x96u, 0xd5u, 0xdbu, 0xc3u, 0x03u, 0x7du, 0x17u, 0x43u, + /* correction point D = - ((2^54 - 1) * G) in Montgomery representation */ + 0x04u, 0x29u, 0x04u, 0x19u, 0x86u, 0x73u, 0x2eu, 0x8eu, 0x3eu, 0x13u, 0x39u, 0x81u, 0x01u, 0x3bu, 0xbcu, 0xd7u, 0x52u, 0x20u, 0x46u, 0x64u, 0xb8u, 0xa9u, 0xb3u, 0x96u, 0x28u, 0x5eu, 0xf2u, 0x3au, 0xa0u, 0xd2u, 0xebu, 0xe2u, 0x17u, 0x6fu, 0xcbu, 0xabu, 0x60u, 0xc1u, 0xdbu, 0xe0u, 0x59u, 0xe5u, 0x5cu, +}; +#else /* CRYPTO_30_LIBCV_BYTES_PER_DIGIT */ +# error "Value of CRYPTO_30_LIBCV_BYTES_PER_DIGIT is not supported" +#endif /* CRYPTO_30_LIBCV_BYTES_PER_DIGIT */ +/* SEC_p160r1 END ****************************************************************************************************/ + +/* NIST_SEC_p224r1 START *********************************************************************************************/ +/* NISTp224r1 = SECp224r1 */ +/* The curve params in shorthand notation: + * Name: SECGp224r1 + * p: 0xffffffffffffffffffffffffffffffff000000000000000000000001 + * a: 0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe + * b: 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4 + * Gx: 0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21 + * Gy: 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34 + * n: 0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d + * h: 0x1 + */ + +#if (actBN_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1Domain[203] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xc8u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x28u, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x1du, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x3cu, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x1cu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x1cu, 0xb4u, 0x05u, 0x0au, 0x85u, 0x0cu, 0x04u, 0xb3u, 0xabu, 0xf5u, 0x41u, 0x32u, 0x56u, 0x50u, 0x44u, 0xb0u, 0xb7u, 0xd7u, 0xbfu, 0xd8u, 0xbau, 0x27u, 0x0bu, 0x39u, 0x43u, 0x23u, 0x55u, 0xffu, 0xb4u, + /* G (basepoint of the curve) */ + 0x04u, 0x39u, 0x04u, 0xb7u, 0x0eu, 0x0cu, 0xbdu, 0x6bu, 0xb4u, 0xbfu, 0x7fu, 0x32u, 0x13u, 0x90u, 0xb9u, 0x4au, 0x03u, 0xc1u, 0xd3u, 0x56u, 0xc2u, 0x11u, 0x22u, 0x34u, 0x32u, 0x80u, 0xd6u, 0x11u, 0x5cu, 0x1du, 0x21u, 0xbdu, 0x37u, 0x63u, 0x88u, 0xb5u, 0xf7u, 0x23u, 0xfbu, 0x4cu, 0x22u, 0xdfu, 0xe6u, 0xcdu, 0x43u, 0x75u, 0xa0u, 0x5au, 0x07u, 0x47u, 0x64u, 0x44u, 0xd5u, 0x81u, 0x99u, 0x85u, 0x00u, 0x7eu, 0x34u, + /* n (order of G) */ + 0x02u, 0x1du, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x16u, 0xa2u, 0xe0u, 0xb8u, 0xf0u, 0x3eu, 0x13u, 0xddu, 0x29u, 0x45u, 0x5cu, 0x5cu, 0x2au, 0x3du, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1DomainExt[195] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xc0u, + /* SEQUENCE */ + 0x30u, 0x81u, 0x9au, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x1cu, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x01u, 0xffu, + /* SEQUENCE */ + 0x30u, 0x3cu, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x1cu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfcu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x1cu, 0x9cu, 0x3fu, 0xa6u, 0x33u, 0x7fu, 0xc0u, 0x2fu, 0x93u, 0x3du, 0xceu, 0xbau, 0x98u, 0xc8u, 0x52u, 0x81u, 0x50u, 0x74u, 0x3bu, 0x1cu, 0xc0u, 0xccu, 0xf0u, 0x13u, 0x10u, 0xe7u, 0x68u, 0xcdu, 0xf7u, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x39u, 0x04u, 0x92u, 0xf5u, 0xb5u, 0x16u, 0xa2u, 0x1bu, 0x5eu, 0x60u, 0x6du, 0xd3u, 0xafu, 0x9bu, 0xf9u, 0x6bu, 0xecu, 0x04u, 0xf2u, 0x2fu, 0xe2u, 0x20u, 0x60u, 0x18u, 0xbfu, 0xaau, 0xbcu, 0x90u, 0x52u, 0x27u, 0x10u, 0x0cu, 0x12u, 0x18u, 0x61u, 0x47u, 0x86u, 0xf1u, 0xaeu, 0xa9u, 0xc5u, 0xaeu, 0x03u, 0xdfu, 0xe8u, 0x78u, 0xe8u, 0xc1u, 0x55u, 0x13u, 0x05u, 0x33u, 0x5au, 0x6bu, 0x2eu, 0xdcu, 0xa1u, 0xe6u, + /* SEQUENCE */ + 0x30u, 0x21u, + /* n_RR (R^2 in order field) */ + 0x04u, 0x1cu, 0xd4u, 0xbau, 0xa4u, 0xcfu, 0x18u, 0x22u, 0xbcu, 0x47u, 0xb1u, 0xe9u, 0x79u, 0x61u, 0x6au, 0xd0u, 0x9du, 0x91u, 0x97u, 0xa5u, 0x45u, 0x52u, 0x6bu, 0xdau, 0xaeu, 0x6cu, 0x3au, 0xd0u, 0x12u, 0x89u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x01u, 0xebu, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1SpeedUpExt[483] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0xdfu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0xd8u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x18u, 0xddu, 0x00u, 0xacu, 0xcau, 0xfbu, 0x50u, 0xf5u, 0x10u, 0xc9u, 0x11u, 0xf7u, 0x2au, 0x0fu, 0x16u, 0x89u, 0xbeu, 0x27u, 0xf7u, 0xa3u, 0x56u, 0x50u, 0xdfu, 0x9bu, 0x4cu, 0xa9u, 0xa1u, 0xedu, 0x6au, 0x5du, 0xb1u, 0xa2u, 0x5cu, 0xabu, 0xb8u, 0x80u, 0x0cu, 0x84u, 0xceu, 0xd0u, 0x76u, 0xccu, 0x10u, 0x19u, 0xe7u, 0x2eu, 0x60u, 0x0fu, 0xc9u, 0x0au, 0xe1u, 0x86u, 0x02u, 0xaau, 0xc7u, 0x9cu, + /* (2^75 + 1) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x7du, 0xdfu, 0xbau, 0xa5u, 0x30u, 0x42u, 0x21u, 0xfcu, 0x33u, 0x50u, 0xe8u, 0x78u, 0x22u, 0x92u, 0xffu, 0x62u, 0x7eu, 0xc1u, 0x30u, 0x50u, 0x71u, 0x1fu, 0xceu, 0x8du, 0xf0u, 0x6du, 0x61u, 0x1du, 0x68u, 0x65u, 0xb8u, 0xd4u, 0x02u, 0x1du, 0x49u, 0x5du, 0xbau, 0x4du, 0xe4u, 0x4du, 0x41u, 0x02u, 0xe4u, 0xe3u, 0x09u, 0xb2u, 0xabu, 0x6fu, 0x4du, 0x42u, 0xadu, 0xaau, 0xc5u, 0xecu, 0x6du, 0x9cu, + /* (2^75 + 2) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x84u, 0xb4u, 0x25u, 0xe8u, 0x77u, 0xd5u, 0x72u, 0x90u, 0xd6u, 0x97u, 0x56u, 0xdeu, 0xd1u, 0x42u, 0x49u, 0x43u, 0x57u, 0xd7u, 0xbbu, 0x8bu, 0x2cu, 0xe1u, 0xb4u, 0x90u, 0xabu, 0xf3u, 0x8cu, 0x1fu, 0x1au, 0x97u, 0x11u, 0xdeu, 0xfdu, 0xe3u, 0x23u, 0xabu, 0xa9u, 0x21u, 0x64u, 0x5au, 0x3bu, 0xa7u, 0x2fu, 0x33u, 0x0au, 0x7eu, 0x07u, 0x76u, 0x16u, 0x44u, 0xffu, 0xe5u, 0x7eu, 0x92u, 0xd0u, 0x9du, + /* (2^150 + 1) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x9du, 0x5cu, 0x98u, 0xa9u, 0x42u, 0xcfu, 0xb8u, 0x3cu, 0x41u, 0x6cu, 0x64u, 0x5au, 0xc0u, 0x63u, 0x2du, 0x43u, 0xd3u, 0xb7u, 0xc7u, 0x33u, 0xc6u, 0xe7u, 0x1du, 0x41u, 0x00u, 0x67u, 0xbfu, 0x54u, 0x1eu, 0xebu, 0x3fu, 0x8cu, 0xb7u, 0x1fu, 0xd5u, 0xddu, 0xc3u, 0xf3u, 0x48u, 0xa1u, 0x7eu, 0x81u, 0x8fu, 0xe0u, 0x8du, 0x72u, 0x23u, 0xb3u, 0xdfu, 0xddu, 0x55u, 0xf2u, 0x24u, 0xccu, 0x79u, 0xe3u, + /* (2^150 + 2) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0xf5u, 0xb8u, 0xcau, 0x58u, 0x85u, 0xa6u, 0xa6u, 0xebu, 0xd9u, 0x28u, 0x9cu, 0x74u, 0xfau, 0x2au, 0x53u, 0x1fu, 0xd7u, 0x9au, 0x88u, 0x5eu, 0x15u, 0xd9u, 0x6eu, 0xc3u, 0x8fu, 0x63u, 0x9cu, 0xf3u, 0xfbu, 0x20u, 0x0cu, 0xe2u, 0x4cu, 0x5cu, 0xe6u, 0xa1u, 0xd9u, 0xfau, 0xd8u, 0xe5u, 0x63u, 0x1fu, 0xa0u, 0x04u, 0x0bu, 0x0fu, 0xd1u, 0xeeu, 0xdfu, 0xffu, 0xb5u, 0x17u, 0x96u, 0x7au, 0xfdu, 0xfcu, + /* (2^150 + 2^75 + 1) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x34u, 0x7bu, 0xbcu, 0x79u, 0x1cu, 0xf6u, 0x1bu, 0xdfu, 0x7fu, 0x96u, 0xb5u, 0x5fu, 0x7eu, 0xabu, 0x4au, 0x0au, 0xa0u, 0x98u, 0xbau, 0xfbu, 0xdfu, 0x89u, 0x19u, 0x33u, 0xf5u, 0x45u, 0xe4u, 0xddu, 0xe0u, 0x57u, 0xe1u, 0xcau, 0xecu, 0x54u, 0x6eu, 0xd2u, 0x2du, 0x74u, 0xc2u, 0x3eu, 0x1fu, 0x2au, 0x61u, 0x4fu, 0x38u, 0x6du, 0x8cu, 0x37u, 0x19u, 0x39u, 0xa2u, 0x3eu, 0x12u, 0x38u, 0x73u, 0x43u, + /* (2^150 + 2^75 + 2) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x99u, 0x12u, 0x11u, 0xc0u, 0xf8u, 0x74u, 0xb0u, 0x93u, 0xb7u, 0xa8u, 0xe3u, 0xceu, 0x9du, 0x60u, 0xb0u, 0xedu, 0xd9u, 0xbcu, 0x5eu, 0x28u, 0xdcu, 0xb0u, 0xb0u, 0xb8u, 0x0cu, 0xe9u, 0xeeu, 0xd8u, 0xb6u, 0xd0u, 0x53u, 0x98u, 0x1au, 0x4du, 0x50u, 0x75u, 0xe7u, 0xf0u, 0x7du, 0x12u, 0x44u, 0x79u, 0x53u, 0x26u, 0x81u, 0x52u, 0x5au, 0x94u, 0x9au, 0x00u, 0xd6u, 0xd4u, 0x53u, 0x89u, 0x2bu, 0xbdu, + /* correction point D = - ((2^75 - 1) * G) in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0xafu, 0x18u, 0x1au, 0xe7u, 0x7cu, 0xc3u, 0xe9u, 0x18u, 0x71u, 0x5bu, 0x80u, 0x6eu, 0x41u, 0x32u, 0x20u, 0x05u, 0xd7u, 0xfau, 0x89u, 0x1du, 0xbcu, 0xc7u, 0xa3u, 0x56u, 0x67u, 0x32u, 0xb0u, 0xdfu, 0x24u, 0x9au, 0x58u, 0xfeu, 0x10u, 0xa2u, 0x0du, 0x6bu, 0x7fu, 0xa9u, 0xc4u, 0xd7u, 0xbau, 0x4cu, 0x3eu, 0x36u, 0x66u, 0x22u, 0xfau, 0x0du, 0xedu, 0xf1u, 0x46u, 0x69u, 0xd5u, 0xc2u, 0x44u, 0xedu, +}; + +#elif (actBN_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1Domain[203] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xc8u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x28u, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x1du, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x3cu, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x1cu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x1cu, 0xb4u, 0x05u, 0x0au, 0x85u, 0x0cu, 0x04u, 0xb3u, 0xabu, 0xf5u, 0x41u, 0x32u, 0x56u, 0x50u, 0x44u, 0xb0u, 0xb7u, 0xd7u, 0xbfu, 0xd8u, 0xbau, 0x27u, 0x0bu, 0x39u, 0x43u, 0x23u, 0x55u, 0xffu, 0xb4u, + /* G (basepoint of the curve) */ + 0x04u, 0x39u, 0x04u, 0xb7u, 0x0eu, 0x0cu, 0xbdu, 0x6bu, 0xb4u, 0xbfu, 0x7fu, 0x32u, 0x13u, 0x90u, 0xb9u, 0x4au, 0x03u, 0xc1u, 0xd3u, 0x56u, 0xc2u, 0x11u, 0x22u, 0x34u, 0x32u, 0x80u, 0xd6u, 0x11u, 0x5cu, 0x1du, 0x21u, 0xbdu, 0x37u, 0x63u, 0x88u, 0xb5u, 0xf7u, 0x23u, 0xfbu, 0x4cu, 0x22u, 0xdfu, 0xe6u, 0xcdu, 0x43u, 0x75u, 0xa0u, 0x5au, 0x07u, 0x47u, 0x64u, 0x44u, 0xd5u, 0x81u, 0x99u, 0x85u, 0x00u, 0x7eu, 0x34u, + /* n (order of G) */ + 0x02u, 0x1du, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x16u, 0xa2u, 0xe0u, 0xb8u, 0xf0u, 0x3eu, 0x13u, 0xddu, 0x29u, 0x45u, 0x5cu, 0x5cu, 0x2au, 0x3du, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1DomainExt[197] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xc2u, + /* SEQUENCE */ + 0x30u, 0x81u, 0x9bu, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x1cu, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x02u, 0xffu, 0xffu, + /* SEQUENCE */ + 0x30u, 0x3cu, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x1cu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfcu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x1cu, 0x9cu, 0x3fu, 0xa6u, 0x33u, 0x7fu, 0xc0u, 0x2fu, 0x93u, 0x3du, 0xceu, 0xbau, 0x98u, 0xc8u, 0x52u, 0x81u, 0x50u, 0x74u, 0x3bu, 0x1cu, 0xc0u, 0xccu, 0xf0u, 0x13u, 0x10u, 0xe7u, 0x68u, 0xcdu, 0xf7u, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x39u, 0x04u, 0x92u, 0xf5u, 0xb5u, 0x16u, 0xa2u, 0x1bu, 0x5eu, 0x60u, 0x6du, 0xd3u, 0xafu, 0x9bu, 0xf9u, 0x6bu, 0xecu, 0x04u, 0xf2u, 0x2fu, 0xe2u, 0x20u, 0x60u, 0x18u, 0xbfu, 0xaau, 0xbcu, 0x90u, 0x52u, 0x27u, 0x10u, 0x0cu, 0x12u, 0x18u, 0x61u, 0x47u, 0x86u, 0xf1u, 0xaeu, 0xa9u, 0xc5u, 0xaeu, 0x03u, 0xdfu, 0xe8u, 0x78u, 0xe8u, 0xc1u, 0x55u, 0x13u, 0x05u, 0x33u, 0x5au, 0x6bu, 0x2eu, 0xdcu, 0xa1u, 0xe6u, + /* SEQUENCE */ + 0x30u, 0x22u, + /* n_RR (R^2 in order field) */ + 0x04u, 0x1cu, 0xd4u, 0xbau, 0xa4u, 0xcfu, 0x18u, 0x22u, 0xbcu, 0x47u, 0xb1u, 0xe9u, 0x79u, 0x61u, 0x6au, 0xd0u, 0x9du, 0x91u, 0x97u, 0xa5u, 0x45u, 0x52u, 0x6bu, 0xdau, 0xaeu, 0x6cu, 0x3au, 0xd0u, 0x12u, 0x89u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x02u, 0xc2u, 0xebu, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1SpeedUpExt[483] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0xdfu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0xd8u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x18u, 0xddu, 0x00u, 0xacu, 0xcau, 0xfbu, 0x50u, 0xf5u, 0x10u, 0xc9u, 0x11u, 0xf7u, 0x2au, 0x0fu, 0x16u, 0x89u, 0xbeu, 0x27u, 0xf7u, 0xa3u, 0x56u, 0x50u, 0xdfu, 0x9bu, 0x4cu, 0xa9u, 0xa1u, 0xedu, 0x6au, 0x5du, 0xb1u, 0xa2u, 0x5cu, 0xabu, 0xb8u, 0x80u, 0x0cu, 0x84u, 0xceu, 0xd0u, 0x76u, 0xccu, 0x10u, 0x19u, 0xe7u, 0x2eu, 0x60u, 0x0fu, 0xc9u, 0x0au, 0xe1u, 0x86u, 0x02u, 0xaau, 0xc7u, 0x9cu, + /* (2^75 + 1) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x7du, 0xdfu, 0xbau, 0xa5u, 0x30u, 0x42u, 0x21u, 0xfcu, 0x33u, 0x50u, 0xe8u, 0x78u, 0x22u, 0x92u, 0xffu, 0x62u, 0x7eu, 0xc1u, 0x30u, 0x50u, 0x71u, 0x1fu, 0xceu, 0x8du, 0xf0u, 0x6du, 0x61u, 0x1du, 0x68u, 0x65u, 0xb8u, 0xd4u, 0x02u, 0x1du, 0x49u, 0x5du, 0xbau, 0x4du, 0xe4u, 0x4du, 0x41u, 0x02u, 0xe4u, 0xe3u, 0x09u, 0xb2u, 0xabu, 0x6fu, 0x4du, 0x42u, 0xadu, 0xaau, 0xc5u, 0xecu, 0x6du, 0x9cu, + /* (2^75 + 2) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x84u, 0xb4u, 0x25u, 0xe8u, 0x77u, 0xd5u, 0x72u, 0x90u, 0xd6u, 0x97u, 0x56u, 0xdeu, 0xd1u, 0x42u, 0x49u, 0x43u, 0x57u, 0xd7u, 0xbbu, 0x8bu, 0x2cu, 0xe1u, 0xb4u, 0x90u, 0xabu, 0xf3u, 0x8cu, 0x1fu, 0x1au, 0x97u, 0x11u, 0xdeu, 0xfdu, 0xe3u, 0x23u, 0xabu, 0xa9u, 0x21u, 0x64u, 0x5au, 0x3bu, 0xa7u, 0x2fu, 0x33u, 0x0au, 0x7eu, 0x07u, 0x76u, 0x16u, 0x44u, 0xffu, 0xe5u, 0x7eu, 0x92u, 0xd0u, 0x9du, + /* (2^150 + 1) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x9du, 0x5cu, 0x98u, 0xa9u, 0x42u, 0xcfu, 0xb8u, 0x3cu, 0x41u, 0x6cu, 0x64u, 0x5au, 0xc0u, 0x63u, 0x2du, 0x43u, 0xd3u, 0xb7u, 0xc7u, 0x33u, 0xc6u, 0xe7u, 0x1du, 0x41u, 0x00u, 0x67u, 0xbfu, 0x54u, 0x1eu, 0xebu, 0x3fu, 0x8cu, 0xb7u, 0x1fu, 0xd5u, 0xddu, 0xc3u, 0xf3u, 0x48u, 0xa1u, 0x7eu, 0x81u, 0x8fu, 0xe0u, 0x8du, 0x72u, 0x23u, 0xb3u, 0xdfu, 0xddu, 0x55u, 0xf2u, 0x24u, 0xccu, 0x79u, 0xe3u, + /* (2^150 + 2) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0xf5u, 0xb8u, 0xcau, 0x58u, 0x85u, 0xa6u, 0xa6u, 0xebu, 0xd9u, 0x28u, 0x9cu, 0x74u, 0xfau, 0x2au, 0x53u, 0x1fu, 0xd7u, 0x9au, 0x88u, 0x5eu, 0x15u, 0xd9u, 0x6eu, 0xc3u, 0x8fu, 0x63u, 0x9cu, 0xf3u, 0xfbu, 0x20u, 0x0cu, 0xe2u, 0x4cu, 0x5cu, 0xe6u, 0xa1u, 0xd9u, 0xfau, 0xd8u, 0xe5u, 0x63u, 0x1fu, 0xa0u, 0x04u, 0x0bu, 0x0fu, 0xd1u, 0xeeu, 0xdfu, 0xffu, 0xb5u, 0x17u, 0x96u, 0x7au, 0xfdu, 0xfcu, + /* (2^150 + 2^75 + 1) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x34u, 0x7bu, 0xbcu, 0x79u, 0x1cu, 0xf6u, 0x1bu, 0xdfu, 0x7fu, 0x96u, 0xb5u, 0x5fu, 0x7eu, 0xabu, 0x4au, 0x0au, 0xa0u, 0x98u, 0xbau, 0xfbu, 0xdfu, 0x89u, 0x19u, 0x33u, 0xf5u, 0x45u, 0xe4u, 0xddu, 0xe0u, 0x57u, 0xe1u, 0xcau, 0xecu, 0x54u, 0x6eu, 0xd2u, 0x2du, 0x74u, 0xc2u, 0x3eu, 0x1fu, 0x2au, 0x61u, 0x4fu, 0x38u, 0x6du, 0x8cu, 0x37u, 0x19u, 0x39u, 0xa2u, 0x3eu, 0x12u, 0x38u, 0x73u, 0x43u, + /* (2^150 + 2^75 + 2) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x99u, 0x12u, 0x11u, 0xc0u, 0xf8u, 0x74u, 0xb0u, 0x93u, 0xb7u, 0xa8u, 0xe3u, 0xceu, 0x9du, 0x60u, 0xb0u, 0xedu, 0xd9u, 0xbcu, 0x5eu, 0x28u, 0xdcu, 0xb0u, 0xb0u, 0xb8u, 0x0cu, 0xe9u, 0xeeu, 0xd8u, 0xb6u, 0xd0u, 0x53u, 0x98u, 0x1au, 0x4du, 0x50u, 0x75u, 0xe7u, 0xf0u, 0x7du, 0x12u, 0x44u, 0x79u, 0x53u, 0x26u, 0x81u, 0x52u, 0x5au, 0x94u, 0x9au, 0x00u, 0xd6u, 0xd4u, 0x53u, 0x89u, 0x2bu, 0xbdu, + /* correction point D = - ((2^75 - 1) * G) in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0xafu, 0x18u, 0x1au, 0xe7u, 0x7cu, 0xc3u, 0xe9u, 0x18u, 0x71u, 0x5bu, 0x80u, 0x6eu, 0x41u, 0x32u, 0x20u, 0x05u, 0xd7u, 0xfau, 0x89u, 0x1du, 0xbcu, 0xc7u, 0xa3u, 0x56u, 0x67u, 0x32u, 0xb0u, 0xdfu, 0x24u, 0x9au, 0x58u, 0xfeu, 0x10u, 0xa2u, 0x0du, 0x6bu, 0x7fu, 0xa9u, 0xc4u, 0xd7u, 0xbau, 0x4cu, 0x3eu, 0x36u, 0x66u, 0x22u, 0xfau, 0x0du, 0xedu, 0xf1u, 0x46u, 0x69u, 0xd5u, 0xc2u, 0x44u, 0xedu, +}; + +#elif (actBN_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1Domain[203] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xc8u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x28u, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x1du, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x3cu, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x1cu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x1cu, 0xb4u, 0x05u, 0x0au, 0x85u, 0x0cu, 0x04u, 0xb3u, 0xabu, 0xf5u, 0x41u, 0x32u, 0x56u, 0x50u, 0x44u, 0xb0u, 0xb7u, 0xd7u, 0xbfu, 0xd8u, 0xbau, 0x27u, 0x0bu, 0x39u, 0x43u, 0x23u, 0x55u, 0xffu, 0xb4u, + /* G (basepoint of the curve) */ + 0x04u, 0x39u, 0x04u, 0xb7u, 0x0eu, 0x0cu, 0xbdu, 0x6bu, 0xb4u, 0xbfu, 0x7fu, 0x32u, 0x13u, 0x90u, 0xb9u, 0x4au, 0x03u, 0xc1u, 0xd3u, 0x56u, 0xc2u, 0x11u, 0x22u, 0x34u, 0x32u, 0x80u, 0xd6u, 0x11u, 0x5cu, 0x1du, 0x21u, 0xbdu, 0x37u, 0x63u, 0x88u, 0xb5u, 0xf7u, 0x23u, 0xfbu, 0x4cu, 0x22u, 0xdfu, 0xe6u, 0xcdu, 0x43u, 0x75u, 0xa0u, 0x5au, 0x07u, 0x47u, 0x64u, 0x44u, 0xd5u, 0x81u, 0x99u, 0x85u, 0x00u, 0x7eu, 0x34u, + /* n (order of G) */ + 0x02u, 0x1du, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0x16u, 0xa2u, 0xe0u, 0xb8u, 0xf0u, 0x3eu, 0x13u, 0xddu, 0x29u, 0x45u, 0x5cu, 0x5cu, 0x2au, 0x3du, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1DomainExt[201] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xc6u, + /* SEQUENCE */ + 0x30u, 0x81u, 0x9du, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x1cu, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x04u, 0xffu, 0xffu, 0xffu, 0xffu, + /* SEQUENCE */ + 0x30u, 0x3cu, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x1cu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfcu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x1cu, 0x9cu, 0x3fu, 0xa6u, 0x33u, 0x7fu, 0xc0u, 0x2fu, 0x93u, 0x3du, 0xceu, 0xbau, 0x98u, 0xc8u, 0x52u, 0x81u, 0x50u, 0x74u, 0x3bu, 0x1cu, 0xc0u, 0xccu, 0xf0u, 0x13u, 0x10u, 0xe7u, 0x68u, 0xcdu, 0xf7u, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x39u, 0x04u, 0x92u, 0xf5u, 0xb5u, 0x16u, 0xa2u, 0x1bu, 0x5eu, 0x60u, 0x6du, 0xd3u, 0xafu, 0x9bu, 0xf9u, 0x6bu, 0xecu, 0x04u, 0xf2u, 0x2fu, 0xe2u, 0x20u, 0x60u, 0x18u, 0xbfu, 0xaau, 0xbcu, 0x90u, 0x52u, 0x27u, 0x10u, 0x0cu, 0x12u, 0x18u, 0x61u, 0x47u, 0x86u, 0xf1u, 0xaeu, 0xa9u, 0xc5u, 0xaeu, 0x03u, 0xdfu, 0xe8u, 0x78u, 0xe8u, 0xc1u, 0x55u, 0x13u, 0x05u, 0x33u, 0x5au, 0x6bu, 0x2eu, 0xdcu, 0xa1u, 0xe6u, + /* SEQUENCE */ + 0x30u, 0x24u, + /* n_RR (R^2 in order field) */ + 0x04u, 0x1cu, 0xd4u, 0xbau, 0xa4u, 0xcfu, 0x18u, 0x22u, 0xbcu, 0x47u, 0xb1u, 0xe9u, 0x79u, 0x61u, 0x6au, 0xd0u, 0x9du, 0x91u, 0x97u, 0xa5u, 0x45u, 0x52u, 0x6bu, 0xdau, 0xaeu, 0x6cu, 0x3au, 0xd0u, 0x12u, 0x89u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x04u, 0x6au, 0x1fu, 0xc2u, 0xebu, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1SpeedUpExt[483] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0xdfu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0xd8u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x18u, 0xddu, 0x00u, 0xacu, 0xcau, 0xfbu, 0x50u, 0xf5u, 0x10u, 0xc9u, 0x11u, 0xf7u, 0x2au, 0x0fu, 0x16u, 0x89u, 0xbeu, 0x27u, 0xf7u, 0xa3u, 0x56u, 0x50u, 0xdfu, 0x9bu, 0x4cu, 0xa9u, 0xa1u, 0xedu, 0x6au, 0x5du, 0xb1u, 0xa2u, 0x5cu, 0xabu, 0xb8u, 0x80u, 0x0cu, 0x84u, 0xceu, 0xd0u, 0x76u, 0xccu, 0x10u, 0x19u, 0xe7u, 0x2eu, 0x60u, 0x0fu, 0xc9u, 0x0au, 0xe1u, 0x86u, 0x02u, 0xaau, 0xc7u, 0x9cu, + /* (2^75 + 1) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x7du, 0xdfu, 0xbau, 0xa5u, 0x30u, 0x42u, 0x21u, 0xfcu, 0x33u, 0x50u, 0xe8u, 0x78u, 0x22u, 0x92u, 0xffu, 0x62u, 0x7eu, 0xc1u, 0x30u, 0x50u, 0x71u, 0x1fu, 0xceu, 0x8du, 0xf0u, 0x6du, 0x61u, 0x1du, 0x68u, 0x65u, 0xb8u, 0xd4u, 0x02u, 0x1du, 0x49u, 0x5du, 0xbau, 0x4du, 0xe4u, 0x4du, 0x41u, 0x02u, 0xe4u, 0xe3u, 0x09u, 0xb2u, 0xabu, 0x6fu, 0x4du, 0x42u, 0xadu, 0xaau, 0xc5u, 0xecu, 0x6du, 0x9cu, + /* (2^75 + 2) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x84u, 0xb4u, 0x25u, 0xe8u, 0x77u, 0xd5u, 0x72u, 0x90u, 0xd6u, 0x97u, 0x56u, 0xdeu, 0xd1u, 0x42u, 0x49u, 0x43u, 0x57u, 0xd7u, 0xbbu, 0x8bu, 0x2cu, 0xe1u, 0xb4u, 0x90u, 0xabu, 0xf3u, 0x8cu, 0x1fu, 0x1au, 0x97u, 0x11u, 0xdeu, 0xfdu, 0xe3u, 0x23u, 0xabu, 0xa9u, 0x21u, 0x64u, 0x5au, 0x3bu, 0xa7u, 0x2fu, 0x33u, 0x0au, 0x7eu, 0x07u, 0x76u, 0x16u, 0x44u, 0xffu, 0xe5u, 0x7eu, 0x92u, 0xd0u, 0x9du, + /* (2^150 + 1) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x9du, 0x5cu, 0x98u, 0xa9u, 0x42u, 0xcfu, 0xb8u, 0x3cu, 0x41u, 0x6cu, 0x64u, 0x5au, 0xc0u, 0x63u, 0x2du, 0x43u, 0xd3u, 0xb7u, 0xc7u, 0x33u, 0xc6u, 0xe7u, 0x1du, 0x41u, 0x00u, 0x67u, 0xbfu, 0x54u, 0x1eu, 0xebu, 0x3fu, 0x8cu, 0xb7u, 0x1fu, 0xd5u, 0xddu, 0xc3u, 0xf3u, 0x48u, 0xa1u, 0x7eu, 0x81u, 0x8fu, 0xe0u, 0x8du, 0x72u, 0x23u, 0xb3u, 0xdfu, 0xddu, 0x55u, 0xf2u, 0x24u, 0xccu, 0x79u, 0xe3u, + /* (2^150 + 2) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0xf5u, 0xb8u, 0xcau, 0x58u, 0x85u, 0xa6u, 0xa6u, 0xebu, 0xd9u, 0x28u, 0x9cu, 0x74u, 0xfau, 0x2au, 0x53u, 0x1fu, 0xd7u, 0x9au, 0x88u, 0x5eu, 0x15u, 0xd9u, 0x6eu, 0xc3u, 0x8fu, 0x63u, 0x9cu, 0xf3u, 0xfbu, 0x20u, 0x0cu, 0xe2u, 0x4cu, 0x5cu, 0xe6u, 0xa1u, 0xd9u, 0xfau, 0xd8u, 0xe5u, 0x63u, 0x1fu, 0xa0u, 0x04u, 0x0bu, 0x0fu, 0xd1u, 0xeeu, 0xdfu, 0xffu, 0xb5u, 0x17u, 0x96u, 0x7au, 0xfdu, 0xfcu, + /* (2^150 + 2^75 + 1) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x34u, 0x7bu, 0xbcu, 0x79u, 0x1cu, 0xf6u, 0x1bu, 0xdfu, 0x7fu, 0x96u, 0xb5u, 0x5fu, 0x7eu, 0xabu, 0x4au, 0x0au, 0xa0u, 0x98u, 0xbau, 0xfbu, 0xdfu, 0x89u, 0x19u, 0x33u, 0xf5u, 0x45u, 0xe4u, 0xddu, 0xe0u, 0x57u, 0xe1u, 0xcau, 0xecu, 0x54u, 0x6eu, 0xd2u, 0x2du, 0x74u, 0xc2u, 0x3eu, 0x1fu, 0x2au, 0x61u, 0x4fu, 0x38u, 0x6du, 0x8cu, 0x37u, 0x19u, 0x39u, 0xa2u, 0x3eu, 0x12u, 0x38u, 0x73u, 0x43u, + /* (2^150 + 2^75 + 2) * G in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0x99u, 0x12u, 0x11u, 0xc0u, 0xf8u, 0x74u, 0xb0u, 0x93u, 0xb7u, 0xa8u, 0xe3u, 0xceu, 0x9du, 0x60u, 0xb0u, 0xedu, 0xd9u, 0xbcu, 0x5eu, 0x28u, 0xdcu, 0xb0u, 0xb0u, 0xb8u, 0x0cu, 0xe9u, 0xeeu, 0xd8u, 0xb6u, 0xd0u, 0x53u, 0x98u, 0x1au, 0x4du, 0x50u, 0x75u, 0xe7u, 0xf0u, 0x7du, 0x12u, 0x44u, 0x79u, 0x53u, 0x26u, 0x81u, 0x52u, 0x5au, 0x94u, 0x9au, 0x00u, 0xd6u, 0xd4u, 0x53u, 0x89u, 0x2bu, 0xbdu, + /* correction point D = - ((2^75 - 1) * G) in Montgomery representation */ + 0x04u, 0x39u, 0x04u, 0xafu, 0x18u, 0x1au, 0xe7u, 0x7cu, 0xc3u, 0xe9u, 0x18u, 0x71u, 0x5bu, 0x80u, 0x6eu, 0x41u, 0x32u, 0x20u, 0x05u, 0xd7u, 0xfau, 0x89u, 0x1du, 0xbcu, 0xc7u, 0xa3u, 0x56u, 0x67u, 0x32u, 0xb0u, 0xdfu, 0x24u, 0x9au, 0x58u, 0xfeu, 0x10u, 0xa2u, 0x0du, 0x6bu, 0x7fu, 0xa9u, 0xc4u, 0xd7u, 0xbau, 0x4cu, 0x3eu, 0x36u, 0x66u, 0x22u, 0xfau, 0x0du, 0xedu, 0xf1u, 0x46u, 0x69u, 0xd5u, 0xc2u, 0x44u, 0xedu, +}; +#else /* actBN_BYTES_PER_DIGIT */ +# error "Value of actBN_BYTES_PER_DIGIT is not supported" +#endif /* actBN_BYTES_PER_DIGIT */ +/* NIST_SEC_p224r1 END *********************************************************************************************/ + +/* NIST_ANSI_SEC_p256r1 START *********************************************************************************************/ +/* NISTp256r1 = ANSIp256r1 = SECp256r1 */ +/* The curve params in shorthand notation: + * Name: "NISTp256r1", + * p: "0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + * a: "0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + * b: "0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + * Gx: "0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + * Gy: "0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + * n: "0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + * h: "0x1", + */ + +#if (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain[227] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xe0u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x2cu, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x21u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, + /* SEQUENCE */ + 0x30u, 0x44u, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x20u, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x20u, 0x5au, 0xc6u, 0x35u, 0xd8u, 0xaau, 0x3au, 0x93u, 0xe7u, 0xb3u, 0xebu, 0xbdu, 0x55u, 0x76u, 0x98u, 0x86u, 0xbcu, 0x65u, 0x1du, 0x06u, 0xb0u, 0xccu, 0x53u, 0xb0u, 0xf6u, 0x3bu, 0xceu, 0x3cu, 0x3eu, 0x27u, 0xd2u, 0x60u, 0x4bu, + /* G (basepoint of the curve) */ + 0x04u, 0x41u, 0x04u, 0x6bu, 0x17u, 0xd1u, 0xf2u, 0xe1u, 0x2cu, 0x42u, 0x47u, 0xf8u, 0xbcu, 0xe6u, 0xe5u, 0x63u, 0xa4u, 0x40u, 0xf2u, 0x77u, 0x03u, 0x7du, 0x81u, 0x2du, 0xebu, 0x33u, 0xa0u, 0xf4u, 0xa1u, 0x39u, 0x45u, 0xd8u, 0x98u, 0xc2u, 0x96u, 0x4fu, 0xe3u, 0x42u, 0xe2u, 0xfeu, 0x1au, 0x7fu, 0x9bu, 0x8eu, 0xe7u, 0xebu, 0x4au, 0x7cu, 0x0fu, 0x9eu, 0x16u, 0x2bu, 0xceu, 0x33u, 0x57u, 0x6bu, 0x31u, 0x5eu, 0xceu, 0xcbu, 0xb6u, 0x40u, 0x68u, 0x37u, 0xbfu, 0x51u, 0xf5u, + /* n (order of G) */ + 0x02u, 0x21u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xbcu, 0xe6u, 0xfau, 0xadu, 0xa7u, 0x17u, 0x9eu, 0x84u, 0xf3u, 0xb9u, 0xcau, 0xc2u, 0xfcu, 0x63u, 0x25u, 0x51u, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt[219] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xd8u, + /* SEQUENCE */ + 0x30u, 0x81u, 0xaeu, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x20u, 0x00u, 0x00u, 0x00u, 0x04u, 0xffu, 0xffu, 0xffu, 0xfdu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xfbu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x44u, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x20u, 0xffu, 0xffu, 0xffu, 0xfcu, 0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x20u, 0xdcu, 0x30u, 0x06u, 0x1du, 0x04u, 0x87u, 0x48u, 0x34u, 0xe5u, 0xa2u, 0x20u, 0xabu, 0xf7u, 0x21u, 0x2eu, 0xd6u, 0xacu, 0xf0u, 0x05u, 0xcdu, 0x78u, 0x84u, 0x30u, 0x90u, 0xd8u, 0x9cu, 0xdfu, 0x62u, 0x29u, 0xc4u, 0xbdu, 0xdfu, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x41u, 0x04u, 0x18u, 0x90u, 0x5fu, 0x76u, 0xa5u, 0x37u, 0x55u, 0xc6u, 0x79u, 0xfbu, 0x73u, 0x2bu, 0x77u, 0x62u, 0x25u, 0x10u, 0x75u, 0xbau, 0x95u, 0xfcu, 0x5fu, 0xedu, 0xb6u, 0x01u, 0x79u, 0xe7u, 0x30u, 0xd4u, 0x18u, 0xa9u, 0x14u, 0x3cu, 0x85u, 0x71u, 0xffu, 0x18u, 0x25u, 0x88u, 0x5du, 0x85u, 0xd2u, 0xe8u, 0x86u, 0x88u, 0xddu, 0x21u, 0xf3u, 0x25u, 0x8bu, 0x4au, 0xb8u, 0xe4u, 0xbau, 0x19u, 0xe4u, 0x5cu, 0xddu, 0xf2u, 0x53u, 0x57u, 0xceu, 0x95u, 0x56u, 0x0au, + /* SEQUENCE */ + 0x30u, 0x25u, + /* n_RR (R^2 in order field) */ + 0x04u, 0x20u, 0x66u, 0xe1u, 0x2du, 0x94u, 0xf3u, 0xd9u, 0x56u, 0x20u, 0x28u, 0x45u, 0xb2u, 0x39u, 0x2bu, 0x6bu, 0xecu, 0x59u, 0x46u, 0x99u, 0x79u, 0x9cu, 0x49u, 0xbdu, 0x6fu, 0xa6u, 0x83u, 0x24u, 0x4cu, 0x95u, 0xbeu, 0x79u, 0xeeu, 0xa2u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x01u, 0x4fu, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt[547] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x02u, 0x1fu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x02u, 0x18u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0xf6u, 0xbbu, 0x32u, 0xe4u, 0x3du, 0xcfu, 0x3au, 0x3bu, 0x73u, 0x22u, 0x05u, 0x03u, 0x8du, 0x14u, 0x90u, 0xd9u, 0xaau, 0x6au, 0xe3u, 0xc1u, 0xa4u, 0x33u, 0x82u, 0x7du, 0x85u, 0x00u, 0x46u, 0xd4u, 0x10u, 0xddu, 0xd6u, 0x4du, 0x78u, 0xc5u, 0x77u, 0x51u, 0x0au, 0x5bu, 0x8au, 0x3bu, 0x19u, 0xa8u, 0xfbu, 0x0eu, 0x92u, 0x04u, 0x2du, 0xbeu, 0x15u, 0x2cu, 0xd7u, 0xcbu, 0xebu, 0x23u, 0x6fu, 0xf8u, 0x2fu, 0x36u, 0x48u, 0xd3u, 0x61u, 0xbeu, 0xe1u, 0xa5u, + /* (2^86 + 1) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0xdau, 0x59u, 0xadu, 0x0du, 0xc7u, 0x0du, 0xedu, 0xbcu, 0x33u, 0x6bu, 0xccu, 0x89u, 0x6fu, 0x1fu, 0xcau, 0x13u, 0x1fu, 0x08u, 0x80u, 0xb0u, 0xe1u, 0xf4u, 0xe3u, 0x02u, 0x46u, 0x15u, 0xd9u, 0x12u, 0xc1u, 0xd8u, 0x5fu, 0x12u, 0x2au, 0xefu, 0xd9u, 0x5au, 0xddu, 0xc8u, 0x4fu, 0x79u, 0xa3u, 0xb1u, 0xc2u, 0xf2u, 0x60u, 0x32u, 0x1bu, 0xbbu, 0xbau, 0xedu, 0x81u, 0xcdu, 0xf4u, 0x99u, 0x0cu, 0xfdu, 0x38u, 0x97u, 0xefu, 0xaeu, 0xb0u, 0xf6u, 0x2eu, 0xceu, + /* (2^86 + 2) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x15u, 0xfdu, 0x84u, 0x55u, 0x0fu, 0x1cu, 0x86u, 0x84u, 0x57u, 0x5fu, 0xccu, 0x49u, 0x01u, 0x57u, 0xf2u, 0xadu, 0x6cu, 0x12u, 0xfau, 0xa9u, 0xfau, 0xf7u, 0x90u, 0xe8u, 0x63u, 0x36u, 0xffu, 0x57u, 0xbau, 0xf5u, 0x98u, 0x07u, 0x70u, 0xaau, 0x92u, 0xc6u, 0xdau, 0x2bu, 0x23u, 0x7cu, 0xd0u, 0xb6u, 0x16u, 0xcau, 0x6fu, 0x5eu, 0x49u, 0x06u, 0xd4u, 0x73u, 0xffu, 0x4eu, 0x67u, 0x6cu, 0x6cu, 0x11u, 0x94u, 0x4fu, 0x97u, 0x01u, 0xe2u, 0x2cu, 0xd1u, 0x70u, + /* (2^172 + 1) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x73u, 0xa6u, 0x37u, 0x95u, 0x2fu, 0x83u, 0x7fu, 0x32u, 0x36u, 0x06u, 0x82u, 0xc0u, 0xe4u, 0x0eu, 0x81u, 0x25u, 0xecu, 0xfdu, 0xb3u, 0xa2u, 0x98u, 0x9au, 0x01u, 0x82u, 0x21u, 0xe0u, 0x7fu, 0x9au, 0xbcu, 0x0au, 0x70u, 0xc0u, 0xb7u, 0x1eu, 0xf4u, 0xefu, 0x34u, 0xe2u, 0x2au, 0xb1u, 0xf9u, 0x35u, 0x21u, 0x23u, 0xafu, 0x3du, 0x5du, 0x7eu, 0xefu, 0xb9u, 0x7fu, 0xecu, 0xebu, 0xf4u, 0xc7u, 0xa5u, 0xf4u, 0xebu, 0x8cu, 0xefu, 0x9cu, 0x0du, 0x32u, 0x6bu, + /* (2^172 + 2) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x04u, 0x51u, 0x20u, 0x9du, 0x10u, 0x44u, 0xf3u, 0xfeu, 0x9bu, 0x45u, 0x74u, 0xb0u, 0x53u, 0x96u, 0x9bu, 0xccu, 0x6fu, 0xb2u, 0x38u, 0xc2u, 0xd5u, 0xe1u, 0xe9u, 0x0eu, 0x60u, 0x2du, 0x9bu, 0x54u, 0x9du, 0x20u, 0xb7u, 0x33u, 0x8bu, 0x61u, 0x9bu, 0xe0u, 0x6cu, 0xb0u, 0xf9u, 0x64u, 0x96u, 0xa4u, 0x69u, 0xf4u, 0x99u, 0xe2u, 0x5fu, 0xfeu, 0x52u, 0x2cu, 0xb3u, 0x5cu, 0x96u, 0x7bu, 0x2bu, 0x08u, 0x7eu, 0x95u, 0x17u, 0xbbu, 0x66u, 0xddu, 0x6bu, 0xcfu, + /* (2^172 + 2^86 + 1) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x19u, 0x29u, 0xcfu, 0x60u, 0x6du, 0x8eu, 0x17u, 0x6fu, 0x2eu, 0xd8u, 0x08u, 0x5au, 0x69u, 0x55u, 0xc2u, 0x90u, 0x00u, 0x0fu, 0xc8u, 0xd4u, 0x84u, 0x1bu, 0xe9u, 0xedu, 0x8fu, 0x2eu, 0xacu, 0xfeu, 0x49u, 0x38u, 0x89u, 0x95u, 0x68u, 0xfeu, 0x61u, 0x07u, 0x8fu, 0x61u, 0x83u, 0x2bu, 0x13u, 0xa8u, 0x1bu, 0x95u, 0xb2u, 0x6cu, 0x6eu, 0x05u, 0x58u, 0xd7u, 0x67u, 0xadu, 0x6cu, 0xb6u, 0x26u, 0xcdu, 0x2eu, 0xfdu, 0x26u, 0xa5u, 0xfdu, 0x1au, 0x09u, 0xdbu, + /* (2^172 + 2^86 + 2) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0xa2u, 0x13u, 0xc8u, 0x07u, 0xfdu, 0x95u, 0x8bu, 0xe4u, 0xbcu, 0x98u, 0x2cu, 0x36u, 0xe9u, 0x4du, 0xd3u, 0xc1u, 0xaeu, 0x8bu, 0x32u, 0x58u, 0x92u, 0x91u, 0x14u, 0xc8u, 0xe4u, 0x5au, 0x10u, 0xbdu, 0xc1u, 0xe0u, 0x67u, 0x8bu, 0xeau, 0x8du, 0x82u, 0x90u, 0xbau, 0xabu, 0x01u, 0x1bu, 0x40u, 0xdfu, 0x78u, 0xe0u, 0x60u, 0xf5u, 0xa0u, 0x6bu, 0x9eu, 0x99u, 0xe5u, 0x43u, 0x5eu, 0xdeu, 0x80u, 0xaeu, 0xc2u, 0x68u, 0x3du, 0xffu, 0xdau, 0xa2u, 0xccu, 0xa7u, + /* correction point D = - ((2^86 - 1) * G) in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x7au, 0x22u, 0xebu, 0xe8u, 0x23u, 0x5bu, 0xdeu, 0x3bu, 0x6du, 0xfeu, 0x83u, 0xfdu, 0x1bu, 0x62u, 0xe3u, 0xcdu, 0x01u, 0x94u, 0x9au, 0x18u, 0xbau, 0x87u, 0x5fu, 0x3cu, 0x0au, 0x36u, 0xc1u, 0xc7u, 0xbfu, 0x34u, 0x15u, 0x09u, 0x23u, 0xc3u, 0xa9u, 0xc1u, 0x49u, 0x0du, 0x76u, 0xe8u, 0x0au, 0x8eu, 0x84u, 0x2au, 0x66u, 0xa6u, 0x30u, 0x19u, 0x0fu, 0x48u, 0x18u, 0xb6u, 0x72u, 0xcau, 0xfbu, 0x8au, 0x69u, 0x7du, 0x55u, 0xe5u, 0x85u, 0x60u, 0x37u, 0x65u, +}; + +#elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain[227] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xe0u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x2cu, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x21u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, + /* SEQUENCE */ + 0x30u, 0x44u, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x20u, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x20u, 0x5au, 0xc6u, 0x35u, 0xd8u, 0xaau, 0x3au, 0x93u, 0xe7u, 0xb3u, 0xebu, 0xbdu, 0x55u, 0x76u, 0x98u, 0x86u, 0xbcu, 0x65u, 0x1du, 0x06u, 0xb0u, 0xccu, 0x53u, 0xb0u, 0xf6u, 0x3bu, 0xceu, 0x3cu, 0x3eu, 0x27u, 0xd2u, 0x60u, 0x4bu, + /* G (basepoint of the curve) */ + 0x04u, 0x41u, 0x04u, 0x6bu, 0x17u, 0xd1u, 0xf2u, 0xe1u, 0x2cu, 0x42u, 0x47u, 0xf8u, 0xbcu, 0xe6u, 0xe5u, 0x63u, 0xa4u, 0x40u, 0xf2u, 0x77u, 0x03u, 0x7du, 0x81u, 0x2du, 0xebu, 0x33u, 0xa0u, 0xf4u, 0xa1u, 0x39u, 0x45u, 0xd8u, 0x98u, 0xc2u, 0x96u, 0x4fu, 0xe3u, 0x42u, 0xe2u, 0xfeu, 0x1au, 0x7fu, 0x9bu, 0x8eu, 0xe7u, 0xebu, 0x4au, 0x7cu, 0x0fu, 0x9eu, 0x16u, 0x2bu, 0xceu, 0x33u, 0x57u, 0x6bu, 0x31u, 0x5eu, 0xceu, 0xcbu, 0xb6u, 0x40u, 0x68u, 0x37u, 0xbfu, 0x51u, 0xf5u, + /* n (order of G) */ + 0x02u, 0x21u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xbcu, 0xe6u, 0xfau, 0xadu, 0xa7u, 0x17u, 0x9eu, 0x84u, 0xf3u, 0xb9u, 0xcau, 0xc2u, 0xfcu, 0x63u, 0x25u, 0x51u, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt[221] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xdau, + /* SEQUENCE */ + 0x30u, 0x81u, 0xafu, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x20u, 0x00u, 0x00u, 0x00u, 0x04u, 0xffu, 0xffu, 0xffu, 0xfdu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xfbu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x02u, 0x00u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x44u, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x20u, 0xffu, 0xffu, 0xffu, 0xfcu, 0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x20u, 0xdcu, 0x30u, 0x06u, 0x1du, 0x04u, 0x87u, 0x48u, 0x34u, 0xe5u, 0xa2u, 0x20u, 0xabu, 0xf7u, 0x21u, 0x2eu, 0xd6u, 0xacu, 0xf0u, 0x05u, 0xcdu, 0x78u, 0x84u, 0x30u, 0x90u, 0xd8u, 0x9cu, 0xdfu, 0x62u, 0x29u, 0xc4u, 0xbdu, 0xdfu, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x41u, 0x04u, 0x18u, 0x90u, 0x5fu, 0x76u, 0xa5u, 0x37u, 0x55u, 0xc6u, 0x79u, 0xfbu, 0x73u, 0x2bu, 0x77u, 0x62u, 0x25u, 0x10u, 0x75u, 0xbau, 0x95u, 0xfcu, 0x5fu, 0xedu, 0xb6u, 0x01u, 0x79u, 0xe7u, 0x30u, 0xd4u, 0x18u, 0xa9u, 0x14u, 0x3cu, 0x85u, 0x71u, 0xffu, 0x18u, 0x25u, 0x88u, 0x5du, 0x85u, 0xd2u, 0xe8u, 0x86u, 0x88u, 0xddu, 0x21u, 0xf3u, 0x25u, 0x8bu, 0x4au, 0xb8u, 0xe4u, 0xbau, 0x19u, 0xe4u, 0x5cu, 0xddu, 0xf2u, 0x53u, 0x57u, 0xceu, 0x95u, 0x56u, 0x0au, + /* SEQUENCE */ + 0x30u, 0x26u, + /* n_RR (R^2 in order field) */ + 0x04u, 0x20u, 0x66u, 0xe1u, 0x2du, 0x94u, 0xf3u, 0xd9u, 0x56u, 0x20u, 0x28u, 0x45u, 0xb2u, 0x39u, 0x2bu, 0x6bu, 0xecu, 0x59u, 0x46u, 0x99u, 0x79u, 0x9cu, 0x49u, 0xbdu, 0x6fu, 0xa6u, 0x83u, 0x24u, 0x4cu, 0x95u, 0xbeu, 0x79u, 0xeeu, 0xa2u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x02u, 0xbcu, 0x4fu, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt[547] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x02u, 0x1fu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x02u, 0x18u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0xf6u, 0xbbu, 0x32u, 0xe4u, 0x3du, 0xcfu, 0x3au, 0x3bu, 0x73u, 0x22u, 0x05u, 0x03u, 0x8du, 0x14u, 0x90u, 0xd9u, 0xaau, 0x6au, 0xe3u, 0xc1u, 0xa4u, 0x33u, 0x82u, 0x7du, 0x85u, 0x00u, 0x46u, 0xd4u, 0x10u, 0xddu, 0xd6u, 0x4du, 0x78u, 0xc5u, 0x77u, 0x51u, 0x0au, 0x5bu, 0x8au, 0x3bu, 0x19u, 0xa8u, 0xfbu, 0x0eu, 0x92u, 0x04u, 0x2du, 0xbeu, 0x15u, 0x2cu, 0xd7u, 0xcbu, 0xebu, 0x23u, 0x6fu, 0xf8u, 0x2fu, 0x36u, 0x48u, 0xd3u, 0x61u, 0xbeu, 0xe1u, 0xa5u, + /* (2^86 + 1) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0xdau, 0x59u, 0xadu, 0x0du, 0xc7u, 0x0du, 0xedu, 0xbcu, 0x33u, 0x6bu, 0xccu, 0x89u, 0x6fu, 0x1fu, 0xcau, 0x13u, 0x1fu, 0x08u, 0x80u, 0xb0u, 0xe1u, 0xf4u, 0xe3u, 0x02u, 0x46u, 0x15u, 0xd9u, 0x12u, 0xc1u, 0xd8u, 0x5fu, 0x12u, 0x2au, 0xefu, 0xd9u, 0x5au, 0xddu, 0xc8u, 0x4fu, 0x79u, 0xa3u, 0xb1u, 0xc2u, 0xf2u, 0x60u, 0x32u, 0x1bu, 0xbbu, 0xbau, 0xedu, 0x81u, 0xcdu, 0xf4u, 0x99u, 0x0cu, 0xfdu, 0x38u, 0x97u, 0xefu, 0xaeu, 0xb0u, 0xf6u, 0x2eu, 0xceu, + /* (2^86 + 2) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x15u, 0xfdu, 0x84u, 0x55u, 0x0fu, 0x1cu, 0x86u, 0x84u, 0x57u, 0x5fu, 0xccu, 0x49u, 0x01u, 0x57u, 0xf2u, 0xadu, 0x6cu, 0x12u, 0xfau, 0xa9u, 0xfau, 0xf7u, 0x90u, 0xe8u, 0x63u, 0x36u, 0xffu, 0x57u, 0xbau, 0xf5u, 0x98u, 0x07u, 0x70u, 0xaau, 0x92u, 0xc6u, 0xdau, 0x2bu, 0x23u, 0x7cu, 0xd0u, 0xb6u, 0x16u, 0xcau, 0x6fu, 0x5eu, 0x49u, 0x06u, 0xd4u, 0x73u, 0xffu, 0x4eu, 0x67u, 0x6cu, 0x6cu, 0x11u, 0x94u, 0x4fu, 0x97u, 0x01u, 0xe2u, 0x2cu, 0xd1u, 0x70u, + /* (2^172 + 1) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x73u, 0xa6u, 0x37u, 0x95u, 0x2fu, 0x83u, 0x7fu, 0x32u, 0x36u, 0x06u, 0x82u, 0xc0u, 0xe4u, 0x0eu, 0x81u, 0x25u, 0xecu, 0xfdu, 0xb3u, 0xa2u, 0x98u, 0x9au, 0x01u, 0x82u, 0x21u, 0xe0u, 0x7fu, 0x9au, 0xbcu, 0x0au, 0x70u, 0xc0u, 0xb7u, 0x1eu, 0xf4u, 0xefu, 0x34u, 0xe2u, 0x2au, 0xb1u, 0xf9u, 0x35u, 0x21u, 0x23u, 0xafu, 0x3du, 0x5du, 0x7eu, 0xefu, 0xb9u, 0x7fu, 0xecu, 0xebu, 0xf4u, 0xc7u, 0xa5u, 0xf4u, 0xebu, 0x8cu, 0xefu, 0x9cu, 0x0du, 0x32u, 0x6bu, + /* (2^172 + 2) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x04u, 0x51u, 0x20u, 0x9du, 0x10u, 0x44u, 0xf3u, 0xfeu, 0x9bu, 0x45u, 0x74u, 0xb0u, 0x53u, 0x96u, 0x9bu, 0xccu, 0x6fu, 0xb2u, 0x38u, 0xc2u, 0xd5u, 0xe1u, 0xe9u, 0x0eu, 0x60u, 0x2du, 0x9bu, 0x54u, 0x9du, 0x20u, 0xb7u, 0x33u, 0x8bu, 0x61u, 0x9bu, 0xe0u, 0x6cu, 0xb0u, 0xf9u, 0x64u, 0x96u, 0xa4u, 0x69u, 0xf4u, 0x99u, 0xe2u, 0x5fu, 0xfeu, 0x52u, 0x2cu, 0xb3u, 0x5cu, 0x96u, 0x7bu, 0x2bu, 0x08u, 0x7eu, 0x95u, 0x17u, 0xbbu, 0x66u, 0xddu, 0x6bu, 0xcfu, + /* (2^172 + 2^86 + 1) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x19u, 0x29u, 0xcfu, 0x60u, 0x6du, 0x8eu, 0x17u, 0x6fu, 0x2eu, 0xd8u, 0x08u, 0x5au, 0x69u, 0x55u, 0xc2u, 0x90u, 0x00u, 0x0fu, 0xc8u, 0xd4u, 0x84u, 0x1bu, 0xe9u, 0xedu, 0x8fu, 0x2eu, 0xacu, 0xfeu, 0x49u, 0x38u, 0x89u, 0x95u, 0x68u, 0xfeu, 0x61u, 0x07u, 0x8fu, 0x61u, 0x83u, 0x2bu, 0x13u, 0xa8u, 0x1bu, 0x95u, 0xb2u, 0x6cu, 0x6eu, 0x05u, 0x58u, 0xd7u, 0x67u, 0xadu, 0x6cu, 0xb6u, 0x26u, 0xcdu, 0x2eu, 0xfdu, 0x26u, 0xa5u, 0xfdu, 0x1au, 0x09u, 0xdbu, + /* (2^172 + 2^86 + 2) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0xa2u, 0x13u, 0xc8u, 0x07u, 0xfdu, 0x95u, 0x8bu, 0xe4u, 0xbcu, 0x98u, 0x2cu, 0x36u, 0xe9u, 0x4du, 0xd3u, 0xc1u, 0xaeu, 0x8bu, 0x32u, 0x58u, 0x92u, 0x91u, 0x14u, 0xc8u, 0xe4u, 0x5au, 0x10u, 0xbdu, 0xc1u, 0xe0u, 0x67u, 0x8bu, 0xeau, 0x8du, 0x82u, 0x90u, 0xbau, 0xabu, 0x01u, 0x1bu, 0x40u, 0xdfu, 0x78u, 0xe0u, 0x60u, 0xf5u, 0xa0u, 0x6bu, 0x9eu, 0x99u, 0xe5u, 0x43u, 0x5eu, 0xdeu, 0x80u, 0xaeu, 0xc2u, 0x68u, 0x3du, 0xffu, 0xdau, 0xa2u, 0xccu, 0xa7u, + /* correction point D = - ((2^86 - 1) * G) in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x7au, 0x22u, 0xebu, 0xe8u, 0x23u, 0x5bu, 0xdeu, 0x3bu, 0x6du, 0xfeu, 0x83u, 0xfdu, 0x1bu, 0x62u, 0xe3u, 0xcdu, 0x01u, 0x94u, 0x9au, 0x18u, 0xbau, 0x87u, 0x5fu, 0x3cu, 0x0au, 0x36u, 0xc1u, 0xc7u, 0xbfu, 0x34u, 0x15u, 0x09u, 0x23u, 0xc3u, 0xa9u, 0xc1u, 0x49u, 0x0du, 0x76u, 0xe8u, 0x0au, 0x8eu, 0x84u, 0x2au, 0x66u, 0xa6u, 0x30u, 0x19u, 0x0fu, 0x48u, 0x18u, 0xb6u, 0x72u, 0xcau, 0xfbu, 0x8au, 0x69u, 0x7du, 0x55u, 0xe5u, 0x85u, 0x60u, 0x37u, 0x65u, +}; + +#elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain[227] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xe0u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x2cu, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x21u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, + /* SEQUENCE */ + 0x30u, 0x44u, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x20u, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x20u, 0x5au, 0xc6u, 0x35u, 0xd8u, 0xaau, 0x3au, 0x93u, 0xe7u, 0xb3u, 0xebu, 0xbdu, 0x55u, 0x76u, 0x98u, 0x86u, 0xbcu, 0x65u, 0x1du, 0x06u, 0xb0u, 0xccu, 0x53u, 0xb0u, 0xf6u, 0x3bu, 0xceu, 0x3cu, 0x3eu, 0x27u, 0xd2u, 0x60u, 0x4bu, + /* G (basepoint of the curve) */ + 0x04u, 0x41u, 0x04u, 0x6bu, 0x17u, 0xd1u, 0xf2u, 0xe1u, 0x2cu, 0x42u, 0x47u, 0xf8u, 0xbcu, 0xe6u, 0xe5u, 0x63u, 0xa4u, 0x40u, 0xf2u, 0x77u, 0x03u, 0x7du, 0x81u, 0x2du, 0xebu, 0x33u, 0xa0u, 0xf4u, 0xa1u, 0x39u, 0x45u, 0xd8u, 0x98u, 0xc2u, 0x96u, 0x4fu, 0xe3u, 0x42u, 0xe2u, 0xfeu, 0x1au, 0x7fu, 0x9bu, 0x8eu, 0xe7u, 0xebu, 0x4au, 0x7cu, 0x0fu, 0x9eu, 0x16u, 0x2bu, 0xceu, 0x33u, 0x57u, 0x6bu, 0x31u, 0x5eu, 0xceu, 0xcbu, 0xb6u, 0x40u, 0x68u, 0x37u, 0xbfu, 0x51u, 0xf5u, + /* n (order of G) */ + 0x02u, 0x21u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xbcu, 0xe6u, 0xfau, 0xadu, 0xa7u, 0x17u, 0x9eu, 0x84u, 0xf3u, 0xb9u, 0xcau, 0xc2u, 0xfcu, 0x63u, 0x25u, 0x51u, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt[225] = { + /* SEQUENCE */ + 0x30u, 0x81u, 0xdeu, + /* SEQUENCE */ + 0x30u, 0x81u, 0xb1u, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x20u, 0x00u, 0x00u, 0x00u, 0x04u, 0xffu, 0xffu, 0xffu, 0xfdu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xfbu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x04u, 0x00u, 0x00u, 0x00u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x44u, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x20u, 0xffu, 0xffu, 0xffu, 0xfcu, 0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x20u, 0xdcu, 0x30u, 0x06u, 0x1du, 0x04u, 0x87u, 0x48u, 0x34u, 0xe5u, 0xa2u, 0x20u, 0xabu, 0xf7u, 0x21u, 0x2eu, 0xd6u, 0xacu, 0xf0u, 0x05u, 0xcdu, 0x78u, 0x84u, 0x30u, 0x90u, 0xd8u, 0x9cu, 0xdfu, 0x62u, 0x29u, 0xc4u, 0xbdu, 0xdfu, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x41u, 0x04u, 0x18u, 0x90u, 0x5fu, 0x76u, 0xa5u, 0x37u, 0x55u, 0xc6u, 0x79u, 0xfbu, 0x73u, 0x2bu, 0x77u, 0x62u, 0x25u, 0x10u, 0x75u, 0xbau, 0x95u, 0xfcu, 0x5fu, 0xedu, 0xb6u, 0x01u, 0x79u, 0xe7u, 0x30u, 0xd4u, 0x18u, 0xa9u, 0x14u, 0x3cu, 0x85u, 0x71u, 0xffu, 0x18u, 0x25u, 0x88u, 0x5du, 0x85u, 0xd2u, 0xe8u, 0x86u, 0x88u, 0xddu, 0x21u, 0xf3u, 0x25u, 0x8bu, 0x4au, 0xb8u, 0xe4u, 0xbau, 0x19u, 0xe4u, 0x5cu, 0xddu, 0xf2u, 0x53u, 0x57u, 0xceu, 0x95u, 0x56u, 0x0au, + /* SEQUENCE */ + 0x30u, 0x28u, + /* n_RR (R^2 in order field) */ + 0x04u, 0x20u, 0x66u, 0xe1u, 0x2du, 0x94u, 0xf3u, 0xd9u, 0x56u, 0x20u, 0x28u, 0x45u, 0xb2u, 0x39u, 0x2bu, 0x6bu, 0xecu, 0x59u, 0x46u, 0x99u, 0x79u, 0x9cu, 0x49u, 0xbdu, 0x6fu, 0xa6u, 0x83u, 0x24u, 0x4cu, 0x95u, 0xbeu, 0x79u, 0xeeu, 0xa2u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x04u, 0xeeu, 0x00u, 0xbcu, 0x4fu, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt[547] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x02u, 0x1fu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x02u, 0x18u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0xf6u, 0xbbu, 0x32u, 0xe4u, 0x3du, 0xcfu, 0x3au, 0x3bu, 0x73u, 0x22u, 0x05u, 0x03u, 0x8du, 0x14u, 0x90u, 0xd9u, 0xaau, 0x6au, 0xe3u, 0xc1u, 0xa4u, 0x33u, 0x82u, 0x7du, 0x85u, 0x00u, 0x46u, 0xd4u, 0x10u, 0xddu, 0xd6u, 0x4du, 0x78u, 0xc5u, 0x77u, 0x51u, 0x0au, 0x5bu, 0x8au, 0x3bu, 0x19u, 0xa8u, 0xfbu, 0x0eu, 0x92u, 0x04u, 0x2du, 0xbeu, 0x15u, 0x2cu, 0xd7u, 0xcbu, 0xebu, 0x23u, 0x6fu, 0xf8u, 0x2fu, 0x36u, 0x48u, 0xd3u, 0x61u, 0xbeu, 0xe1u, 0xa5u, + /* (2^86 + 1) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0xdau, 0x59u, 0xadu, 0x0du, 0xc7u, 0x0du, 0xedu, 0xbcu, 0x33u, 0x6bu, 0xccu, 0x89u, 0x6fu, 0x1fu, 0xcau, 0x13u, 0x1fu, 0x08u, 0x80u, 0xb0u, 0xe1u, 0xf4u, 0xe3u, 0x02u, 0x46u, 0x15u, 0xd9u, 0x12u, 0xc1u, 0xd8u, 0x5fu, 0x12u, 0x2au, 0xefu, 0xd9u, 0x5au, 0xddu, 0xc8u, 0x4fu, 0x79u, 0xa3u, 0xb1u, 0xc2u, 0xf2u, 0x60u, 0x32u, 0x1bu, 0xbbu, 0xbau, 0xedu, 0x81u, 0xcdu, 0xf4u, 0x99u, 0x0cu, 0xfdu, 0x38u, 0x97u, 0xefu, 0xaeu, 0xb0u, 0xf6u, 0x2eu, 0xceu, + /* (2^86 + 2) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x15u, 0xfdu, 0x84u, 0x55u, 0x0fu, 0x1cu, 0x86u, 0x84u, 0x57u, 0x5fu, 0xccu, 0x49u, 0x01u, 0x57u, 0xf2u, 0xadu, 0x6cu, 0x12u, 0xfau, 0xa9u, 0xfau, 0xf7u, 0x90u, 0xe8u, 0x63u, 0x36u, 0xffu, 0x57u, 0xbau, 0xf5u, 0x98u, 0x07u, 0x70u, 0xaau, 0x92u, 0xc6u, 0xdau, 0x2bu, 0x23u, 0x7cu, 0xd0u, 0xb6u, 0x16u, 0xcau, 0x6fu, 0x5eu, 0x49u, 0x06u, 0xd4u, 0x73u, 0xffu, 0x4eu, 0x67u, 0x6cu, 0x6cu, 0x11u, 0x94u, 0x4fu, 0x97u, 0x01u, 0xe2u, 0x2cu, 0xd1u, 0x70u, + /* (2^172 + 1) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x73u, 0xa6u, 0x37u, 0x95u, 0x2fu, 0x83u, 0x7fu, 0x32u, 0x36u, 0x06u, 0x82u, 0xc0u, 0xe4u, 0x0eu, 0x81u, 0x25u, 0xecu, 0xfdu, 0xb3u, 0xa2u, 0x98u, 0x9au, 0x01u, 0x82u, 0x21u, 0xe0u, 0x7fu, 0x9au, 0xbcu, 0x0au, 0x70u, 0xc0u, 0xb7u, 0x1eu, 0xf4u, 0xefu, 0x34u, 0xe2u, 0x2au, 0xb1u, 0xf9u, 0x35u, 0x21u, 0x23u, 0xafu, 0x3du, 0x5du, 0x7eu, 0xefu, 0xb9u, 0x7fu, 0xecu, 0xebu, 0xf4u, 0xc7u, 0xa5u, 0xf4u, 0xebu, 0x8cu, 0xefu, 0x9cu, 0x0du, 0x32u, 0x6bu, + /* (2^172 + 2) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x04u, 0x51u, 0x20u, 0x9du, 0x10u, 0x44u, 0xf3u, 0xfeu, 0x9bu, 0x45u, 0x74u, 0xb0u, 0x53u, 0x96u, 0x9bu, 0xccu, 0x6fu, 0xb2u, 0x38u, 0xc2u, 0xd5u, 0xe1u, 0xe9u, 0x0eu, 0x60u, 0x2du, 0x9bu, 0x54u, 0x9du, 0x20u, 0xb7u, 0x33u, 0x8bu, 0x61u, 0x9bu, 0xe0u, 0x6cu, 0xb0u, 0xf9u, 0x64u, 0x96u, 0xa4u, 0x69u, 0xf4u, 0x99u, 0xe2u, 0x5fu, 0xfeu, 0x52u, 0x2cu, 0xb3u, 0x5cu, 0x96u, 0x7bu, 0x2bu, 0x08u, 0x7eu, 0x95u, 0x17u, 0xbbu, 0x66u, 0xddu, 0x6bu, 0xcfu, + /* (2^172 + 2^86 + 1) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x19u, 0x29u, 0xcfu, 0x60u, 0x6du, 0x8eu, 0x17u, 0x6fu, 0x2eu, 0xd8u, 0x08u, 0x5au, 0x69u, 0x55u, 0xc2u, 0x90u, 0x00u, 0x0fu, 0xc8u, 0xd4u, 0x84u, 0x1bu, 0xe9u, 0xedu, 0x8fu, 0x2eu, 0xacu, 0xfeu, 0x49u, 0x38u, 0x89u, 0x95u, 0x68u, 0xfeu, 0x61u, 0x07u, 0x8fu, 0x61u, 0x83u, 0x2bu, 0x13u, 0xa8u, 0x1bu, 0x95u, 0xb2u, 0x6cu, 0x6eu, 0x05u, 0x58u, 0xd7u, 0x67u, 0xadu, 0x6cu, 0xb6u, 0x26u, 0xcdu, 0x2eu, 0xfdu, 0x26u, 0xa5u, 0xfdu, 0x1au, 0x09u, 0xdbu, + /* (2^172 + 2^86 + 2) * G in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0xa2u, 0x13u, 0xc8u, 0x07u, 0xfdu, 0x95u, 0x8bu, 0xe4u, 0xbcu, 0x98u, 0x2cu, 0x36u, 0xe9u, 0x4du, 0xd3u, 0xc1u, 0xaeu, 0x8bu, 0x32u, 0x58u, 0x92u, 0x91u, 0x14u, 0xc8u, 0xe4u, 0x5au, 0x10u, 0xbdu, 0xc1u, 0xe0u, 0x67u, 0x8bu, 0xeau, 0x8du, 0x82u, 0x90u, 0xbau, 0xabu, 0x01u, 0x1bu, 0x40u, 0xdfu, 0x78u, 0xe0u, 0x60u, 0xf5u, 0xa0u, 0x6bu, 0x9eu, 0x99u, 0xe5u, 0x43u, 0x5eu, 0xdeu, 0x80u, 0xaeu, 0xc2u, 0x68u, 0x3du, 0xffu, 0xdau, 0xa2u, 0xccu, 0xa7u, + /* correction point D = - ((2^86 - 1) * G) in Montgomery representation */ + 0x04u, 0x41u, 0x04u, 0x7au, 0x22u, 0xebu, 0xe8u, 0x23u, 0x5bu, 0xdeu, 0x3bu, 0x6du, 0xfeu, 0x83u, 0xfdu, 0x1bu, 0x62u, 0xe3u, 0xcdu, 0x01u, 0x94u, 0x9au, 0x18u, 0xbau, 0x87u, 0x5fu, 0x3cu, 0x0au, 0x36u, 0xc1u, 0xc7u, 0xbfu, 0x34u, 0x15u, 0x09u, 0x23u, 0xc3u, 0xa9u, 0xc1u, 0x49u, 0x0du, 0x76u, 0xe8u, 0x0au, 0x8eu, 0x84u, 0x2au, 0x66u, 0xa6u, 0x30u, 0x19u, 0x0fu, 0x48u, 0x18u, 0xb6u, 0x72u, 0xcau, 0xfbu, 0x8au, 0x69u, 0x7du, 0x55u, 0xe5u, 0x85u, 0x60u, 0x37u, 0x65u, +}; +#else /* CRYPTO_30_LIBCV_BYTES_PER_DIGIT */ +# error "Value of CRYPTO_30_LIBCV_BYTES_PER_DIGIT is not supported" +#endif /* CRYPTO_30_LIBCV_BYTES_PER_DIGIT */ +/* NIST_ANSI_SEC_p256r1 END *********************************************************************************************/ + +/* NIST_SEC_p384r1 START *********************************************************************************************/ +/* NISTp384r1 = SECp384r1 */ +/* The curve params in shorthand notation: + * Name: NISTp384r1 + * p: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff + * a: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc + * b: 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef + * Gx: 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7 + * Gy: 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f + * n: 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973 + * h: 0x1 + */ + +#if (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1Domain[324] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x40u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x3cu, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x31u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, + /* SEQUENCE */ + 0x30u, 0x64u, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x30u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x30u, 0xb3u, 0x31u, 0x2fu, 0xa7u, 0xe2u, 0x3eu, 0xe7u, 0xe4u, 0x98u, 0x8eu, 0x05u, 0x6bu, 0xe3u, 0xf8u, 0x2du, 0x19u, 0x18u, 0x1du, 0x9cu, 0x6eu, 0xfeu, 0x81u, 0x41u, 0x12u, 0x03u, 0x14u, 0x08u, 0x8fu, 0x50u, 0x13u, 0x87u, 0x5au, 0xc6u, 0x56u, 0x39u, 0x8du, 0x8au, 0x2eu, 0xd1u, 0x9du, 0x2au, 0x85u, 0xc8u, 0xedu, 0xd3u, 0xecu, 0x2au, 0xefu, + /* G (basepoint of the curve) */ + 0x04u, 0x61u, 0x04u, 0xaau, 0x87u, 0xcau, 0x22u, 0xbeu, 0x8bu, 0x05u, 0x37u, 0x8eu, 0xb1u, 0xc7u, 0x1eu, 0xf3u, 0x20u, 0xadu, 0x74u, 0x6eu, 0x1du, 0x3bu, 0x62u, 0x8bu, 0xa7u, 0x9bu, 0x98u, 0x59u, 0xf7u, 0x41u, 0xe0u, 0x82u, 0x54u, 0x2au, 0x38u, 0x55u, 0x02u, 0xf2u, 0x5du, 0xbfu, 0x55u, 0x29u, 0x6cu, 0x3au, 0x54u, 0x5eu, 0x38u, 0x72u, 0x76u, 0x0au, 0xb7u, 0x36u, 0x17u, 0xdeu, 0x4au, 0x96u, 0x26u, 0x2cu, 0x6fu, 0x5du, 0x9eu, 0x98u, 0xbfu, 0x92u, 0x92u, 0xdcu, 0x29u, 0xf8u, 0xf4u, 0x1du, 0xbdu, 0x28u, 0x9au, 0x14u, 0x7cu, 0xe9u, 0xdau, 0x31u, 0x13u, 0xb5u, 0xf0u, 0xb8u, 0xc0u, 0x0au, 0x60u, 0xb1u, 0xceu, 0x1du, 0x7eu, 0x81u, 0x9du, 0x7au, 0x43u, 0x1du, 0x7cu, 0x90u, 0xeau, 0x0eu, 0x5fu, + /* n (order of G) */ + 0x02u, 0x31u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xc7u, 0x63u, 0x4du, 0x81u, 0xf4u, 0x37u, 0x2du, 0xdfu, 0x58u, 0x1au, 0x0du, 0xb2u, 0x48u, 0xb0u, 0xa7u, 0x7au, 0xecu, 0xecu, 0x19u, 0x6au, 0xccu, 0xc5u, 0x29u, 0x73u, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt[316] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x38u, + /* SEQUENCE */ + 0x30u, 0x81u, 0xfeu, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x30u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xfeu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xfeu, 0x00u, 0x00u, 0x00u, 0x01u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x64u, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x30u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfbu, 0xffu, 0xffu, 0xffu, 0xfcu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x30u, 0xcdu, 0x08u, 0x11u, 0x4bu, 0x60u, 0x4fu, 0xbfu, 0xf9u, 0xb6u, 0x2bu, 0x21u, 0xf4u, 0x1fu, 0x02u, 0x20u, 0x94u, 0xe3u, 0x37u, 0x4bu, 0xeeu, 0x94u, 0x93u, 0x8au, 0xe2u, 0x77u, 0xf2u, 0x20u, 0x9bu, 0x19u, 0x20u, 0x02u, 0x2eu, 0xf7u, 0x29u, 0xadu, 0xd8u, 0x7au, 0x4cu, 0x32u, 0xecu, 0x08u, 0x11u, 0x88u, 0x71u, 0x9du, 0x41u, 0x2du, 0xccu, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x61u, 0x04u, 0x4du, 0x3au, 0xadu, 0xc2u, 0x29u, 0x9eu, 0x15u, 0x13u, 0x81u, 0x2fu, 0xf7u, 0x23u, 0x61u, 0x4eu, 0xdeu, 0x2bu, 0x64u, 0x54u, 0x86u, 0x84u, 0x59u, 0xa3u, 0x0eu, 0xffu, 0x87u, 0x9cu, 0x3au, 0xfcu, 0x54u, 0x1bu, 0x4du, 0x6eu, 0x20u, 0xe3u, 0x78u, 0xe2u, 0xa0u, 0xd6u, 0xceu, 0x38u, 0x3du, 0xd0u, 0x75u, 0x66u, 0x49u, 0xc0u, 0xb5u, 0x28u, 0x2bu, 0x78u, 0xabu, 0xc2u, 0x5au, 0x15u, 0xc5u, 0xe9u, 0xddu, 0x80u, 0x02u, 0x26u, 0x39u, 0x69u, 0xa8u, 0x40u, 0xc6u, 0xc3u, 0x52u, 0x19u, 0x68u, 0xf4u, 0xffu, 0xd9u, 0x8bu, 0xadu, 0xe7u, 0x56u, 0x2eu, 0x83u, 0xb0u, 0x50u, 0xa1u, 0xbfu, 0xa8u, 0xbfu, 0x7bu, 0xb4u, 0xa9u, 0xacu, 0x23u, 0x04u, 0x3du, 0xadu, 0x4bu, 0x03u, 0xa4u, 0xfeu, + /* SEQUENCE */ + 0x30u, 0x35u, + /* n_RR (R^2 in order field) */ + 0x04u, 0x30u, 0x0cu, 0x84u, 0xeeu, 0x01u, 0x2bu, 0x39u, 0xbfu, 0x21u, 0x3fu, 0xb0u, 0x5bu, 0x7au, 0x28u, 0x26u, 0x68u, 0x95u, 0xd4u, 0x0du, 0x49u, 0x17u, 0x4au, 0xabu, 0x1cu, 0xc5u, 0xbcu, 0x3eu, 0x48u, 0x3au, 0xfcu, 0xb8u, 0x29u, 0x47u, 0xffu, 0x3du, 0x81u, 0xe5u, 0xdfu, 0x1au, 0xa4u, 0x19u, 0x2du, 0x31u, 0x9bu, 0x24u, 0x19u, 0xb4u, 0x09u, 0xa9u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x01u, 0x45u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1SpeedUpExt[803] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x03u, 0x1fu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x03u, 0x18u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xdbu, 0x93u, 0xb7u, 0x76u, 0x42u, 0x74u, 0x60u, 0xc3u, 0x9cu, 0x90u, 0xa4u, 0xfdu, 0x2du, 0xe4u, 0xb5u, 0x06u, 0xdau, 0x82u, 0x14u, 0x95u, 0xf0u, 0x68u, 0x7fu, 0x50u, 0x35u, 0x04u, 0xe6u, 0xf0u, 0xffu, 0x9du, 0x48u, 0xa1u, 0x8eu, 0x6cu, 0x8fu, 0x2eu, 0x02u, 0x2bu, 0x53u, 0xf0u, 0xc8u, 0x22u, 0x9eu, 0x55u, 0x78u, 0x3du, 0xdeu, 0x91u, 0xe3u, 0x49u, 0x47u, 0xf7u, 0x12u, 0x3du, 0xf0u, 0xc2u, 0x07u, 0x0du, 0x43u, 0x09u, 0x00u, 0xb0u, 0xe6u, 0x84u, 0x09u, 0xf1u, 0xfeu, 0x41u, 0x51u, 0x72u, 0xbau, 0xd9u, 0x15u, 0xe4u, 0xf1u, 0x8bu, 0xdcu, 0x58u, 0x82u, 0x58u, 0xe8u, 0xe8u, 0xe4u, 0xa8u, 0xc2u, 0xaau, 0xccu, 0xd8u, 0x42u, 0xeau, 0x84u, 0x63u, 0x31u, 0x40u, 0xbfu, 0xdau, + /* (2^128 + 1) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xebu, 0x65u, 0x7bu, 0x10u, 0xfdu, 0x71u, 0x1bu, 0xa4u, 0x63u, 0x7eu, 0x33u, 0x02u, 0x42u, 0xedu, 0x76u, 0x26u, 0x39u, 0x24u, 0xe5u, 0x0au, 0x74u, 0x20u, 0x40u, 0x8fu, 0xa1u, 0xe4u, 0x4bu, 0x14u, 0xdcu, 0x26u, 0x1eu, 0xc2u, 0xfeu, 0x4au, 0x36u, 0xe7u, 0xffu, 0x13u, 0x31u, 0x4eu, 0x39u, 0x4fu, 0xb8u, 0x4du, 0xe8u, 0x6eu, 0x3fu, 0x64u, 0xa9u, 0x6fu, 0xd3u, 0xb7u, 0x46u, 0x94u, 0xe1u, 0x5au, 0x5bu, 0xe4u, 0x63u, 0xa5u, 0xbeu, 0x56u, 0xf7u, 0x74u, 0x33u, 0x86u, 0xf1u, 0xc6u, 0x88u, 0x6fu, 0xb3u, 0xdbu, 0xe7u, 0x46u, 0x58u, 0x19u, 0xb0u, 0x56u, 0xd8u, 0x72u, 0x30u, 0xe0u, 0x43u, 0x26u, 0x7fu, 0x1fu, 0x42u, 0xc7u, 0xc1u, 0x6du, 0x01u, 0xc5u, 0x34u, 0x09u, 0x49u, 0xbbu, + /* (2^128 + 2) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xcbu, 0x0eu, 0xc2u, 0x40u, 0x54u, 0x40u, 0x30u, 0x0eu, 0x87u, 0xa3u, 0x41u, 0xffu, 0x26u, 0x25u, 0xc6u, 0x45u, 0x16u, 0x92u, 0x6bu, 0x63u, 0x5bu, 0xd7u, 0xe9u, 0x20u, 0x67u, 0x78u, 0xc2u, 0xf9u, 0xa0u, 0x18u, 0x43u, 0x09u, 0x53u, 0xceu, 0x5eu, 0x7eu, 0x08u, 0x3cu, 0xd6u, 0x22u, 0x0au, 0x1fu, 0x01u, 0x6du, 0xa7u, 0xa2u, 0x98u, 0x2cu, 0x74u, 0x1au, 0xc8u, 0x5fu, 0x44u, 0x17u, 0x10u, 0x90u, 0x89u, 0x5du, 0x29u, 0xaeu, 0x22u, 0x31u, 0x0au, 0x17u, 0xa0u, 0xe4u, 0xe8u, 0xc6u, 0x2du, 0x55u, 0xd9u, 0x3au, 0xc8u, 0xf3u, 0x60u, 0x28u, 0x4fu, 0x9bu, 0x94u, 0x35u, 0xdeu, 0xcbu, 0x19u, 0xb5u, 0x88u, 0x64u, 0x57u, 0xe4u, 0x58u, 0x68u, 0x21u, 0xd5u, 0xfau, 0x6du, 0xe7u, 0x19u, + /* (2^256 + 1) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0x27u, 0x1fu, 0x07u, 0x17u, 0x8fu, 0xcbu, 0x87u, 0xf1u, 0x05u, 0xbeu, 0x51u, 0xb7u, 0xbfu, 0x50u, 0x01u, 0x59u, 0xdeu, 0x1du, 0x76u, 0x17u, 0x79u, 0xfdu, 0x9cu, 0x91u, 0xadu, 0xfdu, 0x85u, 0xb0u, 0x3eu, 0xeeu, 0x3du, 0x12u, 0x05u, 0x29u, 0x17u, 0xc3u, 0x19u, 0x0eu, 0xb1u, 0x98u, 0x56u, 0x21u, 0x11u, 0x90u, 0xa3u, 0x53u, 0xe8u, 0x89u, 0x8fu, 0x8eu, 0x6eu, 0x28u, 0x9eu, 0x96u, 0xb1u, 0x5du, 0xb0u, 0xd7u, 0xa7u, 0x36u, 0x56u, 0x49u, 0x97u, 0x6eu, 0x0au, 0x22u, 0xcbu, 0xe1u, 0x06u, 0x3bu, 0x1du, 0x7fu, 0xb2u, 0x56u, 0x47u, 0x92u, 0x8fu, 0x5fu, 0xb8u, 0xc0u, 0xb1u, 0xb7u, 0x24u, 0x6eu, 0xdau, 0x12u, 0xdau, 0x8du, 0x02u, 0x67u, 0x3eu, 0x27u, 0x3au, 0x75u, 0xacu, 0x71u, + /* (2^256 + 2) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xf2u, 0x4du, 0xd6u, 0xbbu, 0xbfu, 0x42u, 0x7fu, 0x21u, 0xcdu, 0xfdu, 0xfau, 0xb5u, 0xdau, 0xc6u, 0xf6u, 0x43u, 0x3au, 0x95u, 0x5eu, 0xe9u, 0xb5u, 0x18u, 0x78u, 0x08u, 0x07u, 0xa0u, 0xf7u, 0xceu, 0xb2u, 0xa8u, 0x0du, 0xc3u, 0x29u, 0x61u, 0xf5u, 0x2bu, 0x7au, 0x4fu, 0xd5u, 0xe5u, 0x10u, 0xd5u, 0x62u, 0xf2u, 0xa6u, 0x9bu, 0xcbu, 0x2cu, 0x29u, 0x1cu, 0x6au, 0xd9u, 0x08u, 0x25u, 0x5eu, 0xb5u, 0x29u, 0x1eu, 0x34u, 0x6du, 0x78u, 0xc7u, 0x45u, 0x39u, 0x1du, 0x45u, 0x2au, 0x53u, 0xb7u, 0x99u, 0xdeu, 0x3fu, 0x43u, 0x48u, 0x17u, 0xd4u, 0x2bu, 0x0du, 0x78u, 0x68u, 0x45u, 0xe1u, 0xf8u, 0x6eu, 0x60u, 0x3au, 0x03u, 0x33u, 0x56u, 0xcau, 0xe7u, 0x8cu, 0xadu, 0x54u, 0x83u, 0x5bu, + /* (2^256 + 2^128 + 1) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xd8u, 0x86u, 0x59u, 0x88u, 0x6eu, 0xe9u, 0xa9u, 0x30u, 0x8bu, 0x73u, 0x9au, 0xd5u, 0x7cu, 0x92u, 0x77u, 0xcfu, 0xeau, 0x79u, 0xa5u, 0xf5u, 0xadu, 0x3eu, 0xd3u, 0x4fu, 0x9du, 0x18u, 0x12u, 0x68u, 0x0eu, 0x0du, 0x07u, 0xfeu, 0xb3u, 0x65u, 0x74u, 0xa8u, 0xdcu, 0xa4u, 0x20u, 0xbau, 0x25u, 0x53u, 0x9du, 0xe9u, 0x8eu, 0xceu, 0x21u, 0x8du, 0x89u, 0x76u, 0xb7u, 0x03u, 0x05u, 0xf5u, 0x11u, 0x22u, 0x3eu, 0x1au, 0x96u, 0xb1u, 0x40u, 0xc7u, 0x3au, 0x2du, 0x67u, 0xf8u, 0x64u, 0x1eu, 0x21u, 0x04u, 0x5fu, 0x63u, 0xd3u, 0x12u, 0x8fu, 0x12u, 0x97u, 0xeeu, 0x31u, 0x5eu, 0xe0u, 0x13u, 0x8cu, 0x65u, 0x08u, 0xf3u, 0x52u, 0x4fu, 0xafu, 0x07u, 0xbfu, 0xb6u, 0x21u, 0x59u, 0x1au, 0x3eu, + /* (2^256 + 2^128 + 2) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0x0du, 0xe7u, 0x0du, 0x3bu, 0x66u, 0xb9u, 0x3au, 0x52u, 0x65u, 0x4cu, 0xdau, 0xdfu, 0x52u, 0xf1u, 0x6bu, 0x74u, 0x88u, 0x86u, 0x03u, 0x4cu, 0x4cu, 0xbeu, 0x5eu, 0x85u, 0x8cu, 0x1du, 0x85u, 0x06u, 0x11u, 0x6cu, 0x4du, 0x0cu, 0xa8u, 0x73u, 0xecu, 0xbfu, 0x64u, 0x10u, 0xc9u, 0xe3u, 0x6cu, 0x2du, 0x76u, 0x2eu, 0xedu, 0xc2u, 0xe9u, 0xfcu, 0xddu, 0x97u, 0x4eu, 0x2bu, 0x20u, 0x21u, 0x36u, 0x30u, 0x0bu, 0xb0u, 0x73u, 0x97u, 0x58u, 0x9bu, 0x48u, 0x03u, 0x47u, 0x00u, 0xb8u, 0x65u, 0xcfu, 0x33u, 0x89u, 0x9fu, 0x1du, 0x05u, 0xa1u, 0xf5u, 0x0fu, 0x57u, 0x8fu, 0x57u, 0xb8u, 0x3cu, 0x56u, 0x9fu, 0x87u, 0x3fu, 0xafu, 0x2au, 0xa1u, 0xdeu, 0x0eu, 0x75u, 0x03u, 0x7au, 0x58u, 0xabu, + /* correction point D = - ((2^128 - 1) * G) in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xbbu, 0x3fu, 0x5au, 0x84u, 0x87u, 0xf9u, 0x1au, 0x36u, 0x48u, 0x28u, 0x20u, 0xd6u, 0x7fu, 0x73u, 0x36u, 0xd6u, 0xc4u, 0xeau, 0x85u, 0x36u, 0xe6u, 0x51u, 0xcau, 0xb5u, 0xc6u, 0x06u, 0xd7u, 0x47u, 0x6du, 0x24u, 0x4du, 0xa9u, 0x32u, 0x12u, 0xa5u, 0x0cu, 0x71u, 0x17u, 0x13u, 0xf4u, 0x79u, 0xc0u, 0x00u, 0xdau, 0x6fu, 0xc6u, 0xb7u, 0xeeu, 0xc7u, 0xe7u, 0x30u, 0x8cu, 0x0bu, 0x91u, 0xb3u, 0x09u, 0x6au, 0x2cu, 0x2bu, 0x3au, 0xd4u, 0xf6u, 0x83u, 0xe1u, 0x87u, 0xe5u, 0x0fu, 0x70u, 0xd1u, 0xceu, 0x0fu, 0xbfu, 0xa6u, 0x5au, 0x46u, 0x6eu, 0xb8u, 0xb0u, 0x82u, 0x52u, 0x00u, 0x33u, 0x7fu, 0xcbu, 0x6au, 0xdau, 0xc8u, 0x40u, 0xeau, 0x24u, 0x6cu, 0xfdu, 0xbdu, 0x58u, 0xc5u, 0x4cu, +}; + +#elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1Domain[324] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x40u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x3cu, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x31u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, + /* SEQUENCE */ + 0x30u, 0x64u, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x30u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x30u, 0xb3u, 0x31u, 0x2fu, 0xa7u, 0xe2u, 0x3eu, 0xe7u, 0xe4u, 0x98u, 0x8eu, 0x05u, 0x6bu, 0xe3u, 0xf8u, 0x2du, 0x19u, 0x18u, 0x1du, 0x9cu, 0x6eu, 0xfeu, 0x81u, 0x41u, 0x12u, 0x03u, 0x14u, 0x08u, 0x8fu, 0x50u, 0x13u, 0x87u, 0x5au, 0xc6u, 0x56u, 0x39u, 0x8du, 0x8au, 0x2eu, 0xd1u, 0x9du, 0x2au, 0x85u, 0xc8u, 0xedu, 0xd3u, 0xecu, 0x2au, 0xefu, + /* G (basepoint of the curve) */ + 0x04u, 0x61u, 0x04u, 0xaau, 0x87u, 0xcau, 0x22u, 0xbeu, 0x8bu, 0x05u, 0x37u, 0x8eu, 0xb1u, 0xc7u, 0x1eu, 0xf3u, 0x20u, 0xadu, 0x74u, 0x6eu, 0x1du, 0x3bu, 0x62u, 0x8bu, 0xa7u, 0x9bu, 0x98u, 0x59u, 0xf7u, 0x41u, 0xe0u, 0x82u, 0x54u, 0x2au, 0x38u, 0x55u, 0x02u, 0xf2u, 0x5du, 0xbfu, 0x55u, 0x29u, 0x6cu, 0x3au, 0x54u, 0x5eu, 0x38u, 0x72u, 0x76u, 0x0au, 0xb7u, 0x36u, 0x17u, 0xdeu, 0x4au, 0x96u, 0x26u, 0x2cu, 0x6fu, 0x5du, 0x9eu, 0x98u, 0xbfu, 0x92u, 0x92u, 0xdcu, 0x29u, 0xf8u, 0xf4u, 0x1du, 0xbdu, 0x28u, 0x9au, 0x14u, 0x7cu, 0xe9u, 0xdau, 0x31u, 0x13u, 0xb5u, 0xf0u, 0xb8u, 0xc0u, 0x0au, 0x60u, 0xb1u, 0xceu, 0x1du, 0x7eu, 0x81u, 0x9du, 0x7au, 0x43u, 0x1du, 0x7cu, 0x90u, 0xeau, 0x0eu, 0x5fu, + /* n (order of G) */ + 0x02u, 0x31u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xc7u, 0x63u, 0x4du, 0x81u, 0xf4u, 0x37u, 0x2du, 0xdfu, 0x58u, 0x1au, 0x0du, 0xb2u, 0x48u, 0xb0u, 0xa7u, 0x7au, 0xecu, 0xecu, 0x19u, 0x6au, 0xccu, 0xc5u, 0x29u, 0x73u, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt[318] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x3au, + /* SEQUENCE */ + 0x30u, 0x81u, 0xffu, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x30u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xfeu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xfeu, 0x00u, 0x00u, 0x00u, 0x01u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x02u, 0x00u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x64u, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x30u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfbu, 0xffu, 0xffu, 0xffu, 0xfcu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x30u, 0xcdu, 0x08u, 0x11u, 0x4bu, 0x60u, 0x4fu, 0xbfu, 0xf9u, 0xb6u, 0x2bu, 0x21u, 0xf4u, 0x1fu, 0x02u, 0x20u, 0x94u, 0xe3u, 0x37u, 0x4bu, 0xeeu, 0x94u, 0x93u, 0x8au, 0xe2u, 0x77u, 0xf2u, 0x20u, 0x9bu, 0x19u, 0x20u, 0x02u, 0x2eu, 0xf7u, 0x29u, 0xadu, 0xd8u, 0x7au, 0x4cu, 0x32u, 0xecu, 0x08u, 0x11u, 0x88u, 0x71u, 0x9du, 0x41u, 0x2du, 0xccu, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x61u, 0x04u, 0x4du, 0x3au, 0xadu, 0xc2u, 0x29u, 0x9eu, 0x15u, 0x13u, 0x81u, 0x2fu, 0xf7u, 0x23u, 0x61u, 0x4eu, 0xdeu, 0x2bu, 0x64u, 0x54u, 0x86u, 0x84u, 0x59u, 0xa3u, 0x0eu, 0xffu, 0x87u, 0x9cu, 0x3au, 0xfcu, 0x54u, 0x1bu, 0x4du, 0x6eu, 0x20u, 0xe3u, 0x78u, 0xe2u, 0xa0u, 0xd6u, 0xceu, 0x38u, 0x3du, 0xd0u, 0x75u, 0x66u, 0x49u, 0xc0u, 0xb5u, 0x28u, 0x2bu, 0x78u, 0xabu, 0xc2u, 0x5au, 0x15u, 0xc5u, 0xe9u, 0xddu, 0x80u, 0x02u, 0x26u, 0x39u, 0x69u, 0xa8u, 0x40u, 0xc6u, 0xc3u, 0x52u, 0x19u, 0x68u, 0xf4u, 0xffu, 0xd9u, 0x8bu, 0xadu, 0xe7u, 0x56u, 0x2eu, 0x83u, 0xb0u, 0x50u, 0xa1u, 0xbfu, 0xa8u, 0xbfu, 0x7bu, 0xb4u, 0xa9u, 0xacu, 0x23u, 0x04u, 0x3du, 0xadu, 0x4bu, 0x03u, 0xa4u, 0xfeu, + /* SEQUENCE */ + 0x30u, 0x36u, + /* n_RR (R^2 in order field) */ + 0x04u, 0x30u, 0x0cu, 0x84u, 0xeeu, 0x01u, 0x2bu, 0x39u, 0xbfu, 0x21u, 0x3fu, 0xb0u, 0x5bu, 0x7au, 0x28u, 0x26u, 0x68u, 0x95u, 0xd4u, 0x0du, 0x49u, 0x17u, 0x4au, 0xabu, 0x1cu, 0xc5u, 0xbcu, 0x3eu, 0x48u, 0x3au, 0xfcu, 0xb8u, 0x29u, 0x47u, 0xffu, 0x3du, 0x81u, 0xe5u, 0xdfu, 0x1au, 0xa4u, 0x19u, 0x2du, 0x31u, 0x9bu, 0x24u, 0x19u, 0xb4u, 0x09u, 0xa9u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x02u, 0xdcu, 0x45u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1SpeedUpExt[803] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x03u, 0x1fu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x03u, 0x18u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xdbu, 0x93u, 0xb7u, 0x76u, 0x42u, 0x74u, 0x60u, 0xc3u, 0x9cu, 0x90u, 0xa4u, 0xfdu, 0x2du, 0xe4u, 0xb5u, 0x06u, 0xdau, 0x82u, 0x14u, 0x95u, 0xf0u, 0x68u, 0x7fu, 0x50u, 0x35u, 0x04u, 0xe6u, 0xf0u, 0xffu, 0x9du, 0x48u, 0xa1u, 0x8eu, 0x6cu, 0x8fu, 0x2eu, 0x02u, 0x2bu, 0x53u, 0xf0u, 0xc8u, 0x22u, 0x9eu, 0x55u, 0x78u, 0x3du, 0xdeu, 0x91u, 0xe3u, 0x49u, 0x47u, 0xf7u, 0x12u, 0x3du, 0xf0u, 0xc2u, 0x07u, 0x0du, 0x43u, 0x09u, 0x00u, 0xb0u, 0xe6u, 0x84u, 0x09u, 0xf1u, 0xfeu, 0x41u, 0x51u, 0x72u, 0xbau, 0xd9u, 0x15u, 0xe4u, 0xf1u, 0x8bu, 0xdcu, 0x58u, 0x82u, 0x58u, 0xe8u, 0xe8u, 0xe4u, 0xa8u, 0xc2u, 0xaau, 0xccu, 0xd8u, 0x42u, 0xeau, 0x84u, 0x63u, 0x31u, 0x40u, 0xbfu, 0xdau, + /* (2^128 + 1) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xebu, 0x65u, 0x7bu, 0x10u, 0xfdu, 0x71u, 0x1bu, 0xa4u, 0x63u, 0x7eu, 0x33u, 0x02u, 0x42u, 0xedu, 0x76u, 0x26u, 0x39u, 0x24u, 0xe5u, 0x0au, 0x74u, 0x20u, 0x40u, 0x8fu, 0xa1u, 0xe4u, 0x4bu, 0x14u, 0xdcu, 0x26u, 0x1eu, 0xc2u, 0xfeu, 0x4au, 0x36u, 0xe7u, 0xffu, 0x13u, 0x31u, 0x4eu, 0x39u, 0x4fu, 0xb8u, 0x4du, 0xe8u, 0x6eu, 0x3fu, 0x64u, 0xa9u, 0x6fu, 0xd3u, 0xb7u, 0x46u, 0x94u, 0xe1u, 0x5au, 0x5bu, 0xe4u, 0x63u, 0xa5u, 0xbeu, 0x56u, 0xf7u, 0x74u, 0x33u, 0x86u, 0xf1u, 0xc6u, 0x88u, 0x6fu, 0xb3u, 0xdbu, 0xe7u, 0x46u, 0x58u, 0x19u, 0xb0u, 0x56u, 0xd8u, 0x72u, 0x30u, 0xe0u, 0x43u, 0x26u, 0x7fu, 0x1fu, 0x42u, 0xc7u, 0xc1u, 0x6du, 0x01u, 0xc5u, 0x34u, 0x09u, 0x49u, 0xbbu, + /* (2^128 + 2) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xcbu, 0x0eu, 0xc2u, 0x40u, 0x54u, 0x40u, 0x30u, 0x0eu, 0x87u, 0xa3u, 0x41u, 0xffu, 0x26u, 0x25u, 0xc6u, 0x45u, 0x16u, 0x92u, 0x6bu, 0x63u, 0x5bu, 0xd7u, 0xe9u, 0x20u, 0x67u, 0x78u, 0xc2u, 0xf9u, 0xa0u, 0x18u, 0x43u, 0x09u, 0x53u, 0xceu, 0x5eu, 0x7eu, 0x08u, 0x3cu, 0xd6u, 0x22u, 0x0au, 0x1fu, 0x01u, 0x6du, 0xa7u, 0xa2u, 0x98u, 0x2cu, 0x74u, 0x1au, 0xc8u, 0x5fu, 0x44u, 0x17u, 0x10u, 0x90u, 0x89u, 0x5du, 0x29u, 0xaeu, 0x22u, 0x31u, 0x0au, 0x17u, 0xa0u, 0xe4u, 0xe8u, 0xc6u, 0x2du, 0x55u, 0xd9u, 0x3au, 0xc8u, 0xf3u, 0x60u, 0x28u, 0x4fu, 0x9bu, 0x94u, 0x35u, 0xdeu, 0xcbu, 0x19u, 0xb5u, 0x88u, 0x64u, 0x57u, 0xe4u, 0x58u, 0x68u, 0x21u, 0xd5u, 0xfau, 0x6du, 0xe7u, 0x19u, + /* (2^256 + 1) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0x27u, 0x1fu, 0x07u, 0x17u, 0x8fu, 0xcbu, 0x87u, 0xf1u, 0x05u, 0xbeu, 0x51u, 0xb7u, 0xbfu, 0x50u, 0x01u, 0x59u, 0xdeu, 0x1du, 0x76u, 0x17u, 0x79u, 0xfdu, 0x9cu, 0x91u, 0xadu, 0xfdu, 0x85u, 0xb0u, 0x3eu, 0xeeu, 0x3du, 0x12u, 0x05u, 0x29u, 0x17u, 0xc3u, 0x19u, 0x0eu, 0xb1u, 0x98u, 0x56u, 0x21u, 0x11u, 0x90u, 0xa3u, 0x53u, 0xe8u, 0x89u, 0x8fu, 0x8eu, 0x6eu, 0x28u, 0x9eu, 0x96u, 0xb1u, 0x5du, 0xb0u, 0xd7u, 0xa7u, 0x36u, 0x56u, 0x49u, 0x97u, 0x6eu, 0x0au, 0x22u, 0xcbu, 0xe1u, 0x06u, 0x3bu, 0x1du, 0x7fu, 0xb2u, 0x56u, 0x47u, 0x92u, 0x8fu, 0x5fu, 0xb8u, 0xc0u, 0xb1u, 0xb7u, 0x24u, 0x6eu, 0xdau, 0x12u, 0xdau, 0x8du, 0x02u, 0x67u, 0x3eu, 0x27u, 0x3au, 0x75u, 0xacu, 0x71u, + /* (2^256 + 2) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xf2u, 0x4du, 0xd6u, 0xbbu, 0xbfu, 0x42u, 0x7fu, 0x21u, 0xcdu, 0xfdu, 0xfau, 0xb5u, 0xdau, 0xc6u, 0xf6u, 0x43u, 0x3au, 0x95u, 0x5eu, 0xe9u, 0xb5u, 0x18u, 0x78u, 0x08u, 0x07u, 0xa0u, 0xf7u, 0xceu, 0xb2u, 0xa8u, 0x0du, 0xc3u, 0x29u, 0x61u, 0xf5u, 0x2bu, 0x7au, 0x4fu, 0xd5u, 0xe5u, 0x10u, 0xd5u, 0x62u, 0xf2u, 0xa6u, 0x9bu, 0xcbu, 0x2cu, 0x29u, 0x1cu, 0x6au, 0xd9u, 0x08u, 0x25u, 0x5eu, 0xb5u, 0x29u, 0x1eu, 0x34u, 0x6du, 0x78u, 0xc7u, 0x45u, 0x39u, 0x1du, 0x45u, 0x2au, 0x53u, 0xb7u, 0x99u, 0xdeu, 0x3fu, 0x43u, 0x48u, 0x17u, 0xd4u, 0x2bu, 0x0du, 0x78u, 0x68u, 0x45u, 0xe1u, 0xf8u, 0x6eu, 0x60u, 0x3au, 0x03u, 0x33u, 0x56u, 0xcau, 0xe7u, 0x8cu, 0xadu, 0x54u, 0x83u, 0x5bu, + /* (2^256 + 2^128 + 1) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xd8u, 0x86u, 0x59u, 0x88u, 0x6eu, 0xe9u, 0xa9u, 0x30u, 0x8bu, 0x73u, 0x9au, 0xd5u, 0x7cu, 0x92u, 0x77u, 0xcfu, 0xeau, 0x79u, 0xa5u, 0xf5u, 0xadu, 0x3eu, 0xd3u, 0x4fu, 0x9du, 0x18u, 0x12u, 0x68u, 0x0eu, 0x0du, 0x07u, 0xfeu, 0xb3u, 0x65u, 0x74u, 0xa8u, 0xdcu, 0xa4u, 0x20u, 0xbau, 0x25u, 0x53u, 0x9du, 0xe9u, 0x8eu, 0xceu, 0x21u, 0x8du, 0x89u, 0x76u, 0xb7u, 0x03u, 0x05u, 0xf5u, 0x11u, 0x22u, 0x3eu, 0x1au, 0x96u, 0xb1u, 0x40u, 0xc7u, 0x3au, 0x2du, 0x67u, 0xf8u, 0x64u, 0x1eu, 0x21u, 0x04u, 0x5fu, 0x63u, 0xd3u, 0x12u, 0x8fu, 0x12u, 0x97u, 0xeeu, 0x31u, 0x5eu, 0xe0u, 0x13u, 0x8cu, 0x65u, 0x08u, 0xf3u, 0x52u, 0x4fu, 0xafu, 0x07u, 0xbfu, 0xb6u, 0x21u, 0x59u, 0x1au, 0x3eu, + /* (2^256 + 2^128 + 2) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0x0du, 0xe7u, 0x0du, 0x3bu, 0x66u, 0xb9u, 0x3au, 0x52u, 0x65u, 0x4cu, 0xdau, 0xdfu, 0x52u, 0xf1u, 0x6bu, 0x74u, 0x88u, 0x86u, 0x03u, 0x4cu, 0x4cu, 0xbeu, 0x5eu, 0x85u, 0x8cu, 0x1du, 0x85u, 0x06u, 0x11u, 0x6cu, 0x4du, 0x0cu, 0xa8u, 0x73u, 0xecu, 0xbfu, 0x64u, 0x10u, 0xc9u, 0xe3u, 0x6cu, 0x2du, 0x76u, 0x2eu, 0xedu, 0xc2u, 0xe9u, 0xfcu, 0xddu, 0x97u, 0x4eu, 0x2bu, 0x20u, 0x21u, 0x36u, 0x30u, 0x0bu, 0xb0u, 0x73u, 0x97u, 0x58u, 0x9bu, 0x48u, 0x03u, 0x47u, 0x00u, 0xb8u, 0x65u, 0xcfu, 0x33u, 0x89u, 0x9fu, 0x1du, 0x05u, 0xa1u, 0xf5u, 0x0fu, 0x57u, 0x8fu, 0x57u, 0xb8u, 0x3cu, 0x56u, 0x9fu, 0x87u, 0x3fu, 0xafu, 0x2au, 0xa1u, 0xdeu, 0x0eu, 0x75u, 0x03u, 0x7au, 0x58u, 0xabu, + /* correction point D = - ((2^128 - 1) * G) in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xbbu, 0x3fu, 0x5au, 0x84u, 0x87u, 0xf9u, 0x1au, 0x36u, 0x48u, 0x28u, 0x20u, 0xd6u, 0x7fu, 0x73u, 0x36u, 0xd6u, 0xc4u, 0xeau, 0x85u, 0x36u, 0xe6u, 0x51u, 0xcau, 0xb5u, 0xc6u, 0x06u, 0xd7u, 0x47u, 0x6du, 0x24u, 0x4du, 0xa9u, 0x32u, 0x12u, 0xa5u, 0x0cu, 0x71u, 0x17u, 0x13u, 0xf4u, 0x79u, 0xc0u, 0x00u, 0xdau, 0x6fu, 0xc6u, 0xb7u, 0xeeu, 0xc7u, 0xe7u, 0x30u, 0x8cu, 0x0bu, 0x91u, 0xb3u, 0x09u, 0x6au, 0x2cu, 0x2bu, 0x3au, 0xd4u, 0xf6u, 0x83u, 0xe1u, 0x87u, 0xe5u, 0x0fu, 0x70u, 0xd1u, 0xceu, 0x0fu, 0xbfu, 0xa6u, 0x5au, 0x46u, 0x6eu, 0xb8u, 0xb0u, 0x82u, 0x52u, 0x00u, 0x33u, 0x7fu, 0xcbu, 0x6au, 0xdau, 0xc8u, 0x40u, 0xeau, 0x24u, 0x6cu, 0xfdu, 0xbdu, 0x58u, 0xc5u, 0x4cu, +}; + +#elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1Domain[324] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x40u, + /* version */ + 0x02u, 0x01u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x3cu, + /* prime OID */ + 0x06u, 0x07u, 0x2au, 0x86u, 0x48u, 0xceu, 0x3du, 0x01u, 0x01u, + /* p (field prime) */ + 0x02u, 0x31u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, + /* SEQUENCE */ + 0x30u, 0x64u, + /* a (coefficient a of the curve equation) */ + 0x04u, 0x30u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfeu, 0xffu, 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u, 0x30u, 0xb3u, 0x31u, 0x2fu, 0xa7u, 0xe2u, 0x3eu, 0xe7u, 0xe4u, 0x98u, 0x8eu, 0x05u, 0x6bu, 0xe3u, 0xf8u, 0x2du, 0x19u, 0x18u, 0x1du, 0x9cu, 0x6eu, 0xfeu, 0x81u, 0x41u, 0x12u, 0x03u, 0x14u, 0x08u, 0x8fu, 0x50u, 0x13u, 0x87u, 0x5au, 0xc6u, 0x56u, 0x39u, 0x8du, 0x8au, 0x2eu, 0xd1u, 0x9du, 0x2au, 0x85u, 0xc8u, 0xedu, 0xd3u, 0xecu, 0x2au, 0xefu, + /* G (basepoint of the curve) */ + 0x04u, 0x61u, 0x04u, 0xaau, 0x87u, 0xcau, 0x22u, 0xbeu, 0x8bu, 0x05u, 0x37u, 0x8eu, 0xb1u, 0xc7u, 0x1eu, 0xf3u, 0x20u, 0xadu, 0x74u, 0x6eu, 0x1du, 0x3bu, 0x62u, 0x8bu, 0xa7u, 0x9bu, 0x98u, 0x59u, 0xf7u, 0x41u, 0xe0u, 0x82u, 0x54u, 0x2au, 0x38u, 0x55u, 0x02u, 0xf2u, 0x5du, 0xbfu, 0x55u, 0x29u, 0x6cu, 0x3au, 0x54u, 0x5eu, 0x38u, 0x72u, 0x76u, 0x0au, 0xb7u, 0x36u, 0x17u, 0xdeu, 0x4au, 0x96u, 0x26u, 0x2cu, 0x6fu, 0x5du, 0x9eu, 0x98u, 0xbfu, 0x92u, 0x92u, 0xdcu, 0x29u, 0xf8u, 0xf4u, 0x1du, 0xbdu, 0x28u, 0x9au, 0x14u, 0x7cu, 0xe9u, 0xdau, 0x31u, 0x13u, 0xb5u, 0xf0u, 0xb8u, 0xc0u, 0x0au, 0x60u, 0xb1u, 0xceu, 0x1du, 0x7eu, 0x81u, 0x9du, 0x7au, 0x43u, 0x1du, 0x7cu, 0x90u, 0xeau, 0x0eu, 0x5fu, + /* n (order of G) */ + 0x02u, 0x31u, 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xc7u, 0x63u, 0x4du, 0x81u, 0xf4u, 0x37u, 0x2du, 0xdfu, 0x58u, 0x1au, 0x0du, 0xb2u, 0x48u, 0xb0u, 0xa7u, 0x7au, 0xecu, 0xecu, 0x19u, 0x6au, 0xccu, 0xc5u, 0x29u, 0x73u, + /* h (cofactor) */ + 0x02u, 0x01u, 0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt[323] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x3fu, + /* SEQUENCE */ + 0x30u, 0x82u, 0x01u, 0x01u, + /* p_RR (R^2 in prime field) */ + 0x04u, 0x30u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xfeu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0xffu, 0xfeu, 0x00u, 0x00u, 0x00u, 0x01u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u, 0x04u, 0x00u, 0x00u, 0x00u, 0x01u, + /* SEQUENCE */ + 0x30u, 0x64u, + /* a_R (a in Montgomery representation) */ + 0x04u, 0x30u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xfbu, 0xffu, 0xffu, 0xffu, 0xfcu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, 0xffu, 0xffu, 0xffu, 0xfcu, + /* b_R (b in Montgomery representation) */ + 0x04u, 0x30u, 0xcdu, 0x08u, 0x11u, 0x4bu, 0x60u, 0x4fu, 0xbfu, 0xf9u, 0xb6u, 0x2bu, 0x21u, 0xf4u, 0x1fu, 0x02u, 0x20u, 0x94u, 0xe3u, 0x37u, 0x4bu, 0xeeu, 0x94u, 0x93u, 0x8au, 0xe2u, 0x77u, 0xf2u, 0x20u, 0x9bu, 0x19u, 0x20u, 0x02u, 0x2eu, 0xf7u, 0x29u, 0xadu, 0xd8u, 0x7au, 0x4cu, 0x32u, 0xecu, 0x08u, 0x11u, 0x88u, 0x71u, 0x9du, 0x41u, 0x2du, 0xccu, + /* G_R (G in Montgomery representation) */ + 0x04u, 0x61u, 0x04u, 0x4du, 0x3au, 0xadu, 0xc2u, 0x29u, 0x9eu, 0x15u, 0x13u, 0x81u, 0x2fu, 0xf7u, 0x23u, 0x61u, 0x4eu, 0xdeu, 0x2bu, 0x64u, 0x54u, 0x86u, 0x84u, 0x59u, 0xa3u, 0x0eu, 0xffu, 0x87u, 0x9cu, 0x3au, 0xfcu, 0x54u, 0x1bu, 0x4du, 0x6eu, 0x20u, 0xe3u, 0x78u, 0xe2u, 0xa0u, 0xd6u, 0xceu, 0x38u, 0x3du, 0xd0u, 0x75u, 0x66u, 0x49u, 0xc0u, 0xb5u, 0x28u, 0x2bu, 0x78u, 0xabu, 0xc2u, 0x5au, 0x15u, 0xc5u, 0xe9u, 0xddu, 0x80u, 0x02u, 0x26u, 0x39u, 0x69u, 0xa8u, 0x40u, 0xc6u, 0xc3u, 0x52u, 0x19u, 0x68u, 0xf4u, 0xffu, 0xd9u, 0x8bu, 0xadu, 0xe7u, 0x56u, 0x2eu, 0x83u, 0xb0u, 0x50u, 0xa1u, 0xbfu, 0xa8u, 0xbfu, 0x7bu, 0xb4u, 0xa9u, 0xacu, 0x23u, 0x04u, 0x3du, 0xadu, 0x4bu, 0x03u, 0xa4u, 0xfeu, + /* SEQUENCE */ + 0x30u, 0x38u, + /* n_RR (R^2 in order field) */ + 0x04u, 0x30u, 0x0cu, 0x84u, 0xeeu, 0x01u, 0x2bu, 0x39u, 0xbfu, 0x21u, 0x3fu, 0xb0u, 0x5bu, 0x7au, 0x28u, 0x26u, 0x68u, 0x95u, 0xd4u, 0x0du, 0x49u, 0x17u, 0x4au, 0xabu, 0x1cu, 0xc5u, 0xbcu, 0x3eu, 0x48u, 0x3au, 0xfcu, 0xb8u, 0x29u, 0x47u, 0xffu, 0x3du, 0x81u, 0xe5u, 0xdfu, 0x1au, 0xa4u, 0x19u, 0x2du, 0x31u, 0x9bu, 0x24u, 0x19u, 0xb4u, 0x09u, 0xa9u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u, 0x04u, 0xe8u, 0x8fu, 0xdcu, 0x45u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1SpeedUpExt[803] = { + /* SEQUENCE */ + 0x30u, 0x82u, 0x03u, 0x1fu, + /* groups parameter */ + 0x04u, 0x01u, 0x03u, + /* SEQUENCE */ + 0x30u, 0x82u, 0x03u, 0x18u, + /* 2 * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xdbu, 0x93u, 0xb7u, 0x76u, 0x42u, 0x74u, 0x60u, 0xc3u, 0x9cu, 0x90u, 0xa4u, 0xfdu, 0x2du, 0xe4u, 0xb5u, 0x06u, 0xdau, 0x82u, 0x14u, 0x95u, 0xf0u, 0x68u, 0x7fu, 0x50u, 0x35u, 0x04u, 0xe6u, 0xf0u, 0xffu, 0x9du, 0x48u, 0xa1u, 0x8eu, 0x6cu, 0x8fu, 0x2eu, 0x02u, 0x2bu, 0x53u, 0xf0u, 0xc8u, 0x22u, 0x9eu, 0x55u, 0x78u, 0x3du, 0xdeu, 0x91u, 0xe3u, 0x49u, 0x47u, 0xf7u, 0x12u, 0x3du, 0xf0u, 0xc2u, 0x07u, 0x0du, 0x43u, 0x09u, 0x00u, 0xb0u, 0xe6u, 0x84u, 0x09u, 0xf1u, 0xfeu, 0x41u, 0x51u, 0x72u, 0xbau, 0xd9u, 0x15u, 0xe4u, 0xf1u, 0x8bu, 0xdcu, 0x58u, 0x82u, 0x58u, 0xe8u, 0xe8u, 0xe4u, 0xa8u, 0xc2u, 0xaau, 0xccu, 0xd8u, 0x42u, 0xeau, 0x84u, 0x63u, 0x31u, 0x40u, 0xbfu, 0xdau, + /* (2^128 + 1) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xebu, 0x65u, 0x7bu, 0x10u, 0xfdu, 0x71u, 0x1bu, 0xa4u, 0x63u, 0x7eu, 0x33u, 0x02u, 0x42u, 0xedu, 0x76u, 0x26u, 0x39u, 0x24u, 0xe5u, 0x0au, 0x74u, 0x20u, 0x40u, 0x8fu, 0xa1u, 0xe4u, 0x4bu, 0x14u, 0xdcu, 0x26u, 0x1eu, 0xc2u, 0xfeu, 0x4au, 0x36u, 0xe7u, 0xffu, 0x13u, 0x31u, 0x4eu, 0x39u, 0x4fu, 0xb8u, 0x4du, 0xe8u, 0x6eu, 0x3fu, 0x64u, 0xa9u, 0x6fu, 0xd3u, 0xb7u, 0x46u, 0x94u, 0xe1u, 0x5au, 0x5bu, 0xe4u, 0x63u, 0xa5u, 0xbeu, 0x56u, 0xf7u, 0x74u, 0x33u, 0x86u, 0xf1u, 0xc6u, 0x88u, 0x6fu, 0xb3u, 0xdbu, 0xe7u, 0x46u, 0x58u, 0x19u, 0xb0u, 0x56u, 0xd8u, 0x72u, 0x30u, 0xe0u, 0x43u, 0x26u, 0x7fu, 0x1fu, 0x42u, 0xc7u, 0xc1u, 0x6du, 0x01u, 0xc5u, 0x34u, 0x09u, 0x49u, 0xbbu, + /* (2^128 + 2) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xcbu, 0x0eu, 0xc2u, 0x40u, 0x54u, 0x40u, 0x30u, 0x0eu, 0x87u, 0xa3u, 0x41u, 0xffu, 0x26u, 0x25u, 0xc6u, 0x45u, 0x16u, 0x92u, 0x6bu, 0x63u, 0x5bu, 0xd7u, 0xe9u, 0x20u, 0x67u, 0x78u, 0xc2u, 0xf9u, 0xa0u, 0x18u, 0x43u, 0x09u, 0x53u, 0xceu, 0x5eu, 0x7eu, 0x08u, 0x3cu, 0xd6u, 0x22u, 0x0au, 0x1fu, 0x01u, 0x6du, 0xa7u, 0xa2u, 0x98u, 0x2cu, 0x74u, 0x1au, 0xc8u, 0x5fu, 0x44u, 0x17u, 0x10u, 0x90u, 0x89u, 0x5du, 0x29u, 0xaeu, 0x22u, 0x31u, 0x0au, 0x17u, 0xa0u, 0xe4u, 0xe8u, 0xc6u, 0x2du, 0x55u, 0xd9u, 0x3au, 0xc8u, 0xf3u, 0x60u, 0x28u, 0x4fu, 0x9bu, 0x94u, 0x35u, 0xdeu, 0xcbu, 0x19u, 0xb5u, 0x88u, 0x64u, 0x57u, 0xe4u, 0x58u, 0x68u, 0x21u, 0xd5u, 0xfau, 0x6du, 0xe7u, 0x19u, + /* (2^256 + 1) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0x27u, 0x1fu, 0x07u, 0x17u, 0x8fu, 0xcbu, 0x87u, 0xf1u, 0x05u, 0xbeu, 0x51u, 0xb7u, 0xbfu, 0x50u, 0x01u, 0x59u, 0xdeu, 0x1du, 0x76u, 0x17u, 0x79u, 0xfdu, 0x9cu, 0x91u, 0xadu, 0xfdu, 0x85u, 0xb0u, 0x3eu, 0xeeu, 0x3du, 0x12u, 0x05u, 0x29u, 0x17u, 0xc3u, 0x19u, 0x0eu, 0xb1u, 0x98u, 0x56u, 0x21u, 0x11u, 0x90u, 0xa3u, 0x53u, 0xe8u, 0x89u, 0x8fu, 0x8eu, 0x6eu, 0x28u, 0x9eu, 0x96u, 0xb1u, 0x5du, 0xb0u, 0xd7u, 0xa7u, 0x36u, 0x56u, 0x49u, 0x97u, 0x6eu, 0x0au, 0x22u, 0xcbu, 0xe1u, 0x06u, 0x3bu, 0x1du, 0x7fu, 0xb2u, 0x56u, 0x47u, 0x92u, 0x8fu, 0x5fu, 0xb8u, 0xc0u, 0xb1u, 0xb7u, 0x24u, 0x6eu, 0xdau, 0x12u, 0xdau, 0x8du, 0x02u, 0x67u, 0x3eu, 0x27u, 0x3au, 0x75u, 0xacu, 0x71u, + /* (2^256 + 2) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xf2u, 0x4du, 0xd6u, 0xbbu, 0xbfu, 0x42u, 0x7fu, 0x21u, 0xcdu, 0xfdu, 0xfau, 0xb5u, 0xdau, 0xc6u, 0xf6u, 0x43u, 0x3au, 0x95u, 0x5eu, 0xe9u, 0xb5u, 0x18u, 0x78u, 0x08u, 0x07u, 0xa0u, 0xf7u, 0xceu, 0xb2u, 0xa8u, 0x0du, 0xc3u, 0x29u, 0x61u, 0xf5u, 0x2bu, 0x7au, 0x4fu, 0xd5u, 0xe5u, 0x10u, 0xd5u, 0x62u, 0xf2u, 0xa6u, 0x9bu, 0xcbu, 0x2cu, 0x29u, 0x1cu, 0x6au, 0xd9u, 0x08u, 0x25u, 0x5eu, 0xb5u, 0x29u, 0x1eu, 0x34u, 0x6du, 0x78u, 0xc7u, 0x45u, 0x39u, 0x1du, 0x45u, 0x2au, 0x53u, 0xb7u, 0x99u, 0xdeu, 0x3fu, 0x43u, 0x48u, 0x17u, 0xd4u, 0x2bu, 0x0du, 0x78u, 0x68u, 0x45u, 0xe1u, 0xf8u, 0x6eu, 0x60u, 0x3au, 0x03u, 0x33u, 0x56u, 0xcau, 0xe7u, 0x8cu, 0xadu, 0x54u, 0x83u, 0x5bu, + /* (2^256 + 2^128 + 1) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xd8u, 0x86u, 0x59u, 0x88u, 0x6eu, 0xe9u, 0xa9u, 0x30u, 0x8bu, 0x73u, 0x9au, 0xd5u, 0x7cu, 0x92u, 0x77u, 0xcfu, 0xeau, 0x79u, 0xa5u, 0xf5u, 0xadu, 0x3eu, 0xd3u, 0x4fu, 0x9du, 0x18u, 0x12u, 0x68u, 0x0eu, 0x0du, 0x07u, 0xfeu, 0xb3u, 0x65u, 0x74u, 0xa8u, 0xdcu, 0xa4u, 0x20u, 0xbau, 0x25u, 0x53u, 0x9du, 0xe9u, 0x8eu, 0xceu, 0x21u, 0x8du, 0x89u, 0x76u, 0xb7u, 0x03u, 0x05u, 0xf5u, 0x11u, 0x22u, 0x3eu, 0x1au, 0x96u, 0xb1u, 0x40u, 0xc7u, 0x3au, 0x2du, 0x67u, 0xf8u, 0x64u, 0x1eu, 0x21u, 0x04u, 0x5fu, 0x63u, 0xd3u, 0x12u, 0x8fu, 0x12u, 0x97u, 0xeeu, 0x31u, 0x5eu, 0xe0u, 0x13u, 0x8cu, 0x65u, 0x08u, 0xf3u, 0x52u, 0x4fu, 0xafu, 0x07u, 0xbfu, 0xb6u, 0x21u, 0x59u, 0x1au, 0x3eu, + /* (2^256 + 2^128 + 2) * G in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0x0du, 0xe7u, 0x0du, 0x3bu, 0x66u, 0xb9u, 0x3au, 0x52u, 0x65u, 0x4cu, 0xdau, 0xdfu, 0x52u, 0xf1u, 0x6bu, 0x74u, 0x88u, 0x86u, 0x03u, 0x4cu, 0x4cu, 0xbeu, 0x5eu, 0x85u, 0x8cu, 0x1du, 0x85u, 0x06u, 0x11u, 0x6cu, 0x4du, 0x0cu, 0xa8u, 0x73u, 0xecu, 0xbfu, 0x64u, 0x10u, 0xc9u, 0xe3u, 0x6cu, 0x2du, 0x76u, 0x2eu, 0xedu, 0xc2u, 0xe9u, 0xfcu, 0xddu, 0x97u, 0x4eu, 0x2bu, 0x20u, 0x21u, 0x36u, 0x30u, 0x0bu, 0xb0u, 0x73u, 0x97u, 0x58u, 0x9bu, 0x48u, 0x03u, 0x47u, 0x00u, 0xb8u, 0x65u, 0xcfu, 0x33u, 0x89u, 0x9fu, 0x1du, 0x05u, 0xa1u, 0xf5u, 0x0fu, 0x57u, 0x8fu, 0x57u, 0xb8u, 0x3cu, 0x56u, 0x9fu, 0x87u, 0x3fu, 0xafu, 0x2au, 0xa1u, 0xdeu, 0x0eu, 0x75u, 0x03u, 0x7au, 0x58u, 0xabu, + /* correction point D = - ((2^128 - 1) * G) in Montgomery representation */ + 0x04u, 0x61u, 0x04u, 0xbbu, 0x3fu, 0x5au, 0x84u, 0x87u, 0xf9u, 0x1au, 0x36u, 0x48u, 0x28u, 0x20u, 0xd6u, 0x7fu, 0x73u, 0x36u, 0xd6u, 0xc4u, 0xeau, 0x85u, 0x36u, 0xe6u, 0x51u, 0xcau, 0xb5u, 0xc6u, 0x06u, 0xd7u, 0x47u, 0x6du, 0x24u, 0x4du, 0xa9u, 0x32u, 0x12u, 0xa5u, 0x0cu, 0x71u, 0x17u, 0x13u, 0xf4u, 0x79u, 0xc0u, 0x00u, 0xdau, 0x6fu, 0xc6u, 0xb7u, 0xeeu, 0xc7u, 0xe7u, 0x30u, 0x8cu, 0x0bu, 0x91u, 0xb3u, 0x09u, 0x6au, 0x2cu, 0x2bu, 0x3au, 0xd4u, 0xf6u, 0x83u, 0xe1u, 0x87u, 0xe5u, 0x0fu, 0x70u, 0xd1u, 0xceu, 0x0fu, 0xbfu, 0xa6u, 0x5au, 0x46u, 0x6eu, 0xb8u, 0xb0u, 0x82u, 0x52u, 0x00u, 0x33u, 0x7fu, 0xcbu, 0x6au, 0xdau, 0xc8u, 0x40u, 0xeau, 0x24u, 0x6cu, 0xfdu, 0xbdu, 0x58u, 0xc5u, 0x4cu, +}; +#else /* CRYPTO_30_LIBCV_BYTES_PER_DIGIT */ +# error "Value of CRYPTO_30_LIBCV_BYTES_PER_DIGIT is not supported" +#endif /* CRYPTO_30_LIBCV_BYTES_PER_DIGIT */ +/* NIST_SEC_p384r1 END *********************************************************************************************/ + +/* NIST_SEC_p521r1 START *********************************************************************************************/ +/* NISTp521r1 = SECp521r1 */ +/* The curve params in shorthand notation: + * Name: secp521r1 + * p: 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + * a: 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc + * b: 0x51953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00 + * Gx: 0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66 + * Gy: 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650 + * n: 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409 + * h: 0x1 + */ + +#if (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1Domain[432] = { + /* SEQUENCE */ + 0x30u,0x82u,0x01u,0xacu, + /* version */ + 0x02u,0x01u,0x01u, + /* SEQUENCE */ + 0x30u,0x4du, + /* prime OID */ + 0x06u,0x07u,0x2au,0x86u,0x48u,0xceu,0x3du,0x01u,0x01u, + /* p (field prime) */ + 0x02u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu, + /* SEQUENCE */ + 0x30u,0x81u,0x88u, + /* a (coefficient a of the curve equation) */ + 0x04u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u,0x42u,0x00u,0x51u,0x95u,0x3eu,0xb9u,0x61u,0x8eu,0x1cu,0x9au,0x1fu,0x92u,0x9au,0x21u,0xa0u,0xb6u,0x85u,0x40u,0xeeu,0xa2u,0xdau,0x72u,0x5bu,0x99u,0xb3u,0x15u,0xf3u,0xb8u,0xb4u,0x89u,0x91u,0x8eu,0xf1u,0x09u,0xe1u,0x56u,0x19u,0x39u,0x51u,0xecu,0x7eu,0x93u,0x7bu,0x16u,0x52u,0xc0u,0xbdu,0x3bu,0xb1u,0xbfu,0x07u,0x35u,0x73u,0xdfu,0x88u,0x3du,0x2cu,0x34u,0xf1u,0xefu,0x45u,0x1fu,0xd4u,0x6bu,0x50u,0x3fu,0x00u, + /* G (basepoint of the curve) */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0xc6u,0x85u,0x8eu,0x06u,0xb7u,0x04u,0x04u,0xe9u,0xcdu,0x9eu,0x3eu,0xcbu,0x66u,0x23u,0x95u,0xb4u,0x42u,0x9cu,0x64u,0x81u,0x39u,0x05u,0x3fu,0xb5u,0x21u,0xf8u,0x28u,0xafu,0x60u,0x6bu,0x4du,0x3du,0xbau,0xa1u,0x4bu,0x5eu,0x77u,0xefu,0xe7u,0x59u,0x28u,0xfeu,0x1du,0xc1u,0x27u,0xa2u,0xffu,0xa8u,0xdeu,0x33u,0x48u,0xb3u,0xc1u,0x85u,0x6au,0x42u,0x9bu,0xf9u,0x7eu,0x7eu,0x31u,0xc2u,0xe5u,0xbdu,0x66u,0x01u,0x18u,0x39u,0x29u,0x6au,0x78u,0x9au,0x3bu,0xc0u,0x04u,0x5cu,0x8au,0x5fu,0xb4u,0x2cu,0x7du,0x1bu,0xd9u,0x98u,0xf5u,0x44u,0x49u,0x57u,0x9bu,0x44u,0x68u,0x17u,0xafu,0xbdu,0x17u,0x27u,0x3eu,0x66u,0x2cu,0x97u,0xeeu,0x72u,0x99u,0x5eu,0xf4u,0x26u,0x40u,0xc5u,0x50u,0xb9u,0x01u,0x3fu,0xadu,0x07u,0x61u,0x35u,0x3cu,0x70u,0x86u,0xa2u,0x72u,0xc2u,0x40u,0x88u,0xbeu,0x94u,0x76u,0x9fu,0xd1u,0x66u,0x50u, + /* n (order of G) */ + 0x02u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xfau,0x51u,0x86u,0x87u,0x83u,0xbfu,0x2fu,0x96u,0x6bu,0x7fu,0xccu,0x01u,0x48u,0xf7u,0x09u,0xa5u,0xd0u,0x3bu,0xb5u,0xc9u,0xb8u,0x89u,0x9cu,0x47u,0xaeu,0xbbu,0x6fu,0xb7u,0x1eu,0x91u,0x38u,0x64u,0x09u, + /* h (cofactor) */ + 0x02u,0x01u,0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt[427] = { + /* SEQUENCE */ + 0x30u,0x82u,0x01u,0xa7u, + /* SEQUENCE */ + 0x30u,0x82u,0x01u,0x5au, + /* p_RR (R^2 in prime field) */ + 0x04u,0x42u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x40u,0x00u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u,0x01u,0x01u, + /* SEQUENCE */ + 0x30u,0x81u,0x88u, + /* a_R (a in Montgomery representation) */ + 0x04u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xfeu,0x7fu, + /* b_R (b in Montgomery representation) */ + 0x04u,0x42u,0x00u,0xcau,0x9fu,0x5cu,0xb0u,0xc7u,0x0eu,0x4du,0x0fu,0xc9u,0x4du,0x10u,0xd0u,0x5bu,0x42u,0xa0u,0x77u,0x51u,0x6du,0x39u,0x2du,0xccu,0xd9u,0x8au,0xf9u,0xdcu,0x5au,0x44u,0xc8u,0xc7u,0x78u,0x84u,0xf0u,0xabu,0x0cu,0x9cu,0xa8u,0xf6u,0x3fu,0x49u,0xbdu,0x8bu,0x29u,0x60u,0x5eu,0x9du,0xd8u,0xdfu,0x83u,0x9au,0xb9u,0xefu,0xc4u,0x1eu,0x96u,0x1au,0x78u,0xf7u,0xa2u,0x8fu,0xeau,0x35u,0xa8u,0x1fu,0x80u,0x14u, + /* G_R (G in Montgomery representation) */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x42u,0xc7u,0x03u,0x5bu,0x82u,0x02u,0x74u,0xe6u,0xcfu,0x1fu,0x65u,0xb3u,0x11u,0xcau,0xdau,0x21u,0x4eu,0x32u,0x40u,0x9cu,0x82u,0x9fu,0xdau,0x90u,0xfcu,0x14u,0x57u,0xb0u,0x35u,0xa6u,0x9eu,0xddu,0x50u,0xa5u,0xafu,0x3bu,0xf7u,0xf3u,0xacu,0x94u,0x7fu,0x0eu,0xe0u,0x93u,0xd1u,0x7fu,0xd4u,0x6fu,0x19u,0xa4u,0x59u,0xe0u,0xc2u,0xb5u,0x21u,0x4du,0xfcu,0xbfu,0x3fu,0x18u,0xe1u,0x72u,0xdeu,0xb3u,0x31u,0x00u,0x1cu,0x94u,0xb5u,0x3cu,0x4du,0x1du,0xe0u,0x02u,0x2eu,0x45u,0x2fu,0xdau,0x16u,0x3eu,0x8du,0xecu,0xccu,0x7au,0xa2u,0x24u,0xabu,0xcdu,0xa2u,0x34u,0x0bu,0xd7u,0xdeu,0x8bu,0x93u,0x9fu,0x33u,0x16u,0x4bu,0xf7u,0x39u,0x4cu,0xafu,0x7au,0x13u,0x20u,0x62u,0xa8u,0x5cu,0x80u,0x9fu,0xd6u,0x83u,0xb0u,0x9au,0x9eu,0x38u,0x43u,0x51u,0x39u,0x61u,0x20u,0x44u,0x5fu,0x4au,0x3bu,0x4fu,0xe8u,0xb3u,0x28u,0x46u, + /* SEQUENCE */ + 0x30u,0x47u, + /* n_RR (R^2 in order field) */ + 0x04u,0x42u,0x01u,0xeau,0x03u,0x91u,0xa3u,0x9au,0x5bu,0x5au,0x3au,0xfeu,0x8cu,0x44u,0x38u,0x3du,0x2du,0x8eu,0x03u,0xd1u,0x49u,0x2du,0x0du,0x45u,0x5bu,0xccu,0x6du,0x61u,0xa8u,0xe5u,0x67u,0xbcu,0xcfu,0xf3u,0xd1u,0x3du,0x47u,0x71u,0x0au,0x7fu,0x95u,0xe3u,0x35u,0x83u,0x8eu,0x57u,0xadu,0xa6u,0xe9u,0x91u,0x17u,0x1eu,0x2eu,0xf2u,0x1du,0x46u,0x42u,0xa2u,0x3fu,0xb7u,0x35u,0x1cu,0x54u,0x08u,0x56u,0xc0u,0xfbu,0xb8u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u,0x01u,0xc7u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1SpeedUpExt[1099] = { + /* SEQUENCE */ + 0x30u,0x82u,0x04u,0x47u, + /* groups parameter */ + 0x04u,0x01u,0x03u, + /* SEQUENCE */ + 0x30u,0x82u,0x04u,0x40u, + /* 2 * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x9eu,0x10u,0xc8u,0x12u,0x13u,0xbfu,0x3fu,0x34u,0x17u,0xe5u,0x94u,0x40u,0xa4u,0x61u,0x41u,0x3au,0x3au,0x01u,0x93u,0xcdu,0x8eu,0x66u,0x03u,0x1au,0x96u,0x37u,0x2au,0x82u,0xebu,0xb4u,0xdfu,0x4bu,0xd9u,0xd9u,0x02u,0x6du,0x37u,0x7au,0xaau,0x83u,0xd5u,0x08u,0x25u,0x1du,0x1au,0xe2u,0xd7u,0xa0u,0xe7u,0x97u,0xd1u,0xb2u,0x6bu,0x07u,0xecu,0xb3u,0xfau,0x1fu,0x1cu,0x99u,0xddu,0x36u,0xbcu,0x1eu,0x90u,0x00u,0x5du,0xc6u,0x63u,0xfcu,0x36u,0xd9u,0x33u,0x80u,0x53u,0xf9u,0xf6u,0x77u,0x77u,0x69u,0xf8u,0x5au,0xe3u,0x5au,0x88u,0x3eu,0x26u,0xd4u,0xbbu,0xa0u,0x55u,0x90u,0xd1u,0x4cu,0x83u,0x62u,0x16u,0xddu,0xd9u,0xf1u,0xbbu,0xefu,0x4fu,0x92u,0x8fu,0xb5u,0xc9u,0xc9u,0xbfu,0xd4u,0xcdu,0x19u,0x24u,0x7au,0x75u,0x7eu,0x5fu,0x4au,0xf6u,0xe0u,0x7au,0x7bu,0x8du,0xf1u,0xabu,0x6bu,0x30u,0xfau,0x0du,0x81u,0x3du, + /* (2^174 + 1) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0xe1u,0x51u,0x77u,0xdeu,0x42u,0x44u,0xaau,0x8eu,0xe7u,0x2cu,0xafu,0x4fu,0x9au,0x9bu,0x7fu,0x03u,0xd4u,0x89u,0x83u,0xe0u,0x29u,0xe1u,0x71u,0x95u,0x01u,0x11u,0xd0u,0x8cu,0xf0u,0x9eu,0x3du,0x8eu,0x89u,0xdcu,0x58u,0x7cu,0xbdu,0xbfu,0xb5u,0x83u,0x46u,0x90u,0x12u,0x37u,0x72u,0x61u,0x14u,0xe2u,0x5du,0x61u,0x01u,0xf7u,0x70u,0x19u,0x66u,0x03u,0x9bu,0x00u,0x2du,0x1bu,0xe3u,0xdcu,0x24u,0x50u,0x06u,0x01u,0x65u,0x10u,0x55u,0xa3u,0x7au,0x73u,0xf2u,0x90u,0xb4u,0x97u,0xb8u,0x96u,0x39u,0xecu,0x68u,0x80u,0x9cu,0x84u,0x3cu,0xa1u,0xf5u,0x24u,0xf1u,0x19u,0x88u,0x88u,0xbcu,0x65u,0x89u,0xa2u,0x47u,0xbcu,0x46u,0xbbu,0x90u,0x68u,0xfbu,0x9cu,0x8cu,0x39u,0xa4u,0x7au,0x03u,0x24u,0x05u,0x68u,0x26u,0xf0u,0x6du,0x0eu,0x2fu,0x9eu,0x40u,0xefu,0x93u,0x3bu,0x76u,0x91u,0x73u,0xdau,0x33u,0x84u,0x0du,0x7eu,0x96u, + /* (2^174 + 2) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x36u,0x4fu,0xacu,0x85u,0x6du,0x00u,0xf2u,0x4eu,0x2fu,0x9du,0x89u,0x81u,0x04u,0x7fu,0x3eu,0x03u,0xa3u,0xcau,0x57u,0xb3u,0x54u,0x4fu,0x02u,0x99u,0x0fu,0x4du,0x2fu,0xf9u,0x33u,0xcbu,0x96u,0x58u,0x23u,0x27u,0x9bu,0xcbu,0xbcu,0xd9u,0x6cu,0x80u,0xcdu,0x03u,0x7au,0xd9u,0x19u,0x12u,0x6bu,0x32u,0xe2u,0xb7u,0x4bu,0x24u,0x91u,0x5bu,0x79u,0x51u,0x1eu,0x81u,0x09u,0xffu,0x6au,0x5eu,0x75u,0x85u,0x85u,0x01u,0x11u,0xc7u,0x8cu,0xd0u,0x72u,0x64u,0xbdu,0xbeu,0x73u,0x43u,0x7fu,0xe5u,0xc1u,0x20u,0x3eu,0x74u,0xfdu,0xa7u,0xe8u,0x16u,0x3bu,0xdau,0x93u,0xd5u,0x7cu,0xdeu,0x89u,0x23u,0xecu,0x09u,0xeau,0x5fu,0x93u,0x90u,0x79u,0x30u,0xd9u,0x54u,0x1cu,0x1au,0x37u,0x24u,0x98u,0x8cu,0xceu,0x93u,0xa2u,0x9eu,0x59u,0x84u,0x8au,0xb0u,0x1eu,0x24u,0xa6u,0x36u,0x82u,0x6du,0xfbu,0x8cu,0xfdu,0xb6u,0x74u,0xf7u,0xacu, + /* (2^348 + 1) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x8cu,0x2cu,0xfeu,0x90u,0x6fu,0x1cu,0x23u,0x3eu,0xb0u,0x76u,0xa1u,0xf7u,0x67u,0x7au,0x2bu,0xcau,0xf2u,0xa9u,0x17u,0xd7u,0xf9u,0xfbu,0x6cu,0x75u,0x42u,0xd9u,0x25u,0xe2u,0x3au,0x47u,0x4bu,0xd6u,0x9eu,0x7cu,0xd7u,0xa6u,0xf1u,0x60u,0xbcu,0x3au,0x70u,0x39u,0x54u,0xc0u,0x56u,0x3bu,0x54u,0x46u,0x87u,0x3eu,0xc2u,0xacu,0xddu,0xdeu,0x0bu,0xacu,0x33u,0x5eu,0xcdu,0x06u,0xe6u,0xb4u,0xc3u,0x4bu,0xf5u,0x00u,0xc8u,0xf0u,0x5bu,0xa3u,0x73u,0x91u,0xf1u,0x3cu,0x04u,0xfdu,0xb9u,0x06u,0x58u,0xfbu,0xaeu,0x48u,0x0eu,0xdfu,0x52u,0xedu,0x74u,0x05u,0x6du,0x5au,0x23u,0x44u,0x3fu,0x3au,0x46u,0x0cu,0xd3u,0xbau,0x05u,0x1cu,0x5cu,0xa9u,0xcdu,0x13u,0x11u,0x41u,0x96u,0x58u,0x5au,0xb8u,0x77u,0x44u,0xfcu,0x7au,0x9bu,0x98u,0xdeu,0x63u,0xffu,0x72u,0x2au,0x76u,0xf3u,0x16u,0x3bu,0x5cu,0xacu,0x74u,0x0cu,0x0eu,0x71u, + /* (2^348 + 2) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0xecu,0x3fu,0x0au,0x19u,0xefu,0xbau,0xafu,0xccu,0x4bu,0xffu,0x94u,0x65u,0xc1u,0xecu,0x0fu,0xd3u,0xc4u,0xd2u,0x67u,0x22u,0xc6u,0xebu,0x0bu,0x8bu,0xa9u,0xc2u,0xd7u,0x7du,0x80u,0x23u,0xc4u,0x64u,0xe6u,0x9bu,0x15u,0xd9u,0x81u,0xbfu,0x6au,0x56u,0x90u,0xacu,0xe1u,0x97u,0x65u,0x81u,0xc6u,0xdau,0x53u,0x36u,0xa1u,0x3fu,0xa7u,0x4du,0x01u,0x90u,0x55u,0xabu,0x41u,0xcfu,0x26u,0xceu,0x39u,0xa8u,0x46u,0x01u,0xa4u,0xddu,0xdeu,0xe9u,0xb2u,0x92u,0x9eu,0x4cu,0x3au,0xfbu,0x96u,0x26u,0x73u,0x18u,0xf9u,0x04u,0xb5u,0x5au,0x4au,0xe0u,0x60u,0x58u,0xb7u,0xb0u,0x0cu,0x13u,0xfdu,0xe5u,0x80u,0x3fu,0xf9u,0x2bu,0x8eu,0x8bu,0x7eu,0xa1u,0x10u,0x43u,0xb2u,0x6cu,0xd9u,0xccu,0xe1u,0x02u,0x07u,0x04u,0xe1u,0xbfu,0x30u,0x42u,0x04u,0xc9u,0x37u,0xa8u,0xd9u,0xd0u,0x09u,0xe4u,0x8cu,0x82u,0x6du,0x1du,0xa3u,0xebu,0x46u, + /* (2^348 + 2^174 + 1) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0x67u,0x9bu,0xa9u,0xddu,0x43u,0x03u,0xe7u,0xb4u,0x83u,0xc5u,0xd0u,0xbfu,0x7du,0x9eu,0xa6u,0x48u,0xe9u,0xd6u,0x8fu,0xabu,0xc3u,0xf7u,0x17u,0x61u,0x10u,0x10u,0x55u,0xcau,0x2du,0x38u,0xd5u,0xb4u,0x82u,0xffu,0xbcu,0x66u,0xbeu,0x23u,0x37u,0x84u,0x03u,0xdcu,0x85u,0x6cu,0xd5u,0xfeu,0x76u,0xc1u,0xf0u,0xf2u,0xc4u,0xf9u,0xe5u,0x54u,0x90u,0x7bu,0xaau,0xd2u,0xf4u,0x7au,0x32u,0x0du,0xbfu,0x04u,0x4eu,0x01u,0xb1u,0x9fu,0xfau,0x6fu,0xc9u,0x20u,0xbcu,0x36u,0x89u,0x33u,0x5bu,0x5cu,0xedu,0x2cu,0xc2u,0x1fu,0xabu,0x89u,0x1eu,0xccu,0xdeu,0xa4u,0x73u,0x38u,0xe9u,0xaau,0xa7u,0xd1u,0x7fu,0xc6u,0x95u,0xc1u,0xcbu,0x94u,0x4bu,0x6du,0x8fu,0x8bu,0x4bu,0x43u,0xa6u,0x4cu,0xa2u,0xb2u,0x17u,0xbbu,0xd4u,0x2eu,0xe9u,0x05u,0x9eu,0x84u,0x42u,0x2au,0x64u,0xbcu,0xdau,0xf1u,0xc8u,0xf1u,0x5cu,0xd9u,0x13u,0x00u,0x47u, + /* (2^348 + 2^174 + 2) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x3bu,0x98u,0x9bu,0x87u,0x4du,0x06u,0x72u,0x8du,0x7au,0x77u,0x20u,0xa9u,0xd6u,0xf1u,0xf8u,0xbcu,0x3au,0x39u,0x6fu,0x04u,0x4fu,0xeau,0x08u,0x93u,0xbdu,0x35u,0x1bu,0xffu,0xccu,0xd7u,0x5eu,0xdeu,0x0du,0x6au,0xfau,0xe5u,0x34u,0x97u,0x4bu,0x61u,0x8au,0x5eu,0x2cu,0x93u,0xf8u,0x6cu,0xc8u,0x47u,0xe5u,0x1bu,0x51u,0xbau,0x32u,0x35u,0xe0u,0x22u,0x69u,0x2au,0xc5u,0xf6u,0xdcu,0x31u,0x1eu,0xe0u,0x3du,0x01u,0xefu,0xfbu,0x64u,0x11u,0x06u,0x31u,0x02u,0xb2u,0xe4u,0xb7u,0x21u,0xb7u,0x1au,0xc5u,0x63u,0xc7u,0x63u,0xb3u,0x2cu,0x08u,0x13u,0xdbu,0x35u,0x78u,0x45u,0x6cu,0xddu,0x7du,0xaau,0x9cu,0x0cu,0x45u,0x37u,0xfeu,0x2eu,0xf8u,0x73u,0x35u,0xdau,0x6du,0x3bu,0x6au,0x39u,0x48u,0x4fu,0xbbu,0xceu,0xdau,0xbau,0x6bu,0xb0u,0x6bu,0xccu,0xeau,0xdau,0xc2u,0x5fu,0x27u,0x0eu,0xedu,0x90u,0x57u,0x32u,0x5eu,0x2bu, + /* correction point D = - ((2^174 - 1) * G) in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0x3au,0x67u,0xe5u,0xe1u,0x41u,0xb5u,0x93u,0xf6u,0xc7u,0x9cu,0x37u,0x00u,0x20u,0x7du,0x83u,0xcbu,0x87u,0x5fu,0x2au,0x22u,0xdfu,0x95u,0x81u,0x8cu,0x5eu,0xa0u,0x2du,0x84u,0x05u,0xa4u,0xb3u,0x3au,0x69u,0x06u,0x98u,0xfdu,0xc0u,0x3eu,0xadu,0x83u,0x83u,0x40u,0x79u,0xadu,0x6eu,0xe1u,0x3bu,0x59u,0x60u,0xb4u,0x65u,0xb5u,0x96u,0x5bu,0xd5u,0x4eu,0x79u,0xf0u,0xf7u,0xb6u,0x57u,0x92u,0x99u,0x39u,0xd9u,0x00u,0x79u,0x0du,0x13u,0x65u,0x21u,0xb9u,0x51u,0x80u,0xeau,0xd6u,0x4bu,0xe9u,0x83u,0xc1u,0x3au,0x91u,0x3du,0x85u,0x8cu,0xf5u,0x0cu,0x74u,0x4cu,0x47u,0xe0u,0xc7u,0x32u,0x98u,0xd8u,0x5au,0xa2u,0x8eu,0xceu,0xbau,0xedu,0x8eu,0x3eu,0x9cu,0x05u,0xb2u,0x30u,0x35u,0x91u,0x13u,0xc2u,0x4cu,0xe3u,0x56u,0xebu,0x9cu,0xc0u,0x07u,0x2cu,0x68u,0x5cu,0x6fu,0xfau,0xb3u,0xd3u,0x55u,0xe3u,0x32u,0x37u,0xdfu,0x15u, +}; + +#elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1Domain[432] = { + /* SEQUENCE */ + 0x30u,0x82u,0x01u,0xacu, + /* version */ + 0x02u,0x01u,0x01u, + /* SEQUENCE */ + 0x30u,0x4du, + /* prime OID */ + 0x06u,0x07u,0x2au,0x86u,0x48u,0xceu,0x3du,0x01u,0x01u, + /* p (field prime) */ + 0x02u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu, + /* SEQUENCE */ + 0x30u,0x81u,0x88u, + /* a (coefficient a of the curve equation) */ + 0x04u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u,0x42u,0x00u,0x51u,0x95u,0x3eu,0xb9u,0x61u,0x8eu,0x1cu,0x9au,0x1fu,0x92u,0x9au,0x21u,0xa0u,0xb6u,0x85u,0x40u,0xeeu,0xa2u,0xdau,0x72u,0x5bu,0x99u,0xb3u,0x15u,0xf3u,0xb8u,0xb4u,0x89u,0x91u,0x8eu,0xf1u,0x09u,0xe1u,0x56u,0x19u,0x39u,0x51u,0xecu,0x7eu,0x93u,0x7bu,0x16u,0x52u,0xc0u,0xbdu,0x3bu,0xb1u,0xbfu,0x07u,0x35u,0x73u,0xdfu,0x88u,0x3du,0x2cu,0x34u,0xf1u,0xefu,0x45u,0x1fu,0xd4u,0x6bu,0x50u,0x3fu,0x00u, + /* G (basepoint of the curve) */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0xc6u,0x85u,0x8eu,0x06u,0xb7u,0x04u,0x04u,0xe9u,0xcdu,0x9eu,0x3eu,0xcbu,0x66u,0x23u,0x95u,0xb4u,0x42u,0x9cu,0x64u,0x81u,0x39u,0x05u,0x3fu,0xb5u,0x21u,0xf8u,0x28u,0xafu,0x60u,0x6bu,0x4du,0x3du,0xbau,0xa1u,0x4bu,0x5eu,0x77u,0xefu,0xe7u,0x59u,0x28u,0xfeu,0x1du,0xc1u,0x27u,0xa2u,0xffu,0xa8u,0xdeu,0x33u,0x48u,0xb3u,0xc1u,0x85u,0x6au,0x42u,0x9bu,0xf9u,0x7eu,0x7eu,0x31u,0xc2u,0xe5u,0xbdu,0x66u,0x01u,0x18u,0x39u,0x29u,0x6au,0x78u,0x9au,0x3bu,0xc0u,0x04u,0x5cu,0x8au,0x5fu,0xb4u,0x2cu,0x7du,0x1bu,0xd9u,0x98u,0xf5u,0x44u,0x49u,0x57u,0x9bu,0x44u,0x68u,0x17u,0xafu,0xbdu,0x17u,0x27u,0x3eu,0x66u,0x2cu,0x97u,0xeeu,0x72u,0x99u,0x5eu,0xf4u,0x26u,0x40u,0xc5u,0x50u,0xb9u,0x01u,0x3fu,0xadu,0x07u,0x61u,0x35u,0x3cu,0x70u,0x86u,0xa2u,0x72u,0xc2u,0x40u,0x88u,0xbeu,0x94u,0x76u,0x9fu,0xd1u,0x66u,0x50u, + /* n (order of G) */ + 0x02u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xfau,0x51u,0x86u,0x87u,0x83u,0xbfu,0x2fu,0x96u,0x6bu,0x7fu,0xccu,0x01u,0x48u,0xf7u,0x09u,0xa5u,0xd0u,0x3bu,0xb5u,0xc9u,0xb8u,0x89u,0x9cu,0x47u,0xaeu,0xbbu,0x6fu,0xb7u,0x1eu,0x91u,0x38u,0x64u,0x09u, + /* h (cofactor) */ + 0x02u,0x01u,0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt[429] = { + /* SEQUENCE */ + 0x30u,0x82u,0x01u,0xa9u, + /* SEQUENCE */ + 0x30u,0x82u,0x01u,0x5bu, + /* p_RR (R^2 in prime field) */ + 0x04u,0x42u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x40u,0x00u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u,0x02u,0x00u,0x01u, + /* SEQUENCE */ + 0x30u,0x81u,0x88u, + /* a_R (a in Montgomery representation) */ + 0x04u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xfeu,0x7fu, + /* b_R (b in Montgomery representation) */ + 0x04u,0x42u,0x00u,0xcau,0x9fu,0x5cu,0xb0u,0xc7u,0x0eu,0x4du,0x0fu,0xc9u,0x4du,0x10u,0xd0u,0x5bu,0x42u,0xa0u,0x77u,0x51u,0x6du,0x39u,0x2du,0xccu,0xd9u,0x8au,0xf9u,0xdcu,0x5au,0x44u,0xc8u,0xc7u,0x78u,0x84u,0xf0u,0xabu,0x0cu,0x9cu,0xa8u,0xf6u,0x3fu,0x49u,0xbdu,0x8bu,0x29u,0x60u,0x5eu,0x9du,0xd8u,0xdfu,0x83u,0x9au,0xb9u,0xefu,0xc4u,0x1eu,0x96u,0x1au,0x78u,0xf7u,0xa2u,0x8fu,0xeau,0x35u,0xa8u,0x1fu,0x80u,0x14u, + /* G_R (G in Montgomery representation) */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x42u,0xc7u,0x03u,0x5bu,0x82u,0x02u,0x74u,0xe6u,0xcfu,0x1fu,0x65u,0xb3u,0x11u,0xcau,0xdau,0x21u,0x4eu,0x32u,0x40u,0x9cu,0x82u,0x9fu,0xdau,0x90u,0xfcu,0x14u,0x57u,0xb0u,0x35u,0xa6u,0x9eu,0xddu,0x50u,0xa5u,0xafu,0x3bu,0xf7u,0xf3u,0xacu,0x94u,0x7fu,0x0eu,0xe0u,0x93u,0xd1u,0x7fu,0xd4u,0x6fu,0x19u,0xa4u,0x59u,0xe0u,0xc2u,0xb5u,0x21u,0x4du,0xfcu,0xbfu,0x3fu,0x18u,0xe1u,0x72u,0xdeu,0xb3u,0x31u,0x00u,0x1cu,0x94u,0xb5u,0x3cu,0x4du,0x1du,0xe0u,0x02u,0x2eu,0x45u,0x2fu,0xdau,0x16u,0x3eu,0x8du,0xecu,0xccu,0x7au,0xa2u,0x24u,0xabu,0xcdu,0xa2u,0x34u,0x0bu,0xd7u,0xdeu,0x8bu,0x93u,0x9fu,0x33u,0x16u,0x4bu,0xf7u,0x39u,0x4cu,0xafu,0x7au,0x13u,0x20u,0x62u,0xa8u,0x5cu,0x80u,0x9fu,0xd6u,0x83u,0xb0u,0x9au,0x9eu,0x38u,0x43u,0x51u,0x39u,0x61u,0x20u,0x44u,0x5fu,0x4au,0x3bu,0x4fu,0xe8u,0xb3u,0x28u,0x46u, + /* SEQUENCE */ + 0x30u,0x48u, + /* n_RR (R^2 in order field) */ + 0x04u,0x42u,0x01u,0xeau,0x03u,0x91u,0xa3u,0x9au,0x5bu,0x5au,0x3au,0xfeu,0x8cu,0x44u,0x38u,0x3du,0x2du,0x8eu,0x03u,0xd1u,0x49u,0x2du,0x0du,0x45u,0x5bu,0xccu,0x6du,0x61u,0xa8u,0xe5u,0x67u,0xbcu,0xcfu,0xf3u,0xd1u,0x3du,0x47u,0x71u,0x0au,0x7fu,0x95u,0xe3u,0x35u,0x83u,0x8eu,0x57u,0xadu,0xa6u,0xe9u,0x91u,0x17u,0x1eu,0x2eu,0xf2u,0x1du,0x46u,0x42u,0xa2u,0x3fu,0xb7u,0x35u,0x1cu,0x54u,0x08u,0x56u,0xc0u,0xfbu,0xb8u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u,0x02u,0x95u,0xc7u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1SpeedUpExt[1099] = { + /* SEQUENCE */ + 0x30u,0x82u,0x04u,0x47u, + /* groups parameter */ + 0x04u,0x01u,0x03u, + /* SEQUENCE */ + 0x30u,0x82u,0x04u,0x40u, + /* 2 * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x9eu,0x10u,0xc8u,0x12u,0x13u,0xbfu,0x3fu,0x34u,0x17u,0xe5u,0x94u,0x40u,0xa4u,0x61u,0x41u,0x3au,0x3au,0x01u,0x93u,0xcdu,0x8eu,0x66u,0x03u,0x1au,0x96u,0x37u,0x2au,0x82u,0xebu,0xb4u,0xdfu,0x4bu,0xd9u,0xd9u,0x02u,0x6du,0x37u,0x7au,0xaau,0x83u,0xd5u,0x08u,0x25u,0x1du,0x1au,0xe2u,0xd7u,0xa0u,0xe7u,0x97u,0xd1u,0xb2u,0x6bu,0x07u,0xecu,0xb3u,0xfau,0x1fu,0x1cu,0x99u,0xddu,0x36u,0xbcu,0x1eu,0x90u,0x00u,0x5du,0xc6u,0x63u,0xfcu,0x36u,0xd9u,0x33u,0x80u,0x53u,0xf9u,0xf6u,0x77u,0x77u,0x69u,0xf8u,0x5au,0xe3u,0x5au,0x88u,0x3eu,0x26u,0xd4u,0xbbu,0xa0u,0x55u,0x90u,0xd1u,0x4cu,0x83u,0x62u,0x16u,0xddu,0xd9u,0xf1u,0xbbu,0xefu,0x4fu,0x92u,0x8fu,0xb5u,0xc9u,0xc9u,0xbfu,0xd4u,0xcdu,0x19u,0x24u,0x7au,0x75u,0x7eu,0x5fu,0x4au,0xf6u,0xe0u,0x7au,0x7bu,0x8du,0xf1u,0xabu,0x6bu,0x30u,0xfau,0x0du,0x81u,0x3du, + /* (2^174 + 1) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0xe1u,0x51u,0x77u,0xdeu,0x42u,0x44u,0xaau,0x8eu,0xe7u,0x2cu,0xafu,0x4fu,0x9au,0x9bu,0x7fu,0x03u,0xd4u,0x89u,0x83u,0xe0u,0x29u,0xe1u,0x71u,0x95u,0x01u,0x11u,0xd0u,0x8cu,0xf0u,0x9eu,0x3du,0x8eu,0x89u,0xdcu,0x58u,0x7cu,0xbdu,0xbfu,0xb5u,0x83u,0x46u,0x90u,0x12u,0x37u,0x72u,0x61u,0x14u,0xe2u,0x5du,0x61u,0x01u,0xf7u,0x70u,0x19u,0x66u,0x03u,0x9bu,0x00u,0x2du,0x1bu,0xe3u,0xdcu,0x24u,0x50u,0x06u,0x01u,0x65u,0x10u,0x55u,0xa3u,0x7au,0x73u,0xf2u,0x90u,0xb4u,0x97u,0xb8u,0x96u,0x39u,0xecu,0x68u,0x80u,0x9cu,0x84u,0x3cu,0xa1u,0xf5u,0x24u,0xf1u,0x19u,0x88u,0x88u,0xbcu,0x65u,0x89u,0xa2u,0x47u,0xbcu,0x46u,0xbbu,0x90u,0x68u,0xfbu,0x9cu,0x8cu,0x39u,0xa4u,0x7au,0x03u,0x24u,0x05u,0x68u,0x26u,0xf0u,0x6du,0x0eu,0x2fu,0x9eu,0x40u,0xefu,0x93u,0x3bu,0x76u,0x91u,0x73u,0xdau,0x33u,0x84u,0x0du,0x7eu,0x96u, + /* (2^174 + 2) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x36u,0x4fu,0xacu,0x85u,0x6du,0x00u,0xf2u,0x4eu,0x2fu,0x9du,0x89u,0x81u,0x04u,0x7fu,0x3eu,0x03u,0xa3u,0xcau,0x57u,0xb3u,0x54u,0x4fu,0x02u,0x99u,0x0fu,0x4du,0x2fu,0xf9u,0x33u,0xcbu,0x96u,0x58u,0x23u,0x27u,0x9bu,0xcbu,0xbcu,0xd9u,0x6cu,0x80u,0xcdu,0x03u,0x7au,0xd9u,0x19u,0x12u,0x6bu,0x32u,0xe2u,0xb7u,0x4bu,0x24u,0x91u,0x5bu,0x79u,0x51u,0x1eu,0x81u,0x09u,0xffu,0x6au,0x5eu,0x75u,0x85u,0x85u,0x01u,0x11u,0xc7u,0x8cu,0xd0u,0x72u,0x64u,0xbdu,0xbeu,0x73u,0x43u,0x7fu,0xe5u,0xc1u,0x20u,0x3eu,0x74u,0xfdu,0xa7u,0xe8u,0x16u,0x3bu,0xdau,0x93u,0xd5u,0x7cu,0xdeu,0x89u,0x23u,0xecu,0x09u,0xeau,0x5fu,0x93u,0x90u,0x79u,0x30u,0xd9u,0x54u,0x1cu,0x1au,0x37u,0x24u,0x98u,0x8cu,0xceu,0x93u,0xa2u,0x9eu,0x59u,0x84u,0x8au,0xb0u,0x1eu,0x24u,0xa6u,0x36u,0x82u,0x6du,0xfbu,0x8cu,0xfdu,0xb6u,0x74u,0xf7u,0xacu, + /* (2^348 + 1) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x8cu,0x2cu,0xfeu,0x90u,0x6fu,0x1cu,0x23u,0x3eu,0xb0u,0x76u,0xa1u,0xf7u,0x67u,0x7au,0x2bu,0xcau,0xf2u,0xa9u,0x17u,0xd7u,0xf9u,0xfbu,0x6cu,0x75u,0x42u,0xd9u,0x25u,0xe2u,0x3au,0x47u,0x4bu,0xd6u,0x9eu,0x7cu,0xd7u,0xa6u,0xf1u,0x60u,0xbcu,0x3au,0x70u,0x39u,0x54u,0xc0u,0x56u,0x3bu,0x54u,0x46u,0x87u,0x3eu,0xc2u,0xacu,0xddu,0xdeu,0x0bu,0xacu,0x33u,0x5eu,0xcdu,0x06u,0xe6u,0xb4u,0xc3u,0x4bu,0xf5u,0x00u,0xc8u,0xf0u,0x5bu,0xa3u,0x73u,0x91u,0xf1u,0x3cu,0x04u,0xfdu,0xb9u,0x06u,0x58u,0xfbu,0xaeu,0x48u,0x0eu,0xdfu,0x52u,0xedu,0x74u,0x05u,0x6du,0x5au,0x23u,0x44u,0x3fu,0x3au,0x46u,0x0cu,0xd3u,0xbau,0x05u,0x1cu,0x5cu,0xa9u,0xcdu,0x13u,0x11u,0x41u,0x96u,0x58u,0x5au,0xb8u,0x77u,0x44u,0xfcu,0x7au,0x9bu,0x98u,0xdeu,0x63u,0xffu,0x72u,0x2au,0x76u,0xf3u,0x16u,0x3bu,0x5cu,0xacu,0x74u,0x0cu,0x0eu,0x71u, + /* (2^348 + 2) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0xecu,0x3fu,0x0au,0x19u,0xefu,0xbau,0xafu,0xccu,0x4bu,0xffu,0x94u,0x65u,0xc1u,0xecu,0x0fu,0xd3u,0xc4u,0xd2u,0x67u,0x22u,0xc6u,0xebu,0x0bu,0x8bu,0xa9u,0xc2u,0xd7u,0x7du,0x80u,0x23u,0xc4u,0x64u,0xe6u,0x9bu,0x15u,0xd9u,0x81u,0xbfu,0x6au,0x56u,0x90u,0xacu,0xe1u,0x97u,0x65u,0x81u,0xc6u,0xdau,0x53u,0x36u,0xa1u,0x3fu,0xa7u,0x4du,0x01u,0x90u,0x55u,0xabu,0x41u,0xcfu,0x26u,0xceu,0x39u,0xa8u,0x46u,0x01u,0xa4u,0xddu,0xdeu,0xe9u,0xb2u,0x92u,0x9eu,0x4cu,0x3au,0xfbu,0x96u,0x26u,0x73u,0x18u,0xf9u,0x04u,0xb5u,0x5au,0x4au,0xe0u,0x60u,0x58u,0xb7u,0xb0u,0x0cu,0x13u,0xfdu,0xe5u,0x80u,0x3fu,0xf9u,0x2bu,0x8eu,0x8bu,0x7eu,0xa1u,0x10u,0x43u,0xb2u,0x6cu,0xd9u,0xccu,0xe1u,0x02u,0x07u,0x04u,0xe1u,0xbfu,0x30u,0x42u,0x04u,0xc9u,0x37u,0xa8u,0xd9u,0xd0u,0x09u,0xe4u,0x8cu,0x82u,0x6du,0x1du,0xa3u,0xebu,0x46u, + /* (2^348 + 2^174 + 1) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0x67u,0x9bu,0xa9u,0xddu,0x43u,0x03u,0xe7u,0xb4u,0x83u,0xc5u,0xd0u,0xbfu,0x7du,0x9eu,0xa6u,0x48u,0xe9u,0xd6u,0x8fu,0xabu,0xc3u,0xf7u,0x17u,0x61u,0x10u,0x10u,0x55u,0xcau,0x2du,0x38u,0xd5u,0xb4u,0x82u,0xffu,0xbcu,0x66u,0xbeu,0x23u,0x37u,0x84u,0x03u,0xdcu,0x85u,0x6cu,0xd5u,0xfeu,0x76u,0xc1u,0xf0u,0xf2u,0xc4u,0xf9u,0xe5u,0x54u,0x90u,0x7bu,0xaau,0xd2u,0xf4u,0x7au,0x32u,0x0du,0xbfu,0x04u,0x4eu,0x01u,0xb1u,0x9fu,0xfau,0x6fu,0xc9u,0x20u,0xbcu,0x36u,0x89u,0x33u,0x5bu,0x5cu,0xedu,0x2cu,0xc2u,0x1fu,0xabu,0x89u,0x1eu,0xccu,0xdeu,0xa4u,0x73u,0x38u,0xe9u,0xaau,0xa7u,0xd1u,0x7fu,0xc6u,0x95u,0xc1u,0xcbu,0x94u,0x4bu,0x6du,0x8fu,0x8bu,0x4bu,0x43u,0xa6u,0x4cu,0xa2u,0xb2u,0x17u,0xbbu,0xd4u,0x2eu,0xe9u,0x05u,0x9eu,0x84u,0x42u,0x2au,0x64u,0xbcu,0xdau,0xf1u,0xc8u,0xf1u,0x5cu,0xd9u,0x13u,0x00u,0x47u, + /* (2^348 + 2^174 + 2) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x3bu,0x98u,0x9bu,0x87u,0x4du,0x06u,0x72u,0x8du,0x7au,0x77u,0x20u,0xa9u,0xd6u,0xf1u,0xf8u,0xbcu,0x3au,0x39u,0x6fu,0x04u,0x4fu,0xeau,0x08u,0x93u,0xbdu,0x35u,0x1bu,0xffu,0xccu,0xd7u,0x5eu,0xdeu,0x0du,0x6au,0xfau,0xe5u,0x34u,0x97u,0x4bu,0x61u,0x8au,0x5eu,0x2cu,0x93u,0xf8u,0x6cu,0xc8u,0x47u,0xe5u,0x1bu,0x51u,0xbau,0x32u,0x35u,0xe0u,0x22u,0x69u,0x2au,0xc5u,0xf6u,0xdcu,0x31u,0x1eu,0xe0u,0x3du,0x01u,0xefu,0xfbu,0x64u,0x11u,0x06u,0x31u,0x02u,0xb2u,0xe4u,0xb7u,0x21u,0xb7u,0x1au,0xc5u,0x63u,0xc7u,0x63u,0xb3u,0x2cu,0x08u,0x13u,0xdbu,0x35u,0x78u,0x45u,0x6cu,0xddu,0x7du,0xaau,0x9cu,0x0cu,0x45u,0x37u,0xfeu,0x2eu,0xf8u,0x73u,0x35u,0xdau,0x6du,0x3bu,0x6au,0x39u,0x48u,0x4fu,0xbbu,0xceu,0xdau,0xbau,0x6bu,0xb0u,0x6bu,0xccu,0xeau,0xdau,0xc2u,0x5fu,0x27u,0x0eu,0xedu,0x90u,0x57u,0x32u,0x5eu,0x2bu, + /* correction point D = - ((2^174 - 1) * G) in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0x3au,0x67u,0xe5u,0xe1u,0x41u,0xb5u,0x93u,0xf6u,0xc7u,0x9cu,0x37u,0x00u,0x20u,0x7du,0x83u,0xcbu,0x87u,0x5fu,0x2au,0x22u,0xdfu,0x95u,0x81u,0x8cu,0x5eu,0xa0u,0x2du,0x84u,0x05u,0xa4u,0xb3u,0x3au,0x69u,0x06u,0x98u,0xfdu,0xc0u,0x3eu,0xadu,0x83u,0x83u,0x40u,0x79u,0xadu,0x6eu,0xe1u,0x3bu,0x59u,0x60u,0xb4u,0x65u,0xb5u,0x96u,0x5bu,0xd5u,0x4eu,0x79u,0xf0u,0xf7u,0xb6u,0x57u,0x92u,0x99u,0x39u,0xd9u,0x00u,0x79u,0x0du,0x13u,0x65u,0x21u,0xb9u,0x51u,0x80u,0xeau,0xd6u,0x4bu,0xe9u,0x83u,0xc1u,0x3au,0x91u,0x3du,0x85u,0x8cu,0xf5u,0x0cu,0x74u,0x4cu,0x47u,0xe0u,0xc7u,0x32u,0x98u,0xd8u,0x5au,0xa2u,0x8eu,0xceu,0xbau,0xedu,0x8eu,0x3eu,0x9cu,0x05u,0xb2u,0x30u,0x35u,0x91u,0x13u,0xc2u,0x4cu,0xe3u,0x56u,0xebu,0x9cu,0xc0u,0x07u,0x2cu,0x68u,0x5cu,0x6fu,0xfau,0xb3u,0xd3u,0x55u,0xe3u,0x32u,0x37u,0xdfu,0x15u, +}; + +#elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1Domain[432] = { + /* SEQUENCE */ + 0x30u,0x82u,0x01u,0xacu, + /* version */ + 0x02u,0x01u,0x01u, + /* SEQUENCE */ + 0x30u,0x4du, + /* prime OID */ + 0x06u,0x07u,0x2au,0x86u,0x48u,0xceu,0x3du,0x01u,0x01u, + /* p (field prime) */ + 0x02u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu, + /* SEQUENCE */ + 0x30u,0x81u,0x88u, + /* a (coefficient a of the curve equation) */ + 0x04u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xfcu, + /* b (coefficient b of the curve equation) */ + 0x04u,0x42u,0x00u,0x51u,0x95u,0x3eu,0xb9u,0x61u,0x8eu,0x1cu,0x9au,0x1fu,0x92u,0x9au,0x21u,0xa0u,0xb6u,0x85u,0x40u,0xeeu,0xa2u,0xdau,0x72u,0x5bu,0x99u,0xb3u,0x15u,0xf3u,0xb8u,0xb4u,0x89u,0x91u,0x8eu,0xf1u,0x09u,0xe1u,0x56u,0x19u,0x39u,0x51u,0xecu,0x7eu,0x93u,0x7bu,0x16u,0x52u,0xc0u,0xbdu,0x3bu,0xb1u,0xbfu,0x07u,0x35u,0x73u,0xdfu,0x88u,0x3du,0x2cu,0x34u,0xf1u,0xefu,0x45u,0x1fu,0xd4u,0x6bu,0x50u,0x3fu,0x00u, + /* G (basepoint of the curve) */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0xc6u,0x85u,0x8eu,0x06u,0xb7u,0x04u,0x04u,0xe9u,0xcdu,0x9eu,0x3eu,0xcbu,0x66u,0x23u,0x95u,0xb4u,0x42u,0x9cu,0x64u,0x81u,0x39u,0x05u,0x3fu,0xb5u,0x21u,0xf8u,0x28u,0xafu,0x60u,0x6bu,0x4du,0x3du,0xbau,0xa1u,0x4bu,0x5eu,0x77u,0xefu,0xe7u,0x59u,0x28u,0xfeu,0x1du,0xc1u,0x27u,0xa2u,0xffu,0xa8u,0xdeu,0x33u,0x48u,0xb3u,0xc1u,0x85u,0x6au,0x42u,0x9bu,0xf9u,0x7eu,0x7eu,0x31u,0xc2u,0xe5u,0xbdu,0x66u,0x01u,0x18u,0x39u,0x29u,0x6au,0x78u,0x9au,0x3bu,0xc0u,0x04u,0x5cu,0x8au,0x5fu,0xb4u,0x2cu,0x7du,0x1bu,0xd9u,0x98u,0xf5u,0x44u,0x49u,0x57u,0x9bu,0x44u,0x68u,0x17u,0xafu,0xbdu,0x17u,0x27u,0x3eu,0x66u,0x2cu,0x97u,0xeeu,0x72u,0x99u,0x5eu,0xf4u,0x26u,0x40u,0xc5u,0x50u,0xb9u,0x01u,0x3fu,0xadu,0x07u,0x61u,0x35u,0x3cu,0x70u,0x86u,0xa2u,0x72u,0xc2u,0x40u,0x88u,0xbeu,0x94u,0x76u,0x9fu,0xd1u,0x66u,0x50u, + /* n (order of G) */ + 0x02u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xfau,0x51u,0x86u,0x87u,0x83u,0xbfu,0x2fu,0x96u,0x6bu,0x7fu,0xccu,0x01u,0x48u,0xf7u,0x09u,0xa5u,0xd0u,0x3bu,0xb5u,0xc9u,0xb8u,0x89u,0x9cu,0x47u,0xaeu,0xbbu,0x6fu,0xb7u,0x1eu,0x91u,0x38u,0x64u,0x09u, + /* h (cofactor) */ + 0x02u,0x01u,0x01u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt[433] = { + /* SEQUENCE */ + 0x30u,0x82u,0x01u,0xadu, + /* SEQUENCE */ + 0x30u,0x82u,0x01u,0x5du, + /* p_RR (R^2 in prime field) */ + 0x04u,0x42u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x00u,0x40u,0x00u,0x00u,0x00u,0x00u,0x00u, + /* p_bar (low digit of -(p^-1)) */ + 0x04u,0x04u,0x00u,0x00u,0x00u,0x01u, + /* SEQUENCE */ + 0x30u,0x81u,0x88u, + /* a_R (a in Montgomery representation) */ + 0x04u,0x42u,0x01u,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xffu,0xfeu,0x7fu,0xffu,0xffu, + /* b_R (b in Montgomery representation) */ + 0x04u,0x42u,0x01u,0x5cu,0xb0u,0xc7u,0x0eu,0x4du,0x0fu,0xc9u,0x4du,0x10u,0xd0u,0x5bu,0x42u,0xa0u,0x77u,0x51u,0x6du,0x39u,0x2du,0xccu,0xd9u,0x8au,0xf9u,0xdcu,0x5au,0x44u,0xc8u,0xc7u,0x78u,0x84u,0xf0u,0xabu,0x0cu,0x9cu,0xa8u,0xf6u,0x3fu,0x49u,0xbdu,0x8bu,0x29u,0x60u,0x5eu,0x9du,0xd8u,0xdfu,0x83u,0x9au,0xb9u,0xefu,0xc4u,0x1eu,0x96u,0x1au,0x78u,0xf7u,0xa2u,0x8fu,0xeau,0x35u,0xa8u,0x1fu,0x80u,0x14u,0x65u,0x4fu, + /* G_R (G in Montgomery representation) */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x03u,0x5bu,0x82u,0x02u,0x74u,0xe6u,0xcfu,0x1fu,0x65u,0xb3u,0x11u,0xcau,0xdau,0x21u,0x4eu,0x32u,0x40u,0x9cu,0x82u,0x9fu,0xdau,0x90u,0xfcu,0x14u,0x57u,0xb0u,0x35u,0xa6u,0x9eu,0xddu,0x50u,0xa5u,0xafu,0x3bu,0xf7u,0xf3u,0xacu,0x94u,0x7fu,0x0eu,0xe0u,0x93u,0xd1u,0x7fu,0xd4u,0x6fu,0x19u,0xa4u,0x59u,0xe0u,0xc2u,0xb5u,0x21u,0x4du,0xfcu,0xbfu,0x3fu,0x18u,0xe1u,0x72u,0xdeu,0xb3u,0x31u,0xa1u,0x63u,0x00u,0xb5u,0x3cu,0x4du,0x1du,0xe0u,0x02u,0x2eu,0x45u,0x2fu,0xdau,0x16u,0x3eu,0x8du,0xecu,0xccu,0x7au,0xa2u,0x24u,0xabu,0xcdu,0xa2u,0x34u,0x0bu,0xd7u,0xdeu,0x8bu,0x93u,0x9fu,0x33u,0x16u,0x4bu,0xf7u,0x39u,0x4cu,0xafu,0x7au,0x13u,0x20u,0x62u,0xa8u,0x5cu,0x80u,0x9fu,0xd6u,0x83u,0xb0u,0x9au,0x9eu,0x38u,0x43u,0x51u,0x39u,0x61u,0x20u,0x44u,0x5fu,0x4au,0x3bu,0x4fu,0xe8u,0xb3u,0x28u,0x46u,0x0eu,0x4au, + /* SEQUENCE */ + 0x30u,0x4au, + /* n_RR (R^2 in order field) */ + 0x04u,0x42u,0x01u,0x9au,0x5bu,0x5au,0x3au,0xfeu,0x8cu,0x44u,0x38u,0x3du,0x2du,0x8eu,0x03u,0xd1u,0x49u,0x2du,0x0du,0x45u,0x5bu,0xccu,0x6du,0x61u,0xa8u,0xe5u,0x67u,0xbcu,0xcfu,0xf3u,0xd1u,0x42u,0xb7u,0x75u,0x6eu,0x3au,0x4fu,0xb3u,0x5bu,0x72u,0xd3u,0x40u,0x27u,0x05u,0x5du,0x4du,0xd6u,0xd3u,0x07u,0x91u,0xd9u,0xdcu,0x18u,0x35u,0x4au,0x56u,0x43u,0x74u,0xa6u,0x42u,0x11u,0x63u,0x11u,0x5au,0x61u,0xc6u,0x4cu,0xa7u, + /* n_bar (low digit of -(n^-1)) */ + 0x04u,0x04u,0x79u,0xa9u,0x95u,0xc7u, +}; +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1SpeedUpExt[1099] = { + /* SEQUENCE */ + 0x30u,0x82u,0x04u,0x47u, + /* groups parameter */ + 0x04u,0x01u,0x03u, + /* SEQUENCE */ + 0x30u,0x82u,0x04u,0x40u, + /* 2 * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0xc8u,0x12u,0x13u,0xbfu,0x3fu,0x34u,0x17u,0xe5u,0x94u,0x40u,0xa4u,0x61u,0x41u,0x3au,0x3au,0x01u,0x93u,0xcdu,0x8eu,0x66u,0x03u,0x1au,0x96u,0x37u,0x2au,0x82u,0xebu,0xb4u,0xdfu,0x4bu,0xd9u,0xd9u,0x02u,0x6du,0x37u,0x7au,0xaau,0x83u,0xd5u,0x08u,0x25u,0x1du,0x1au,0xe2u,0xd7u,0xa0u,0xe7u,0x97u,0xd1u,0xb2u,0x6bu,0x07u,0xecu,0xb3u,0xfau,0x1fu,0x1cu,0x99u,0xddu,0x36u,0xbcu,0x1eu,0x90u,0xcfu,0x08u,0x00u,0x63u,0xfcu,0x36u,0xd9u,0x33u,0x80u,0x53u,0xf9u,0xf6u,0x77u,0x77u,0x69u,0xf8u,0x5au,0xe3u,0x5au,0x88u,0x3eu,0x26u,0xd4u,0xbbu,0xa0u,0x55u,0x90u,0xd1u,0x4cu,0x83u,0x62u,0x16u,0xddu,0xd9u,0xf1u,0xbbu,0xefu,0x4fu,0x92u,0x8fu,0xb5u,0xc9u,0xc9u,0xbfu,0xd4u,0xcdu,0x19u,0x24u,0x7au,0x75u,0x7eu,0x5fu,0x4au,0xf6u,0xe0u,0x7au,0x7bu,0x8du,0xf1u,0xabu,0x6bu,0x30u,0xfau,0x0du,0x81u,0x3du,0x2eu,0xe3u, + /* (2^174 + 1) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x77u,0xdeu,0x42u,0x44u,0xaau,0x8eu,0xe7u,0x2cu,0xafu,0x4fu,0x9au,0x9bu,0x7fu,0x03u,0xd4u,0x89u,0x83u,0xe0u,0x29u,0xe1u,0x71u,0x95u,0x01u,0x11u,0xd0u,0x8cu,0xf0u,0x9eu,0x3du,0x8eu,0x89u,0xdcu,0x58u,0x7cu,0xbdu,0xbfu,0xb5u,0x83u,0x46u,0x90u,0x12u,0x37u,0x72u,0x61u,0x14u,0xe2u,0x5du,0x61u,0x01u,0xf7u,0x70u,0x19u,0x66u,0x03u,0x9bu,0x00u,0x2du,0x1bu,0xe3u,0xdcu,0x24u,0x50u,0x06u,0x70u,0xa8u,0x00u,0x55u,0xa3u,0x7au,0x73u,0xf2u,0x90u,0xb4u,0x97u,0xb8u,0x96u,0x39u,0xecu,0x68u,0x80u,0x9cu,0x84u,0x3cu,0xa1u,0xf5u,0x24u,0xf1u,0x19u,0x88u,0x88u,0xbcu,0x65u,0x89u,0xa2u,0x47u,0xbcu,0x46u,0xbbu,0x90u,0x68u,0xfbu,0x9cu,0x8cu,0x39u,0xa4u,0x7au,0x03u,0x24u,0x05u,0x68u,0x26u,0xf0u,0x6du,0x0eu,0x2fu,0x9eu,0x40u,0xefu,0x93u,0x3bu,0x76u,0x91u,0x73u,0xdau,0x33u,0x84u,0x0du,0x7eu,0x96u,0xb2u,0x88u, + /* (2^174 + 2) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0xacu,0x85u,0x6du,0x00u,0xf2u,0x4eu,0x2fu,0x9du,0x89u,0x81u,0x04u,0x7fu,0x3eu,0x03u,0xa3u,0xcau,0x57u,0xb3u,0x54u,0x4fu,0x02u,0x99u,0x0fu,0x4du,0x2fu,0xf9u,0x33u,0xcbu,0x96u,0x58u,0x23u,0x27u,0x9bu,0xcbu,0xbcu,0xd9u,0x6cu,0x80u,0xcdu,0x03u,0x7au,0xd9u,0x19u,0x12u,0x6bu,0x32u,0xe2u,0xb7u,0x4bu,0x24u,0x91u,0x5bu,0x79u,0x51u,0x1eu,0x81u,0x09u,0xffu,0x6au,0x5eu,0x75u,0x85u,0x85u,0x9bu,0x27u,0x01u,0x8cu,0xd0u,0x72u,0x64u,0xbdu,0xbeu,0x73u,0x43u,0x7fu,0xe5u,0xc1u,0x20u,0x3eu,0x74u,0xfdu,0xa7u,0xe8u,0x16u,0x3bu,0xdau,0x93u,0xd5u,0x7cu,0xdeu,0x89u,0x23u,0xecu,0x09u,0xeau,0x5fu,0x93u,0x90u,0x79u,0x30u,0xd9u,0x54u,0x1cu,0x1au,0x37u,0x24u,0x98u,0x8cu,0xceu,0x93u,0xa2u,0x9eu,0x59u,0x84u,0x8au,0xb0u,0x1eu,0x24u,0xa6u,0x36u,0x82u,0x6du,0xfbu,0x8cu,0xfdu,0xb6u,0x74u,0xf7u,0xacu,0x88u,0xe3u, + /* (2^348 + 1) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0xfeu,0x90u,0x6fu,0x1cu,0x23u,0x3eu,0xb0u,0x76u,0xa1u,0xf7u,0x67u,0x7au,0x2bu,0xcau,0xf2u,0xa9u,0x17u,0xd7u,0xf9u,0xfbu,0x6cu,0x75u,0x42u,0xd9u,0x25u,0xe2u,0x3au,0x47u,0x4bu,0xd6u,0x9eu,0x7cu,0xd7u,0xa6u,0xf1u,0x60u,0xbcu,0x3au,0x70u,0x39u,0x54u,0xc0u,0x56u,0x3bu,0x54u,0x46u,0x87u,0x3eu,0xc2u,0xacu,0xddu,0xdeu,0x0bu,0xacu,0x33u,0x5eu,0xcdu,0x06u,0xe6u,0xb4u,0xc3u,0x4bu,0xf5u,0xc6u,0x16u,0x00u,0x5bu,0xa3u,0x73u,0x91u,0xf1u,0x3cu,0x04u,0xfdu,0xb9u,0x06u,0x58u,0xfbu,0xaeu,0x48u,0x0eu,0xdfu,0x52u,0xedu,0x74u,0x05u,0x6du,0x5au,0x23u,0x44u,0x3fu,0x3au,0x46u,0x0cu,0xd3u,0xbau,0x05u,0x1cu,0x5cu,0xa9u,0xcdu,0x13u,0x11u,0x41u,0x96u,0x58u,0x5au,0xb8u,0x77u,0x44u,0xfcu,0x7au,0x9bu,0x98u,0xdeu,0x63u,0xffu,0x72u,0x2au,0x76u,0xf3u,0x16u,0x3bu,0x5cu,0xacu,0x74u,0x0cu,0x0eu,0x71u,0x64u,0x78u, + /* (2^348 + 2) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0x0au,0x19u,0xefu,0xbau,0xafu,0xccu,0x4bu,0xffu,0x94u,0x65u,0xc1u,0xecu,0x0fu,0xd3u,0xc4u,0xd2u,0x67u,0x22u,0xc6u,0xebu,0x0bu,0x8bu,0xa9u,0xc2u,0xd7u,0x7du,0x80u,0x23u,0xc4u,0x64u,0xe6u,0x9bu,0x15u,0xd9u,0x81u,0xbfu,0x6au,0x56u,0x90u,0xacu,0xe1u,0x97u,0x65u,0x81u,0xc6u,0xdau,0x53u,0x36u,0xa1u,0x3fu,0xa7u,0x4du,0x01u,0x90u,0x55u,0xabu,0x41u,0xcfu,0x26u,0xceu,0x39u,0xa8u,0x46u,0x76u,0x1fu,0x01u,0xdeu,0xe9u,0xb2u,0x92u,0x9eu,0x4cu,0x3au,0xfbu,0x96u,0x26u,0x73u,0x18u,0xf9u,0x04u,0xb5u,0x5au,0x4au,0xe0u,0x60u,0x58u,0xb7u,0xb0u,0x0cu,0x13u,0xfdu,0xe5u,0x80u,0x3fu,0xf9u,0x2bu,0x8eu,0x8bu,0x7eu,0xa1u,0x10u,0x43u,0xb2u,0x6cu,0xd9u,0xccu,0xe1u,0x02u,0x07u,0x04u,0xe1u,0xbfu,0x30u,0x42u,0x04u,0xc9u,0x37u,0xa8u,0xd9u,0xd0u,0x09u,0xe4u,0x8cu,0x82u,0x6du,0x1du,0xa3u,0xebu,0x46u,0xd2u,0x6eu, + /* (2^348 + 2^174 + 1) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0xa9u,0xddu,0x43u,0x03u,0xe7u,0xb4u,0x83u,0xc5u,0xd0u,0xbfu,0x7du,0x9eu,0xa6u,0x48u,0xe9u,0xd6u,0x8fu,0xabu,0xc3u,0xf7u,0x17u,0x61u,0x10u,0x10u,0x55u,0xcau,0x2du,0x38u,0xd5u,0xb4u,0x82u,0xffu,0xbcu,0x66u,0xbeu,0x23u,0x37u,0x84u,0x03u,0xdcu,0x85u,0x6cu,0xd5u,0xfeu,0x76u,0xc1u,0xf0u,0xf2u,0xc4u,0xf9u,0xe5u,0x54u,0x90u,0x7bu,0xaau,0xd2u,0xf4u,0x7au,0x32u,0x0du,0xbfu,0x04u,0x4eu,0x33u,0xcdu,0x01u,0xfau,0x6fu,0xc9u,0x20u,0xbcu,0x36u,0x89u,0x33u,0x5bu,0x5cu,0xedu,0x2cu,0xc2u,0x1fu,0xabu,0x89u,0x1eu,0xccu,0xdeu,0xa4u,0x73u,0x38u,0xe9u,0xaau,0xa7u,0xd1u,0x7fu,0xc6u,0x95u,0xc1u,0xcbu,0x94u,0x4bu,0x6du,0x8fu,0x8bu,0x4bu,0x43u,0xa6u,0x4cu,0xa2u,0xb2u,0x17u,0xbbu,0xd4u,0x2eu,0xe9u,0x05u,0x9eu,0x84u,0x42u,0x2au,0x64u,0xbcu,0xdau,0xf1u,0xc8u,0xf1u,0x5cu,0xd9u,0x13u,0x00u,0x47u,0xd8u,0xcfu, + /* (2^348 + 2^174 + 2) * G in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x00u,0x9bu,0x87u,0x4du,0x06u,0x72u,0x8du,0x7au,0x77u,0x20u,0xa9u,0xd6u,0xf1u,0xf8u,0xbcu,0x3au,0x39u,0x6fu,0x04u,0x4fu,0xeau,0x08u,0x93u,0xbdu,0x35u,0x1bu,0xffu,0xccu,0xd7u,0x5eu,0xdeu,0x0du,0x6au,0xfau,0xe5u,0x34u,0x97u,0x4bu,0x61u,0x8au,0x5eu,0x2cu,0x93u,0xf8u,0x6cu,0xc8u,0x47u,0xe5u,0x1bu,0x51u,0xbau,0x32u,0x35u,0xe0u,0x22u,0x69u,0x2au,0xc5u,0xf6u,0xdcu,0x31u,0x1eu,0xe0u,0x3du,0x9du,0xccu,0x01u,0x64u,0x11u,0x06u,0x31u,0x02u,0xb2u,0xe4u,0xb7u,0x21u,0xb7u,0x1au,0xc5u,0x63u,0xc7u,0x63u,0xb3u,0x2cu,0x08u,0x13u,0xdbu,0x35u,0x78u,0x45u,0x6cu,0xddu,0x7du,0xaau,0x9cu,0x0cu,0x45u,0x37u,0xfeu,0x2eu,0xf8u,0x73u,0x35u,0xdau,0x6du,0x3bu,0x6au,0x39u,0x48u,0x4fu,0xbbu,0xceu,0xdau,0xbau,0x6bu,0xb0u,0x6bu,0xccu,0xeau,0xdau,0xc2u,0x5fu,0x27u,0x0eu,0xedu,0x90u,0x57u,0x32u,0x5eu,0x2bu,0xf7u,0xfdu, + /* correction point D = - ((2^174 - 1) * G) in Montgomery representation */ + 0x04u,0x81u,0x85u,0x04u,0x01u,0xe5u,0xe1u,0x41u,0xb5u,0x93u,0xf6u,0xc7u,0x9cu,0x37u,0x00u,0x20u,0x7du,0x83u,0xcbu,0x87u,0x5fu,0x2au,0x22u,0xdfu,0x95u,0x81u,0x8cu,0x5eu,0xa0u,0x2du,0x84u,0x05u,0xa4u,0xb3u,0x3au,0x69u,0x06u,0x98u,0xfdu,0xc0u,0x3eu,0xadu,0x83u,0x83u,0x40u,0x79u,0xadu,0x6eu,0xe1u,0x3bu,0x59u,0x60u,0xb4u,0x65u,0xb5u,0x96u,0x5bu,0xd5u,0x4eu,0x79u,0xf0u,0xf7u,0xb6u,0x57u,0x92u,0x99u,0x39u,0xd9u,0x1du,0x33u,0x01u,0x13u,0x65u,0x21u,0xb9u,0x51u,0x80u,0xeau,0xd6u,0x4bu,0xe9u,0x83u,0xc1u,0x3au,0x91u,0x3du,0x85u,0x8cu,0xf5u,0x0cu,0x74u,0x4cu,0x47u,0xe0u,0xc7u,0x32u,0x98u,0xd8u,0x5au,0xa2u,0x8eu,0xceu,0xbau,0xedu,0x8eu,0x3eu,0x9cu,0x05u,0xb2u,0x30u,0x35u,0x91u,0x13u,0xc2u,0x4cu,0xe3u,0x56u,0xebu,0x9cu,0xc0u,0x07u,0x2cu,0x68u,0x5cu,0x6fu,0xfau,0xb3u,0xd3u,0x55u,0xe3u,0x32u,0x37u,0xdfu,0x15u,0x3cu,0x86u, +}; +#else /* CRYPTO_30_LIBCV_BYTES_PER_DIGIT */ +# error "Value of CRYPTO_30_LIBCV_BYTES_PER_DIGIT is not supported" +#endif /* CRYPTO_30_LIBCV_BYTES_PER_DIGIT */ +/* NIST_SEC_p521r1 END *********************************************************************************************/ + +/* Edwards448 START **************************************************************************************************/ +/* group order: + * q = 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d + * = 181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779 + * = 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3 + * (446 bit long) + */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveEdwards448GroupOrder[56] = +{ + 0xabu, 0x58u, 0x44u, 0xf3u, 0x23u, 0x78u, 0xc2u, 0x92u, 0x8du, 0xc5u, 0x8fu, 0x55u, 0x21u, 0x6cu, 0xc2u, 0x72u, + 0xaeu, 0xd6u, 0x36u, 0x90u, 0xc4u, 0x4eu, 0xdbu, 0x49u, 0x7cu, 0xcau, 0x23u, 0xe9u, 0xffu, 0xffu, 0xffu, 0xffu, + 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, + 0xffu, 0xffu, 0xffu, 0xffu, 0x3fu, 0xffu, 0xffu, 0xffu +}; +/* Edwards448 END ****************************************************************************************************/ + +/* Sm2p256v1 START *********************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * The curve params in shorthand notation: + * Name: Sm2p256v1 + * p: 0xfffffffe ffffffff ffffffff ffffffff ffffffff 00000000 ffffffff ffffffff + * a: 0xfffffffe ffffffff ffffffff ffffffff ffffffff 00000000 ffffffff fffffffc + * b: 0x28e9fa9e 9d9f5e34 4d5a9e4b cf6509a7 f39789f5 15ab8f92 ddbcbd41 4d940e93 + * Gx: 0x32c4ae2c 1f198119 5f990446 6a39c994 8fe30bbf f2660be1 715a4589 334c74c7 + * Gy: 0xbc3736a2 f4f6779c 59bdcee3 6b692153 d0a9877c c62a4740 02df32e5 2139f0a0 + * n: 0xfffffffe ffffffff ffffffff ffffffff 7203df6b 21c6052b 53bbf409 39d54123 + * h: 0x01 + */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSm2P256v1Domain[227] = +{ + /* SEQUENCE */ + 0x30,0x81,0xe0, + /* version */ + 0x02,0x01,0x01, + /* SEQUENCE */ + 0x30,0x2c, + /* prime OID */ + 0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x01,0x01, + /* p (field prime) */ + 0x02,0x21,0x00,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + /* SEQUENCE */ + 0x30,0x44, + /* a (coefficient a of the curve equation) */ + 0x04,0x20,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc, + /* b (coefficient b of the curve equation) */ + 0x04,0x20,0x28,0xe9,0xfa,0x9e,0x9d,0x9f,0x5e,0x34,0x4d,0x5a,0x9e,0x4b,0xcf,0x65,0x09,0xa7,0xf3,0x97,0x89,0xf5,0x15,0xab,0x8f,0x92,0xdd,0xbc,0xbd,0x41,0x4d,0x94,0x0e,0x93, + /* G (basepoint of the curve) */ + 0x04,0x41,0x04,0x32,0xc4,0xae,0x2c,0x1f,0x19,0x81,0x19,0x5f,0x99,0x04,0x46,0x6a,0x39,0xc9,0x94,0x8f,0xe3,0x0b,0xbf,0xf2,0x66,0x0b,0xe1,0x71,0x5a,0x45,0x89,0x33,0x4c,0x74,0xc7,0xbc,0x37,0x36,0xa2,0xf4,0xf6,0x77,0x9c,0x59,0xbd,0xce,0xe3,0x6b,0x69,0x21,0x53,0xd0,0xa9,0x87,0x7c,0xc6,0x2a,0x47,0x40,0x02,0xdf,0x32,0xe5,0x21,0x39,0xf0,0xa0, + /* n (order of G) */ + 0x02,0x21,0x00,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x72,0x03,0xdf,0x6b,0x21,0xc6,0x05,0x2b,0x53,0xbb,0xf4,0x09,0x39,0xd5,0x41,0x23, + /* h (cofactor) */ + 0x02,0x01,0x01 +}; +#if (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSm2P256v1DomainExt[219] = +{ + /* SEQUENCE */ + 0x30,0x81,0xd8, + /* SEQUENCE */ + 0x30,0x81,0xae, + /* p_RR (R^2 in prime field) */ + 0x04,0x20,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03, + /* p_bar (low digit of -(p^-1)) */ + 0x04,0x01,0x01, + /* SEQUENCE */ + 0x30,0x44, + /* a_R (a in Montgomery representation) */ + 0x04,0x20,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc, + /* b_R (b in Montgomery representation) */ + 0x04,0x20,0x24,0x0f,0xe1,0x88,0xba,0x20,0xe2,0xc8,0x52,0x79,0x81,0x50,0x5e,0xa5,0x1c,0x3c,0x71,0xcf,0x37,0x9a,0xe9,0xb5,0x37,0xab,0x90,0xd2,0x30,0x63,0x2b,0xc0,0xdd,0x42, + /* G_R (G in Montgomery representation) */ + 0x04,0x41,0x04,0x91,0x16,0x7a,0x5e,0xe1,0xc1,0x3b,0x05,0xd6,0xa1,0xed,0x99,0xac,0x24,0xc3,0xc3,0x3e,0x79,0x81,0xed,0xdc,0xa6,0xc0,0x50,0x61,0x32,0x89,0x90,0xf4,0x18,0x02,0x9e,0x63,0xcd,0x65,0xd4,0x81,0xd7,0x35,0xbd,0x8d,0x4c,0xfb,0x06,0x6e,0x2a,0x48,0xf8,0xc1,0xf5,0xe5,0x78,0x8d,0x32,0x95,0xfa,0xc1,0x35,0x4e,0x59,0x3c,0x2d,0x0d,0xdd, + /* SEQUENCE */ + 0x30,0x25, + /* n_RR (R^2 in order field) */ + 0x04,0x20,0x1e,0xb5,0xe4,0x12,0xa2,0x2b,0x3d,0x3b,0x62,0x0f,0xc8,0x4c,0x3a,0xff,0xe0,0xd4,0x34,0x64,0x50,0x4a,0xde,0x6f,0xa2,0xfa,0x90,0x11,0x92,0xaf,0x7c,0x11,0x4f,0x20, + /* n_bar (low digit of -(n^-1)) */ + 0x04,0x01,0x75 +}; +#elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSm2P256v1DomainExt[221] = +{ + /* SEQUENCE */ + 0x30,0x81,0xda, + /* SEQUENCE */ + 0x30,0x81,0xaf, + /* p_RR (R^2 in prime field) */ + 0x04,0x20,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03, + /* p_bar (low digit of -(p^-1)) */ + 0x04,0x02,0x00,0x01, + /* SEQUENCE */ + 0x30,0x44, + /* a_R (a in Montgomery representation) */ + 0x04,0x20,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc, + /* b_R (b in Montgomery representation) */ + 0x04,0x20,0x24,0x0f,0xe1,0x88,0xba,0x20,0xe2,0xc8,0x52,0x79,0x81,0x50,0x5e,0xa5,0x1c,0x3c,0x71,0xcf,0x37,0x9a,0xe9,0xb5,0x37,0xab,0x90,0xd2,0x30,0x63,0x2b,0xc0,0xdd,0x42, + /* G_R (G in Montgomery representation) */ + 0x04,0x41,0x04,0x91,0x16,0x7a,0x5e,0xe1,0xc1,0x3b,0x05,0xd6,0xa1,0xed,0x99,0xac,0x24,0xc3,0xc3,0x3e,0x79,0x81,0xed,0xdc,0xa6,0xc0,0x50,0x61,0x32,0x89,0x90,0xf4,0x18,0x02,0x9e,0x63,0xcd,0x65,0xd4,0x81,0xd7,0x35,0xbd,0x8d,0x4c,0xfb,0x06,0x6e,0x2a,0x48,0xf8,0xc1,0xf5,0xe5,0x78,0x8d,0x32,0x95,0xfa,0xc1,0x35,0x4e,0x59,0x3c,0x2d,0x0d,0xdd, + /* SEQUENCE */ + 0x30,0x26, + /* n_RR (R^2 in order field) */ + 0x04,0x20,0x1e,0xb5,0xe4,0x12,0xa2,0x2b,0x3d,0x3b,0x62,0x0f,0xc8,0x4c,0x3a,0xff,0xe0,0xd4,0x34,0x64,0x50,0x4a,0xde,0x6f,0xa2,0xfa,0x90,0x11,0x92,0xaf,0x7c,0x11,0x4f,0x20, + /* n_bar (low digit of -(n^-1)) */ + 0x04,0x02,0x09,0x75 +}; +#elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSm2P256v1DomainExt[225] = +{ + /* SEQUENCE */ + 0x30,0x81,0xde, + /* SEQUENCE */ + 0x30,0x81,0xb1, + /* p_RR (R^2 in prime field) */ + 0x04,0x20,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03, + /* p_bar (low digit of -(p^-1)) */ + 0x04,0x04,0x00,0x00,0x00,0x01, + /* SEQUENCE */ + 0x30,0x44, + /* a_R (a in Montgomery representation) */ + 0x04,0x20,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc, + /* b_R (b in Montgomery representation) */ + 0x04,0x20,0x24,0x0f,0xe1,0x88,0xba,0x20,0xe2,0xc8,0x52,0x79,0x81,0x50,0x5e,0xa5,0x1c,0x3c,0x71,0xcf,0x37,0x9a,0xe9,0xb5,0x37,0xab,0x90,0xd2,0x30,0x63,0x2b,0xc0,0xdd,0x42, + /* G_R (G in Montgomery representation) */ + 0x04,0x41,0x04,0x91,0x16,0x7a,0x5e,0xe1,0xc1,0x3b,0x05,0xd6,0xa1,0xed,0x99,0xac,0x24,0xc3,0xc3,0x3e,0x79,0x81,0xed,0xdc,0xa6,0xc0,0x50,0x61,0x32,0x89,0x90,0xf4,0x18,0x02,0x9e,0x63,0xcd,0x65,0xd4,0x81,0xd7,0x35,0xbd,0x8d,0x4c,0xfb,0x06,0x6e,0x2a,0x48,0xf8,0xc1,0xf5,0xe5,0x78,0x8d,0x32,0x95,0xfa,0xc1,0x35,0x4e,0x59,0x3c,0x2d,0x0d,0xdd, + /* SEQUENCE */ + 0x30,0x28, + /* n_RR (R^2 in order field) */ + 0x04,0x20,0x1e,0xb5,0xe4,0x12,0xa2,0x2b,0x3d,0x3b,0x62,0x0f,0xc8,0x4c,0x3a,0xff,0xe0,0xd4,0x34,0x64,0x50,0x4a,0xde,0x6f,0xa2,0xfa,0x90,0x11,0x92,0xaf,0x7c,0x11,0x4f,0x20, + /* n_bar (low digit of -(n^-1)) */ + 0x04,0x04,0x72,0x35,0x09,0x75 +}; +#endif +CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSm2P256v1SpeedUpExt[547] = +{ + /* SEQUENCE */ + 0x30,0x82,0x02,0x1f, + /* groups parameter */ + 0x04,0x01,0x03, + /* SEQUENCE */ + 0x30,0x82,0x02,0x18, + /* 2 * G in Montgomery representation */ + 0x04,0x41,0x04,0x0d,0x7e,0x9c,0x18,0xca,0xa5,0x73,0x6a,0x53,0x49,0xd9,0x4b,0x57,0x88,0xcd,0x24,0x83,0xbd,0xc9,0xba,0x2d,0x8f,0xa9,0x38,0x0a,0xf0,0x37,0xbf,0xbc,0x3b,0xe4,0x6a,0x94,0x7e,0x74,0x65,0x6c,0x21,0xbd,0xf5,0xc7,0xb1,0x45,0x16,0x9b,0x71,0x57,0xac,0xcc,0xbd,0x8d,0x37,0xc4,0xa8,0xe8,0x2b,0x6a,0x7e,0x1a,0x1d,0x69,0xdb,0x9a,0xc1, + /* (2^86 + 1) * G in Montgomery representation */ + 0x04,0x41,0x04,0x49,0xe7,0x25,0x75,0xfe,0xdd,0x2b,0x2d,0x61,0xb1,0xb3,0x8f,0x2e,0x2b,0xd6,0xd3,0x05,0x57,0x69,0xcc,0x7a,0x57,0xcc,0x35,0xaf,0x6e,0xa6,0xe4,0xc6,0xda,0xe1,0x87,0xe2,0x25,0x8e,0xfb,0x47,0x02,0xd9,0xff,0x47,0xd1,0xd3,0xfd,0xd5,0x7e,0x25,0x2a,0x59,0x37,0x2d,0xa0,0x68,0x98,0x9c,0x52,0xf1,0x3f,0xbc,0x50,0x1d,0xd3,0xfa,0x13, + /* (2^86 + 2) * G in Montgomery representation */ + 0x04,0x41,0x04,0x7d,0xd4,0x32,0x93,0x82,0xbd,0x00,0x16,0xfa,0x7c,0x06,0x88,0x02,0x50,0x75,0xac,0x4c,0xde,0xfd,0xe9,0x44,0xe4,0xa8,0xc8,0x95,0x64,0xb5,0xe3,0xc9,0x41,0xf8,0xe2,0x8c,0xe2,0x6e,0x6b,0x4b,0x91,0xf8,0x55,0x31,0x8e,0xf1,0x67,0x0d,0xe9,0x7e,0xed,0x75,0x7d,0x29,0x1c,0xc6,0xd6,0x45,0x45,0x3c,0xf5,0x87,0x1c,0xb9,0x6d,0x1f,0x98, + /* (2^172 + 1) * G in Montgomery representation */ + 0x04,0x41,0x04,0x88,0xf1,0xea,0x0c,0x12,0x62,0x22,0xb5,0x7c,0xf8,0x3e,0x30,0xd5,0x18,0x05,0x00,0x8e,0xc4,0x0a,0x13,0xea,0x25,0x4a,0xa9,0x9f,0x8c,0x30,0xf6,0x66,0xdc,0x3e,0xd1,0x1e,0x18,0x8a,0x57,0x72,0x69,0x66,0xbe,0x70,0x60,0x9d,0x57,0xbd,0x89,0xb6,0xc3,0x5e,0x69,0xe6,0x3c,0x95,0xcf,0xf0,0xdb,0x09,0x62,0x25,0x60,0x35,0x8d,0x62,0x19, + /* (2^172 + 2) * G in Montgomery representation */ + 0x04,0x41,0x04,0x6b,0x79,0x8e,0x7a,0xfb,0x07,0x18,0x3a,0x02,0xe7,0x85,0x3c,0xb8,0x43,0xa2,0xde,0x8b,0x94,0x62,0xd2,0x37,0x06,0x02,0x09,0x2c,0x8e,0x1c,0x4f,0x26,0x0a,0xb6,0xcd,0xb0,0xcc,0x80,0xbb,0x44,0xe0,0xb1,0x81,0x07,0x33,0x41,0x69,0xdf,0xdc,0xd4,0xf3,0x05,0x48,0xbe,0xdb,0xe7,0xe1,0xe1,0x1a,0xa7,0x2c,0xb0,0x08,0x4f,0xfa,0x08,0xb4, + /* (2^172 + 2^86 + 1) * G in Montgomery representation */ + 0x04,0x41,0x04,0x88,0x17,0xcf,0xe0,0xe9,0x62,0xbf,0xbe,0xd0,0x4d,0xfb,0x7d,0x57,0x81,0xc4,0x33,0x52,0x52,0x11,0x3d,0x89,0x1b,0xf9,0x31,0x95,0xfe,0xb1,0x4a,0x94,0x4c,0xcd,0x35,0x53,0x6c,0x1b,0xba,0xc5,0xe5,0xd7,0xa5,0xe6,0x06,0x87,0x93,0x00,0x8d,0x03,0x2e,0x74,0x35,0xa2,0x61,0x3c,0x00,0x41,0xa4,0x7d,0x7e,0xca,0x9a,0x39,0x25,0xff,0x3b, + /* (2^172 + 2^86 + 2) * G in Montgomery representation */ + 0x04,0x41,0x04,0xf9,0x75,0x83,0xc1,0xf4,0x5e,0xb3,0xb3,0x79,0x3a,0x76,0x32,0x76,0xe9,0xc9,0xd3,0x11,0x5c,0x11,0x6c,0x74,0xfb,0xcf,0xec,0x5c,0x72,0x4e,0x0d,0x09,0x90,0xc1,0xc1,0x49,0x91,0x7f,0x46,0xce,0x88,0xba,0xcf,0x7f,0xf4,0xbd,0x21,0x2c,0x65,0x39,0x5a,0x09,0xa5,0x16,0x7d,0x6e,0x75,0xdb,0x9f,0x93,0xad,0xb6,0xec,0xc9,0x82,0x70,0x0e, + /* correction point D = - ((2^86 - 1) * G) in Montgomery representation */ + 0x04,0x41,0x04,0xff,0x69,0xbf,0x41,0x4f,0x65,0xad,0x33,0x87,0xb1,0xb3,0xb5,0x40,0xab,0xc8,0x7d,0x38,0x1e,0x9e,0xac,0x2b,0x20,0x2e,0x5f,0x10,0xe6,0x9c,0x66,0xa1,0xa0,0xa6,0x05,0x3d,0x72,0xac,0x40,0xc3,0x24,0x44,0xb4,0xc8,0xbb,0xaf,0x30,0xe2,0x8b,0xf9,0xac,0x7f,0x6d,0x46,0xb4,0x28,0x0c,0x84,0x2c,0x35,0xa1,0x7f,0x09,0xde,0x5a,0x88,0x80 +}; +/* Sm2p256v1 END *********************************************************************************************/ + +#define CRYPTO_30_LIBCV_STOP_SEC_CONST_8BIT +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Curve.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Curve.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Curve.h new file mode 100644 index 0000000..c0474a0 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Curve.h @@ -0,0 +1,151 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Curve.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Internal header file for curve parameter prototypes + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_CURVE_H) +# define CRYPTO_30_LIBCV_CURVE_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +# include "Crypto_30_LibCv_Services.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CONST_8BIT +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* Empty curve vector START *********************************************************************************************/ +/* This vector is used to initialize pointers which shall point to the EC domain, the EC domain extension and + * the EC SpeedUp extension. If one of the regular curve parameters were used for this purpose, the corresponding + * arrays will always be used and therefore never be removed by the linker. + * Since this array does not start with the ASN1 sequence tag '0x30', the parser of the underlying crypto + * library will recognize these domains as invalid. */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveEmptyDomain[2]; +/* Empty curve vector END ***********************************************************************************************/ + +/* SEC_p160r1 START *****************************************************************************************************/ +/* SECp160r1 */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1Domain[155]; +# if (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1DomainExt[147]; +# elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1DomainExt[149]; +# elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1DomainExt[153]; +# endif +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSecP160R1SpeedUpExt[355]; +/* SEC_p160r1 END *********************************************************************************************/ + +/* NIST_SEC_p224r1 START *********************************************************************************************/ +/* NISTp224r1 = SECp224r1 */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1Domain[203]; +# if (actBN_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1DomainExt[195]; +# elif (actBN_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1DomainExt[197]; +# elif (actBN_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1DomainExt[201]; +# endif +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP224R1SpeedUpExt[483]; +/* NIST_SEC_p224r1 END *********************************************************************************************/ + +/* NIST_ANSI_SEC_p256r1 START *********************************************************************************************/ +/* NISTp256r1 = ANSIp256r1 = SECp256r1 */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain[227]; +# if (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt[219]; +# elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt[221]; +# elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt[225]; +# endif +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt[547]; +/* NIST_ANSI_SEC_p256r1 END *********************************************************************************************/ + +/* NIST_SEC_p384r1 START *********************************************************************************************/ +/* NISTp384r1 = SECp384r1 */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1Domain[324]; +# if (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt[316]; +# elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt[318]; +# elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt[323]; +# endif +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP384R1SpeedUpExt[803]; +/* NIST_SEC_p384r1 END *********************************************************************************************/ + +/* NIST_SEC_p521r1 START *********************************************************************************************/ +/* NISTp521r1 = SECp521r1 */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1Domain[432]; +# if (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt[427]; +# elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt[429]; +# elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt[433]; +# endif +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveNistSecP521R1SpeedUpExt[1099]; +/* NIST_SEC_p521r1 END *********************************************************************************************/ + +/* Edwards448 START **************************************************************************************************/ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveEdwards448GroupOrder[56]; +/* Edwards448 END ****************************************************************************************************/ + +/* Sm2p256v1 START *********************************************************************************************/ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSm2P256v1Domain[227]; +# if (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 1) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSm2P256v1DomainExt[219]; +# elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 2) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSm2P256v1DomainExt[221]; +# elif (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSm2P256v1DomainExt[225]; +# endif +extern CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_EccCurveSm2P256v1SpeedUpExt[547]; +/* Sm2p256v1 END *********************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CONST_8BIT +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#endif /* CRYPTO_30_LIBCV_CURVE_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Curve.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Custom.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Custom.h new file mode 100644 index 0000000..6b66a07 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Custom.h @@ -0,0 +1,626 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Custom.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Internal header file for custom algorithms + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#ifndef CRYPTO_30_LIBCV_CUSTOM_H +# define CRYPTO_30_LIBCV_CUSTOM_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +# include "Crypto_30_LibCv_Custom_Generated.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* ----- Additional Key Element defines ---------------------------------------------- */ + +/* AES MAC */ +# ifndef CRYPTO_KE_CUSTOM_MAC_AES_ROUNDKEY /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_MAC_AES_ROUNDKEY (129u) +# endif + +/* Key Derive */ +# ifndef CRYPTO_KE_CUSTOM_KEYDERIVATION_LABEL /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_KEYDERIVATION_LABEL (130u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO (131u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_ADDITIONAL_INFO /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_ADDITIONAL_INFO (131u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_KEYDERIVATION_CONTEXT /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_KEYDERIVATION_CONTEXT (3061u) +# endif + +/* RSA */ +# ifndef CRYPTO_KE_CUSTOM_RSA_MODULUS /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_MODULUS (160u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_RSA_PUBLIC_EXPONENT /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_PUBLIC_EXPONENT (161u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_RSA_PRIVATE_EXPONENT /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_PRIVATE_EXPONENT (162u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_RSA_SALT /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_SALT (163u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_RSA_SALT_LENGTH /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_SALT_LENGTH (164u) +# endif + +/* TLS */ +# ifndef CRYPTO_KE_CUSTOM_TLS_CLIENT_HELLO_RANDOM /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_TLS_CLIENT_HELLO_RANDOM (3000u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_TLS_SERVER_HELLO_RANDOM /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_TLS_SERVER_HELLO_RANDOM (3001u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_TLS_HMAC_KEY_SIZE /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_TLS_HMAC_KEY_SIZE (3002u) +# endif + +/* Key Exchange */ +# ifndef CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY (3003u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY_2 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY_2 (3004u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_KEYEXCHANGE_INTERMEDIATE /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_KEYEXCHANGE_INTERMEDIATE (3005u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_KEYEXCHANGE_NUM_ECU /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_KEYEXCHANGE_NUM_ECU (3006u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_KEYEXCHANGE_ECU_ID /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_KEYEXCHANGE_ECU_ID (3007u) +# endif + +/* Smart Charge Communication */ +# ifndef CRYPTO_KE_CUSTOM_SCC_CONTRACT_PUBLIC_KEY /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SCC_CONTRACT_PUBLIC_KEY (3013u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_SCC_IV_AND_ENCRYPTED_PRIVATE_KEY /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SCC_IV_AND_ENCRYPTED_PRIVATE_KEY (3014u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_SCC_CONTRACT_AAD /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SCC_CONTRACT_AAD (3060u) +# endif + +/* Random Number Generation */ +# ifndef CRYPTO_KE_CUSTOM_RANDOM_PERSONALIZATION_STRING /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RANDOM_PERSONALIZATION_STRING (3015u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_RANDOM_ADDITIONAL_INPUT /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RANDOM_ADDITIONAL_INPUT (3016u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_RANDOM_NONCE /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RANDOM_NONCE (3017u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER (3018u) +# endif + +/* SHE Key Update */ +# ifndef CRYPTO_KE_CUSTOM_SHE_COUNTER /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SHE_COUNTER (3019u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_SHE_UID /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SHE_UID (3021u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_SHE_BOOT_PROTECTION /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SHE_BOOT_PROTECTION (3056u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_SHE_DEBUGGER_PROTECTION /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SHE_DEBUGGER_PROTECTION (3057u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_SHE_DEBUG_CMD /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SHE_DEBUG_CMD (3059u) +# endif + +/* RSA CRT */ +# ifndef CRYPTO_KE_CUSTOM_RSA_PRIME_P /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_PRIME_P (3051u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_RSA_PRIME_Q /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_PRIME_Q (3052u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_RSA_EXPONENT_DP /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_EXPONENT_DP (3053u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_RSA_EXPONENT_DQ /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_EXPONENT_DQ (3054u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_RSA_INVERSE_QI /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_INVERSE_QI (3055u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_LABEL /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_LABEL (3058u) +# endif + +/* Spake2+ */ +# ifndef CRYPTO_KE_CUSTOM_W0 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_W0 (3084u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_W1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_W1 (3085u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_L /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_L (3086u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_VERIFICATION /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VERIFICATION (3087u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_VERIFICATION_RESULT /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VERIFICATION_RESULT (3088u) +# endif + +/* EdDsa */ +# ifndef CRYPTO_KE_CUSTOM_EDDSA_CONTEXT /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_EDDSA_CONTEXT (3061u) +# endif + +/* SlhDsa */ +# ifndef CRYPTO_KE_CUSTOM_SLHDSA_CONTEXT /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SLHDSA_CONTEXT (3062u) +# endif + +/* Sm2 Signature */ +# ifndef CRYPTO_KE_CUSTOM_SM2_ID /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SM2_ID (3092u) +# endif + +# ifndef CRYPTO_KE_CUSTOM_SM2_GENERATE_PUBLIC_KEY /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SM2_GENERATE_PUBLIC_KEY (3093u) +# endif + +/* ----- Custom Algorithm Mode Defines ---------------------------------------------- */ +/* ECC curve p224r1 */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_P224R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_P224R1 (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_P224r1) +# endif + +/* ECC curve p256r1 */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_P256R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_P256R1 (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_P256r1) +# endif + +/* RSA CRT */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_RSASSA_PKCS1_v1_5_CRT /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_RSASSA_PKCS1_v1_5_CRT (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_RSASSA_PKCS1_v1_5_CRT) +# endif + +# ifndef CRYPTO_ALGOMODE_CUSTOM_RSAES_OAEP_CRT /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_RSAES_OAEP_CRT (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_RSAES_OAEP_CRT) +# endif + +/* Use Derivation function e.g. for NIST DRBG AES128 */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_USE_DF /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_USE_DF (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_UseDF) +# endif + +/* ECC curve p384r1 */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_P384R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_P384R1 (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_P384r1) +# endif + +/* ECC curve p160r1 */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_P160R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_P160R1 (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_P160r1) +# endif + +/* ECC curve p521r1 */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_P521R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_P521R1 (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_P521r1) +# endif + +/* Aead Aes Ccm */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_CCM /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_CCM (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_CCM) +# endif + +/* EdDsaEd448 Pure */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_ED448_PURE /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_ED448_PURE (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_EdDsaEd448Pure) +# endif + +/* EdDsaEd448 Prehash */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_ED448_PH /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_ED448_PH (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_EdDsaEd448Ph) +# endif + +/* EdDsaEd25519 Pure */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_ED25519_PURE /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_ED25519_PURE (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_EdDsaEd25519Pure) +# endif + +/* EdDsaEd25519 Context */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_ED25519_CTX /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_ED25519_CTX (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_EdDsaEd25519Ctx) +# endif + +/* EdDsaEd25519 Prehash */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_ED25519_PH /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_ED25519_PH (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_EdDsaEd25519Ph) +# endif + +/* SlhDsa Sha2-128s */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_SHA2_128S /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_SHA2_128S (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_SHA2_128S) +# endif + +# ifndef CRYPTO_ALGOMODE_CUSTOM_SHA2_128S_DETERMINISTIC /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_SHA2_128S_DETERMINISTIC (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_SHA2_128S_Deterministic) +# endif + +/* SM2 Sm2p256v1 curve */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_SM2P256V1 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_SM2P256V1 (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_Sm2P256v1) +# endif + +/* Modes */ +# ifndef CRYPTO_ALGOMODE_CUSTOM_MODE_1 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_MODE_1 (CryptoConf_CryptoPrimitiveAlgorithmModeCustom_Crypto_30_LibCv_Mode1) +# endif + +/* ----- Custom Algorithm Family Defines ---------------------------------------------- */ +/* Ecc-ANSI conform */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_ECCANSI /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_ECCANSI (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_ECCANSI) +# endif + +/* Ecc-SEC conform */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_ECCSEC /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_ECCSEC (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_ECCSEC) +# endif + +/* NIST 800-90A DRBG conform */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_DRBG /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_DRBG (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_DRBG) +# endif + +/* FIPS 186.2 conform */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_FIPS186 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_FIPS186 (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_FIPS186) +# endif + +/* Padding PKCS7 */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_PADDING_PKCS7 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_PADDING_PKCS7 (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_PaddingPKCS7) +# endif + +/* Key exchange X25519 */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_X25519 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_X25519 (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_X25519) +# endif + +/* Key exchange X448 */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_X448 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_X448 (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_X448) +# endif + +/* Key Derive ISO15118 */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_ISO15118 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_ISO15118 (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_ISO15118) +# endif + +/* Key Derive ISO15118-20 */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_ISO15118_20 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_ISO15118_20 (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_ISO15118_20) +# endif + +/* Poly 1305 */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_POLY_1305 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_POLY_1305 (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_POLY1305) +# endif + +/* Spake2+ */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_SPAKE2_PLUS /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_SPAKE2_PLUS (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_SPAKE2PLUS) +# endif + +/* HKDF */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_HKDF /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_HKDF (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_HKDF) +# endif + +/* Cmd get ID */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_CMD_GET_ID /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_CMD_GET_ID (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_CmdGetId) +# endif + +/* Cipher Suites */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_CIPHER_SUITE_8 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_CIPHER_SUITE_8 (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_CipherSuite8) +# endif + +/* Hash MD5 */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_MD5 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_MD5 (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_MD5) +# endif + +/* Burmester Desmedt */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_BD /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_BD (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_BD) +# endif + +/* Ed448 */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_ED448 /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_ED448 (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_ED448) +# endif + +/* IsPublicKeyOnCurve */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_ISPUBLICKEYONCURVE /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_ISPUBLICKEYONCURVE (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_IsPublicKeyOnCurve) +# endif + +/* HKDF Expand */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_HKDF_EXPAND /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_HKDF_EXPAND (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_HKDF_Expand) +# endif + +/* IsSecretKeyOnCurve */ +# ifndef CRYPTO_ALGOFAM_CUSTOM_ISPRIVATEKEYONCURVE /* COV_CRYPTO_30_LIBCV_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_ISPRIVATEKEYONCURVE (CryptoConf_CryptoPrimitiveAlgorithmFamilyCustom_Crypto_30_LibCv_IsPrivateKeyOnCurve) +# endif + +/* ----- Custom Key Exchange Algorithm Defines ---------------------------------------------- */ +/* Exchange algorithm x25519 */ +# ifndef CRYPTO_30_LIBCV_KEY_EXCHANGE_X25519 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_X25519 (0u) +# endif + +/* Exchange algorithm ANSI p256r1 */ +# ifndef CRYPTO_30_LIBCV_KEY_EXCHANGE_ANSIP256R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_ANSIP256R1 (1u) +# endif + +/* Exchange algorithm SEC p256r1 */ +# ifndef CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP256R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP256R1 (2u) +# endif + +/* Exchange algorithm Nist p224r1 for burmester desmedt */ +# ifndef CRYPTO_30_LIBCV_KEY_EXCHANGE_NISTP224R1_BD /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_NISTP224R1_BD (3u) +# endif + +/* Exchange algorithm SEC p384r1 */ +# ifndef CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP384R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP384R1 (4u) +# endif + +/* Exchange algorithm Spake2+ Cipher Suite 8 */ +# ifndef CRYPTO_30_LIBCV_KEY_EXCHANGE_SPAKE2_PLUS_CIPHERSUITE_8 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_SPAKE2_PLUS_CIPHERSUITE_8 (5u) +# endif +# ifndef CRYPTO_30_LIBCV_KEY_EXCHANGE_SPAKE2_PLUS_CIPHERSUITE_8_1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_SPAKE2_PLUS_CIPHERSUITE_8_1 (6u) +# endif + +/* Exchange algorithm SEC p521r1 */ +# ifndef CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP521R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP521R1 (7u) +# endif + +/* Exchange algorithm x448 */ +# ifndef CRYPTO_30_LIBCV_KEY_EXCHANGE_X448 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_X448 (8u) +# endif + +/* Exchange algorithm p256r1 for burmester desmedt */ +# ifndef CRYPTO_30_LIBCV_KEY_EXCHANGE_P256R1_BD /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_P256R1_BD (9u) +# endif + +/* Exchange algorithm NIST/SEC p224r1 */ +# ifndef CRYPTO_30_LIBCV_KEY_EXCHANGE_P224R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_P224R1 (10u) +# endif + +/* ----- Custom Key Generate Algorithm Defines ---------------------------------------------- */ +/* Key Generate Symmetric Generic */ +# ifndef CRYPTO_30_LIBCV_KEY_GENERATE_SYMMETRIC /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_GENERATE_SYMMETRIC (0u) +# endif +/* Key Generate algorithm P256R1 */ +# ifndef CRYPTO_30_LIBCV_KEY_GENERATE_P256R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_GENERATE_P256R1 (1u) +# endif +/* Key Generate algorithm P384R1 */ +# ifndef CRYPTO_30_LIBCV_KEY_GENERATE_P384R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_GENERATE_P384R1 (2u) +# endif +# ifndef CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ED25519 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ED25519 (3u) +# endif +# ifndef CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_P521R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_P521R1 (4u) +# endif +# ifndef CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SM2P256V1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SM2P256V1 (5u) +# endif + +/* ----- Custom Key Derivation Algorithm Defines ---------------------------------------------- */ +/* KDF_NIST_800-108 'KDF in Counter Mode' with SHA-256 as PRF */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256 (1u) +# endif + +/* NIST.FIPS.186-4 'Key Pair Generation Using Extra Random Bits' with 'KDF in Counter Mode' as RBG */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB (2u) +# endif + +/* NIST.SP.800-56A Single-Step KDF with Option 1: H(x) = hash(x) */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_KDF_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256 (3u) +# endif + +/* ISO 15118 install and update certificate. */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_KDF_ISO_15118_CERTIFICATE_HANDLING /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_ISO_15118_CERTIFICATE_HANDLING (4u) +# endif + +/* KDF X9.63 SHA 1 */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA1 (5u) +# endif + +/* KDF X9.63 SHA 256 */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA256 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA256 (6u) +# endif + +/* KDF X9.63 SHA 512 */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA512 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA512 (7u) +# endif + +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_KDF_NIST_800_108_CTR_CMAC_AES /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_NIST_800_108_CTR_CMAC_AES (8u) +# endif + +/* PBKDF2 HMAC SHA 1 */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1 (9u) +# endif + +/* PBKDF2 HMAC SHA 256 */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256 (10u) +# endif + +/* HKDF HMAC SHA 256 */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256 (11u) +# endif + +/* KDF Spake2+ P256R1 */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_SPAKE2_PLUS_P256R1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_SPAKE2_PLUS_P256R1 (12u) +# endif + +/* HKDF HMAC Option 1 SHA2-256 */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256 (13u) +# endif + +/* HKDF HMAC SHA2-384 */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384 (14u) +# endif + +/* HKDF HMAC Option 1 SHA2-512 */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512 (15u) +# endif + +/* ISO 15118-20 install certificate. */ +# ifndef CRYPTO_30_LIBCV_KDF_ALGO_KDF_ISO_15118_20_CERTIFICATE_HANDLING /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_ISO_15118_20_CERTIFICATE_HANDLING (16u) +# endif + +/* HKDF Expand HMAC SHA2-256 */ +# ifndef CRYPTO_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256 (17u) +# endif + +/* HKDF Expand HMAC SHA2-384 */ +# ifndef CRYPTO_KDF_ALGO_HKDF_EXPAND_HMAC_SHA384 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA384 (18u) +# endif + +/* ----- Custom Random Seed Algorithm Defines ---------------------------------------------- */ +/* Random Seed according to FIPS 186-2 SHA1 */ +# ifndef CRYPTO_30_LIBCV_RNG_FIPS_186_2_SHA1 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_RNG_FIPS_186_2_SHA1 (0u) +# endif + +/* Random Seed according to NIST 800-90A CTR_DRBG with AES-128 */ +# ifndef CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES128 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES128 (1u) +# endif + +/* Random Seed according to NIST 800-90A CTR_DRBG with AES-128 and DF */ +# ifndef CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES128_DF /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES128_DF (2u) +# endif + +/* Random Seed according to NIST 800-90A HASH_DRBG */ +# ifndef CRYPTO_30_LIBCV_RNG_NIST_800_90A_HASH_DRBG_SHA_512 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_RNG_NIST_800_90A_HASH_DRBG_SHA_512 (3u) +# endif + +/* Random Seed according to NIST 800-90A CTR_DRBG with AES-256 */ +# ifndef CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES256 /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES256 (4u) +# endif + +/* Random Seed according to NIST 800-90A CTR_DRBG with AES-256 and DF */ +# ifndef CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES256_DF /* COV_CRYPTO_30_LIBCV_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES256_DF (5u) +# endif + +#endif /* CRYPTO_30_LIBCV_CUSTOM_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Custom.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Decrypt.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Decrypt.h new file mode 100644 index 0000000..1f43d63 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Decrypt.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Decrypt.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for CIPHER Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_DECRYPT_H) +# define CRYPTO_30_LIBCV_DECRYPT_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_AESDECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesDecrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the CipherAesDecrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-137765, CREQ-317644, CREQ-158941 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesDecrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_AESDECRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SM4DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm4Decrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the SM4-Decrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key size is not correct. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-Sm4Decrypt + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm4Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_SM4DECRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAPKCS1DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the RsaPkcs1Decrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-137764, CREQ-190479 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAPKCS1DECRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAOAEPSHA1DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepSha1Decrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the RsaOaep Decrypt Sha1 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-168409 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepSha1Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA1DECRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAOAEPSHA256DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepSha256Decrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the RsaOaep Decrypt Sha256 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-168409 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepSha256Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA256DECRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAOAEPCRTSHA1DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepCrtSha1Decrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the RsaOaep Crt Decrypt Sha1 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-168872 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepCrtSha1Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAOAEPCRTSHA1DECRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAOAEPCRTSHA256DECRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepCrtSha256Decrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the RsaOaep Crt Decrypt Sha256 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-168872 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepCrtSha256Decrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAOAEPCRTSHA256DECRYPT == STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_DECRYPT_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Decrypt.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Encrypt.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Encrypt.h new file mode 100644 index 0000000..f6bc64d --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Encrypt.h @@ -0,0 +1,190 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Encrypt.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for CIPHER Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_ENCRYPT_H) +# define CRYPTO_30_LIBCV_ENCRYPT_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_AESENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_AesEncrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the AesEncrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-137759, CREQ-317643, CREQ-158942 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_AesEncrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_AESENCRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SM4ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm4Encrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the SM4-Encrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key size is not correct. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-Sm4Encrypt + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm4Encrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_SM4ENCRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAPKCS1ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Encrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the RsaPkcs1Encrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-137760 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Encrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAPKCS1ENCRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAOAEPSHA1ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepSha1Encrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the RsaOaep Encrypt Sha1 to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-168408 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepSha1Encrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA1ENCRYPT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAOAEPSHA256ENCRYPT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaOaepSha256Encrypt() + *********************************************************************************************************************/ +/*! \brief Dispatches the RsaOaep Encrypt Sha256 to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-168408 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaOaepSha256Encrypt( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAOAEPSHA256ENCRYPT == STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_ENCRYPT_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Encrypt.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Hash.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Hash.c new file mode 100644 index 0000000..f2fd6e6 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Hash.c @@ -0,0 +1,235 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Hash.c + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Implementation for HASH Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_HASH_SOURCE +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Crypto_30_LibCv.h" +#include "Crypto_30_LibCv_Services.h" +#include "Crypto_30_LibCv_Hash.h" + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ +#define CRYPTO_30_LIBCV_VSECPRIM_HASH_ALGO_INVALID (0xFFu) + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ +#if ((CRYPTO_30_LIBCV_HASH == STD_ON) || (((CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) && (CRYPTO_30_LIBCV_SIGNATURE_PRE_HASH == STD_ON))) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Hash_ModeStart() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Hash_ModeStart( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + Crypto_AlgorithmFamilyType hashAlgoFam) +{ + eslt_ErrorCode retValCv; + Std_ReturnType retVal = E_NOT_OK; + vSecPrimType_HashAlgorithm esLibHashAlgoIdentifier = CRYPTO_30_LIBCV_VSECPRIM_HASH_ALGO_INVALID; + + /* Get hash algorithm identifier for vSecPrim */ +# if (CRYPTO_30_LIBCV_HASH_CUSTOM_MD5 == STD_ON) + if (hashAlgoFam == CRYPTO_ALGOFAM_CUSTOM_CRYPTO_30_LIBCV_MD5) + { + esLibHashAlgoIdentifier = VSECPRIM_DIGEST_MD5; + } + else +# endif /* (CRYPTO_30_LIBCV_HASH_CUSTOM_MD5 == STD_ON) */ + if (hashAlgoFam < Crypto_30_LibCv_GetSizeOfFamilyToHashMapping()) + { + esLibHashAlgoIdentifier = Crypto_30_LibCv_GetFamilyToHashMapping(hashAlgoFam); + } + else + { + /* esLibHashAlgoIdentifier already set */ + } + + /* Initialize algorithm. */ + retValCv = esl_initWorkSpaceHeader(&(workSpace->header), VSECPRIM_SIZEOF_WS_HASH, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retValCv = vSecPrim_initHash(workSpace, esLibHashAlgoIdentifier, VSECPRIM_OUTPUT_TRUNCATION_ALLOWED); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Hash_ModeStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Hash_ModeUpdate() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Hash_ModeUpdate( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + uint32 inputLength, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) inputPtr) +{ + eslt_ErrorCode retValCv; + Std_ReturnType retVal = E_NOT_OK; + + /* # Process input data. */ + retValCv = vSecPrim_updateHash(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))inputPtr); + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Hash_ModeUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Hash_ModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Hash_ModeFinish( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) outputLengthPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) outputPtr) +{ + eslt_ErrorCode retValCv; + Std_ReturnType retVal = E_NOT_OK; + eslt_Length outputLength = (eslt_Length)(*outputLengthPtr); + + /* # Write results in output buffers. Output size adaption is done in vSecPrim. */ + retValCv = vSecPrim_finalizeHash(workSpace, &outputLength, outputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + *outputLengthPtr = outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Hash_ModeFinish() */ +#endif /* ((CRYPTO_30_LIBCV_HASH == STD_ON) || (((CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) && (CRYPTO_30_LIBCV_SIGNATURE_PRE_HASH == STD_ON))) */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ +#if (CRYPTO_30_LIBCV_HASH == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Hash() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Hash( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpaceHash = Crypto_30_LibCv_GetWorkspaceOfHash(Crypto_30_LibCv_GetHashIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(vSecPrimType_WorkSpaceHash)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_Hash_ModeStart(workSpaceHash, job->jobPrimitiveInfo->primitiveInfo->algorithm.family); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_Hash_ModeUpdate(workSpaceHash, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + break; + } + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_Hash_ModeFinish(workSpaceHash, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; + } + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Hash() */ +#endif /* (CRYPTO_30_LIBCV_HASH == STD_ON) */ + +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Hash.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Hash.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Hash.h new file mode 100644 index 0000000..e132226 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Hash.h @@ -0,0 +1,151 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Hash.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for HASH Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_HASH_H) +# define CRYPTO_30_LIBCV_HASH_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_HASH == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Hash() + *********************************************************************************************************************/ +/*! \brief Dispatches the Hash job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. + * It will evaluate the correct hash based on the given job. + * Based on the jobs operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-139111, CREQ-139110, CREQ-178100, CREQ-139109, CREQ-321212, CREQ-257656, CREQ-321213, + * CREQ-247953, CREQ-266807, CREQ-321214, CREQ-321215, CREQ-321216, CREQ-Crypto-Sm3Hash, + * CREQ-Crypto-SHA2-512-224, CREQ-Crypto-SHA2-512-256, CREQ-Crypto-SHA2-224 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Hash( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_HASH == STD_ON) */ + +# if ((CRYPTO_30_LIBCV_HASH == STD_ON) || (((CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) && (CRYPTO_30_LIBCV_SIGNATURE_PRE_HASH == STD_ON))) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Hash_ModeStart() + *********************************************************************************************************************/ +/*!\brief Handles hash operation mode START. + * \details This function initializes both the workspace header and algorithm. + * \param[in] workSpace Pointer to the vSecPrim workspace. + * \param[in] hashAlgoFam Algorithm family of the hash. + * \return E_OK Start operation was successful. + * E_NOT_OK Start operation failed. + * \pre workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Hash_ModeStart( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + Crypto_AlgorithmFamilyType hashAlgoFam); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Hash_ModeUpdate() + *********************************************************************************************************************/ +/*!\brief Handles hash operation mode UPDATE. + * \details This function processes the input data. + * \param[in] workSpace Pointer to the vSecPrim workspace. + * \param[in] inputLength Length of the input data in bytes. + * \param[in] inputPtr Pointer to the input data which should be hashed. + * \return E_OK Update operation was successful. + * E_NOT_OK Update operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Hash_ModeUpdate( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + uint32 inputLength, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) inputPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Hash_ModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles hash operation mode FINISH. + * \details This function writes the results in output buffers, adapts the output size of the hash value and + * copies the data to the output location. + * \param[in] workSpace Pointer to the vSecPrim workspace. + * \param[in,out] outputLengthPtr Pointer to the output length of the hash. + * If the output length is smaller than the hash output, + * the hash output will be truncated accordingly. + * \param[out] outputPtr Pointer to the output buffer of the hash. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre outputLengthPtr and outputPtr has to be valid. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Hash_ModeFinish( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) outputLengthPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) outputPtr); +# endif /* ((CRYPTO_30_LIBCV_HASH == STD_ON) || (((CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) && (CRYPTO_30_LIBCV_SIGNATURE_PRE_HASH == STD_ON))) */ +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_HASH_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Hash.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_InternalApi.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_InternalApi.h new file mode 100644 index 0000000..cab03fe --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_InternalApi.h @@ -0,0 +1,402 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_InternalApi.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Internal API Functions. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_INTERNALAPI_H) +# define CRYPTO_30_LIBCV_INTERNALAPI_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Services.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +typedef struct +{ + boolean isKeyValid; /* 1 key is valid, 0 key is invalid */ + boolean isSheKey; /* 1 key is an she key, 0 key is not a she key */ + boolean write_protection; /* 0 rewriting and erasing enabled, 1 rewriting and erasing disabled */ + /* The following flags are only relevant for SHE keys */ + boolean boot_protection; /* 0 key usage is not limited according to result of secure boot, 1 usage is limited */ + boolean debugger_protection; /* 0 use of a debug interface does not impose a limitation on key usage, 1 key can not be used if debugger is attached */ + boolean key_usage; /* 0 key can be used for AES ECB+CBC encrypt/decrypt, 1 key can be used for CMAC generate/verify */ + boolean disable_wildcard; /* 0 key update by wildcard UID is enabled, 1 key update by wildcard is disabled */ + boolean cmac_usage; /* 0 key can be used to execute CMAC generate, 1 key can not be used to execute CMAC generate but only for CMAC verify */ +} Crypto_30_LibCv_KeyFlagType; + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyElementGetStorageIndex() + *********************************************************************************************************************/ +/*! \brief The key element storage index can be provided for all read access rights values. + * \details This interface shall be used to get a key element of the key identified by the + * cryptoKeyId and store the key element in the memory location pointed to by the result pointer. + * The key element will be searched and checked vor validity. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be provided. + * \param[in] keyElementId Holds the Id of the key element which shall be provided. + * \param[in,out] resultIndexPtr Holds the pointer to the storage index which shall be provided. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \param[in] lengthCheck Length check mode. + * \param[in] serviceType SHE service Type. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre The crypto key has to be locked for read access. + * resultIndexPtr has to be a valid ptr. + * resultLengthPtr has to be a valid ptr. + * lengthCheck has to be a valid parameter. + * serviceType has to be a valid parameter. + * \context TASK + * \reentrant TRUE, for different crypto keys. + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyElementGetStorageIndex( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck, + Crypto_30_LibCv_ServiceType serviceType); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_GetKeyFlags() + *********************************************************************************************************************/ +/*! \brief Retrieving information about key flags + * \details The function checks the key for validity and its key extensions and sets the output buffer. + * \param[in] cryptoKeyId Holds the identifier of the key + * \param[in] keyElementId Holds the identifier of the key element + * \param[out] keyFlagsPtr Contains the pointer to the data where the key flag data shall be stored + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre The crypto key has to be locked for read access. + * keyFlagsPtr has to be a valid ptr. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_GetKeyFlags( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_KeyFlagType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyFlagsPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyReadLockGetNotProtected() + *********************************************************************************************************************/ +/*! + * \brief Try to get key read lock. + * \details This access is not protected by a exclusive area. + * \param[in] cryptoKeyId Id of the crypto key. + * \return E_OK Lock key read access success. + * E_NOT_OK Lock key read access failed. + * \pre The caller must ensure that this call is protected by a exclusive area which prohibits + * multiple calls to LibCv Api's. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyReadLockGetNotProtected( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyReadLockReleaseNotProtected() + *********************************************************************************************************************/ +/*! + * \brief Release key read lock. + * \details This access is not protected by a exclusive area. + * \param[in] cryptoKeyId Id of the crypto key. + * \return E_OK Release key read access success. + * E_NOT_OK Request failed, the key is not available. + * \pre The caller must ensure that this call is protected by a exclusive area which prohibits + * multiple calls to LibCv Api's. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyReadLockReleaseNotProtected( + uint32 cryptoKeyId); + +# if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_GetKeyListRedirection() + **********************************************************************************************************************/ +/*! \brief Create list of keys for redirection. + * \details A key is only referenced once in the list with the highest access. + * \param[in] job Pointer to the job which shall checked. + * \param[in,out] keyList Pointer to the keyList. + * \pre job has to be a valid job object. + * keyList has to be a valid keyList object with at least 6 elements if redirection is used, otherwise 1. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_GetKeyListRedirection( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_RedirectPreRedirKeys() + **********************************************************************************************************************/ +/*! \brief Pre redirect keys and in- and out-buffer. + * \details Set the in- and out-buffer to the redirected keys. + * \param[in,out] redirectBuffer Pointer to the redirection buffer. + * \param[in,out] job Pointer to the configuration of the job. + * \return E_OK Request success. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_EMPTY Request failed, key is empty. + * \pre Lock has to be reserved for the job object. + * redirectBuffer has to be a valid pointer. + * job has to be a job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_RedirectPreRedirKeys( + P2VAR(Crypto_30_LibCv_Redirect_Type, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) redirectBuffer, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_RedirectPostRestoreBuffer() + **********************************************************************************************************************/ +/*! \brief Post redirect keys and in- and out-buffer. + * \details Save result and restore in- and out-buffer. + * \param[in,out] redirectBuffer Pointer to the redirection buffer. + * \param[in,out] job Pointer to the configuration of the job. + * \param[in] result Current update result + * \return E_OK Request successful. + * E_NOT_OK Redirect Keys are not available. + * \pre Lock has to be reserved for the job object. + * redirectBuffer has to be a valid pointer. + * job has to be a job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_RedirectPostRestoreBuffer( + P2VAR(Crypto_30_LibCv_Redirect_Type, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) redirectBuffer, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Std_ReturnType result); +# endif /* (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyListAddKey() + **********************************************************************************************************************/ +/*! \brief Add Key to key list. + * \details Add key to keyList if the key is not in keyList. If the Key is in KeyList update keyAccess. + * \param[in,out] keyList Pointer to the keyList. + * \param[in] cryptoKeyId KeyId of the key which shall be add. + * \param[in] keyAccess Key access right of the key which shall be add. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre keyList has to be a valid keyList object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyListAddKey( + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList, + uint32 cryptoKeyId, + uint8 keyAccess); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyListPreLockKeys() + **********************************************************************************************************************/ +/*! \brief Lock keys in key list. + * \details Lock keys in key list according to their read/write access. + * This access is not protected by a exclusive area. + * \param[in] keyList Pointer to the keyList. + * \return E_OK Request success. + * E_NOT_OK Request failed, since key is already locked or not available. + * \pre keyList has to be a valid keyList object. + * The caller must ensure that this call is protected by a exclusive area which prohibits + * multiple calls to LibCv Api's. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyListPreLockKeys( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyListPostFreeKeys() + **********************************************************************************************************************/ +/*! \brief Free keys in key list. + * \details Free keys in key list according to their read/write access. + * This access is not protected by a exclusive area. + * \param[in] keyList Pointer to the keyList. + * \return E_OK Request success. + * E_NOT_OK Request failed, since key is not available. + * \pre keyList has to be a valid keyList object. + * The caller must ensure that this call is protected by a exclusive area which prohibits + * multiple calls to LibCv Api's. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyListPostFreeKeys( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyListPreLockKeysProtected() + **********************************************************************************************************************/ +/*! \brief Lock keys in key list. + * \details Lock keys in key list according to their read/write access. + * \param[in] keyList Pointer to the keyList. + * \return E_OK Request success. + * E_NOT_OK Request failed, since key is already locked or not available. + * \pre keyList has to be a valid keyList object. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyListPreLockKeysProtected( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyListPostFreeKeysProtected() + **********************************************************************************************************************/ +/*! \brief Free keys in key list. + * \details Free keys in key list according to their read/write access. + * \param[in] keyList Pointer to the keyList. + * \return E_OK Request success. + * E_NOT_OK Request failed, since key is not available. + * \pre keyList has to be a valid keyList object. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyListPostFreeKeysProtected( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyElementSearch() + *********************************************************************************************************************/ +/*! \brief Searches the key elementIndex. + * \details Searches the key elementIndex of the given keyElementId in the given cryptoKeyId. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] keyElementId Holds the identifier of the key element which shall be set. + * \param[out] elementIndex Holds the pointer to the found key element index. + * \return E_OK Request successful. + * E_NOT_OK Request failed, key or key element not found. + * \pre elementIndex has to be a valid element index Ptr. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyElementSearch( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) elementIndex); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyWriteLockGetNotProtected() + *********************************************************************************************************************/ +/*! + * \brief Try to get key write lock. + * \details Try to get key write lock. Only one write lock can be allocated, if there is no read lock. + * \param[in] cryptoKeyId Id of the crypto key. + * \return E_OK Lock key write access success. + * E_NOT_OK Lock key write access failed. + * \pre The caller has to ensure that this call is protected by a exclusive area. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyWriteLockGetNotProtected( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyWriteLockReleaseNotProtected() + *********************************************************************************************************************/ +/*! + * \brief Release key write lock. + * \details Release key write lock. Only one write lock can be allocated. + * \param[in] cryptoKeyId Id of the crypto key. + * \return E_OK Request success. + * E_NOT_OK Request failed as key is not available. + * \pre The caller has to ensure that this call is protected by a exclusive area. + * The caller has to ensure that the key is locked for write access. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyWriteLockReleaseNotProtected( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyElementSetInternalStandard() + *********************************************************************************************************************/ +/*! \brief Copies data to key storage. + * \details Copies data of the keyPtr to the internal key storage identified by the elementIndex. + * If keyLength is zero the old value is deleted. + * \param[in] elementIndex Holds the identifier of the keyElement in the keyStorage. + * \param[in] keyPtr Holds the data which shall be copied to the key storage + * \param[in] keyLength Specifies the number of bytes which shall be copied. + * \return E_OK Request success. + * E_NOT_OK Request failed as elementIndex is not valid. + * \pre keyLength has to be smaller or equal in length to available key storage space. + * keyPtr has to be a valid ptr. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyElementSetInternalStandard( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength); + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_INTERNALAPI_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_InternalApi.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyDerive.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyDerive.c new file mode 100644 index 0000000..d5181a7 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyDerive.c @@ -0,0 +1,5359 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeyDerive.c + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Implementation of Key Derive Services. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_KEYDERIVE_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +#include "Crypto_30_LibCv.h" +#include "Crypto_30_LibCv_Services.h" +#include "Crypto_30_LibCv_KeyDerive.h" +#include "Crypto_30_LibCv_KeyExchange.h" + +#include "Crypto_30_LibCv_Custom.h" +#include "Crypto_30_LibCv_Curve.h" + +#if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) +# include "actBigNum.h" +#endif + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ +typedef struct +{ + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) sourceKey; + uint32 sourceKeyLength; + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) label; + uint32 labelLength; + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) context; + uint32 contextLength; + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) targetKey; + uint32 targetKeyLength; + Crypto_30_LibCv_SizeOfKeyElementsType targetKEIdx; +} Crypto_30_LibCv_Nist800108_KDF_InputOutput; + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ + + /* KDF */ +#define CRYPTO_30_LIBCV_KEY_DERIVE_SIZEOF_ALGORITHM (1u) + +/* KDF ISO15118 */ +#define CRYPTO_30_LIBCV_ISO15118_SIZEOF_IV (16u) +#define CRYPTO_30_LIBCV_ISO15118_PRIV_KEY_START (CRYPTO_30_LIBCV_ISO15118_SIZEOF_IV) +#define CRYPTO_30_LIBCV_ISO15118_SIZEOF_IV_AND_PRIV_KEY (48u) +#define CRYPTO_30_LIBCV_ISO15118_SIZEOF_OTHER_INFO (3u) + +/* KDF ISO15118-20 */ +#define CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_IV (12u) +#define CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_TAG (16u) +#define CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_OTHER_INFO (3u) +#define CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_DERIVED_KEY (32u) +#define CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_IV_PRIV_KEY_TAG_P521 (94u) +#define CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_SHARED_SECRET_P521 (CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE) +#define CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_P521 (66u) +#define CRYPTO_30_LIBCV_ISO15118_20_IV_START_P521 (0u) +#define CRYPTO_30_LIBCV_ISO15118_20_PRIV_KEY_START_P521 (CRYPTO_30_LIBCV_ISO15118_20_IV_START_P521 + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_IV) +#define CRYPTO_30_LIBCV_ISO15118_20_TAG_START_P521 (CRYPTO_30_LIBCV_ISO15118_20_PRIV_KEY_START_P521 + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_P521) +#define CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_IV_PRIV_KEY_TAG_X448 (84u) +#define CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_SHARED_SECRET_X448 (ESL_SIZEOF_X448_SHARED_SECRET) +#define CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_X448 (ESL_SIZEOF_X448_PRIVATE_KEY) +#define CRYPTO_30_LIBCV_ISO15118_20_IV_START_X448 (0u) +#define CRYPTO_30_LIBCV_ISO15118_20_PRIV_KEY_START_X448 (CRYPTO_30_LIBCV_ISO15118_20_IV_START_X448 + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_IV) +#define CRYPTO_30_LIBCV_ISO15118_20_TAG_START_X448 (CRYPTO_30_LIBCV_ISO15118_20_PRIV_KEY_START_X448 + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_X448) + +/* KDF NIST 800-56A */ +#define CRYPTO_30_LIBCV_NIST80056A_COUNTER_SIZE (4u) +#define CRYPTO_30_LIBCV_NIST80056A_OTHER_INFO_MAXSIZE (5u) + +/* NIST 800-108 NIST/FIPS 186.4 */ +#define CRYPTO_30_LIBCV_SIZEOF_KDF_PRF_INPUT_BUFFER (256u + 12u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_MAX_PARENT_KEY (256u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_MAX_TARGET_KEY (256u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_MAX_TARGET_KEY_PLUS_8 (256u + 8u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_SALT_SYMMETRIC (6u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_SALT_ASYMMETRIC (38u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_PRIME (32u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_CONTEXT (4u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_TARGET_KEY_LENGTH (2u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_LABEL_LENGTH (4u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_ALGORITHM_LENGTH (1u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_PRIME_ASYM_EXTEND (8u) + +/* General */ +#define CRYPTO_30_LIBCV_SIZEOF_KDF_ITERATIONSLENGTH (CRYPTO_30_LIBCV_SIZEOF_UINT32) +#define CRYPTO_30_LIBCV_SIZEOF_HKDF_ITERATIONSLENGTH (1u) + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384_ENABLED == STD_ON)) +# define CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_ENABLED STD_ON +#else +# define CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_ENABLED STD_OFF +#endif + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA384_ENABLED == STD_ON)) +# define CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_ENABLED STD_ON +#else +# define CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_ENABLED STD_OFF +#endif + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON)) + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Kdf_HandleInputParams() + *********************************************************************************************************************/ +/*! \brief Check KDF input parameters + * \details Gets and checks input parameters of the KDF according to NIST 800-108 NIST/FIPS 186-4. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] deriveAlgorithm The algorithm from the Algorithm key element + * \param[out] prfInputBuffer Input for the PRF + * \param[out] prfInputBufferLength Written Length of the PRF intput + * \param[out] saltBuffer The salt from the Salt key element (needs to be defined in the calling function because primeMinus1PtrPtr points into that buffer) + * \param[out] targetKeyLength Length of the target key + * \param[out] parentKeyLength Length of the parent key + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY The required key is busy. + * \pre All pointers need to be valid. + * Length of the buffer provided by deriveAlgorithm has to be 1 Byte. + * Length of the buffer provided by prfInputBuffer has to be CRYPTO_30_LIBCV_SIZEOF_KDF_PRF_INPUT_BUFFER Bytes. + * Length of the buffer provided by saltBuffer has to be CRYPTO_30_LIBCV_SIZEOF_KDF_SALT_ASYMMETRIC Bytes. + * cryptoKeyId and targetCryptoKeyId have to be a valid identifiers. + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Kdf_HandleInputParams( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 deriveAlgorithm, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) prfInputBuffer, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) prfInputBufferLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) saltBuffer, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) targetKeyLength, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) parentKeyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt() + *********************************************************************************************************************/ +/*! \brief Gets and checks the salt input parameter of the KDF + * \details Gets and checks the salt input parameter of the KDF according to NIST 800-108 NIST/FIPS 186-4. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] deriveAlgorithm The algorithm from the Algorithm key element + * \param[out] prfInputBuffer Input for the PRF + * \param[out] prfInputBufferLength Written Length of the PRF intput + * \param[out] saltBuffer The salt from the Salt key element (needs to be defined in the calling function because primeMinus1PtrPtr points into that buffer) + * \param[out] targetKeyLength Length of the target key + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the buffer provided by deriveAlgorithm has to be 1 Byte. + * Length of the buffer provided by prfInputBuffer has to be CRYPTO_30_LIBCV_SIZEOF_KDF_PRF_INPUT_BUFFER Bytes. + * Length of the buffer provided by saltBuffer has to be CRYPTO_30_LIBCV_SIZEOF_KDF_SALT_ASYMMETRIC Bytes. + * cryptoKeyId and targetCryptoKeyId have to be a valid identifiers. + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 deriveAlgorithm, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) prfInputBuffer, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) prfInputBufferLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) saltBuffer, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) targetKeyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt_TargetKeyLength() + *********************************************************************************************************************/ +/*! \brief Gets and checks the target key length from the salt input parameter of the KDF + * \details Gets and checks the target key length from the salt input parameter of the KDF according to + * NIST 800-108 NIST/FIPS 186-4. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] deriveAlgorithm The algorithm from the Algorithm key element + * \param[in] saltBuffer The salt from the Salt key element (needs to be defined in the calling function because primeMinus1PtrPtr points into that buffer) + * \param[out] targetKeyLength Length of the target key + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the buffer provided by deriveAlgorithm has to be 1 Byte. + * Length of the buffer provided by saltBuffer has to be CRYPTO_30_LIBCV_SIZEOF_KDF_SALT_ASYMMETRIC Bytes. + * targetCryptoKeyId has to be a valid identifier. + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt_TargetKeyLength( + uint32 targetCryptoKeyId, + uint8 deriveAlgorithm, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) saltBuffer, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) targetKeyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Kdf_CallPRF() + *********************************************************************************************************************/ +/*! \brief Calls the PRF function of the KDF + * \details Calls the PRF function of the KDF according to NIST 800-108 NIST/FIPS 186-4. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in,out] prfInputBuffer Input for the PRF + * \param[in] prfInputBufferLength Written Length of the PRF intput + * \param[out] targetKey Buffer for the target key + * \param[in] targetKeyLength Length of the target key + * \param[in] parentKeyLength Length of the parent key + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the buffer provided by targetKey has to be CRYPTO_30_LIBCV_SIZEOF_KDF_MAX_TARGET_KEY_PLUS_8 Bytes. + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Kdf_CallPRF( + P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) prfInputBuffer, + uint32 prfInputBufferLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) targetKey, + uint32 targetKeyLength, uint32 parentKeyLength); +#endif /* #if ((CRYPTO_30_LIBCV_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Kdf_AsymDivideByPrimeMinusOne() + *********************************************************************************************************************/ +/*! \brief Divides the given target key by the given prime-1 and adds one to the result + * \details Divides the given target key by the given prime-1 and adds one to the result according to NIST/FIPS 186-4. + * \param[out] targetKey Buffer for the target key + * \param[in] targetKeyLength Length of the target key + * \param[in] primeMinus1Ptr Pointer to the position of the prime minus-1 data within the salt + * \param[in] primeMinus1Length Length of the prime-1 + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the buffer provided by targetKey has to be CRYPTO_30_LIBCV_SIZEOF_KDF_MAX_TARGET_KEY_PLUS_8 Bytes. + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Kdf_AsymDivideByPrimeMinusOne( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) targetKey, + uint32 targetKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) primeMinus1Ptr, + uint32 primeMinus1Length); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_With_Ws_AndLoadKey() + *********************************************************************************************************************/ +/*! \brief Calculate one pass c1e1s KDF. + * \details Calculate the the one pass c1e1s corresponding to NIST 800 56A and load all required key elements. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_With_Ws_AndLoadKey( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_AndLoadKey() + *********************************************************************************************************************/ +/*! \brief Calculate one pass c1e1s KDF. + * \details Calculate the the one pass c1e1s corresponding to NIST 800 56A and load all required key elements. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-145593 + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_AndLoadKey( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON) \ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist80056A_SingleStepKdfHash() + *********************************************************************************************************************/ +/*! \brief Calculate single step KDF. + * \details Calculate the single step kdf with HASH/Sha256 corresponding to NIST 800 56A. + * \param[in,out] workspace Hols the primitive workspace. + * \param[in] sharedSecretPtr Pointer to the shared secret. + * \param[in] sharedSecretLength Length of the shared secret. + * \param[in] otherInfoPtr Pointer to the other-information. + * \param[in] otherInfoLength Length of the other-information. + * \param[out] derivedKeyPtr Pointer to the derived key. + * \param[in,out] derivedKeyLengthPtr Pointer to the length of the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre sharedSecretPtr has to be a valid pointer with the length sharedSecretLength. + * otherInfoPtr has to be a valid pointer with the length otherInfoLength. + * derivedKeyPtr has to be a valid pointer with the length *derivedKeyLengthPtr. + * derivedKeyLengthPtr has to be a valid length pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist80056A_SingleStepKdfHash( + P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) sharedSecretPtr, + uint32 sharedSecretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) otherInfoPtr, + uint32 otherInfoLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) derivedKeyPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) derivedKeyLengthPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S() + *********************************************************************************************************************/ +/*! \brief Calculate one pass c1e1s KDF. + * \details Calculate the the one pass c1e1s corresponding to NIST 800 56A. + * \param[in,out] workspace Hols the primitive workspace. + * \param[in] privateKeyPtr Pointer to the private key. + * \param[in] privateKeyLength Length of the private key. + * \param[in] partnerPubKeyPtr Pointer to the partner public key. + * \param[in] partnerPubKeyLength Length of the partner public key. + * \param[in] otherInfoPtr Pointer to the other-information. + * \param[in] otherInfoPtrLength Length of the other-information. + * \param[out] derivedKeyPtr Pointer to the derived key. + * \param[in,out] derivedKeyLengthPtr Pointer to the length of the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre privateKeyPtr has to be a valid pointer with the length privateKeyLength. + * partnerPubKeyPtr has to be a valid pointer with the length partnerPubKeyLength. + * otherInfoPtr has to be a valid pointer with the length otherInfoLength. + * derivedKeyPtr has to be a valid pointer with the length *derivedKeyLengthPtr. + * derivedKeyLengthPtr has to be a valid length pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + uint32 partnerPubKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) otherInfoPtr, + uint32 otherInfoPtrLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) derivedKeyPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) derivedKeyLengthPtr); +#endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON) \ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_CheckKey() + *********************************************************************************************************************/ +/*! \brief Check key according to ISO15118. + * \details Check if the key pair is valid according to ISO15118. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] privateKeyPtr Pointer to the private key. + * \param[in] privateKeyLength Length of the private key. + * \param[in] pubKeyPtr Pointer to the public key. + * \param[in] pubKeyLength Length of the public key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre privateKeyPtr has to be a valid pointer with the length privateKeyLength. + * pubKeyPtr has to be a valid pointer with the length pubKeyLength. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_CheckKey( + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) pubKeyPtr, + uint32 pubKeyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_Aes128Decrypt() + *********************************************************************************************************************/ +/*! \brief Decrypt Aes128 data. + * \details Decrypt Aes128 data corresponding to ISO15118(extract private key). + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] ivPtr Pointer to the initial vector. + * \param[in] keyPtr Pointer to the encryption key. + * \param[in] encryptedMessagePtr Pointer to the encrypted message. + * \param[in] encryptedMessageLength Length of the encrypted message. + * \param[out] plainMessagePtr Pointer to the plain message. + * \param[in,out] plainMessageLengthPtr Length of the plain message. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre encryptedMessagePtr has to be a valid pointer with the length encryptedMessageLength. + * plainMessagePtr has to be a valid pointer with the length plainMessageLengthPtr. + * plainMessageLengthPtr has to be a length valid pointer. + * ivPtr has to be a length valid pointer to a valid IV with the length CRYPTO_30_LIBCV_ISO15118_SIZEOF_IV. + * keyPtr has to be a length valid pointer to a valid AES128 key with the length ESL_SIZEOF_AES128_KEY. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_Aes128Decrypt( + P2VAR(eslt_WorkSpaceAES128, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) ivPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) encryptedMessagePtr, + uint32 encryptedMessageLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) plainMessagePtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) plainMessageLengthPtr); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_ECDSA() + *********************************************************************************************************************/ +/*! \brief Check ECDSA key according to ISO15118-20. + * \details Check if the key pair is valid according to ISO15118-20. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] privateKeyPtr Valid pointer to the private key with the length privateKeyLength. + * \param[in] privateKeyLength Length of the private key. + * \param[in] pubKeyPtr Valid pointer to the public key with the length pubKeyLength. + * \param[in] pubKeyLength Length of the public key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_ECDSA( + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) pubKeyPtr, + uint32 pubKeyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_X448() + *********************************************************************************************************************/ +/*! \brief Check X448 key according to ISO15118-20. + * \details Check if the key pair is valid according to ISO15118-20. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] privateKeyPtr Valid pointer to the private key with the length privateKeyLength. + * \param[in] privateKeyLength Length of the private key. + * \param[in] pubKeyPtr Valid pointer to the public key with the length pubKeyLength. + * \param[in] pubKeyLength Length of the public key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_X448( + P2VAR(eslt_WorkSpaceEdDH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) pubKeyPtr, + uint32 pubKeyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_AesGcm256Decrypt() + *********************************************************************************************************************/ +/*! \brief Decrypt AesGcm256 data. + * \details Decrypt AesGcm256 data corresponding to ISO15118-20(extract contract private key). + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] ivPtr Valid pointer to the initial vector with the length CRYPTO_30_LIBCV_ISO15118_SIZEOF_IV. + * \param[in] keyPtr Valid pointer to the AESGcm256 encryption key with the length CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_DERIVED_KEY. + * \param[in] aadPtr Valid pointer to the AAD (PCID + SKI) with the length aadLength. + * \param[in] aadLength Length of the AAD. + * \param[in] tagPtr Valid pointer to the AESGcm256 tag with the length CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_TAG. + * \param[in] encryptedMessagePtr Valid pointer to the encrypted message with the length encryptedMessageLength. + * \param[in] encryptedMessageLength Length of the encrypted message. + * \param[out] plainMessagePtr Valid pointer to the plain message with the length plainMessageLengthPtr. + * \param[in,out] plainMessageLengthPtr Length of the plain message. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_AesGcm256Decrypt( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) ivPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) aadPtr, + uint32 aadLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) tagPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) encryptedMessagePtr, + uint32 encryptedMessageLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) plainMessagePtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) plainMessageLengthPtr); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SERVICE_KEY_DERIVE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Derive_UpdateKeyState() + **********************************************************************************************************************/ +/*! \brief Update Key State after key derive. + * \details - + * \param[in] objectId Holds the identifier of driver object. + * \param[in] targetCryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] retVal Holds the retVal of the key derive. + * \pre cryptoKeyId has to be a valid identifier. + * objectId has to be a valid identifier. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Derive_UpdateKeyState( + uint32 objectId, + uint32 targetCryptoKeyId, + Std_ReturnType retVal); +#endif + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864_WS() + *********************************************************************************************************************/ +/*! \brief Derive Key for NIST 800-108 NIST/FIPS 186.4 + * \details Dispatch and derive the key according to NIST 800-108 NIST/FIPS 186-4. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] deriveAlgorithm The algorithm from the Algorithm key element + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY The required key is busy. + * \pre cryptoKeyId has to be a valid crypto key. + * targetCryptoKeyId has to be a valid crypto key. + * deriveAlgorithm has to be a valid (CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256 + * or CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB). + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864_WS( + P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 deriveAlgorithm); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864() + *********************************************************************************************************************/ +/*! \brief Derive Key for NIST 800-108 NIST/FIPS 186.4 + * \details Dispatch and derive the key according to NIST 800-108 NIST/FIPS 186-4. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] deriveAlgorithm The algorithm from the Algorithm key element + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY The required key is busy. + * \pre cryptoKeyId has to be a valid crypto key. + * targetCryptoKeyId has to be a valid crypto key. + * deriveAlgorithm has to be a valid (CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256 + * or CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB). + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-132407, CREQ-145592 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 deriveAlgorithm); +#endif /* CRYPTO_30_LIBCV_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256_ENABLED || CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_108_CTR_CMAC_AES_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist800108_GetInputOutput() + *********************************************************************************************************************/ +/*! \brief Get inputs and outputs used by NIST800-108 KDF. + * \details Get pointers and lengths of the key elements providing sourceKey, label, context and targetKey. + * Label and context are optional and may be NULL_PTR with length zero. All members of + * pInputOutputContainer are initialized by this function only if E_OK is returned. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetKeyId Holds the identifier of the key which is used to store the derived key. + * \param[out] pInputOutputContainer Pointer to the container where this function writes the pointers and lengths + * of the key elements used as input and output. + * \return E_OK Request successful, all members of pInputOutputContainer were initialized. + * E_NOT_OK Request failed, some members of pInputOutputContainer may be uninitialized. + * CRYPTO_E_KEY_NOT_VALID Request failed, key is not valid. + * \pre cryptoKeyId has to be a valid crypto key. + * targetCryptoKeyId has to be a valid crypto key. + * pInputOutputContainer must be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys. + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist800108_GetInputOutput( + uint32 cryptoKeyId, + uint32 targetKeyId, + P2VAR(Crypto_30_LibCv_Nist800108_KDF_InputOutput, AUTOMATIC, AUTOMATIC) pInputOutputContainer); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Calc_Nist800108_CTR_CMAC_AES() + *********************************************************************************************************************/ +/*! \brief Derive Key using NIST 800-108 Counter mode with CMAC AES. + * \details Choose AES128 or AES256 based on sourceKey length (16 or 32 Byte) and derive key using ESLib. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in,out] pInputOutputContainer Pointer to container holding pointers and lengths of input and output. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_SIZE_MISMATCH SourceKey has not the correct length of 16 or 32 bytes. + * \pre Pointers must be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Calc_Nist800108_CTR_CMAC_AES( + P2VAR(eslt_WorkSpaceKDFnist800108, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_30_LibCv_Nist800108_KDF_InputOutput, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) pInputOutputContainer); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic_WS() + *********************************************************************************************************************/ +/*! \brief Derive Key for NIST 800-108 using the ESLib for calculation. + * \details Get needed input and output, choose algorithm and derive the key. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre workspace must be a valid pointer. + * cryptoKeyId has to be a valid crypto key. + * targetCryptoKeyId has to be a valid crypto key. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic_WS( + P2VAR(eslt_WorkSpaceKDFnist800108, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic() + *********************************************************************************************************************/ +/*! \brief Derive Key for NIST 800-108 using the ESLib for calculation. + * \details Provide workspace on stack and call Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic_WS(). + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre cryptoKeyId has to be a valid crypto key. + * targetCryptoKeyId has to be a valid crypto key. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_108_CTR_CMAC_AES_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_WS() + *********************************************************************************************************************/ +/*! \brief Derives a ISO15118 key. + * \details Install and update the key according to ISO15118. Calculate the session key an decrypt the new private key. + * \param[in,out] workspace Holds the primitives workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_WS( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118() + *********************************************************************************************************************/ +/*! \brief Derives a ISO15118 key. + * \details Install and update the key according to ISO15118. Calculate the session key an decrypt the new private key. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace DSGN-DrvCrypto_LibCv_ISO15118CertificateInstallationAndUpdate + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); +#endif /* CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleSECP521() + *********************************************************************************************************************/ +/*! \brief Derives a ISO15118-20 key with curve SECP521R1. + * \details Calculates the session key and decrypt the contract private key according to ISO15118-20 using SECP521R1. + * \param[in,out] workspace Holds the primitives workspace. + * \param[in] privKeyPtr Pointer to the provision certificate private key. + * \param[in] privKeyLength Length of the provision certificate private key. + * \param[in] partnerPubKeyPtr Pointer to the partner public key. + * \param[in] partnerPubKeyLength Length of the partner public key. + * \param[in] encryptedDataKeyPtr Pointer to the data which holds the IV and the encrypted contract private key. + * \param[in] associatedDataPtr Pointer to the associated data of the encryptedDataKey. + * \param[in] associatedDataLength Length of the associated data. + * \param[out] contractCertPrivateKeyPtr Pointer to where the contract certificate private key should be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre privKeyPtr is a valid pointer to a key of length privKeyLength. + * partnerPubKeyPtr is a valid pointer to a key of length partnerPubKeyLength. + * encryptedDataKeyPtr is a valid pointer to a key of length CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_IV_PRIV_KEY_TAG_P521. + * associatedDataPtr is a valid pointer to associatedData of length associatedDataLength. + * contractCertPrivateKeyPtr is a valid pointer of length >= CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_P521. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleSECP521( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118_20, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privKeyPtr, + uint32 privKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + uint32 partnerPubKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) encryptedDataKeyPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) contractCertPrivateKeyPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleX448() + *********************************************************************************************************************/ +/*! \brief Derives a ISO15118-20 key with Curve448. + * \details Calculates the session key and decrypt the contract private key according to ISO15118-20 using X448. + * \param[in,out] workspace Holds the primitives workspace. + * \param[in] privKeyPtr Pointer to the provision certificate private key. + * \param[in] privKeyLength Length of the provision certificate private key. + * \param[in] partnerPubKeyPtr Pointer to the partner public key. + * \param[in] partnerPubKeyLength Length of the partner public key. + * \param[in] encryptedDataKeyPtr Pointer to the data which holds the IV and the encrypted contract private key. + * \param[in] associatedDataPtr Pointer to the associated data of the encryptedDataKey. + * \param[in] associatedDataLength Length of the associated data. + * \param[out] contractCertPrivateKeyPtr Pointer to where the contract certificate private key should be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre privKeyPtr is a valid pointer to a key of length privKeyLength. + * partnerPubKeyPtr is a valid pointer to a key of length partnerPubKeyLength. + * encryptedDataKeyPtr is a valid pointer to a key of length CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_IV_PRIV_KEY_TAG_X448. + * associatedDataPtr is a valid pointer to associatedData of length associatedDataLength. + * contractCertPrivateKeyPtr is a valid pointer of length >= CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_X448. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleX448( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118_20, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privKeyPtr, + uint32 privKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + uint32 partnerPubKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) encryptedDataKeyPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) contractCertPrivateKeyPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_WS() + *********************************************************************************************************************/ +/*! \brief Derives a ISO15118-20 key. + * \details Installs the key according to ISO15118-20. Calculates the session key an decrypt the contract private key. + * \param[in,out] workspace Holds the primitives workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_WS( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118_20, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20() + *********************************************************************************************************************/ +/*! \brief Derives a ISO15118-20 key. + * \details Installs the key according to ISO15118-20. Calculate the session key an decrypt the contract private key. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace DSGN-DrvCrypto_LibCv_ISO15118-20-CertificateInstallation + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); +#endif /* CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA1() + **********************************************************************************************************************/ +/*! \brief Derives a PBKDF2 HMAC SHA1 key. + * \details Derives a key according to PBKDF2 HMAC SHA1 with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret), + * CRYPTO_KE_KEYDERIVATION_SALT(Seed) and CRYPTO_KE_KEYDERIVATION_ITERATIONS(Iteration). + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-248610 + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA1( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA1() + **********************************************************************************************************************/ +/*! \brief Derives a PBKDF2 HMAC SHA1 key. + * \details Derives a key according to PBKDF2 HMAC SHA1 with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret), + * CRYPTO_KE_KEYDERIVATION_SALT(Seed) and CRYPTO_KE_KEYDERIVATION_ITERATIONS(Iteration). + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] secretLength Holds the length of the secret. + * \param[in] secretPtr Holds the pointer to the secret with length of secretLength. + * \param[in] infoLength Holds the length of the info. + * \param[in] infoPtr Holds the pointer to the info with length of infoLength. + * \param[in] keyLength Holds the length of the key. + * \param[in,out] keyPtr Holds the pointer to the key with length of keyLength. + * \param[in] iterations Holds the value to the iterations. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA1( + P2VAR(eslt_WorkSpaceKDF2HMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + uint32 iterations); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1_ENABLED == STD_ON) */ + +#if((CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA_WS() + **********************************************************************************************************************/ +/*! \brief Derives a PBKDF2 HMAC SHA1 or PBKDF2 HMAC SHA256 key. + * \details Derives a key according to PBKDF2 HMAC SHA1 or PBKDF2 HMAC SHA256 with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret), + * CRYPTO_KE_KEYDERIVATION_SALT(Seed) and CRYPTO_KE_KEYDERIVATION_ITERATIONS(Iteration). + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] algorithm Holds the identifier of the algorithm which is used for the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA_WS( + P2VAR(eslt_WorkSpaceKDF2, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 algorithm); +#endif /* ( CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1_ENABLED == STD_ON || CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA256() + **********************************************************************************************************************/ +/*! \brief Derives a PBKDF2 HMAC SHA256 key. + * \details Derives a key according to PBKDF2 HMAC SHA256 with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret), + * CRYPTO_KE_KEYDERIVATION_SALT(Seed) and CRYPTO_KE_KEYDERIVATION_ITERATIONS(Iteration). + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-248610 + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA256( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA256() + **********************************************************************************************************************/ +/*! \brief Derives a PBKDF2 HMAC SHA256 key. + * \details Derives a key according to PBKDF2 HMAC SHA256 with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret), + * CRYPTO_KE_KEYDERIVATION_SALT(Seed) and CRYPTO_KE_KEYDERIVATION_ITERATIONS(Iteration). + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] secretLength Holds the length of the secret. + * \param[in] secretPtr Holds the pointer to the secret with length of secretLength. + * \param[in] infoLength Holds the length of the info. + * \param[in] infoPtr Holds the pointer to the info with length of infoLength. + * \param[in] keyLength Holds the length of the key. + * \param[in,out] keyPtr Holds the pointer to the key with length of keyLength. + * \param[in] iterations Holds the value of the iterations. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA256( + P2VAR(eslt_WorkSpaceKDF2HMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + uint32 iterations); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS() + **********************************************************************************************************************/ +/*! \brief Derives a HKDF HMAC key. + * \details Derives a key according to HKDF HMAC with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret), + * CRYPTO_KE_KEYDERIVATION_SALT(Seed) and CRYPTO_KE_KEYDERIVATION_ITERATIONS(Iteration). + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] hashAlgorithmId Holds the identifier of the hash algorithm to use for HMAC. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS( + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 hashAlgorithmId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC() + **********************************************************************************************************************/ +/*! \brief Derives a HKDF HMAC SHA256 key. + * \details Derives a key according to HKDF HMAC with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret), + * CRYPTO_KE_KEYDERIVATION_SALT(Seed) and CRYPTO_KE_KEYDERIVATION_ITERATIONS(Iteration). + * By passing a suitable workspace to Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] hashAlgorithmId Holds the identifier of the hash algorithm to use for HMAC. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-266053 + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 hashAlgorithmId); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA256() + **********************************************************************************************************************/ +/*! \brief Derives a HKDF HMAC SHA256 key. + * \details Derives a key according to HKDF HMAC SHA256. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] secretLength Holds the length of the secret. + * \param[in] secretPtr Holds the pointer to the secret with length of secretLength. + * \param[in] saltLength Holds the length of the salt. + * \param[in] saltPtr Holds the pointer to the salt with length of saltLength. + * \param[in] infoLength Holds the length of the info. + * \param[in] infoPtr Holds the pointer to the info with length of infoLength. + * \param[in] keyLength Holds the length of the key. + * \param[in,out] keyPtr Holds the pointer to the key with length of keyLength. + * \param[in] iterations Holds the value of the iterations. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA256( + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 saltLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) saltPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + uint8 iterations); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256_ENABLED == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1_WS() + **********************************************************************************************************************/ +/*! \brief Derives a HKDF Hash Option 1 key. + * \details Derives a key according to HKDF option 1 with the specified CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret). + * The hash function is specified using the CRYPTO_KE_KEYDERIVATION_ALGORITHM(Algorithm). + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] hashId Holds the identifier of the Hash. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-304740 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1_WS( + P2VAR(eslt_WorkSpaceHKDFHASH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + eslt_HashAlgorithm hashId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1() + **********************************************************************************************************************/ +/*! \brief Derives a HKDF Hash Option 1 key. + * \details Derives a key according to HKDF Hash Option 1 with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret) + * and optionally CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO (additional information). + * The hash function is specified using the CRYPTO_KE_KEYDERIVATION_ALGORITHM(Algorithm). + * By passing a suitable workspace to Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1_WS. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] hashId Holds the identifier of the hash. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + eslt_HashAlgorithm hashId); +#endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512_ENABLED == STD_ON)) */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_Hash_Option_1() + **********************************************************************************************************************/ +/*! \brief Derives a HKDF Hash Option 1 key. + * \details Derives a key according to HKDF Hash Option 1. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] secretLength Holds the length of the secret. + * \param[in] secretPtr Holds the pointer to the secret with length of secretLength. + * \param[in] infoLength Holds the length of the info. + * \param[in] infoPtr Holds the pointer to the info with length of infoLength. + * \param[in] keyLength Holds the length of the key. + * \param[in,out] keyPtr Holds the pointer to the key with length of keyLength. + * \param[in] hashId Holds the value of the hash id. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_Hash_Option_1( + P2VAR(eslt_WorkSpaceHKDFHASH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + eslt_HashAlgorithm hashId); +#endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA384() + **********************************************************************************************************************/ +/*! \brief Derives a HKDF HMAC SHA384 key. + * \details Derives a key according to HKDF HMAC SHA384. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] secretLength Holds the length of the secret. + * \param[in] secretPtr Holds the pointer to the secret with length of secretLength. + * \param[in] saltLength Holds the length of the salt. + * \param[in] saltPtr Holds the pointer to the salt with length of saltLength. + * \param[in] infoLength Holds the length of the info. + * \param[in] infoPtr Holds the pointer to the info with length of infoLength. + * \param[in] keyLength Holds the length of the key. + * \param[in,out] keyPtr Holds the pointer to the key with length of keyLength. + * \param[in] iterations Holds the value of the iterations. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA384( + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 saltLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) saltPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + uint8 iterations); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC() + **********************************************************************************************************************/ +/*! \brief Expands a key according to the second step of HKDF HMAC. + * \details Expands a given key according to HKDF HMAC with a local workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] hashAlgorithmId Holds the identifier of the hash algorithm to use for HMAC. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-Crypto-HKDFExpand + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 hashAlgorithmId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC_WS() + **********************************************************************************************************************/ +/*! \brief Expands a key according to the second step of HKDF HMAC. + * \details Expands a given key according to HKDF HMAC with provided workspace. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in] hashAlgorithmId Holds the identifier of the hash algorithm to use for HMAC. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC_WS( + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 hashAlgorithmId); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_SPAKE2_PLUS_P256R1_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Spake2Plus_WS() + **********************************************************************************************************************/ +/*! \brief Derives a Spake2+ key. + * \details Derives a key according to Spake2+ preamble phase with the given Secret [w0s|w1s], the function derives + * w0, w1 and l. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Spake2Plus_WS( + P2VAR(eslt_WorkSpaceSPAKE2PPreamble, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Spake2Plus() + **********************************************************************************************************************/ +/*! \brief Derives a Spake2+ key. + * \details Derives a key according to Spake2+ preamble phase with the given Secret [w0s|w1s], the function derives + * w0, w1 and l. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_Spake2+ + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Spake2Plus( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_Spake2Plus() + **********************************************************************************************************************/ +/*! \brief Derives a Spake2+ key. + * \details Derives a key according to Spake2+ with the given Secret [w0s|w1s], the function derives + * w0, w1 and l. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] domainPtr Pointer to domain parameter structure + * \param[in] domainExtPtr Pointer to domain parameter extension structure + * \param[in] secretPtr Holds the pointer to the secret [w0s|w1s] with length of secretLength. + * \param[in] secretLength Holds the length of the secret. + * \param[in,out] w0Ptr Holds the pointer to the value w0 with length of w0Length. + * \param[in] w0Length Holds the length of the w0. + * \param[in,out] w1Ptr Holds the pointer to the value w1 with length of w1Length. + * \param[in] w1Length Holds the length of the w1. + * \param[in,out] lPtr Holds the pointer to the point l with length of lLength. + * \param[in] lLength Holds the length of the l. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_Spake2Plus( + P2VAR(eslt_WorkSpaceSPAKE2PPreamble, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 secretLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) w0Ptr, + uint32 w0Length, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) w1Ptr, + uint32 w1Length, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) lPtr, + uint32 lLength); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA256_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_Calc() + **********************************************************************************************************************/ +/*! \brief Derives a KDF X9.63 key with Sha-256. + * \details Derives a key according to KDF X9.63 Sha-256 with the given secret and + * optional seed. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] secretLength Holds the length of the secret. + * \param[in] secretPtr Holds the pointer to the secret with length of secretLength. + * \param[in] infoLength Holds the length of the info. + * \param[in] infoPtr Holds the pointer to the info with length of infoLength. + * \param[in] keyLength Holds the length of the key. + * \param[in,out] keyPtr Holds the pointer to the key with length of keyLength. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_Calc( + P2VAR(eslt_WorkSpaceKDFX963SHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_256() + **********************************************************************************************************************/ +/*! \brief Derives a KDF X9.63 key with Sha-256. + * \details Derives a key according to KDF X9.63 Sha-256 with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret) and + * optional CRYPTO_KE_KEYDERIVATION_SALT(Seed). + * By passing a suitable workspace to Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_WS + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-191710 + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_256( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_WS() + **********************************************************************************************************************/ +/*! \brief Derives a KDF X9.63 key with Sha-256. + * \details Derives a key according to KDF X9.63 Sha-256 with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret) and + * optional CRYPTO_KE_KEYDERIVATION_SALT(Seed). + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_WS( + P2VAR(eslt_WorkSpaceKDFX963SHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA256_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA512_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_Calc() + **********************************************************************************************************************/ +/*! \brief Derives a KDF X9.63 key with Sha-512. + * \details Derives a key according tp KDF X9.63 Sha-512 with the given secret and + * optional seed. + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] secretLength Holds the length of the secret. + * \param[in] secretPtr Holds the pointer to the secret with length of secretLength. + * \param[in] infoLength Holds the length of the info. + * \param[in] infoPtr Holds the pointer to the info with length of infoLength. + * \param[in] keyLength Holds the length of the key. + * \param[in,out] keyPtr Holds the pointer to the key with length of keyLength. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_Calc( + P2VAR(eslt_WorkSpaceKDFX963SHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_512() + **********************************************************************************************************************/ +/*! \brief Derives a KDF X9.63 key with Sha-512. + * \details Derives a key according tp KDF X9.63 Sha-512 with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret) and + * optional CRYPTO_KE_KEYDERIVATION_SALT(Seed). + * By passing a suitable workspace to Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_WS + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-191710 + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_512( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_WS() + **********************************************************************************************************************/ +/*! \brief Derives a KDF X9.63 key with Sha-512. + * \details Derives a key according to KDF X9.63 Sha-512 with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret) and + * optional CRYPTO_KE_KEYDERIVATION_SALT(Seed). + * \param[in,out] workspace Holds the primitive workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_WS( + P2VAR(eslt_WorkSpaceKDFX963SHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA512_ENABLED == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA512_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_Get_Secret_And_Salt() + **********************************************************************************************************************/ +/*! \brief Gets the secret and salt index and checks the target key. + * \details Gets the index for secret and salt and checks the target key for validity. + * \param[in,out] secretLength Holds the length of the secret. + * \param[in,out] secretIndex Holds the secret index. + * \param[in,out] saltLength Holds the length of the salt. + * \param[in,out] saltIndex Holds the salt index. + * \param[in,out] keyLength Holds the length of the key. + * \param[in,out] keyElementIndex Holds the key element index. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_Get_Secret_And_Salt( + P2VAR(uint32, AUTOMATIC, AUTOMATIC) secretLength, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) secretIndex, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) saltLength, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) saltIndex, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) keyLength, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) keyElementIndex, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); +#endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA512_ENABLED == STD_ON)) */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt_TargetKeyLength() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt_TargetKeyLength( + uint32 targetCryptoKeyId, + uint8 deriveAlgorithm, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) saltBuffer, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) targetKeyLength) +{ + Std_ReturnType retVal = E_OK; + + uint32 configuredTargetKeyLength = 0u; + + /* #1 Get configured target key length */ + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex; + if (Crypto_30_LibCv_Local_KeyElementSearch(targetCryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &elementIndex) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* Get Configured Target Key Length */ + configuredTargetKeyLength = Crypto_30_LibCv_GetKeyElementLength(elementIndex); + } + else + { + retVal = E_NOT_OK; /* PRQA S 2982 */ /* MD_MSR_RetVal */ + } + + /* #2 Compare the configured length against the target key length given in salt */ + /* The keyLength (k) in salt is given in bytes and Big Endian Format. This has to be converted to size in bits and little endian format later */ + (*targetKeyLength) = (((((uint32)(saltBuffer[4])) << 8) | ((uint32)(saltBuffer[5])))); /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_INLINE_STACK */ + + /* Check valid target key length */ + if ((*targetKeyLength > CRYPTO_30_LIBCV_SIZEOF_KDF_MAX_TARGET_KEY) || + ((*targetKeyLength) > configuredTargetKeyLength)) + { + retVal = E_NOT_OK; + } + +# if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) +# if (CRYPTO_30_LIBCV_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256_ENABLED == STD_ON) + /* #3 For Asym keys check that length is supported by used prime numbers */ + if (deriveAlgorithm == CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB) +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(deriveAlgorithm); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + { + if ((*targetKeyLength) != CRYPTO_30_LIBCV_SIZEOF_KDF_PRIME) + { + retVal = E_NOT_OK; + } + + /* #4 For Asymmetric key derivation target key has to be extended by 8 bytes, because it is divided by prime-1 in the second step */ + (*targetKeyLength) += CRYPTO_30_LIBCV_SIZEOF_KDF_PRIME_ASYM_EXTEND; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_INLINE_STACK */ + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(deriveAlgorithm); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + + return retVal; +} /* Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt_TargetKeyLength() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 deriveAlgorithm, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) prfInputBuffer, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) prfInputBufferLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) saltBuffer, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) targetKeyLength) +{ + Std_ReturnType retVal; + + Crypto_30_LibCv_SizeOfKeyStorageType saltIndex; + uint32 saltLength; + + /* #1 Load Salt / Context from the salt key element */ + /* 4 byte Context | 2 byte target Key Length in Big Endian (k) | 32 byte curve specific Prime-1 */ + /* For Asym keys the salt contains also the 32 byte prime-1 */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_SALT, &saltIndex, &saltLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* #2 Check expected salt length according to the algorithm */ + if (retVal == E_OK) + { +# if (CRYPTO_30_LIBCV_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256_ENABLED == STD_ON) +# if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) + if (deriveAlgorithm == CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256) +# endif + { + if (saltLength != CRYPTO_30_LIBCV_SIZEOF_KDF_SALT_SYMMETRIC) + { + retVal = E_NOT_OK; + } + } +# if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) + else +# endif +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) + { + /* CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB */ + if (saltLength != CRYPTO_30_LIBCV_SIZEOF_KDF_SALT_ASYMMETRIC) + { + retVal = E_NOT_OK; + } + } +# endif + } + + /* #4 Copy the 4 byte Context into the PRF input buffer */ + if (retVal == E_OK) + { + Crypto_30_LibCv_CopyData(saltBuffer, Crypto_30_LibCv_GetAddrKeyStorage(saltIndex), saltLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + Crypto_30_LibCv_CopyData(&(prfInputBuffer[*prfInputBufferLength]), saltBuffer, CRYPTO_30_LIBCV_SIZEOF_KDF_CONTEXT); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + (*prfInputBufferLength) += CRYPTO_30_LIBCV_SIZEOF_KDF_CONTEXT; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_INLINE_STACK */ + + retVal = Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt_TargetKeyLength(targetCryptoKeyId, deriveAlgorithm, saltBuffer, targetKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + return retVal; +} /* Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Kdf_HandleInputParams() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + */ +/* PRQA S 6060 9 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Kdf_HandleInputParams( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 deriveAlgorithm, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) prfInputBuffer, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) prfInputBufferLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) saltBuffer, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) targetKeyLength, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) parentKeyLength) +{ + Std_ReturnType retVal; + Crypto_30_LibCv_SizeOfKeyStorageType passwordIndex = 0u; /* init with valid value */ + Crypto_30_LibCv_SizeOfKeyStorageType labelIndex = 0u; /* init with valid value */ + uint32 labelLength = CRYPTO_30_LIBCV_SIZEOF_KDF_LABEL_LENGTH; + + (*parentKeyLength) = CRYPTO_30_LIBCV_SIZEOF_KDF_MAX_PARENT_KEY; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_INLINE_STACK */ + + /* #2 Get Parent Key from the password key element and write it to the PRF input buffer */ + + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &passwordIndex, parentKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + Crypto_30_LibCv_CopyData(prfInputBuffer, Crypto_30_LibCv_GetAddrKeyStorage(passwordIndex), *parentKeyLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + (*prfInputBufferLength) += *parentKeyLength; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_INLINE_STACK */ + + /* #3 Get Label from the Label key element and write it to the PRF input buffer */ + /* Skip one byte for iteration counter */ + (*prfInputBufferLength)++; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_INLINE_STACK */ + + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYDERIVATION_LABEL, &labelIndex, &labelLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + } + + if (retVal == E_OK) + { + Crypto_30_LibCv_CopyData(&(prfInputBuffer[*prfInputBufferLength]), Crypto_30_LibCv_GetAddrKeyStorage(labelIndex), labelLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + (*prfInputBufferLength) += labelLength; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_INLINE_STACK */ + + /* #4 Add constant byte 0x00 to the PRF input buffer */ + prfInputBuffer[*prfInputBufferLength] = 0x00u; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + (*prfInputBufferLength)++; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_INLINE_STACK */ + + /* #5 Get and check the Salt element */ + retVal = Crypto_30_LibCv_Local_Kdf_HandleInputParams_Salt(cryptoKeyId, targetCryptoKeyId, deriveAlgorithm, prfInputBuffer, prfInputBufferLength, saltBuffer, targetKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + /* #6 Convert target key length to bits and little endian and copy it to the input buffer */ + if (retVal == E_OK) + { + /* Set k in bits and little endian (lo byte first) */ + prfInputBuffer[*prfInputBufferLength] = (uint8)((uint16)((*targetKeyLength << 3u)) & 0x00FFu); /* lo byte */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + prfInputBuffer[*prfInputBufferLength + 1u] = (uint8)((uint16)((*targetKeyLength) >> 5u) & 0x00FFu); /* hi byte */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ /* PRQA S 2985 */ /* MD_CRYPTO_30_LIBCV_2985 */ + (*prfInputBufferLength) += CRYPTO_30_LIBCV_SIZEOF_KDF_TARGET_KEY_LENGTH; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_INLINE_STACK */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_Kdf_HandleInputParams() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Kdf_CallPRF() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6060, 6080 7 */ /* MD_CRYPTO_30_LIBCV_STPAR, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Kdf_CallPRF( + P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) prfInputBuffer, + uint32 prfInputBufferLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) targetKey, + uint32 targetKeyLength, + uint32 parentKeyLength) +{ + Std_ReturnType retVal = E_OK; + uint32_least derivedLength; + uint8 i = 1u; + + /* #1 Iterate over the target key length */ + for (derivedLength = 0u; derivedLength < targetKeyLength; derivedLength += ESL_SIZEOF_SHA256_DIGEST) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND_WITH_CHECK */ + { + uint8 tempHashBuf[ESL_SIZEOF_SHA256_DIGEST] = { 0u }; + + /* #11 Set the iteration counter i in the PRF input buffer. Inserted after parent key */ + prfInputBuffer[parentKeyLength] = i; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + i++; + + /* #12 Call SHA-256 as PRF */ + retVal = E_NOT_OK; + /* CRYPTO_OPERATIONMODE_START: */ + if (esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_SHA256, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + { + if (esl_initSHA256((P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + { + /* CRYPTO_OPERATIONMODE_UPDATE: */ + if (esl_updateSHA256((P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, (eslt_Length)prfInputBufferLength, (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))prfInputBuffer) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_DATA_PTR */ + { + /* CRYPTO_OPERATIONMODE_FINISH: */ + if (esl_finalizeSHA256((P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))tempHashBuf) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS */ + { + retVal = E_OK; + } + } + } + } + + /* #13 Copy the PRF result to the end of the target key buffer */ + if (retVal == E_OK) + { + if ((derivedLength + ESL_SIZEOF_SHA256_DIGEST) <= targetKeyLength) + { + Crypto_30_LibCv_CopyData(&(targetKey[derivedLength]), tempHashBuf, ESL_SIZEOF_SHA256_DIGEST); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + } + else + { + Crypto_30_LibCv_CopyData(&(targetKey[derivedLength]), tempHashBuf, (uint16)(targetKeyLength - derivedLength)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + } + } + else + { + break; + } + /* END Calculate Hash */ + } + return retVal; +} /* Crypto_30_LibCv_Local_Kdf_CallPRF() */ + +# if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Kdf_AsymDivideByPrimeMinusOne() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Kdf_AsymDivideByPrimeMinusOne( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) targetKey, + uint32 targetKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) primeMinus1Ptr, + uint32 primeMinus1Length) +{ + Std_ReturnType retVal = E_OK; + /* #1 Use the library function actBNReduce to divide big numbers */ + /* r = a mod b + ** + ** int actBNReduce(actBNDIGIT* a, + ** actBNLENGTH a_length, + ** actBNDIGIT* b, + ** actBNLENGTH b_length, + ** actBNDIGIT* r, + ** void (*watchdog) (void)); + ** + ** BigNum reduce (r = a mod b). + ** + ** input: (length in digits) + ** - a: first number (will be destroyed) a_length+1 + ** - b: second number (will be returned const b_length + ** but touched by the normalization) + ** - r: result buffer b_length+1 + ** + ** output: + ** - a: the normalized result a mod b b_length + ** - b: second number b_length + ** - r: the result a mod b b_length + ** - returns: -1 if exact b_length <= 1 (error) + ** 0 else (success) */ + +# if (CRYPTO_30_LIBCV_BYTES_PER_DIGIT == 4) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT_DEFINE */ + actBNDIGIT a[264u >> 2]; /* 256 + 8 */ + actBNLENGTH a_length = (actBNLENGTH)(targetKeyLength >> 2); /* PRQA S 4394 */ /* MD_CRYPTO_30_LIBCV_4394 */ + actBNDIGIT b[256u >> 2]; + actBNLENGTH b_length = (actBNLENGTH)(primeMinus1Length >> 2); /* PRQA S 4394 */ /* MD_CRYPTO_30_LIBCV_4394 */ + actBNDIGIT r[264u >> 2]; +# else +# error "Value of CRYPTO_30_LIBCV_BYTES_PER_DIGIT is not supported" +# endif + + uint8 one = 1u; + uint32 res; /* PRQA S 5013 */ /* MD_CRYPTO_30_LIBCV_5013 */ + + /* #11 Set the so far calculated target key as dividend */ + actBNSetOctetString(a, a_length, targetKey, (uint32)targetKeyLength); /* PRQA S 5013 */ /* MD_CRYPTO_30_LIBCV_5013 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + + /* #12 Set the prime-1 as divisor */ + actBNSetOctetString(b, b_length, primeMinus1Ptr, (uint32)primeMinus1Length); /* PRQA S 5013 */ /* MD_CRYPTO_30_LIBCV_5013 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + + /* #13 Call actBNReduce and store the value in targetKey */ + res = actBNReduce(a, a_length, b, b_length, r, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + if (res == (uint32)0) + { + /* #2 Add one and return the result */ + actBNSetOctetString(a, a_length, &one, (uint32)1); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (void)actBNAdd(r, a, r, a_length); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + actBNOctetString(targetKey, (uint32)targetKeyLength, r, a_length); /* PRQA S 5013 */ /* MD_CRYPTO_30_LIBCV_5013 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + } + else + { + retVal = E_NOT_OK; + } + return retVal; +} /* Crypto_30_LibCv_Local_Kdf_AsymDivideByPrimeMinusOne() */ +# endif /* (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864_WS() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864_WS( + P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 deriveAlgorithm) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + uint32 targetKeyLength; + + uint32 parentKeyLength; + uint32 prfInputBufferLength = 0u; +# if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) + uint16 primeMinus1Length; + P2VAR(uint8, AUTOMATIC, AUTOMATIC) primeMinus1Ptr; /* PRQA S 3678 */ /* MD_CRYPTO_30_LIBCV_3678 */ +# endif + + /* Input buffer for the Pseudo Random Function. */ + /* Buffer size is 256 byte maximum parent key length + 12 byte (1 byte iteration | 4 byte Label | 1 byte 0x00 | 6 byte of salt (2 byte TypeID | 2 byte training Counter | 2 byte target Key Length in little endian (k))) */ + uint8 prfInputBuffer[CRYPTO_30_LIBCV_SIZEOF_KDF_PRF_INPUT_BUFFER]; + uint8 saltBuffer[CRYPTO_30_LIBCV_SIZEOF_KDF_SALT_ASYMMETRIC]; + uint8 targetKey[CRYPTO_30_LIBCV_SIZEOF_KDF_MAX_TARGET_KEY_PLUS_8]; /* 256+8 for asym KDF */ + + /* ----- Implementation ------------------------------------------------- */ + Crypto_30_LibCv_ClearData(targetKey, CRYPTO_30_LIBCV_SIZEOF_KDF_MAX_TARGET_KEY_PLUS_8); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* #1 Handle input parameter */ + retVal = Crypto_30_LibCv_Local_Kdf_HandleInputParams(cryptoKeyId, targetCryptoKeyId, deriveAlgorithm, prfInputBuffer, &prfInputBufferLength, saltBuffer, &targetKeyLength, &parentKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* #5 Call PRF */ + if (retVal == E_OK) + { + retVal = Crypto_30_LibCv_Local_Kdf_CallPRF(workspace, prfInputBuffer, prfInputBufferLength, targetKey, targetKeyLength, parentKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + /* #10 Handle the results of the PRF according to the algorithm */ + if (retVal == E_OK) + { +# if (CRYPTO_30_LIBCV_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256_ENABLED == STD_ON) +# if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) + if (deriveAlgorithm == CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256) +# endif + { + /* #15 Symmetric Key Derive finished here. Copy calculated key to key element */ + retVal = Crypto_30_LibCv_Local_KeyElementSet(targetCryptoKeyId, CRYPTO_30_LIBCV_KE_TARGET_KEY, targetKey, targetKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } +# if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) + else +# endif +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) + { + /* CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB */ + /* #20 For Asymmetric Key Derive: */ + + /* #25 Set the prime minus-1 pointer to the start address of the value within the salt buffer and set the data length */ + primeMinus1Ptr = &(saltBuffer[CRYPTO_30_LIBCV_SIZEOF_KDF_SALT_SYMMETRIC]); + primeMinus1Length = CRYPTO_30_LIBCV_SIZEOF_KDF_PRIME; + + /* #30 Calculate private key for asymmetric keys only by dividing key by given prime-1 */ + retVal = Crypto_30_LibCv_Local_Kdf_AsymDivideByPrimeMinusOne(targetKey, targetKeyLength, primeMinus1Ptr, primeMinus1Length); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (retVal == E_OK) + { + /* Skip the first 8 additional bytes */ + /* #35 Asymmetric Key Derive finished. Copy calculated key to key element */ + retVal = Crypto_30_LibCv_Local_KeyElementSet(targetCryptoKeyId, CRYPTO_30_LIBCV_KE_TARGET_KEY, &(targetKey[8]), targetKeyLength - 8u); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + } +# endif + } + Crypto_30_LibCv_ClearData(targetKey, CRYPTO_30_LIBCV_SIZEOF_KDF_MAX_TARGET_KEY_PLUS_8); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* #40 If key was derived successfully, mark it as valid */ + if (retVal != E_OK) + { + retVal = E_NOT_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864_WS() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 deriveAlgorithm) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + eslt_WorkSpaceSHA256 workspace; + /* ----- Implementation ------------------------------------------------- */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864_WS(&workspace, cryptoKeyId, targetCryptoKeyId, deriveAlgorithm); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864() */ +#endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_108_CTR_CMAC_AES_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist800108_GetInputOutput() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist800108_GetInputOutput( + uint32 cryptoKeyId, + uint32 targetKeyId, + P2VAR(Crypto_30_LibCv_Nist800108_KDF_InputOutput, AUTOMATIC, AUTOMATIC) pInputOutputContainer) +{ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyStorageType cryptoKeyIndex, labelIndex, contextIndex; + + /* # Source key */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, + &cryptoKeyIndex, &pInputOutputContainer->sourceKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + pInputOutputContainer->sourceKey = Crypto_30_LibCv_GetAddrKeyStorage(cryptoKeyIndex); /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + + /* # Label (optional) */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYDERIVATION_LABEL, &labelIndex, &pInputOutputContainer->labelLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + pInputOutputContainer->label = Crypto_30_LibCv_GetAddrKeyStorage(labelIndex); /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + else if (retVal == CRYPTO_E_KEY_NOT_AVAILABLE) + { + pInputOutputContainer->label = NULL_PTR; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + pInputOutputContainer->labelLength = 0u; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + } + else + { + /* remain on error code from KeyElementGetStorageIndexJobOptional */ + } + + if (retVal == E_OK) + { + /* # Context (optional) */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYDERIVATION_CONTEXT, &contextIndex, &pInputOutputContainer->contextLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + pInputOutputContainer->context = Crypto_30_LibCv_GetAddrKeyStorage(contextIndex); /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + if (retVal == CRYPTO_E_KEY_NOT_AVAILABLE) + { + pInputOutputContainer->context = NULL_PTR; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + pInputOutputContainer->contextLength = 0u; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + } + else + { + /* remain on error code from KeyElementGetStorageIndexJobOptional */ + } + + if (retVal == E_OK) + { + /* Target key */ + retVal = Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess(targetKeyId, CRYPTO_30_LIBCV_KE_TARGET_KEY, + &pInputOutputContainer->targetKEIdx, &pInputOutputContainer->targetKeyLength, CRYPTO_30_LIBCV_WA_INTERNAL_COPY); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + pInputOutputContainer->targetKey = Crypto_30_LibCv_GetAddrKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(pInputOutputContainer->targetKEIdx)); /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + } + } + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Nist800108_GetInputOutput() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Calc_Nist800108_CTR_CMAC_AES() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Calc_Nist800108_CTR_CMAC_AES( + P2VAR(eslt_WorkSpaceKDFnist800108, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_30_LibCv_Nist800108_KDF_InputOutput, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) pInputOutputContainer) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet = ESL_ERC_ERROR; + + /* Choose AES128 or AES256 depending on the size of the source key. */ + switch(pInputOutputContainer->sourceKeyLength) + { + case ESL_SIZEOF_AES128_KEY: + eslRet = esl_initKDFnist800108_CMAC_AES128(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))pInputOutputContainer->sourceKey, + (eslt_Length)pInputOutputContainer->sourceKeyLength, ESL_KDF800108_MODE_CRT_BE); + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_deriveKDFnist800108_CMAC_AES128(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))pInputOutputContainer->label, + (eslt_Length)pInputOutputContainer->labelLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))pInputOutputContainer->context, + (eslt_Length)pInputOutputContainer->contextLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))pInputOutputContainer->targetKey, + (eslt_Length)pInputOutputContainer->targetKeyLength); + } + break; + + case ESL_SIZEOF_AES256_KEY: + eslRet = esl_initKDFnist800108_CMAC_AES256(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))pInputOutputContainer->sourceKey, + (eslt_Length)pInputOutputContainer->sourceKeyLength, ESL_KDF800108_MODE_CRT_BE); + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_deriveKDFnist800108_CMAC_AES256(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))pInputOutputContainer->label, + (eslt_Length)pInputOutputContainer->labelLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))pInputOutputContainer->context, + (eslt_Length)pInputOutputContainer->contextLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))pInputOutputContainer->targetKey, + (eslt_Length)pInputOutputContainer->targetKeyLength); + } + break; + + default: + /* Key size not supported. */ + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + break; + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + return retVal; +} /* Crypto_30_LibCv_Calc_Nist800108_CTR_CMAC_AES() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic_WS() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic_WS( + P2VAR(eslt_WorkSpaceKDFnist800108, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetKeyId) +{ + Std_ReturnType retVal = E_NOT_OK; + + /* Will be initialized by Crypto_30_LibCv_Local_KeyDerive_Nist800108_GetInputOutput() */ + Crypto_30_LibCv_Nist800108_KDF_InputOutput InputOutputContainer; + + /* Get pointer and length of input and output. */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist800108_GetInputOutput(cryptoKeyId, targetKeyId, &InputOutputContainer); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + retVal = E_NOT_OK; + + /* Init workspace header. */ + if(esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(workspace->header), ESL_MAXSIZEOF_WS_NIST800108KDF, CRYPTO_30_LIBCV_WATCHDOG_PTR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE_PARAMETER */ + == ESL_ERC_NO_ERROR) + { + /* Derive key according to NIST800-108 (only counter mode with CMAC AES is supported by now). */ + retVal = Crypto_30_LibCv_Calc_Nist800108_CTR_CMAC_AES(workspace, &InputOutputContainer); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* Update key element. */ + Crypto_30_LibCv_Local_SetKeyElementStateWritten(InputOutputContainer.targetKEIdx); + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(targetKeyId, InputOutputContainer.targetKEIdx, InputOutputContainer.targetKeyLength); + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic_WS() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_WorkSpaceKDFnist800108 workspace; + /* ----- Implementation ------------------------------------------------- */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic_WS(&workspace, cryptoKeyId, targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_STACK_WORKSPACE */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_108_CTR_CMAC_AES_ENABLED == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON) \ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist80056A_SingleStepKdfHash() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6060, 6080 8 */ /* MD_CRYPTO_30_LIBCV_STPAR, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist80056A_SingleStepKdfHash( + P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) sharedSecretPtr, + uint32 sharedSecretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) otherInfoPtr, + uint32 otherInfoLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) derivedKeyPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) derivedKeyLengthPtr) +{ + /* This check is not required while the sharedSecret size and hash digest size are equal but is required by IS15118 (marked with \fr) */ + /* \fr uint32 repeatSteps; */ + /* \fr uint32 counter; */ + uint32 derivedLength = 0u; + uint8 concatenateBuf[CRYPTO_30_LIBCV_NIST80056A_COUNTER_SIZE + CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE + CRYPTO_30_LIBCV_NIST80056A_OTHER_INFO_MAXSIZE]; + Std_ReturnType retVal = E_NOT_OK; + /* #1 init workspace */ + if (esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) & workspace->header, ESL_MAXSIZEOF_WS_SHA256, CRYPTO_30_LIBCV_WATCHDOG_PTR) != ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + { + /* retVal remains E_NOT_OK */ + } + /* #2 Check that sharedSecretLength does not exceed the maximum ECC key size */ + else if (sharedSecretLength > CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE) + { + /* retVal remains E_NOT_OK */ + } + else + { + /* Single-step KDF Option 1 Hash */ + /* Implementation according to NIST SP 56A: Revision 2, May 2013 (5.8.1.1 The Single-Step KDF Specification) */ + + /* #5 (Spec-Step: 1) calculate repeat Steps. */ + /* repeat Steps = KeyLength(bit)/HashLength(bit) */ + /* This check is not required while the sharedSecret size and hash digest size are equal */ + /* \fr repeatSteps = Crypto_30_LibCv_Byte2Bit(sharedSecretLength) / Crypto_30_LibCv_Byte2Bit(ESL_SIZEOF_SHA256_DIGEST); */ + + /* #10 (Spec-Step: 2) check max repeat Steps. */ + /* This check is not required while the sharedSecret size and hash digest size are equal */ + /* \fr if ((repeatSteps * ESL_SIZEOF_SHA256_DIGEST) <= *derivedKeyLengthPtr) */ + { + + /* #12 add shared secret to string. */ + /* (counter || Z || OtherInfo) */ + Crypto_30_LibCv_CopyData(&concatenateBuf[CRYPTO_30_LIBCV_NIST80056A_COUNTER_SIZE], sharedSecretPtr, sharedSecretLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + + /* #15 add otherInformation to string. */ + /* OtherInfo = (AlgorithmID || PartyUInfo(Transmitter) || PartyVInfo(Receiver)) */ + Crypto_30_LibCv_CopyData(&concatenateBuf[CRYPTO_30_LIBCV_NIST80056A_COUNTER_SIZE + sharedSecretLength], otherInfoPtr, otherInfoLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + + /* #20 (Spec-Step: 4) check max input length hash */ + /* not required */ + + /* #25 (Spec-Step: 3) init Counter */ + /* create the concatenated shared secret (counter || Z || OtherInfo) */ + /* Initialize a 32-bit counter as 1 (big-endian) */ + /* #30 (Spec-Step: 5 + 5.2) process repeat steps + increment counter */ + /* This check is not required while the sharedSecret size and hash digest size are equal */ + /* \fr for (counter = 1u; counter <= repeatSteps; counter++) */ + { + /* retVal = E_NOT_OK; */ + + /* #35 copy counter to string. */ + /* \fr Crypto_30_LibCv_Local_Uint32ToUint8ArrayBigEndian(concatenateBuf, counter); SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + Crypto_30_LibCv_Local_Uint32ToUint8ArrayBigEndian(concatenateBuf, (uint32)1u); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* #40 (Spec-Step: 5.1) Hash(counter || Z || OtherInfo) */ + if (esl_initSHA256((P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE */ + { + if (esl_updateSHA256((P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, (eslt_Length)(CRYPTO_30_LIBCV_NIST80056A_COUNTER_SIZE + sharedSecretLength + otherInfoLength), (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))concatenateBuf) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + { + if (esl_finalizeSHA256((P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&derivedKeyPtr[derivedLength]) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + { + derivedLength += ESL_SIZEOF_SHA256_DIGEST; + retVal = E_OK; + } + } + } + /* This check is not required while the sharedSecret size and hash digest size are equal */ + /* \fr if (retVal != E_OK) + { + break; + } */ + } + } + } + + /* #45 Set derived key length. */ + if (retVal == E_OK) + { + *derivedKeyLengthPtr = derivedLength; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + } + + /* #50 clear buffer */ + Crypto_30_LibCv_ClearData(concatenateBuf, CRYPTO_30_LIBCV_NIST80056A_COUNTER_SIZE + CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE + CRYPTO_30_LIBCV_NIST80056A_OTHER_INFO_MAXSIZE); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Nist80056A_SingleStepKdfHash() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 10 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + uint32 partnerPubKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) otherInfoPtr, + uint32 otherInfoPtrLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) derivedKeyPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) derivedKeyLengthPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 sharedSecret[CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE * 2u]; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ----------------------------------------------- */ + if (Crypto_30_LibCv_Local_Dispatch_EcP_CalculateSharedSecret_With_Ws( + privateKeyPtr, privateKeyLength, + partnerPubKeyPtr, partnerPubKeyLength, + sharedSecret, CRYPTO_30_LIBCV_ECDHE_256_ID, + &workspace->wsEcP) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + { + /* #1 Single-step KDF Option 1 Hash */ + /* use only shared secret X for concatenation */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist80056A_SingleStepKdfHash( + &workspace->wsSHA256, + sharedSecret, CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE, + otherInfoPtr, otherInfoPtrLength, + derivedKeyPtr, derivedKeyLengthPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + } + + /* #5 destroy all working copies. */ + Crypto_30_LibCv_ClearData(sharedSecret, CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE * 2u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S() */ +#endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_With_Ws_AndLoadKey() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 4 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_With_Ws_AndLoadKey( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + + uint32 partnerPubKeyLength = CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE * 2u; + uint32 privKeyLength = CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE; + uint32 otherInfoLength = CRYPTO_30_LIBCV_NIST80056A_OTHER_INFO_MAXSIZE; + uint32 derivedKeyBufLength = CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE; + + Crypto_30_LibCv_SizeOfKeyStorageType partnerPubKeyIndex; + Crypto_30_LibCv_SizeOfKeyStorageType privKeyIndex; + Crypto_30_LibCv_SizeOfKeyStorageType otherInfoIndex; + uint8 derivedKeyBuf[CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE]; + Std_ReturnType retVal = E_NOT_OK; + Std_ReturnType localRet; + + /* ----- Implementation ----------------------------------------------- */ + Crypto_30_LibCv_ClearData(derivedKeyBuf, CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* #1 read other info from key element. */ + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO, &otherInfoIndex, &otherInfoLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY, &partnerPubKeyIndex, &partnerPubKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &privKeyIndex, &privKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRet == E_OK) + { + /* #5 calculate NIST 800 56A */ + if (Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S(workspace, + Crypto_30_LibCv_GetAddrKeyStorage(privKeyIndex), privKeyLength, + Crypto_30_LibCv_GetAddrKeyStorage(partnerPubKeyIndex), partnerPubKeyLength, + Crypto_30_LibCv_GetAddrKeyStorage(otherInfoIndex), otherInfoLength, + derivedKeyBuf, &derivedKeyBufLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + { + if (Crypto_30_LibCv_Local_KeyElementSet(targetCryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, derivedKeyBuf, derivedKeyBufLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + { + retVal = E_OK; + } + } + } + + /* #10 destroy all working copies. */ + Crypto_30_LibCv_ClearData(derivedKeyBuf, derivedKeyBufLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_With_Ws_AndLoadKey() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_AndLoadKey() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_AndLoadKey( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retval; + Crypto_30_LibCv_WorkSpaceISO15118 workspace; /* PRQA S 0759 */ /* MD_MSR_Union */ + + /* ----- Implementation ----------------------------------------------- */ + retval = Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_With_Ws_AndLoadKey(&workspace, cryptoKeyId, targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + return retval; +} /* Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_AndLoadKey() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_CheckKey() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_CheckKey( + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) pubKeyPtr, + uint32 pubKeyLength) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 sharedSecret[CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE * 2u]; + Std_ReturnType retVal = E_NOT_OK; + + /* NISTp256r1 = ANSIp256r1 = SECp256r1 */ + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CONST) basePointOrder = &Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain[192]; + + /* ----- Implementation ----------------------------------------------- */ + /* #1 check if the private key is smaller than the order of the curve base point */ + + if (Crypto_30_LibCv_Local_CompareData_IsSmaller(privateKeyPtr, basePointOrder, privateKeyLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + { + + /* #5 verify key pair with esLib */ + if (Crypto_30_LibCv_Local_Dispatch_EcP_CalculateSharedSecret_With_Ws(privateKeyPtr, privateKeyLength, pubKeyPtr, pubKeyLength, sharedSecret, CRYPTO_30_LIBCV_ECDHE_256_ID, workspace) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + { + retVal = E_OK; + } + } + + /* #10 destroy all working copies. */ + Crypto_30_LibCv_ClearData(sharedSecret, CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE * 2u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_ISO15118_CheckKey() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_Aes128Decrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_Aes128Decrypt( + P2VAR(eslt_WorkSpaceAES128, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) ivPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) encryptedMessagePtr, + uint32 encryptedMessageLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) plainMessagePtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) plainMessageLengthPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + eslt_Length outputDataLen; + uint32 totalOutputDataLen = 0u; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + + /* #0 initialize the AES workspaces */ + if (esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_AES128, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + { + + /* #5 initialize the decryption */ + eslRet = esl_initDecryptAES128((P2VAR(eslt_WorkSpaceAES128, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE */ + ESL_BM_CBC, ESL_PM_OFF, (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))ivPtr); + + if (eslRet == ESL_ERC_NO_ERROR) + { + outputDataLen = (eslt_Length)*plainMessageLengthPtr; + /* #10 decrypt the actual private key */ + eslRet = esl_decryptAES128((P2VAR(eslt_WorkSpaceAES128, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, + (eslt_Length)encryptedMessageLength, (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))encryptedMessagePtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputDataLen, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))plainMessagePtr); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* #15 save the decrypted length */ + totalOutputDataLen = outputDataLen; + /* reset the OutputDataLen */ + outputDataLen = (eslt_Length)(*plainMessageLengthPtr - totalOutputDataLen); + + /* #20 add padding to get least block */ + eslRet = esl_decryptAES128((P2VAR(eslt_WorkSpaceAES128, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)1u, (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))encryptedMessagePtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputDataLen, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&plainMessagePtr[totalOutputDataLen]); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* #25 update the decrypted length */ + totalOutputDataLen += outputDataLen; + } + } + } + if (eslRet == ESL_ERC_NO_ERROR) + { + /* #30 provide the total output data len to the application */ + *plainMessageLengthPtr = totalOutputDataLen; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_ISO15118_Aes128Decrypt() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_WS() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 4 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_WS( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32 encryptedIvAndPrivKeyLength = CRYPTO_30_LIBCV_ISO15118_SIZEOF_IV_AND_PRIV_KEY; + + uint32 privKeyLength = CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE; + uint32 partnerPubKeyLength = CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE * 2u; + + uint32 derivedKeyLength = CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE; + + uint32 newPrivateKeyLength = CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE; + uint32 newPubKeyLength = CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE * 2u; + + Crypto_30_LibCv_SizeOfKeyStorageType encryptedIvAndPrivKeyIndex; + + Crypto_30_LibCv_SizeOfKeyStorageType privKeyIndex; + Crypto_30_LibCv_SizeOfKeyStorageType partnerPubKeyIndex; + + Crypto_30_LibCv_SizeOfKeyStorageType newPubKeyIndex; + + uint8 otherInfo[CRYPTO_30_LIBCV_ISO15118_SIZEOF_OTHER_INFO] = { 0u }; + uint8 derivedKey[CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE] = { 0u }; + + uint8 newPrivateKey[CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE] = { 0u }; + + Std_ReturnType retVal = E_NOT_OK; + Std_ReturnType localRet; + /* ----- Implementation ----------------------------------------------- */ + /* #5 Get KeyElements for CertificateInstallation/Update (ISO 15118) */ + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(targetCryptoKeyId, CRYPTO_KE_CUSTOM_SCC_CONTRACT_PUBLIC_KEY, &newPubKeyIndex, &newPubKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(targetCryptoKeyId, CRYPTO_KE_CUSTOM_SCC_IV_AND_ENCRYPTED_PRIVATE_KEY, &encryptedIvAndPrivKeyIndex, &encryptedIvAndPrivKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(targetCryptoKeyId, CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY, &partnerPubKeyIndex, &partnerPubKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + /* load old partner public value and private key */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &privKeyIndex, &privKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if ((localRet == E_OK) && + (encryptedIvAndPrivKeyLength == CRYPTO_30_LIBCV_ISO15118_SIZEOF_IV_AND_PRIV_KEY)) + { + /* [V2G2-818] + * The algorithm ID shall be one character 0x01. The sender name ID U shall be one character "U" = 0x55 , the receiver name ID V shall be + * one character "V" = 0x56. A symmetric encryption key of exactly 128 bits shall be derived. */ + + /* #10 Set OtherInfo = (AlgorithmID || PartyUInfo(Transmitter) || PartyVInfo(Receiver)) */ + otherInfo[0] = 0x01u; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + otherInfo[1] = 0x55u; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + otherInfo[2] = 0x56u; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + + /* #15 Execute Concatenation KDF */ + localRet = Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S(workspace, + Crypto_30_LibCv_GetAddrKeyStorage(privKeyIndex), privKeyLength, + Crypto_30_LibCv_GetAddrKeyStorage(partnerPubKeyIndex), partnerPubKeyLength, + otherInfo, CRYPTO_30_LIBCV_ISO15118_SIZEOF_OTHER_INFO, + derivedKey, &derivedKeyLength); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (localRet == E_OK) + { + /* #20 decrypt new key */ + localRet = Crypto_30_LibCv_Local_KeyDerive_ISO15118_Aes128Decrypt(&workspace->wsAes, + Crypto_30_LibCv_GetAddrKeyStorage(encryptedIvAndPrivKeyIndex), + derivedKey, + Crypto_30_LibCv_GetAddrKeyStorage(encryptedIvAndPrivKeyIndex + CRYPTO_30_LIBCV_ISO15118_PRIV_KEY_START), + encryptedIvAndPrivKeyLength - CRYPTO_30_LIBCV_ISO15118_PRIV_KEY_START, + newPrivateKey, &newPrivateKeyLength); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (localRet == E_OK) + { + /* #25 Verify new key pair */ + /* The best way the verify that the keys are valid is to generate and verify a signature. This need to be implemented by upper layer e.g. TLS */ + if (Crypto_30_LibCv_Local_KeyDerive_ISO15118_CheckKey(&workspace->wsEcP, + newPrivateKey, newPrivateKeyLength, + Crypto_30_LibCv_GetAddrKeyStorage(newPubKeyIndex), newPubKeyLength) + == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + { + /* #30 Store new key pair */ + if (Crypto_30_LibCv_Local_KeyElementSet(targetCryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &newPrivateKey[0], newPrivateKeyLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + { + retVal = E_OK; + } + } + } + } + } + + /* #40 clear data */ + Crypto_30_LibCv_ClearData(derivedKey, derivedKeyLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + Crypto_30_LibCv_ClearData(newPrivateKey, newPrivateKeyLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_ISO15118_WS() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + Crypto_30_LibCv_WorkSpaceISO15118 workspace; /* PRQA S 0759 */ /* MD_MSR_Union */ + + /* ----- Implementation ----------------------------------------------- */ + retVal = Crypto_30_LibCv_Local_KeyDerive_ISO15118_WS(&workspace, cryptoKeyId, targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_ISO15118() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_ECDSA() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_ECDSA( + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) pubKeyPtr, + uint32 pubKeyLength) +{ + uint8 pubKeyTmp[CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PUBLIC_XY] = {0u}; + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CONST) basePointPtr = &Crypto_30_LibCv_EccCurveNistSecP521R1Domain[229]; + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CONST) curveOrderPtr = &Crypto_30_LibCv_EccCurveNistSecP521R1Domain[363]; + Std_ReturnType retVal = E_OK; + + /* #1 Check if the private key is strictly smaller than the order of the curve base point */ + if (Crypto_30_LibCv_Local_CompareData_IsSmaller(privateKeyPtr, curveOrderPtr, privateKeyLength) != E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + { + retVal = E_NOT_OK; + } + /* #5 Multiplication of the base point with the private key shall generate a key matching the public key */ + else if (Crypto_30_LibCv_Local_Dispatch_EcP_CalculateSharedSecret_With_Ws(privateKeyPtr, privateKeyLength, basePointPtr, pubKeyLength, pubKeyTmp, CRYPTO_30_LIBCV_ECDHE_521_ID, workspace) != E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + { + retVal = E_NOT_OK; + } + else + { + uint8 currentByte = 0u; + + retVal = E_OK; + for (currentByte = 0u; currentByte < pubKeyLength; currentByte++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND */ + { + if (pubKeyTmp[currentByte] != pubKeyPtr[currentByte]) + { + retVal = E_NOT_OK; + break; + } + } + } + + /* #10 destroy all working copies. */ + Crypto_30_LibCv_ClearData(pubKeyTmp, CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PUBLIC_XY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_ECDSA() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_X448() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_X448( + P2VAR(eslt_WorkSpaceEdDH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) pubKeyPtr, + uint32 pubKeyLength) +{ + uint8 pubKeyTmp[CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_SHARED_SECRET_X448] = {0u}; + uint32 pubKeyTmpLength = sizeof(pubKeyTmp); + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CONST) curveOrderPtr = Crypto_30_LibCv_EccCurveEdwards448GroupOrder; + Std_ReturnType retVal = E_OK; + + /* base point in Montgomery coordinates + * U = 5 (447 bit long) + */ + const uint8 basePointU[56] = + { + 0x05u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u + }; + + /* #1 Check if the private key is strictly smaller than the order of the curve base point */ + if (Crypto_30_LibCv_Local_CompareData_IsSmaller(privateKeyPtr, curveOrderPtr, privateKeyLength) != E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + { + retVal = E_NOT_OK; + } + /* #5 Multiplication of the base point with the private key shall generate a key matching the public key */ + else if (Crypto_30_LibCv_Local_Dispatch_EdDH_CalculateSharedSecret_With_Ws( /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + privateKeyPtr, privateKeyLength, + basePointU, pubKeyLength, + pubKeyTmp, &pubKeyTmpLength, workspace) != E_OK) + { + retVal = E_NOT_OK; + } + else + { + uint8 currentByte = 0u; + + retVal = E_OK; + for (currentByte = 0u; currentByte < pubKeyLength; currentByte++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND */ + { + if (pubKeyTmp[currentByte] != pubKeyPtr[currentByte]) + { + retVal = E_NOT_OK; + break; + } + } + } + + /* #10 destroy all working copies. */ + Crypto_30_LibCv_ClearData(pubKeyTmp, CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_SHARED_SECRET_X448); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_X448() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_AesGcm256Decrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6060, 6080 10 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_AesGcm256Decrypt( + P2VAR(eslt_WorkSpaceGCM, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) ivPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) aadPtr, + uint32 aadLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) tagPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) encryptedMessagePtr, + uint32 encryptedMessageLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) plainMessagePtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) plainMessageLengthPtr) +{ + Std_ReturnType retVal = E_NOT_OK; + *plainMessageLengthPtr = 0u; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + + if (esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_GCM, CRYPTO_30_LIBCV_WATCHDOG_PTR) != ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + { + retVal = E_NOT_OK; + } + /* #10 initialize the decryption */ + else if(esl_initDecryptGCM(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr, CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_DERIVED_KEY, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))ivPtr, CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_IV) != ESL_ERC_NO_ERROR) + { + retVal = E_NOT_OK; + } + /* #20 process authentic data */ + else if(esl_updateAuthDataDecryptGCM(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))aadPtr, + (eslt_Length)aadLength) != ESL_ERC_NO_ERROR) + { + retVal = E_NOT_OK; + } + /* #30 decrypt the actual private key */ + else if(esl_updateCiphertextDecryptGCM(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))encryptedMessagePtr, + (eslt_Length)encryptedMessageLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))plainMessagePtr, + (P2VAR(eslt_Size32, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))plainMessageLengthPtr) != ESL_ERC_NO_ERROR) + { + retVal = E_NOT_OK; + } + else if(esl_finalizeDecryptGCM(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&plainMessagePtr[*plainMessageLengthPtr], + (P2VAR(eslt_Size32, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))plainMessageLengthPtr, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))tagPtr) != ESL_ERC_NO_ERROR) + { + retVal = E_NOT_OK; + } + else + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_AesGcm256Decrypt() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleSECP521() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6060 9 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleSECP521( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118_20, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privKeyPtr, + uint32 privKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + uint32 partnerPubKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) encryptedDataKeyPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) contractCertPrivateKeyPtr) +{ + Std_ReturnType retVal = E_NOT_OK; + Std_ReturnType localRet = E_NOT_OK; + + /* #10 Calculate ECDHE Secret (Array needs to be twice the size because LibCv Function stores XY values) */ + uint8 sharedSecret[CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_SHARED_SECRET_P521 * 2u] = {0u}; + + localRet = Crypto_30_LibCv_Local_Dispatch_EcP_CalculateSharedSecret_With_Ws( /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + privKeyPtr, privKeyLength, + partnerPubKeyPtr, partnerPubKeyLength, + sharedSecret, CRYPTO_30_LIBCV_ECDHE_521_ID, + &workspace->wsEcP); + + if (localRet == E_OK) + { + uint8 otherInfo[CRYPTO_30_LIBCV_ISO15118_SIZEOF_OTHER_INFO]; + uint8 derivedKey[CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_DERIVED_KEY]; + + /* #20 Set OtherInfo = (AlgorithmID || PartyUInfo(Transmitter) || PartyVInfo(Receiver)) */ + otherInfo[0] = 0x01u; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + otherInfo[1] = 0x55u; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + otherInfo[2] = 0x56u; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + + /* #30 Execute Concatenation KDF */ + localRet = Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_Hash_Option_1(&workspace->wsHkdfSHA512, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_SHARED_SECRET_P521, sharedSecret, + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_OTHER_INFO, otherInfo, + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_DERIVED_KEY, derivedKey, + ESL_HA_SHA2_512); + + if (localRet == E_OK) + { + uint8 contractCertPrivateKey[CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_P521] = { 0 }; + uint32 contractCertPrivateKeyLength = CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_P521; + + /* #40 Decrypt new key */ + localRet = Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_AesGcm256Decrypt(&workspace->wsAesGcm, /* SBSW_CRYPTO_30_LIBCV_CALL_WORKSPACE_STACK_WITH_STACK_BUFFERS_AND_PTR_AS_PARAMETER */ + &encryptedDataKeyPtr[CRYPTO_30_LIBCV_ISO15118_20_IV_START_P521], + derivedKey, + associatedDataPtr, associatedDataLength, + &encryptedDataKeyPtr[CRYPTO_30_LIBCV_ISO15118_20_TAG_START_P521], + &encryptedDataKeyPtr[CRYPTO_30_LIBCV_ISO15118_20_PRIV_KEY_START_P521], + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_P521, + contractCertPrivateKey, &contractCertPrivateKeyLength); + + if (localRet == E_OK) + { + /* #50 Check decrypted key for correct format */ + if ((contractCertPrivateKey[0] & 0xFEu) != 0u) + { + retVal = E_NOT_OK; + } + else + { + /* #60 Copy decrypted key to buffer */ + Crypto_30_LibCv_CopyData(contractCertPrivateKeyPtr, contractCertPrivateKey, CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_P521); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + retVal = E_OK; + } + } + Crypto_30_LibCv_ClearData(contractCertPrivateKey, CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + Crypto_30_LibCv_ClearData(derivedKey, CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_DERIVED_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + Crypto_30_LibCv_ClearData(sharedSecret, CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_SHARED_SECRET_P521 * 2u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleSECP521() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleX448() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6060 9 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleX448( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118_20, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privKeyPtr, + uint32 privKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + uint32 partnerPubKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) encryptedDataKeyPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) contractCertPrivateKeyPtr) +{ + Std_ReturnType retVal = E_NOT_OK; + Std_ReturnType localRet = E_NOT_OK; + + /* #10 Calculate ECDHE Secret */ + uint8 sharedSecret[CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_SHARED_SECRET_X448] = {0u}; + uint32 sharedSecretLength = CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_SHARED_SECRET_X448; + + localRet = Crypto_30_LibCv_Local_Dispatch_EdDH_CalculateSharedSecret_With_Ws( /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + privKeyPtr, privKeyLength, + partnerPubKeyPtr, partnerPubKeyLength, + sharedSecret, &sharedSecretLength, + &workspace->wsEdDH + ); + + if (localRet == E_OK) + { + uint8 otherInfo[CRYPTO_30_LIBCV_ISO15118_SIZEOF_OTHER_INFO]; + uint8 derivedKey[CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_DERIVED_KEY]; + + /* #20 Set OtherInfo = (AlgorithmID || PartyUInfo(Transmitter) || PartyVInfo(Receiver)) */ + otherInfo[0] = 0x01u; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + otherInfo[1] = 0x55u; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + otherInfo[2] = 0x56u; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + + /* #30 Execute Concatenation KDF */ + localRet = Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_Hash_Option_1(&workspace->wsHkdfSHA512, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_SHARED_SECRET_X448, sharedSecret, + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_OTHER_INFO, otherInfo, + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_DERIVED_KEY, derivedKey, + ESL_HA_SHA2_512); + + if (localRet == E_OK) + { + uint8 contractCertPrivateKey[CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_X448] = { 0 }; + uint32 contractCertPrivateKeyLength = CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_X448; + + /* #40 Decrypt new key */ + localRet = Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_AesGcm256Decrypt(&workspace->wsAesGcm, /* SBSW_CRYPTO_30_LIBCV_CALL_WORKSPACE_STACK_WITH_STACK_BUFFERS_AND_PTR_AS_PARAMETER */ + &encryptedDataKeyPtr[CRYPTO_30_LIBCV_ISO15118_20_IV_START_X448], + derivedKey, + associatedDataPtr, associatedDataLength, + &encryptedDataKeyPtr[CRYPTO_30_LIBCV_ISO15118_20_TAG_START_X448], + &encryptedDataKeyPtr[CRYPTO_30_LIBCV_ISO15118_20_PRIV_KEY_START_X448], + CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_X448, + contractCertPrivateKey, &contractCertPrivateKeyLength); + + if (localRet == E_OK) + { + /* #60 Copy decrypted key to buffer */ + Crypto_30_LibCv_CopyData(contractCertPrivateKeyPtr, contractCertPrivateKey, CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_X448); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + retVal = E_OK; + } + Crypto_30_LibCv_ClearData(contractCertPrivateKey, CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_X448); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + Crypto_30_LibCv_ClearData(derivedKey, CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_DERIVED_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + Crypto_30_LibCv_ClearData(sharedSecret, CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_SHARED_SECRET_X448); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleX448() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_WS() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_WS( + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118_20, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + uint8 contractCertPrivateKey[CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_P521] = { 0 }; + uint32 contractCertPrivateKeyLength = 0u; + uint32 encryptedIvAndPrivKeyLength = CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_IV_PRIV_KEY_TAG_P521; + uint32 aadLength = 0u; + uint32 privKeyLength = CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_P521; + uint32 partnerPubKeyLength = CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PUBLIC_XY; + uint32 contrPubKeyLength = CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PUBLIC_XY; + + Crypto_30_LibCv_SizeOfKeyStorageType encryptedDataKeyIndex; + Crypto_30_LibCv_SizeOfKeyStorageType aadKeyIndex; + Crypto_30_LibCv_SizeOfKeyStorageType privKeyIndex; + Crypto_30_LibCv_SizeOfKeyStorageType partnerPubKeyIndex; + Crypto_30_LibCv_SizeOfKeyStorageType contrPubKeyIndex; + + Std_ReturnType retVal = E_NOT_OK; + Std_ReturnType localRet; + + /* #10 Get KeyElements for CertificateInstallation (ISO 15118-20) */ + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(targetCryptoKeyId, CRYPTO_KE_CUSTOM_SCC_CONTRACT_PUBLIC_KEY, &contrPubKeyIndex, &contrPubKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(targetCryptoKeyId, CRYPTO_KE_CUSTOM_SCC_IV_AND_ENCRYPTED_PRIVATE_KEY, &encryptedDataKeyIndex, &encryptedIvAndPrivKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(targetCryptoKeyId, CRYPTO_KE_CUSTOM_SCC_CONTRACT_AAD, &aadKeyIndex, &aadLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(targetCryptoKeyId, CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY, &partnerPubKeyIndex, &partnerPubKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + /* load own private key */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &privKeyIndex, &privKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + /* #20 Derive contract private key for curve */ + if ((localRet == E_OK) && + (encryptedIvAndPrivKeyLength == CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_IV_PRIV_KEY_TAG_P521)) + { + /* Use curve SEC-P521R1 */ + contractCertPrivateKeyLength = CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_P521; + + localRet = Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleSECP521(workspace, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_AND_KEYSTORE_BUFFER */ + Crypto_30_LibCv_GetAddrKeyStorage(privKeyIndex), privKeyLength, + Crypto_30_LibCv_GetAddrKeyStorage(partnerPubKeyIndex), partnerPubKeyLength, + Crypto_30_LibCv_GetAddrKeyStorage(encryptedDataKeyIndex), + Crypto_30_LibCv_GetAddrKeyStorage(aadKeyIndex), aadLength, + contractCertPrivateKey); + + if (localRet == E_OK) + { + /* #30 Verify new key */ + localRet = Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_ECDSA(&workspace->wsEcP, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_AND_KEYSTORE_BUFFER */ + contractCertPrivateKey, + contractCertPrivateKeyLength, + Crypto_30_LibCv_GetAddrKeyStorage(contrPubKeyIndex), + contrPubKeyLength); + } + } + else if ((localRet == E_OK) && + (encryptedIvAndPrivKeyLength == CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_IV_PRIV_KEY_TAG_X448)) + { + /* Use curve Curve448 */ + contractCertPrivateKeyLength = CRYPTO_30_LIBCV_ISO15118_20_SIZEOF_PRIV_KEY_X448; + + localRet = Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_HandleX448(workspace, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_AND_KEYSTORE_BUFFER */ + Crypto_30_LibCv_GetAddrKeyStorage(privKeyIndex), privKeyLength, + Crypto_30_LibCv_GetAddrKeyStorage(partnerPubKeyIndex), partnerPubKeyLength, + Crypto_30_LibCv_GetAddrKeyStorage(encryptedDataKeyIndex), + Crypto_30_LibCv_GetAddrKeyStorage(aadKeyIndex), aadLength, + contractCertPrivateKey); + + if (localRet == E_OK) + { + /* #30 Verify new key */ + localRet = Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_CheckKey_X448(&workspace->wsEdDH, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_AND_KEYSTORE_BUFFER */ + contractCertPrivateKey, + contractCertPrivateKeyLength, + Crypto_30_LibCv_GetAddrKeyStorage(contrPubKeyIndex), + contrPubKeyLength); + } + } + else + { + localRet = E_NOT_OK; + } + + if (localRet == E_OK) + { + /* #40 Store new key */ + if (Crypto_30_LibCv_Local_KeyElementSet(targetCryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &contractCertPrivateKey[0], contractCertPrivateKeyLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + { + retVal = E_OK; + } + } + + /* #50 clear data */ + Crypto_30_LibCv_ClearData(contractCertPrivateKey, CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_WS() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_ISO15118_20() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_ISO15118_20( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + Crypto_30_LibCv_WorkSpaceISO15118_20 workspace; /* PRQA S 0759 */ /* MD_MSR_Union */ + + /* ----- Implementation ----------------------------------------------- */ + retVal = Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_WS(&workspace, cryptoKeyId, targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_ISO15118_20() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA256_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_Calc() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 9 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_Calc( + P2VAR(eslt_WorkSpaceKDFX963SHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* ----- Implementation ----------------------------------------------- */ + + /* Init workspace header */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_KDFX963SHA256, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Init workspace */ + eslRet = esl_initKDFX963SHA256((P2VAR(eslt_WorkSpaceKDFX963SHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Derive a key with the given length. */ + eslRet = esl_deriveKeyKDFX963SHA256((P2VAR(eslt_WorkSpaceKDFX963SHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (eslt_Length)secretLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))secretPtr, + (eslt_Length)infoLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))infoPtr, + (eslt_Length)keyLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr); + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_Calc() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_256() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_256( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + eslt_WorkSpaceKDFX963SHA256 workspace; + + /* ----- Implementation ----------------------------------------------- */ + retVal= Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_WS(&workspace, cryptoKeyId, targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_KDF_963_256() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_WS() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_WS( + P2VAR(eslt_WorkSpaceKDFX963SHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK, localRet; + + uint32 secretLength, saltLength, keyLength; + Crypto_30_LibCv_SizeOfKeyStorageType secretIndex, saltIndex; + Crypto_30_LibCv_SizeOfKeyElementsType keyElementIndex; + P2VAR(uint8, AUTOMATIC, AUTOMATIC) saltPtr = NULL_PTR; /* PRQA S 3678 */ /* MD_CRYPTO_30_LIBCV_3678 */ + + /* ----- Implementation ----------------------------------------------- */ + /* get key elements for algorithm: CRYPTO_KE_KEYDERIVATION_PASSWORD and optional CRYPTO_KE_KEYDERIVATION_SALT */ + /* get target key element index, length and check access */ + localRet = Crypto_30_LibCv_Local_KeyDerive_KDF_963_Get_Secret_And_Salt( + &secretLength, + &secretIndex, + &saltLength, + &saltIndex, + &keyLength, + &keyElementIndex, + cryptoKeyId, + targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (localRet == E_OK) + { + if (saltLength > 0u) + { + saltPtr = Crypto_30_LibCv_GetAddrKeyStorage(saltIndex); + } + + /* derive key */ + retVal = Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_Calc( + workspace, + secretLength, + Crypto_30_LibCv_GetAddrKeyStorage(secretIndex), + saltLength, + saltPtr, + keyLength, + Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(keyElementIndex)); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* update key element */ + Crypto_30_LibCv_Local_SetKeyElementStateWritten(keyElementIndex); + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(targetCryptoKeyId, keyElementIndex, keyLength); + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_WS() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA256_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA512_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_Calc() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_Calc( + P2VAR(eslt_WorkSpaceKDFX963SHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* ----- Implementation ----------------------------------------------- */ + + /* Init workspace header */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_KDFX963SHA512, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Init workspace */ + eslRet = esl_initKDFX963SHA512((P2VAR(eslt_WorkSpaceKDFX963SHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Derive a key with the given length. */ + eslRet = esl_deriveKeyKDFX963SHA512((P2VAR(eslt_WorkSpaceKDFX963SHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (eslt_Length)secretLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))secretPtr, + (eslt_Length)infoLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))infoPtr, + (eslt_Length)keyLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr); + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_Calc() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_512() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_512( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + eslt_WorkSpaceKDFX963SHA512 workspace; + + /* ----- Implementation ----------------------------------------------- */ + retVal= Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_WS(&workspace, cryptoKeyId, targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_KDF_963_512() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_WS() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_WS( + P2VAR(eslt_WorkSpaceKDFX963SHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK, localRet; + + uint32 secretLength, saltLength, keyLength; + Crypto_30_LibCv_SizeOfKeyStorageType secretIndex, saltIndex; + Crypto_30_LibCv_SizeOfKeyElementsType keyElementIndex; + P2VAR(uint8, AUTOMATIC, AUTOMATIC) saltPtr = NULL_PTR; /* PRQA S 3678 */ /* MD_CRYPTO_30_LIBCV_3678 */ + + /* ----- Implementation ----------------------------------------------- */ + /* get key elements for algorithm: CRYPTO_KE_KEYDERIVATION_PASSWORD and optional CRYPTO_KE_KEYDERIVATION_SALT */ + /* get target key element index, length and check access */ + localRet = Crypto_30_LibCv_Local_KeyDerive_KDF_963_Get_Secret_And_Salt( + &secretLength, + &secretIndex, + &saltLength, + &saltIndex, + &keyLength, + &keyElementIndex, + cryptoKeyId, + targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (localRet == E_OK) + { + if (saltLength > 0u) + { + saltPtr = Crypto_30_LibCv_GetAddrKeyStorage(saltIndex); + } + + /* derive key */ + retVal = Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_Calc( + workspace, + secretLength, + Crypto_30_LibCv_GetAddrKeyStorage(secretIndex), + saltLength, + saltPtr, + keyLength, + Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(keyElementIndex)); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* update key element */ + Crypto_30_LibCv_Local_SetKeyElementStateWritten(keyElementIndex); + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(targetCryptoKeyId, keyElementIndex, keyLength); + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_WS() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA512_ENABLED == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA512_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_KDF_963_Get_Secret_And_Salt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6060 9 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_KDF_963_Get_Secret_And_Salt( + P2VAR(uint32, AUTOMATIC, AUTOMATIC) secretLength, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) secretIndex, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) saltLength, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) saltIndex, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) keyLength, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) keyElementIndex, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType localRet; + + /* ----- Implementation ----------------------------------------------- */ + /* Get secret */ + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, secretIndex, secretLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRet == E_OK) + { + /* Get optional salt */ + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_SALT, saltIndex, saltLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRet == CRYPTO_E_KEY_NOT_AVAILABLE) + { + /* Set length since input in not required. */ + *saltLength = 0u; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + + /* continue processing */ + localRet = E_OK; + } + else + { + /* retVal is already set */ + } + + if (localRet == E_OK) + { + /* get target key element index, length and check access */ + localRet = Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess(targetCryptoKeyId, CRYPTO_30_LIBCV_KE_TARGET_KEY, keyElementIndex, keyLength, CRYPTO_30_LIBCV_WA_INTERNAL_COPY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + } + } + return localRet; +} /* Crypto_30_LibCv_Local_KeyDerive_KDF_963_Get_Secret_And_Salt() */ +#endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA256_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA512_ENABLED == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_SERVICE_KEY_DERIVE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Derive_UpdateKeyState() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Derive_UpdateKeyState( + uint32 objectId, + uint32 targetCryptoKeyId, + Std_ReturnType retVal) +{ + /* ----- Local Variables ---------------------------------------------- */ + /* ----- Implementation ----------------------------------------------- */ + + /* If key was derived successfully, mark it as valid */ + if (retVal == E_OK) + { + Crypto_30_LibCv_SetProcessJob_Trigger_Write(objectId, Crypto_30_LibCv_Internal_KeySetValid(targetCryptoKeyId)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } +} /* Crypto_30_LibCv_Local_Derive_UpdateKeyState() */ +#endif /* (CRYPTO_30_LIBCV_SERVICE_KEY_DERIVE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEY_DERIVE_ALGORITHM == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6030, 6050, 6080 4 */ /* MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock) +{ + uint32 deriveAlgorithmLength = CRYPTO_30_LIBCV_KEY_DERIVE_SIZEOF_ALGORITHM; + Crypto_30_LibCv_SizeOfKeyStorageType deriveAlgorithmIndex; + + Std_ReturnType retVal; + + /* #1 Get Algorithm from the algorithm key element */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_ALGORITHM, &deriveAlgorithmIndex, &deriveAlgorithmLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* #5 Dispatch key derivation according the given algorithm */ + switch (Crypto_30_LibCv_GetKeyStorage(deriveAlgorithmIndex)) + { +# if (CRYPTO_30_LIBCV_KDF_ALGO_SYM_NIST_800_108_CNT_MODE_SHA256_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256: + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864(cryptoKeyId, targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_ASYM_NIST_FIPS_186_4_ERB_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB: + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864(cryptoKeyId, targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_KDF_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256: + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_AndLoadKey(cryptoKeyId, targetCryptoKeyId); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_KDF_ISO_15118_CERTIFICATE_HANDLING: + retVal = Crypto_30_LibCv_Local_KeyDerive_ISO15118(cryptoKeyId, targetCryptoKeyId); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_KDF_ISO_15118_20_CERTIFICATE_HANDLING: + retVal = Crypto_30_LibCv_Local_KeyDerive_ISO15118_20(cryptoKeyId, targetCryptoKeyId); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA256_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA256: + retVal = Crypto_30_LibCv_Local_KeyDerive_KDF_963_256(cryptoKeyId, targetCryptoKeyId); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_X963_SHA512_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA512: + retVal = Crypto_30_LibCv_Local_KeyDerive_KDF_963_512(cryptoKeyId, targetCryptoKeyId); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1: + retVal = Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA1(cryptoKeyId, targetCryptoKeyId); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256: + retVal = Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA256(cryptoKeyId, targetCryptoKeyId); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256: + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC(cryptoKeyId, targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256: + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1(cryptoKeyId, targetCryptoKeyId, ESL_HA_SHA2_256); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_SPAKE2_PLUS_P256R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_SPAKE2_PLUS_P256R1: + retVal = Crypto_30_LibCv_Local_KeyDerive_Spake2Plus(cryptoKeyId, targetCryptoKeyId); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384: + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC(cryptoKeyId, targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512: + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1(cryptoKeyId, targetCryptoKeyId, ESL_HA_SHA2_512); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256: + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC(cryptoKeyId, targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA384_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA384: + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC(cryptoKeyId, targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA384); + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_108_CTR_CMAC_AES_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_KDF_NIST_800_108_CTR_CMAC_AES: + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic(cryptoKeyId, targetCryptoKeyId); + break; +# endif + + default: + retVal = E_NOT_OK; + break; + } + } + else + { + retVal = E_NOT_OK; + } + + /* #10 If key was derived successfully, mark it as valid */ + if (retVal == E_OK) + { + *writeBlock = Crypto_30_LibCv_Internal_KeySetValid(targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } + else + { + /* #11 Map error codes according to AUTOSAR */ + retVal = E_NOT_OK; + *writeBlock = FALSE; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive() */ +#endif /* (CRYPTO_30_LIBCV_SUPPORT_KEY_DERIVE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA1() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 9 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA1( + P2VAR(eslt_WorkSpaceKDF2HMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + uint32 iterations) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* ----- Implementation ----------------------------------------------- */ + + /* Init workspace header */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_KDF2HMACSHA1, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Init workspace */ + eslRet = esl_initKDF2HMACSHA1((P2VAR(eslt_WorkSpaceKDF2HMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, (eslt_Length)iterations); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Derive a key with the given length. */ + eslRet = esl_deriveKeyKDF2HMACSHA1((P2VAR(eslt_WorkSpaceKDF2HMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (eslt_Length)secretLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))secretPtr, + (eslt_Length)infoLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))infoPtr, + (eslt_Length)keyLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr); + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA1() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA1() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA1( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + eslt_WorkSpaceKDF2HMACSHA1 workspace; + + /* ----- Implementation ----------------------------------------------- */ + retVal= Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA_WS(&workspace, cryptoKeyId, targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA1() */ +#endif /* (CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA1 == STD_ON) */ + +#if((CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA1 == STD_ON) || (CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA256 == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA_WS() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA_WS( + P2VAR(eslt_WorkSpaceKDF2, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 algorithm) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK, localRet; + uint32 iterationLength = CRYPTO_30_LIBCV_SIZEOF_KDF_ITERATIONSLENGTH; + uint32 secretLength, saltLength, keyLength; + Crypto_30_LibCv_SizeOfKeyStorageType secretIndex, saltIndex, iterationIndex; + Crypto_30_LibCv_SizeOfKeyElementsType keyElementIndex; + uint32 iterations; + + /* ----- Implementation ----------------------------------------------- */ + /* Get secret */ + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &secretIndex, &secretLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Get salt */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_SALT, &saltIndex, &saltLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Get iterations */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_ITERATIONS, &iterationIndex, &iterationLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Get target key element index, length and check access */ + localRet |= Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess(targetCryptoKeyId, CRYPTO_30_LIBCV_KE_TARGET_KEY, &keyElementIndex, &keyLength, CRYPTO_30_LIBCV_WA_INTERNAL_COPY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRet == E_OK) + { + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&iterations, Crypto_30_LibCv_GetAddrKeyStorage(iterationIndex)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* Dispatch key derivation according the given algorithm */ + switch (algorithm) + { +# if (CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1: + /* Derive key */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA1(workspace, + secretLength, Crypto_30_LibCv_GetAddrKeyStorage(secretIndex), + saltLength, Crypto_30_LibCv_GetAddrKeyStorage(saltIndex), + keyLength, Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(keyElementIndex), + iterations); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256: + /* Derive key */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA256(workspace, + secretLength, Crypto_30_LibCv_GetAddrKeyStorage(secretIndex), + saltLength, Crypto_30_LibCv_GetAddrKeyStorage(saltIndex), + keyLength, Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(keyElementIndex), + iterations); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + break; +# endif + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported State */ + retVal = E_NOT_OK; + break; + } + + if (retVal == E_OK) + { + /* Update key element */ + Crypto_30_LibCv_Local_SetKeyElementStateWritten(keyElementIndex); + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(targetCryptoKeyId, keyElementIndex, keyLength); + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA_WS() */ +#endif /* ( CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA1 == STD_ON || CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA256 == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA256() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA256( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + eslt_WorkSpaceKDF2HMACSHA256 workspace; + + /* ----- Implementation ----------------------------------------------- */ + retVal= Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA_WS(&workspace, cryptoKeyId, targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA256() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA256() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 9 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA256( + P2VAR(eslt_WorkSpaceKDF2HMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + uint32 iterations) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* ----- Implementation ----------------------------------------------- */ + + /* Init workspace header */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_KDF2HMACSHA256, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Init workspace */ + eslRet = esl_initKDF2HMACSHA256((P2VAR(eslt_WorkSpaceKDF2HMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, (eslt_Length)iterations); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Derive a key with the given length. */ + eslRet = esl_deriveKeyKDF2HMACSHA256((P2VAR(eslt_WorkSpaceKDF2HMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (eslt_Length)secretLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))secretPtr, + (eslt_Length)infoLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))infoPtr, + (eslt_Length)keyLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr); + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Calc_PBKDF2_HMAC_SHA256() */ +#endif /* (CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA256 == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS( + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 hashAlgorithmId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK, localRet, localRet_2; + uint32 iterationLength = CRYPTO_30_LIBCV_SIZEOF_HKDF_ITERATIONSLENGTH; + uint32 secretLength, saltLength, infoLength, keyLength; + Crypto_30_LibCv_SizeOfKeyStorageType secretIndex, saltIndex = 0u, infoIndex = 0u, iterationIndex; + Crypto_30_LibCv_SizeOfKeyElementsType keyElementIndex; + P2CONST(uint8, AUTOMATIC, AUTOMATIC) saltPtr; + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr; + + /* ----- Implementation ----------------------------------------------- */ + /* Get salt */ + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_SALT, &saltIndex, &saltLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (localRet == CRYPTO_E_KEY_NOT_AVAILABLE) + { + localRet = E_OK; + saltPtr = NULL_PTR; + saltLength = 0u; + } + else + { + saltPtr = Crypto_30_LibCv_GetAddrKeyStorage(saltIndex); + } + + /* Get additional info */ + localRet_2 = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO, &infoIndex, &infoLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (localRet_2 == CRYPTO_E_KEY_NOT_AVAILABLE) + { + infoPtr = NULL_PTR; + infoLength = 0u; + } + else + { + localRet |= localRet_2; + infoPtr = Crypto_30_LibCv_GetAddrKeyStorage(infoIndex); + } + + /* Get secret */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &secretIndex, &secretLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Get iterations */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_ITERATIONS, &iterationIndex, &iterationLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Get target key element index, length and check access */ + localRet |= Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess(targetCryptoKeyId, CRYPTO_30_LIBCV_KE_TARGET_KEY, &keyElementIndex, &keyLength, CRYPTO_30_LIBCV_WA_INTERNAL_COPY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRet == E_OK) + { + /* Dispatch key derivation according the given algorithm */ + /* Derive key */ + switch(hashAlgorithmId) + { +# if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256: + retVal = Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA256(workspace, + secretLength, Crypto_30_LibCv_GetAddrKeyStorage(secretIndex), + saltLength, saltPtr, + infoLength, infoPtr, + keyLength, Crypto_30_LibCv_GetAddrKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(keyElementIndex)), + *Crypto_30_LibCv_GetAddrKeyStorage(iterationIndex)); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384: + retVal = Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA384(workspace, + secretLength, Crypto_30_LibCv_GetAddrKeyStorage(secretIndex), + saltLength, saltPtr, + infoLength, infoPtr, + keyLength, Crypto_30_LibCv_GetAddrKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(keyElementIndex)), + *Crypto_30_LibCv_GetAddrKeyStorage(iterationIndex)); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + break; +# endif + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported algorithm */ + retVal = E_NOT_OK; + break; + } + + if (retVal == E_OK) + { + /* Update key element */ + Crypto_30_LibCv_Local_SetKeyElementStateWritten(keyElementIndex); + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(targetCryptoKeyId, keyElementIndex, keyLength); + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 hashAlgorithmId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + eslt_WorkSpaceHKDFHMAC workspace; + + /* ----- Implementation ----------------------------------------------- */ + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS(&workspace, cryptoKeyId, targetCryptoKeyId, hashAlgorithmId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA256() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 10 */ /* MD_MSR_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA256( + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 saltLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) saltPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + uint8 iterations) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* ----- Implementation ----------------------------------------------- */ + + /* Init workspace header */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_HKDF_HMAC, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Init workspace */ + eslRet = esl_initHKDF_HMAC_SHA256((P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, iterations); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Derive a key with the given length. */ + eslRet = esl_deriveKeyHKDF_HMAC_SHA256((P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (eslt_Length)secretLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))secretPtr, + (eslt_Length)saltLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))saltPtr, + (eslt_Length)infoLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))infoPtr, + (eslt_Length)keyLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr); + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA256() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256_ENABLED == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1_WS() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1_WS( + P2VAR(eslt_WorkSpaceHKDFHASH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + eslt_HashAlgorithm hashId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK, localRet; + uint32 secretLength, infoLength, keyLength = 0u; + Crypto_30_LibCv_SizeOfKeyStorageType secretIndex = 0u, infoIndex = 0u; + Crypto_30_LibCv_SizeOfKeyElementsType keyElementIndex; + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr; + + /* ----- Implementation ----------------------------------------------- */ + /* Get additional info */ + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO, &infoIndex, &infoLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (localRet == CRYPTO_E_KEY_NOT_AVAILABLE) + { + infoPtr = NULL_PTR; + infoLength = 0u; + localRet = E_OK; + } + else + { + infoPtr = Crypto_30_LibCv_GetAddrKeyStorage(infoIndex); + } + + /* Get secret */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &secretIndex, &secretLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Get target key element index, length and check access */ + localRet |= Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess(targetCryptoKeyId, CRYPTO_30_LIBCV_KE_TARGET_KEY, &keyElementIndex, &keyLength, CRYPTO_30_LIBCV_WA_INTERNAL_COPY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRet == E_OK) + { + /* Dispatch key derivation according the given algorithm */ + /* Derive key */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_Hash_Option_1(workspace, + secretLength, Crypto_30_LibCv_GetAddrKeyStorage(secretIndex), + infoLength, infoPtr, + keyLength, Crypto_30_LibCv_GetAddrKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(keyElementIndex)), + hashId); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* Update key element */ + Crypto_30_LibCv_Local_SetKeyElementStateWritten(keyElementIndex); + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(targetCryptoKeyId, keyElementIndex, keyLength); + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1_WS() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + eslt_HashAlgorithm hashId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + eslt_WorkSpaceHKDFHASH workspace; + + /* ----- Implementation ----------------------------------------------- */ + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1_WS(&workspace, cryptoKeyId, targetCryptoKeyId, hashId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256_ENABLED == STD_ON) || ((CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512_ENABLED == STD_ON)) */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_Hash_Option_1() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 10 */ /* MD_MSR_STPAR */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_Hash_Option_1( + P2VAR(eslt_WorkSpaceHKDFHASH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + eslt_HashAlgorithm hashId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* ----- Implementation ----------------------------------------------- */ + + /* Init workspace header */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_HKDF_HASH, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Init workspace */ + eslRet = esl_initHKDF_Hash_OneStep((P2VAR(eslt_WorkSpaceHKDFHASH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, hashId); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Derive a key with the given length. */ + eslRet = esl_deriveKeyHKDF_Hash_OneStep((P2VAR(eslt_WorkSpaceHKDFHASH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (eslt_Length)secretLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))secretPtr, + (eslt_Length)infoLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))infoPtr, + (eslt_Length)keyLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr); + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_Hash_Option_1() */ + +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256_ENABLED == STD_ON) || ((CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA384() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 10 */ /* MD_MSR_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA384( + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 secretLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 saltLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) saltPtr, + uint32 infoLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr, + uint32 keyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + uint8 iterations) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* ----- Implementation ----------------------------------------------- */ + + /* Init workspace header */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_HKDF_HMAC, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Init workspace */ + eslRet = esl_initHKDF_HMAC_SHA384((P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, iterations); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Derive a key with the given length. */ + eslRet = esl_deriveKeyHKDF_HMAC_SHA384((P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (eslt_Length)secretLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))secretPtr, + (eslt_Length)saltLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))saltPtr, + (eslt_Length)infoLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))infoPtr, + (eslt_Length)keyLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr); + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Calc_HKDF_HMAC_SHA384() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 hashAlgorithmId) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_WorkSpaceHKDFHMAC workspace; + + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC_WS(&workspace, cryptoKeyId, targetCryptoKeyId, hashAlgorithmId); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_STACK_WORKSPACE */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC_WS() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC_WS( + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + uint8 hashAlgorithmId) +{ + Std_ReturnType retVal = E_NOT_OK, localRet = E_NOT_OK; + eslt_ErrorCode eslRet = ESL_ERC_ERROR; + uint32 keyDerivationKeyLength = 0u, infoLength = 0u, targetLength = 0u; + Crypto_30_LibCv_SizeOfKeyStorageType keyDerivationKeyIndex = 0u, infoIndex = 0u; + Crypto_30_LibCv_SizeOfKeyElementsType targetIndex = 0u; + P2CONST(uint8, AUTOMATIC, AUTOMATIC) infoPtr = NULL_PTR; + + /* # Get additional info key element index. */ + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO, &infoIndex, &infoLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + if (localRet == CRYPTO_E_KEY_NOT_AVAILABLE) + { + /* infoPtr remains NULL_PTR and infoLength remains 0u. */ + localRet = E_OK; + } + else + { + infoPtr = Crypto_30_LibCv_GetAddrKeyStorage(infoIndex); + } + + /* # Get key element index to expand from. */ + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &keyDerivationKeyIndex, &keyDerivationKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + /* # Get target key element index, length and check access. */ + localRet |= Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess(targetCryptoKeyId, CRYPTO_30_LIBCV_KE_TARGET_KEY, &targetIndex, &targetLength, CRYPTO_30_LIBCV_WA_INTERNAL_COPY); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (localRet == E_OK) + { + /* # Init workspace header. */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(workspace->header), ESL_MAXSIZEOF_WS_HKDF_HMAC, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE_PARAMETER */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* # Apply key expansion according the given algorithm. */ + switch (hashAlgorithmId) + { +# if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256: + eslRet = esl_initHKDF_HMAC_SHA256(workspace, ESL_HKDF_TWO_STEP_VARIANT); /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_expandKeyHKDF_HMAC_SHA256(workspace, + Crypto_30_LibCv_GetAddrKeyStorage(keyDerivationKeyIndex), (eslt_Length)keyDerivationKeyLength, + infoPtr, (eslt_Length)infoLength, + Crypto_30_LibCv_GetAddrKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(targetIndex)), (eslt_Length)targetLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_KEY_PTR */ + } + break; +# endif +# if (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA384_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA384: + eslRet = esl_initHKDF_HMAC_SHA384(workspace, ESL_HKDF_TWO_STEP_VARIANT); /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_expandKeyHKDF_HMAC_SHA384(workspace, + Crypto_30_LibCv_GetAddrKeyStorage(keyDerivationKeyIndex), (eslt_Length)keyDerivationKeyLength, + infoPtr, (eslt_Length)infoLength, + Crypto_30_LibCv_GetAddrKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(targetIndex)), (eslt_Length)targetLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_KEY_PTR */ + } + break; +# endif + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported algorithm */ + break; + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* # Update key element. */ + Crypto_30_LibCv_Local_SetKeyElementStateWritten(targetIndex); + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(targetCryptoKeyId, targetIndex, targetLength); + retVal = E_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC_WS() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KDF_ALGO_SPAKE2_PLUS_P256R1_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Spake2Plus_WS() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Spake2Plus_WS( + P2VAR(eslt_WorkSpaceSPAKE2PPreamble, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK, localRet; + uint32 secretLength, w0Length, w1Length, lLength; + Crypto_30_LibCv_SizeOfKeyStorageType secretIndex; + Crypto_30_LibCv_SizeOfKeyElementsType w0ElementIndex, w1ElementIndex, lElementIndex; + + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr; + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr; + + /* ----- Implementation ----------------------------------------------- */ + + /* Curve Sizes */ + domainPtr = (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain; + domainExtPtr = (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt; + w0Length = CRYPTO_30_LIBCV_SIZEOF_ECC_256_N; + w1Length = CRYPTO_30_LIBCV_SIZEOF_ECC_256_N; + lLength = 1u + (2u * CRYPTO_30_LIBCV_SIZEOF_ECC_256_P); /* Prefix + Double P Size */ + + /* Get secret [w0s|w1s] */ + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYDERIVATION_PASSWORD, &secretIndex, &secretLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Get w0 key element index, length and check access */ + localRet |= Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccessAndLength(targetCryptoKeyId, CRYPTO_KE_CUSTOM_W0, &w0ElementIndex, w0Length, CRYPTO_30_LIBCV_WA_INTERNAL_COPY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Get w1 key element index, length and check access */ + localRet |= Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccessAndLength(targetCryptoKeyId, CRYPTO_KE_CUSTOM_W1, &w1ElementIndex, w1Length, CRYPTO_30_LIBCV_WA_INTERNAL_COPY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Get l (lx | ly) key element index, length and check access */ + localRet |= Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccessAndLength(targetCryptoKeyId, CRYPTO_KE_CUSTOM_L, &lElementIndex, lLength, CRYPTO_30_LIBCV_WA_INTERNAL_COPY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRet == E_OK) + { + /* Derive key */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Calc_Spake2Plus(workspace, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR */ + domainPtr, + domainExtPtr, + Crypto_30_LibCv_GetAddrKeyStorage(secretIndex), secretLength, + Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(w0ElementIndex), w0Length, + Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(w1ElementIndex), w1Length, + Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(lElementIndex), lLength); + + if (retVal == E_OK) + { + /* Update key element */ + /* w0 */ + Crypto_30_LibCv_Local_SetKeyElementStateWritten(w0ElementIndex); + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(targetCryptoKeyId, w0ElementIndex, w0Length); + /* w1 */ + Crypto_30_LibCv_Local_SetKeyElementStateWritten(w1ElementIndex); + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(targetCryptoKeyId, w1ElementIndex, w1Length); + /* l */ + Crypto_30_LibCv_Local_SetKeyElementStateWritten(lElementIndex); + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(targetCryptoKeyId, lElementIndex, lLength); + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Spake2Plus_WS() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Spake2Plus() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Spake2Plus( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + eslt_WorkSpaceSPAKE2PPreamble workspace; + + /* ----- Implementation ----------------------------------------------- */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Spake2Plus_WS(&workspace, cryptoKeyId, targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Spake2Plus() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive_Calc_Spake2Plus() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6060 12 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive_Calc_Spake2Plus( + P2VAR(eslt_WorkSpaceSPAKE2PPreamble, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) secretPtr, + uint32 secretLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) w0Ptr, + uint32 w0Length, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) w1Ptr, + uint32 w1Length, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) lPtr, + uint32 lLength) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + eslt_Length lLengthPtr, w0LengthPtr, w1LengthPtr; + + /* ----- Implementation ----------------------------------------------- */ + + lLengthPtr = (eslt_Length)lLength; + w0LengthPtr = (eslt_Length)w0Length; + w1LengthPtr = (eslt_Length)w1Length; +/* Init workspace header */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_SIZEOF_WS_SPAKE2PPRE, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Init workspace */ + eslRet = esl_initSPAKE2PPreamble((P2VAR(eslt_WorkSpaceSPAKE2PPreamble, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, + domainPtr, + domainExtPtr); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Derive a key with the given length. */ + eslRet = esl_calcSPAKE2PPreamble((P2VAR(eslt_WorkSpaceSPAKE2PPreamble, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))secretPtr, + (eslt_Length)secretLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))w0Ptr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&w0LengthPtr, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))w1Ptr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&w1LengthPtr, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))lPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&lLengthPtr); + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyDerive_Calc_Spake2Plus() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_SPAKE2_PLUS_P256R1_ENABLED == STD_ON) */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +#if (CRYPTO_30_LIBCV_KEYDERIVENISTFIPS186ERB == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveNistFips186Erb() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveNistFips186Erb( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveNistFips186Erb(Crypto_30_LibCv_GetKeyDeriveNistFips186ErbIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864 */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveNistFips186Erb() */ +#endif /* CRYPTO_30_LIBCV_KEYDERIVENISTFIPS186ERB() */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEISO15118 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveISO15118() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveISO15118( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveISO15118(Crypto_30_LibCv_GetKeyDeriveISO15118IdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_ISO15118 */ + retVal = Crypto_30_LibCv_Local_KeyDerive_ISO15118_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveISO15118() */ +#endif /* CRYPTO_30_LIBCV_KEYDERIVEISO15118() */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEISO15118_20 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveISO15118_20() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveISO15118_20( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118_20, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveISO15118_20(Crypto_30_LibCv_GetKeyDeriveISO15118_20IdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_ISO15118_20 */ + retVal = Crypto_30_LibCv_Local_KeyDerive_ISO15118_20_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveISO15118_20() */ +#endif /* CRYPTO_30_LIBCV_KEYDERIVEISO15118_20() */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEX963SHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveX963SHA256() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveX963SHA256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceKDFX963SHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveX963SHA256(Crypto_30_LibCv_GetKeyDeriveX963SHA256IdxOfObjectInfo(objectId)); + + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_WS */ + retVal = Crypto_30_LibCv_Local_KeyDerive_KDF_963_256_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveX963SHA256() */ +#endif /* CRYPTO_30_LIBCV_KEYDERIVEX963SHA256() */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEX963SHA512 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveX963SHA512() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveX963SHA512( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceKDFX963SHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveX963SHA512(Crypto_30_LibCv_GetKeyDeriveX963SHA512IdxOfObjectInfo(objectId)); + + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_WS */ + retVal = Crypto_30_LibCv_Local_KeyDerive_KDF_963_512_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveX963SHA512() */ +#endif /* CRYPTO_30_LIBCV_KEYDERIVEX963() */ + +#if (CRYPTO_30_LIBCV_KEYDERIVENIST80056AONEPASS == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveNist80056AOnePass() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveNist80056AOnePass( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceISO15118, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveNist80056AOnePass(Crypto_30_LibCv_GetKeyDeriveNist80056AOnePassIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_AndLoadKey */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist80056A_OnePass_C1E1S_With_Ws_AndLoadKey(workspace, job->cryptoKeyId, job->targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveNist80056AOnePass() */ +#endif /* CRYPTO_30_LIBCV_KEYDERIVENIST80056AONEPASS() */ + +#if (CRYPTO_30_LIBCV_KEYDERIVENIST800108CNTSHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveNist800108CntSha256() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveNist800108CntSha256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + P2VAR(eslt_WorkSpaceSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveNist800108CntSha256(Crypto_30_LibCv_GetKeyDeriveNist800108CntSha256IdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864 */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist800108NistFips1864_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveNist800108CntSha256() */ +#endif /* CRYPTO_30_LIBCV_KEYDERIVENIST800108CNTSHA256() */ + +#if (CRYPTO_30_LIBCV_KEYDERIVENIST800108CTRCMACAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveNist800108CtrCmacAes() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveNist800108CtrCmacAes( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceKDFnist800108, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveNist800108CtrCmacAes(Crypto_30_LibCv_GetKeyDeriveNist800108CtrCmacAesIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + retVal = Crypto_30_LibCv_Local_KeyDerive_Nist800108_Generic_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ + /* If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + else + { + retVal = E_OK; + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveNist800108CtrCmacAes() */ +#endif /* CRYPTO_30_LIBCV_KEYDERIVENIST800108CNTSHA256() */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA1 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveKDF2HMACSHA1() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveKDF2HMACSHA1( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceKDF2HMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveKDF2HMACSHA1(Crypto_30_LibCv_GetKeyDeriveKDF2HMACSHA1IdxOfObjectInfo(objectId)); + + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA_WS */ + retVal = Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveKDF2HMACSHA1() */ +#endif /* (CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA1 == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveKDF2HMACSHA256() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveKDF2HMACSHA256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceKDF2HMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveKDF2HMACSHA256(Crypto_30_LibCv_GetKeyDeriveKDF2HMACSHA256IdxOfObjectInfo(objectId)); + + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA_WS */ + retVal = Crypto_30_LibCv_Local_KeyDerive_PBKDF2_HMAC_SHA_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveKDF2HMACSHA256() */ +#endif /* (CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA256 == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEHKDFHMACSHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHMACSHA256() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHMACSHA256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveHKDFHMACSHA256(Crypto_30_LibCv_GetKeyDeriveHKDFHMACSHA256IdxOfObjectInfo(objectId)); + + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS with SHA256 */ + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHMACSHA256() */ +#endif /* (CRYPTO_30_LIBCV_KEYDERIVEHKDFHMACSHA256 == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEHKDFHMACSHA384 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHMACSHA384() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHMACSHA384( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveHKDFHMACSHA384(Crypto_30_LibCv_GetKeyDeriveHKDFHMACSHA384IdxOfObjectInfo(objectId)); + + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS with SHA384 */ + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHMACSHA384() */ +#endif /* (CRYPTO_30_LIBCV_KEYDERIVEHKDFHMACSHA384 == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEHKDFEXPANDHMACSHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFExpandHMACSHA256() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFExpandHMACSHA256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + Std_ReturnType retVal = E_OK; + + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveHKDFExpandHMACSHA256(Crypto_30_LibCv_GetKeyDeriveHKDFExpandHMACSHA256IdxOfObjectInfo(objectId)); + + /* # Call Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS with SHA256 */ + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + if (retVal == E_OK) + { + /* # If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveHKDFExpandHMACSHA256() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEHKDFEXPANDHMACSHA384 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFExpandHMACSHA384() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFExpandHMACSHA384( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + Std_ReturnType retVal = E_OK; + + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceHKDFHMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveHKDFExpandHMACSHA384(Crypto_30_LibCv_GetKeyDeriveHKDFExpandHMACSHA384IdxOfObjectInfo(objectId)); + + /* # Call Crypto_30_LibCv_Local_KeyDerive_HKDF_HMAC_WS with SHA348 */ + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_Expand_HMAC_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId, CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA384); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + if (retVal == E_OK) + { + /* # If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveHKDFExpandHMACSHA384() */ +#endif /* (CRYPTO_30_LIBCV_KDF_ALGO_HKDF_EXPAND_HMAC_SHA348_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYDERIVESPAKE2P == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveSpake2P() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveSpake2P( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceSPAKE2PPreamble, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveSpake2P(Crypto_30_LibCv_GetKeyDeriveSpake2PIdxOfObjectInfo(objectId)); + + /* #10 Derive key */ + retVal = Crypto_30_LibCv_Local_KeyDerive_Spake2Plus_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveSpake2P() */ +#endif /* (CRYPTO_30_LIBCV_KEYDERIVESPAKE2P == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEHKDFHASHOPTION1SHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHashOption1SHA256() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHashOption1SHA256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceHKDFHASH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveHKDFHashOption1SHA256(Crypto_30_LibCv_GetKeyDeriveHKDFHashOption1SHA256IdxOfObjectInfo(objectId)); + + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1_WS */ + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId, ESL_HA_SHA2_256); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHashOption1SHA256() */ +#endif /* (CRYPTO_30_LIBCV_KEYDERIVEHKDFHASHOPTION1SHA256 == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYDERIVEHKDFHASHOPTION1SHA512 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHashOption1SHA512() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHashOption1SHA512( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceHKDFHASH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyDeriveHKDFHashOption1SHA512(Crypto_30_LibCv_GetKeyDeriveHKDFHashOption1SHA512IdxOfObjectInfo(objectId)); + + /* #10 Call Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1_WS */ + retVal = Crypto_30_LibCv_Local_KeyDerive_HKDF_Hash_Option_1_WS(workspace, job->cryptoKeyId, job->targetCryptoKeyId, ESL_HA_SHA2_512); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_Local_Derive_UpdateKeyState(objectId, job->targetCryptoKeyId, retVal); + + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHashOption1SHA512() */ +#endif /* (CRYPTO_30_LIBCV_KEYDERIVEHKDFHASHOPTION1SHA512 == STD_ON) */ + +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeyDerive.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyDerive.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyDerive.h new file mode 100644 index 0000000..eb75b78 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyDerive.h @@ -0,0 +1,502 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeyDerive.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for Key Derive Services. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#ifndef CRYPTO_30_LIBCV_KEYDERIVE_H +# define CRYPTO_30_LIBCV_KEYDERIVE_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_KEY_DERIVE_ALGORITHM == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyDerive() + *********************************************************************************************************************/ +/*! \brief Derives a key + * \details Dispatch the key derivation. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \param[in,out] writeBlock Holds the result if the NvM need to be written. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId is a valid key id. + * targetCryptoKeyId is a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyDerive( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock); +# endif /* (CRYPTO_30_LIBCV_KEY_DERIVE_ALGORITHM == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEYDERIVENISTFIPS186ERB == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveNistFips186Erb() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveNistFips186Erb job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-145592 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveNistFips186Erb( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif/* CRYPTO_30_LIBCV_KEYDERIVENISTFIPS186ERB() */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEISO15118 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveISO15118() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveISO15118 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace DSGN-DrvCrypto_LibCv_ISO15118CertificateInstallationAndUpdate + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveISO15118( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* Crypto_30_LibCv_Dispatch_KeyDeriveISO15118 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEISO15118_20 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveISO15118_20() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveISO15118_20 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace DSGN-DrvCrypto_LibCv_ISO15118-20-CertificateInstallation + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveISO15118_20( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVEISO15118_20 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVENIST80056AONEPASS == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveNist80056AOnePass() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveNist80056AOnePass job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-145593 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveNist80056AOnePass( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* Crypto_30_LibCv_Dispatch_KeyDeriveNist80056AOnePass */ + +# if (CRYPTO_30_LIBCV_KEYDERIVENIST800108CNTSHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveNist800108CntSha256() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveNist800108CntSha256 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-132407 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveNist800108CntSha256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVENIST800108CNTSHA256 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVENIST800108CTRCMACAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveNist800108CtrCmacAes() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveNist800108CtrCmacAes job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-Crypto-KeyDeriveNist800108CtrCmacAes + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveNist800108CtrCmacAes( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVENIST800108CTRCMACAES */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEX963SHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveX963SHA256() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveX963SHA256 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-191710 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveX963SHA256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVEX963SHA256 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEX963SHA512 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveX963SHA512() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveX963SHA512 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-191710 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveX963SHA512( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVEX963SHA512 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA1 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveKDF2HMACSHA1() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveHmacSha1 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-248610 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveKDF2HMACSHA1( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA1 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveKDF2HMACSHA256() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveHmacSha256 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-248610 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveKDF2HMACSHA256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVEKDF2HMACSHA256 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEHKDFHMACSHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHMACSHA256() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveHKDFHmacSha256 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-266053 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHMACSHA256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVEHKDFHMACSHA256 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEHKDFHMACSHA384 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHMACSHA384() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveHKDFHmacSha384 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-266053 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHMACSHA384( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVEHKDFHMACSHA384 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEHKDFEXPANDHMACSHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFExpandHMACSHA256() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveHKDFExpandHmacSha256 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-Crypto-HKDFExpand + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFExpandHMACSHA256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVEHKDFEXPANDHMACSHA256 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEHKDFEXPANDHMACSHA384 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFExpandHMACSHA384() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveHKDFHmacSha384 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-Crypto-HKDFExpand + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFExpandHMACSHA384( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVEHKDFEXPANDHMACSHA384 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEHKDFHASHOPTION1SHA256 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHashOption1SHA256() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveHKDFHashOneStep SHA256 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-304740 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHashOption1SHA256( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVEHKDFHASHOPTION1SHA256 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVEHKDFHASHOPTION1SHA512 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHashOption1SHA512() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDeriveHKDFHashOneStep SHA512 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-304740 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveHKDFHashOption1SHA512( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVEHKDFHASHOPTION1SHA512 */ + +# if (CRYPTO_30_LIBCV_KEYDERIVESPAKE2P == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyDeriveSpake2P() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyDerive Spake2+ preamble job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the job's + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_Spake2+ + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyDeriveSpake2P( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYDERIVESPAKE2P */ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_KEYDERIVE_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeyDerive.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyExchange.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyExchange.c new file mode 100644 index 0000000..58abeb0 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyExchange.c @@ -0,0 +1,4477 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeyExchange.c + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Implementation of Key Exchange Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_KEYEXCHANGE_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +#include "Crypto_30_LibCv.h" +#include "Crypto_30_LibCv_Services.h" +#include "Crypto_30_LibCv_KeyExchange.h" +#include "Crypto_30_LibCv_KeyGenerate.h" +#include "Crypto_30_LibCv_Custom.h" +#include "Crypto_30_LibCv_Curve.h" + +#if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SPAKE2_PLUS_CIPHERSUITE_8_ENABLED == STD_ON) +# include "ESLib_SPAKE2PConstants.h" +#endif + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* Spake2+ */ +#define CRYPTO_30_LIBCV_SPAKE2P_MODE_NORMAL (0u) +#define CRYPTO_30_LIBCV_SPAKE2P_MODE_CHANGED_VERIFICATION (1u) + +#define CRYPTO_30_LIBCV_SPAKE2P_STATE_UNINIT (0u) +#define CRYPTO_30_LIBCV_SPAKE2P_STATE_CALC_PUBVAL (1u) +#define CRYPTO_30_LIBCV_SPAKE2P_STATE_CALC_SECRET (2u) +#define CRYPTO_30_LIBCV_SPAKE2P_STATE_VERIFICATION (3u) + +/* Elliptic curve with burmester desmedt */ +#define CRYPTO_30_LIBCV_SIZEOF_ECDHE_BD_NUM_ECU_LENGTH (1u) +#define CRYPTO_30_LIBCV_SIZEOF_ECDHE_BD_ECU_ID_LENGTH (1u) +#define CRYPTO_30_LIBCV_ECDHE_BD_MIN_NUM_ECU (3u) + +#define CRYPTO_30_LIBCV_ECBD_STATE_UNINIT (0u) +#define CRYPTO_30_LIBCV_ECBD_STATE_CALC_PUBVAL (1u) +#define CRYPTO_30_LIBCV_ECBD_STATE_CALC_INTERMEDIATE (2u) +#define CRYPTO_30_LIBCV_ECBD_STATE_REC_INTERMEDIATE (3u) +#define CRYPTO_30_LIBCV_ECBD_STATE_CALC_SECRET (4u) + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SPAKE2_PLUS_CIPHERSUITE_8_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_A_Pre() + **********************************************************************************************************************/ +/*! \brief Set Preamble Spake2+ Party A + * \details The service stores w0 and w1 in the workspace and sets a preamble flag in the workspace. + * \param[in,out] ws Contains the workspace. + * \param[in] w0Ptr Pointer to w0 + * \param[in] w0Length Length of w0 + * \param[in] w1Ptr Pointer to w1 + * \param[in] w1Length Length of w1 + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be a valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_A_Pre( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) w0Ptr, + uint32 w0Length, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) w1Ptr, + uint32 w1Length); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_B_Pre() + **********************************************************************************************************************/ +/*! \brief Set Preamble Spake2+ Party B + * \details The service stores w0 and l in the workspace and sets a preamble flag in the workspace. + * \param[in,out] ws Contains the workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * \param[in] w0Ptr Pointer to w0 + * \param[in] w0Length Length of w0 + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId has to be a valid crypto key. + * All pointers need to be a valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_B_Pre( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) w0Ptr, + uint32 w0Length); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Pre() + **********************************************************************************************************************/ +/*! \brief Set Preamble Spake2+ + * \details Set Preamble Spake2+ for Party A or Party B + * \param[in,out] ws Contains the workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId has to be a valid crypto key. + * All pointers need to be a valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Pre( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Public() + **********************************************************************************************************************/ +/*! \brief Calculation of the public value according to Spake2+ + * \details - + * \param[in,out] ws Contains the workspace. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid crypto key. + * All pointers need to be a valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Public( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_Calc() + **********************************************************************************************************************/ +/*! \brief Calculation of the public value according to Spake2+ + * \details Calculates the public value for the key exchange and stores the public key in the + * memory location pointed to by the public value pointer. The write access right for the destination + * key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \param[in,out] ws Contains the workspace. + * \param[in] domainPtr Pointer to domain parameter structure + * \param[in] domainExtPtr Pointer to domain parameter extension structure + * \param[in] mode Contain the Spake2+ calculation Mode + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid crypto key. + * All pointers need to be a valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_Calc( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + uint8 mode); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P() + **********************************************************************************************************************/ +/*! \brief Calculation of the public value according to Spake2+ + * \details Calculates the public value for the key exchange and stores the public key in the + * memory location pointed to by the public value pointer. The write access right for the destination + * key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \param[in] domainPtr Pointer to domain parameter structure + * \param[in] domainExtPtr Pointer to domain parameter extension structure + * \param[in] mode Contain the Spake2+ calculation Mode + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid crypto key. + * All pointers need to be a valid. + * \note This service locks the long term workspace if possible. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_Spake2+ + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + uint8 mode); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Spake2P_AdditionalInfoRead() + **********************************************************************************************************************/ +/*! \brief Read single data element. + * \details [info-a | info-b | aad] each [DataLength 4-Byte | Data X-Byte] + * \param[in] infoPtr Holds the pointer to the memory location which contains the info. + * \param[in] infoLength Holds the Length of the infoPtr. + * \param[in,out] readPos Holds the current read position. + * \param[out] dataPos Holds the position of the data. + * \param[out] dataLength Holds the Length of the dataPos. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointer need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Spake2P_AdditionalInfoRead( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) infoPtr, + uint32 infoLength, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) readPos, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) dataPos, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) dataLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_AdditionalInfo() + **********************************************************************************************************************/ +/*! \brief Set additional info for secret for Spake2+ + * \details [info-a | info-b | aad] each [DataLength 4-Byte | Data X-Byte] + * \param[in,out] ws Contains the workspace. + * \param[in] infoPtr Holds the pointer to the memory location which contains the info. + * \param[in] infoLength Holds the Length of the infoPtr. + * \param[in] infoElementRetVal Holds the retval from the key element operation of info data + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointer need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_AdditionalInfo( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) infoPtr, + uint32 infoLength, + Std_ReturnType infoElementRetVal); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Secret() + **********************************************************************************************************************/ +/*! \brief Calculation of the secret for Spake2+ + * \details Secret is calculation. + * \param[in,out] ws Contains the workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \param[in] partnerPublicValueLength Holds the Length of the partnerPublicValuePtr. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId has to be a valid crypto key. + * All pointer need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Secret( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Verification() + **********************************************************************************************************************/ +/*! \brief Key confirmation for Spake2+ + * \details - + * \param[in,out] ws Contains the workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerConfirmationValuePtr Holds the pointer to the memory location which contains the partners + * confirmation value. + * \param[in] partnerConfirmationValueLength Holds the Length of the partnerConfirmationValuePtr. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId has to be a valid crypto key. + * All pointer need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Verification( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerConfirmationValuePtr, + uint32 partnerConfirmationValueLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P() + **********************************************************************************************************************/ +/*! \brief Calculation of the secret for Spake2+ + * \details Depending on the state either secret is calculation or key confirmation is executed. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public/confirmation value. + * \param[in] partnerPublicValueLength Holds the Length of the partnerPublicValuePtr. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId has to be a valid crypto key. + * All pointer need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_Spake2+ + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SPAKE2_PLUS_CIPHERSUITE_8_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X25519_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519() + *********************************************************************************************************************/ +/*! \brief Calculation of the public value for x25519 + * \details Calculates the public value for the key exchange and stores the public key in the + * memory location pointed to by the public value pointer. The write access right for the destination + * key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid crypto key. + * publicValuePtr has to be a valid pointer. + * publicValueLengthPtr has to be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr); +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X25519_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448() + *********************************************************************************************************************/ +/*! \brief Calculation of the public value for x448 + * \details Calculates the public value for the key exchange and stores the public key in the + * memory location pointed to by the public value pointer. The write access right for the destination + * key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid crypto key. + * publicValuePtr has to be a valid pointer. + * publicValueLengthPtr has to be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr); +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic() + *********************************************************************************************************************/ +/*! \brief Calculation of the public value + * \details Calculates the public value for the key exchange and stores the public key in the + * memory location pointed to by the public value pointer. The write access right for the destination + * key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \param[in] domainPtr Pointer to domain parameter structure + * \param[in] domainExtPtr Pointer to domain parameter extension structure + * \param[in] speedUpExtPtr Pointer to precomputation structure + * \param[in] keySize Contains the length of the key element in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid crypto key. + * publicValuePtr has to be a valid pointer. + * publicValueLengthPtr has to be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) speedUpExtPtr, + uint32 keySize); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret + * \details Calculates the shared secret key for the key exchange with the key material of the key identified + * by the cryptoKeyId and the partner public key. The shared secret key is stored + * as a key element in the same key. The write access right for the destination key element + * must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \param[in] partnerPublicValueLength Holds the Length of the partnerPublicValuePtr. + * \param[in] keySize Contains the length of the key element in bytes. + * \param[in] keaId Key exchange algorithm identifier. + * \param[in,out] workspace Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId has to be a valid crypto key. + * partnerPublicValuePtr has to be a valid pointer with size 2*CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic_With_Ws( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength, + uint32 keySize, + uint8 keaId, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculation of the public value + * \details Calculates the public value for the key exchange and stores the public key in the + * memory location pointed to by the public value pointer. The write access right for the destination + * key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \param[in] domainPtr Pointer to domain parameter structure + * \param[in] domainExtPtr Pointer to domain parameter extension structure + * \param[in] speedUpExtPtr Pointer to precomputation structure + * \param[in] keySize Contains the length of the key element in bytes. + * \param[in,out] workspace Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid crypto key. + * publicValuePtr has to be a valid pointer. + * publicValueLengthPtr has to be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic_With_Ws( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) speedUpExtPtr, + uint32 keySize, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ECBD_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchange_CheckDomainKeyLengths() + *********************************************************************************************************************/ +/*! \brief Check of the domain key lengths + * \details Checks if the private and public key lengths provided by the domain parameters are equal to the given expected values. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \param[in] expectedPrivateKeyLength Expected private key length of given curve + * \param[in] expectedPublicKeyLength Expected public key length of given curve + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre EcDomainPtr has to be a valid pointer pointing to valid domain parameters. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchange_CheckDomainKeyLengths( + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + const uint32 expectedPrivateKeyLength, + const uint32 expectedPublicKeyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_CheckDomainKeyLengthsAndProcessCalc() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret + * \details Checks the key length length provided by the domain. If lengths are ok, the given parameters are + * forwarded to the KeyExchangeCalcSecret_BD_Prime function calculating the secret. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerIntermediateValuePtr Holds the pointer to the memory location which contains the intermediate + * value. The value must contain the following format + * [EcuId (1Byte) | Partner intermediate value X | Partner intermediate value Y]. + * \param[in] partnerIntermediateValueLength Holds the Length of the partnerIntermediateValuePtr. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \param[in] expectedPrivateKeyLength Expected private key length of given curve + * \param[in] expectedPublicKeyLength Expected public key length of given curve + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId has to be a valid crypto key. + * partnerIntermediateValuePtr has to be a valid pointer with size (1 + CRYPTO_30_LIBCV_SIZEOF_ECC_..._KEY_PUBLIC_XY). + * EcDomainPtr has to be a valid pointer pointing to valid domain parameters. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_ECBD + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_CheckDomainKeyLengthsAndProcessCalc( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerIntermediateValuePtr, + uint32 partnerIntermediateValueLength, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + const uint32 expectedPrivateKeyLength, + const uint32 expectedPublicKeyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret + * \details Calculates the shared secret key for the key exchange with the key material of the key identified + * by the cryptoKeyId and the partner public key. The shared secret key is stored + * as a key element in the same key. The write access right for the destination key element + * must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerIntermediateValuePtr Holds the pointer to the memory location which contains the intermediate + * value. The value must contain the following format + * [EcuId (1Byte) | Partner intermediate value X | Partner intermediate value Y]. + * \param[in] partnerIntermediateValueLength Holds the Length of the partnerIntermediateValuePtr. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId has to be a valid crypto key. + * partnerIntermediateValuePtr has to be a valid pointer with size (1 + CRYPTO_30_LIBCV_SIZEOF_ECC_..._KEY_PUBLIC_XY). + * EcDomainPtr has to be a valid pointer pointing to valid domain parameters. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerIntermediateValuePtr, + uint32 partnerIntermediateValueLength, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_First() + *********************************************************************************************************************/ +/*! \brief First calc secret + * \details Init calc secret + * \param[in,out] wsPtr Pointer to the Crypto_30_LibCv_WorkSpaceECBD workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre - + * \context TASK + * \reentrant TRUE, for different workspaces + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_First( + P2VAR(Crypto_30_LibCv_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Update() + *********************************************************************************************************************/ +/*! \brief Update calc secret with intermediate value of next key exchange partner. + * \details - + * \param[in,out] wsPtr Pointer to the Crypto_30_LibCv_WorkSpaceECBD workspace. + * \param[in] partnerIntermediateValuePtr Holds the pointer to the memory location which contains the intermediate + * value. The value must contain the following format + * [EcuId (1Byte) | Partner intermediate value X | Partner intermediate value Y]. + * \param[in] partnerIntermediateValueLength Holds the Length of the partnerIntermediateValuePtr. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre wsPtr has to be a valid pointer. + * partnerIntermediateValuePtr has to be a valid pointer with size (1 + CRYPTO_30_LIBCV_SIZEOF_ECC_..._KEY_PUBLIC_XY). + * EcDomainPtr has to be a valid pointer pointing to valid domain parameters. + * \context TASK + * \reentrant TRUE, for different workspaces + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Update( + P2VAR(eslt_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerIntermediateValuePtr, + uint32 partnerIntermediateValueLength, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Finish() + *********************************************************************************************************************/ +/*! \brief Calculate shared secret + * \details - + * \param[in,out] wsPtr Pointer to the Crypto_30_LibCv_WorkSpaceECBD workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange protocol. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre wsPtr has to be a valid pointer. + * cryptoKeyId has to be a valid crypto key. + * EcDomainPtr has to be a valid pointer pointing to valid domain parameters. + * \context TASK + * \reentrant TRUE, for different workspaces + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Finish( + P2VAR(eslt_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr, + uint32 cryptoKeyId, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr); +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ECBD_ENABLED == STD_ON) */ + +#endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X25519_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret + * \details Calculates the shared secret key for the key exchange with the key material of the key identified + * by the cryptoKeyId and the partner public key. The shared secret key is stored + * as a key element in the same key. The write access right for the destination key element + * must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId has to be a valid crypto key. + * partnerPublicValuePtr has to be a valid pointer with size ESL_SIZEOF_X25519_PUBLIC_KEY. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculation of the public value for x25519 + * \details Calculates the public value for the key exchange and stores the public key in the + * memory location pointed to by the public value pointer. The write access right for the destination + * key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \param[in,out] wsX25519 Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid crypto key. + * publicValuePtr has to be a valid pointer. + * publicValueLengthPtr has to be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519_With_Ws( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2VAR(eslt_WorkSpaceX25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsX25519); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_Calculate() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret. + * \details Calculates the shared secret key for the key exchange with the key material of the key identified + * by the cryptoKeyId and the partner public key. The shared secret key is stored + * as a key element in the same key. The write access right for the destination key element + * must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \param[in,out] wsX25519 Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_Calculate( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + P2VAR(eslt_WorkSpaceX25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsX25519); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret + * \details After initializing the workspace, the private key is loaded and the secret is calculated. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \param[in,out] wsX25519 Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_With_Ws( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + P2VAR(eslt_WorkSpaceX25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsX25519); +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X25519_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret + * \details Calculates the shared secret key for the key exchange with the key material of the key identified + * by the cryptoKeyId and the partner public key. The shared secret key is stored + * as a key element in the same key. The write access right for the destination key element + * must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId has to be a valid crypto key. + * partnerPublicValuePtr has to be a valid pointer with size ESL_SIZEOF_X448_PUBLIC_KEY. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculation of the public value for x448 + * \details Calculates the public value for the key exchange and stores the public key in the + * memory location pointed to by the public value pointer. The write access right for the destination + * key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \param[in,out] wsX448 Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid crypto key. + * publicValuePtr has to be a valid pointer. + * publicValueLengthPtr has to be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448_With_Ws( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2VAR(eslt_WorkSpaceEdDH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsX448); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret + * \details Calculates the shared secret key for the key exchange with the key material of the key identified + * by the cryptoKeyId and the partner public key. The shared secret key is stored + * as a key element in the same key. The write access right for the destination key element + * must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \param[in,out] wsX448 Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448_With_Ws( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + P2VAR(eslt_WorkSpaceEdDH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsX448); +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret + * \details Calculates the shared secret key for the key exchange with the key material of the key identified + * by the cryptoKeyId and the partner public key. The shared secret key is stored + * as a key element in the same key. The write access right for the destination key element + * must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \param[in] partnerPublicValueLength Holds the Length of the partnerPublicValuePtr. + * \param[in] keySize Contains the length of the key element in bytes. + * \param[in] keaId Key exchange algorithm identifier. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId has to be a valid crypto key. + * partnerPublicValuePtr has to be a valid pointer with size 2*CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength, + uint32 keySize, + uint8 keaId); +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ECBD_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_CheckDomainKeyLengthsAndProcessCalc() + *********************************************************************************************************************/ +/*! \brief Calculation of the public key + * \details Checks the key length length provided by the domain. If lengths are ok, the given parameters are + * forwarded to the KeyExchangeCalcPubVal_BD_Prime function calculating the public key. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \param[in] EcDomainExtPtr Pointer to the curve domain extension parameters. + * \param[in] EcSpeedUpExtPtr Pointer to the curve speed up extension parameters. + * \param[in] expectedPrivateKeyLength Expected private key length of given curve + * \param[in] expectedPublicKeyLength Expected public key length of given curve + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId has to be a valid crypto key. + * publicValuePtr need to be valid and have at least the length of publicValueLengthPtr. + * all domain pointers have to be valid pointing to valid domain parameters. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_ECBD + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_CheckDomainKeyLengthsAndProcessCalc( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcSpeedUpExtPtr, + const uint32 expectedPrivateKeyLength, + const uint32 expectedPublicKeyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GetPartnerPub() + *********************************************************************************************************************/ +/*! \brief Load left and right public value + * \details Load the left and right public value is ready to use. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] leftStorageIndexPtr Pointer to the storage index of the left public value. + * \param[out] rightStorageIndexPtr Pointer to the storage index of the right public value. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre wsPtr and StorageIndexPtr have to be valid pointers. + * cryptoKeyId has to be a valid crypto key. + * all domain pointers need to be valid pointing to valid domain parameters. + * \context TASK + * \reentrant TRUE, for different keys. + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GetPartnerPub( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_KeyStorageIndexType, AUTOMATIC, AUTOMATIC) leftStorageIndexPtr, + P2VAR(Crypto_30_LibCv_KeyStorageIndexType, AUTOMATIC, AUTOMATIC) rightStorageIndexPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair_Init() + *********************************************************************************************************************/ +/*! \brief Init CalcPubVal elliptic curve burmester desmedt. + * \details - + * \param[in,out] wsPtr Pointer to the Crypto_30_LibCv_WorkSpaceECBD workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \param[in] EcDomainExtPtr Pointer to the curve domain extension parameters. + * \param[in] EcSpeedUpExtPtr Pointer to the curve speed up extension parameters. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre wsPtr has to be a valid pointer. + * cryptoKeyId has to be a valid crypto key. + * all domain pointers need to be valid pointing to valid domain parameters. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair_Init( + P2VAR(Crypto_30_LibCv_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr, + uint32 cryptoKeyId, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcSpeedUpExtPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair() + *********************************************************************************************************************/ +/*! \brief Generate own public and private key. + * \details Generate own public and private key according to the given curve. + * \param[in,out] wsPtr Pointer to the Crypto_30_LibCv_WorkSpaceECBD workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \param[in] EcDomainExtPtr Pointer to the curve domain extension parameters. + * \param[in] EcSpeedUpExtPtr Pointer to the curve speed up extension parameters. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre wsPtr has to be a valid pointer. + * cryptoKeyId has to be a valid crypto key. + * publicValuePtr need to be valid and have at least the length of publicValueLengthPtr. + * all domain pointers need to be valid pointing to valid domain parameters. + * \context TASK + * \reentrant TRUE, true for different workspaces. + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair( + P2VAR(Crypto_30_LibCv_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr, + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcSpeedUpExtPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_CalcIntermediate() + *********************************************************************************************************************/ +/*! \brief Generate intermediate value. + * \details Generate intermediate value according to the given partner public values. + * \param[in,out] wsPtr Pointer to the eslt_WorkSpaceECBD workspace. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the intermediate value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre wsPtr has to be a valid pointer. + * cryptoKeyId has to be a valid crypto key. + * publicValuePtr need to need to be valid and have at least the length of publicValueLengthPtr. + * EcDomainPtr need to be valid pointing to valid domain parameters. + * \context TASK + * \reentrant TRUE, true for different workspaces. + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_CalcIntermediate( + P2VAR(eslt_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr, + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteWorkspace() + *********************************************************************************************************************/ +/*! \brief Delete workspace if it is locked for key. + * \details - + * \param[in] longWsIdx Holds the valid identifier of the long term workspace. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteWorkspace( + Crypto_30_LibCv_SizeOfLongTermWsLockType longWsIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteKeys() + *********************************************************************************************************************/ +/*! \brief Delete all required key elements in key. + * \details - + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \pre cryptoKeyId has to be a valid crypto key. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteKeys( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime() + *********************************************************************************************************************/ +/*! \brief Dispatch public value generation. + * \details Generate own public and private key according to the given curve or + * intermediate value according to the given partner public values. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \param[in] EcDomainExtPtr Pointer to the curve domain extension parameters. + * \param[in] EcSpeedUpExtPtr Pointer to the curve speed up extension parameters. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid crypto key. + * publicValuePtr need to have at least the length of publicValueLengthPtr. + * all domain pointers need to be valid pointing to valid domain parameters. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcSpeedUpExtPtr); + +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ECBD_ENABLED == STD_ON) */ +#endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_EcP_CalculateSharedSecret_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculate shared secret + * \details Calculate shared secret for ECDHE Prime for the given values. + * \param[in] privateKeyPtr Pointer to the private key array. + * \param[in] partnerPubKeyPtr Pointer to the partner public key array. + * \param[out] sharedSecretPtr Pointer to the shared secret. + * \param[in,out] workspace Contains workspace. + * \param[in] EcDomainPtr Pointer to the curve domain parameters. + * \param[in] EcDomainExtPtr Pointer to the extended curve domain parameters. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre privateKeyPtr has to be a valid pointer with a valid length. + * partnerPubKeyPtr has to be a valid pointer with a valid length. + * sharedSecretPtr has to be a valid pointer with the length 2*esl_getLengthOfEcPsecret_comp(EcDomainPtr). + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_EcP_CalculateSharedSecret_With_Ws( + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) sharedSecretPtr, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr); + +#endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SPAKE2_PLUS_CIPHERSUITE_8_ENABLED == STD_ON) + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_A_Pre() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_A_Pre( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) w0Ptr, + uint32 w0Length, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) w1Ptr, + uint32 w1Length) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* ----- Implementation ------------------------------------------------- */ + + /* Set Preamble Members for A */ + eslRet = esl_setPreambleDataPartyASPAKE2P(ws, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))w0Ptr, (eslt_Length)w0Length, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))w1Ptr, (eslt_Length)w1Length); + + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_A_Pre() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_B_Pre() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_B_Pre( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) w0Ptr, + uint32 w0Length) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, localRetVal; + eslt_ErrorCode eslRet; + Crypto_30_LibCv_SizeOfKeyStorageType lElementIndex; + uint32 lElementLength; + /* ----- Implementation ------------------------------------------------- */ + + /* Get L */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_L, &lElementIndex, &lElementLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (localRetVal == E_OK) + { + /* Set Preamble Members for B */ + eslRet = esl_setPreambleDataPartyBSPAKE2P(ws, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))w0Ptr, (eslt_Length)w0Length, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(lElementIndex), (eslt_Length)lElementLength); + + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_B_Pre() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Pre() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Pre( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + uint32 cryptoKeyId) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, localRetVal; + Crypto_30_LibCv_SizeOfKeyStorageType w0ElementIndex, w1ElementIndex; + uint32 w0ElementLength, w1ElementLength; + + /* ----- Implementation ------------------------------------------------- */ + + /* Get w0 */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_W0, &w0ElementIndex, &w0ElementLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRetVal == E_OK) + { + /* Get w1 to determine if this is Party A or Party B */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_W1, &w1ElementIndex, &w1ElementLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRetVal != CRYPTO_E_KEY_NOT_AVAILABLE) + { + if (localRetVal == E_OK) + { + /* Party A */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_A_Pre(ws, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR */ + Crypto_30_LibCv_GetAddrKeyStorage(w0ElementIndex), w0ElementLength, + Crypto_30_LibCv_GetAddrKeyStorage(w1ElementIndex), w1ElementLength); + } + } + else + { + /* Party B */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_B_Pre(ws, cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR */ + Crypto_30_LibCv_GetAddrKeyStorage(w0ElementIndex), w0ElementLength); + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Pre() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Public() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Public( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + eslt_Length reqLength; + + /* ----- Implementation ------------------------------------------------- */ + /* Set Sizes for Cipher Suite */ + reqLength = CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PUBLIC; + + /* Check Length Calc Public Value */ + /* Public Value = [pubVal_x | pubVal_y] */ + if ((Crypto_30_LibCv_Math_Mul2((uint32)reqLength)) > *publicValueLengthPtr) + { + retVal = CRYPTO_E_SMALL_BUFFER; + } + else + { + eslRet = esl_calcPubValSPAKE2P(ws, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR */ + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))publicValuePtr, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&publicValuePtr[reqLength], + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&reqLength); + + if (eslRet == ESL_ERC_NO_ERROR) + { + *publicValueLengthPtr = Crypto_30_LibCv_Math_Mul2((uint32)reqLength); /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + } + else + { + Crypto_30_LibCv_ClearData(publicValuePtr, *publicValueLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_ARRAY_ACCESS_WITH_SIZE_CHECK */ + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Public() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_Calc() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_Calc( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + uint8 mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + eslt_SPAKE2PMode spakeMode; + + /* ----- Implementation ------------------------------------------------- */ + + /* Init Workspace */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))&ws->header, ESL_SIZEOF_WS_SPAKE2P, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (mode == CRYPTO_30_LIBCV_SPAKE2P_MODE_NORMAL) + { + spakeMode = ESL_SPAKE2P_MODE_CIPHERSUITE_8_1; + } + else + { + spakeMode = ESL_SPAKE2P_MODE_CIPHERSUITE_8_2; + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_initSPAKE2P(ws, + domainPtr, + domainExtPtr, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))esl_SPAKE2P_pointM_P256, + (eslt_Length)sizeof(esl_SPAKE2P_pointM_P256), + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))esl_SPAKE2P_pointN_P256, + (eslt_Length)sizeof(esl_SPAKE2P_pointN_P256), + spakeMode); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + + /* Set Preamble */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Pre(ws, cryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ + + if (retVal == E_OK) + { + /* Calc Public Value */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2_Public(ws, publicValuePtr, publicValueLengthPtr); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_Calc() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6050, 6060 8 */ /* MD_MSR_STCAL, MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + uint8 mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + P2VAR(Crypto_30_LibCv_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws; + Crypto_30_LibCv_SizeOfLongTermWsLockType longWsIdx; + + /* ----- Implementation ------------------------------------------------- */ + /* Lock long term workspace */ + if (Crypto_30_LibCv_Local_LongWsLockGet(cryptoKeyId, &longWsIdx) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + + ws = (P2VAR(Crypto_30_LibCv_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&Crypto_30_LibCv_GetLongTermWs(longWsIdx).wsSPAKE2P; + ws->state = CRYPTO_30_LIBCV_SPAKE2P_STATE_CALC_PUBVAL; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + + /* Calculate public value */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P_Calc(cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR */ + publicValuePtr, publicValueLengthPtr, + &ws->wsSpake, + domainPtr, + domainExtPtr, + mode); + if (retVal != E_OK) + { + /* Release long term workspace */ + Crypto_30_LibCv_Local_LongWsLockRelease(cryptoKeyId, longWsIdx); + } + } + else + { + retVal = CRYPTO_E_BUSY; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Spake2P_AdditionalInfoRead() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Spake2P_AdditionalInfoRead( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) infoPtr, + uint32 infoLength, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) readPos, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) dataPos, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) dataLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint32 length; + /* ----- Implementation ------------------------------------------------- */ + *dataLength = 0u; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + + /* [DataLength 4-Byte | Data X-Byte] */ + if ((infoLength >= (*readPos + CRYPTO_30_LIBCV_SIZEOF_UINT32)) && !Crypto_30_LibCv_IsUint32Overflow(*readPos, CRYPTO_30_LIBCV_SIZEOF_UINT32)) + { + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&length, &infoPtr[*readPos]); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + *readPos += CRYPTO_30_LIBCV_SIZEOF_UINT32; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + + if ((infoLength >= (*readPos + length)) && !Crypto_30_LibCv_IsUint32Overflow(*readPos, length)) + { + *dataLength = length; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + *dataPos = *readPos; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + *readPos += length; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_Spake2P_AdditionalInfoRead() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_AdditionalInfo() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_AdditionalInfo( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) infoPtr, + uint32 infoLength, + Std_ReturnType infoElementRetVal) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, localRetVal; + eslt_ErrorCode eslRet; + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) aPtr = NULL_PTR; + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) bPtr = NULL_PTR; + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) aadPtr = NULL_PTR; + uint32 aLength, bLength, aadLength, readPos, dataPos; + /* ----- Implementation ------------------------------------------------- */ + + readPos = 0u; + dataPos = 0u; + if (infoElementRetVal == E_OK) + { + /* Read info-a */ + localRetVal = Crypto_30_LibCv_Local_Spake2P_AdditionalInfoRead(infoPtr, infoLength, &readPos, &dataPos, &aLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + if (aLength != 0u) + { + aPtr = (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&infoPtr[dataPos]; + } + + /* Read info-b */ + localRetVal |= Crypto_30_LibCv_Local_Spake2P_AdditionalInfoRead(infoPtr, infoLength, &readPos, &dataPos, &bLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + if (bLength != 0u) + { + bPtr = (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&infoPtr[dataPos]; + } + + /* Read aad */ + localRetVal |= Crypto_30_LibCv_Local_Spake2P_AdditionalInfoRead(infoPtr, infoLength, &readPos, &dataPos, &aadLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + if (aadLength != 0u) + { + aadPtr = (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&infoPtr[dataPos]; + } + + if (localRetVal == E_OK) + { + eslRet = esl_setAdditionalInformationSPAKE2P(ws, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + aPtr, (eslt_Length)aLength, + bPtr, (eslt_Length)bLength, + aadPtr, (eslt_Length)aadLength); + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_AdditionalInfo() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Secret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Secret( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, localRetVal; + eslt_ErrorCode eslRet; + eslt_Length halfLength, secretLength, verificationLength; + Crypto_30_LibCv_SizeOfKeyStorageType elementIndex; + uint32 elementLength; + uint8 secret[ESL_SIZEOF_SHA256_DIGEST /2u]; + uint8 verification[CRYPTO_30_LIBCV_CMACAES_MAC_SIZE]; + + /* ----- Implementation ------------------------------------------------- */ + secretLength = ESL_SIZEOF_SHA256_DIGEST /2u; + verificationLength = CRYPTO_30_LIBCV_CMACAES_MAC_SIZE; + + /* Set Additional Info (only if required) */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_ADDITIONAL_INFO, &elementIndex, &elementLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRetVal != CRYPTO_E_KEY_NOT_AVAILABLE) + { + localRetVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_AdditionalInfo(ws, Crypto_30_LibCv_GetAddrKeyStorage(elementIndex), elementLength, localRetVal); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR */ + } + else + { + localRetVal = E_OK; + } + + /* Calc Secret */ + if (((Crypto_30_LibCv_Math_Mul2((uint32)CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PUBLIC)) == partnerPublicValueLength) && (localRetVal == E_OK)) + { + halfLength = (eslt_Length)Crypto_30_LibCv_Math_Div2(partnerPublicValueLength); + { + eslRet = esl_calcSharedSecretSPAKE2P(ws, + partnerPublicValuePtr, &partnerPublicValuePtr[halfLength], halfLength, + secret, &secretLength, + verification, &verificationLength); /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Store calculated sharedSecret */ + localRetVal = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_SHAREDVALUE, secret, (uint32)secretLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + localRetVal |= Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_CUSTOM_VERIFICATION, verification, (uint32)verificationLength);/* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + if (localRetVal == E_OK) + { + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + + /* delete buffer content from RAM */ + Crypto_30_LibCv_ClearData(secret, ESL_SIZEOF_SHA256_DIGEST /2u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + Crypto_30_LibCv_ClearData(verification, CRYPTO_30_LIBCV_CMACAES_MAC_SIZE); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Secret() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Verification() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Verification( + P2VAR(eslt_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws, + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerConfirmationValuePtr, + uint32 partnerConfirmationValueLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, localRetVal = E_NOT_OK; + eslt_ErrorCode eslRet; + uint8 verification; + + /* ----- Implementation ------------------------------------------------- */ + verification = CRYPTO_E_VER_NOT_OK; + + /* Check verification */ + eslRet = esl_confirmKeySPAKE2P(ws, partnerConfirmationValuePtr, (eslt_Length)partnerConfirmationValueLength); /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (eslRet == ESL_ERC_INCORRECT_MAC) + { + localRetVal = E_OK; + } + else if (eslRet == ESL_ERC_NO_ERROR) + { + localRetVal = E_OK; + verification = CRYPTO_E_VER_OK; + } + else + { + /* Nothing to do */ + } + + /* Store verification result */ + if (Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_CUSTOM_VERIFICATION_RESULT, &verification, 1u) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + retVal = localRetVal; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Verification() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) ws; + Crypto_30_LibCv_SizeOfLongTermWsLockType longWsIdx; + + /* ----- Implementation ------------------------------------------------- */ + /* Check if long term workspace is locked */ + if (Crypto_30_LibCv_Local_LongWsIsLock(cryptoKeyId, &longWsIdx) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + + ws = (P2VAR(Crypto_30_LibCv_WorkSpaceSPAKE2P, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&Crypto_30_LibCv_GetLongTermWs(longWsIdx).wsSPAKE2P; + if (ws->state == CRYPTO_30_LIBCV_SPAKE2P_STATE_CALC_PUBVAL) + { + /* Calc Secret */ + ws->state = CRYPTO_30_LIBCV_SPAKE2P_STATE_CALC_SECRET; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Secret(&ws->wsSpake, cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR */ + } + else /* (ws->state == CRYPTO_30_LIBCV_SPAKE2P_STATE_CALC_SECRET) */ + { + /* Verification */ + ws->state = CRYPTO_30_LIBCV_SPAKE2P_STATE_VERIFICATION; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P_Verification(&ws->wsSpake, cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_GLOBAL_DATA_PTR */ + } + + /* release lock if request is finished */ + if (retVal != E_OK) + { + Crypto_30_LibCv_ClearData(ws, sizeof(Crypto_30_LibCv_WorkSpaceSPAKE2P)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + Crypto_30_LibCv_Local_LongWsLockRelease(cryptoKeyId, longWsIdx); + } + else if (ws->state == CRYPTO_30_LIBCV_SPAKE2P_STATE_VERIFICATION) + { + Crypto_30_LibCv_Local_LongWsLockRelease(cryptoKeyId, longWsIdx); + } + else + { + /* keep workspace locked, request is continued */ + } + + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P() */ + +#endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SPAKE2_PLUS_CIPHERSUITE_8_ENABLED == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X25519_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr) +{ + /* #10 Init Workspace */ + eslt_WorkSpaceX25519 localWsX25519; + + /* #20 Call Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519_With_Ws */ + return Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519_With_Ws(cryptoKeyId, publicValuePtr, publicValueLengthPtr, &localWsX25519); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519_With_Ws( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2VAR(eslt_WorkSpaceX25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsX25519) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint8 publicKeyBuf[ESL_SIZEOF_X25519_PUBLIC_KEY]; + eslt_Length publicKeyLength = ESL_SIZEOF_X25519_PUBLIC_KEY; + eslt_ErrorCode eslRet; + Std_ReturnType retValKeyElementSetPrivateKey = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Std_ReturnType retValKeyElementSetPublicKey = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + + /* ----- Implementation ------------------------------------------------- */ + + /* #20 Init Workspace */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))&wsX25519->header, ESL_SIZEOF_WS_X25519, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_initECDH(wsX25519, ESL_Curve25519); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* #25 Calculate Keys */ + + if (esl_generateEphemeralKeyPairECDH(wsX25519, publicKeyBuf, &publicKeyLength) == ESL_ERC_NO_ERROR) /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS */ + { + /* #30 Store public and private key to key elements if calculation was successfully */ + retValKeyElementSetPrivateKey = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_PRIVKEY, (P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))(((actX25519Struct*)wsX25519->wsX25519)->privateKey), ESL_SIZEOF_X25519_PRIVATE_KEY); /* PRQA S 3305, 0310 */ /* MD_CRYPTO_30_LIBCV_3305_CRYPTOLIBRARY_CAST, MD_CRYPTO_30_LIBCV_0310_CRYPTOLIBRARY_CAST */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + retValKeyElementSetPublicKey = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_OWNPUBKEY, (P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))publicKeyBuf, ESL_SIZEOF_X25519_PUBLIC_KEY); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + if ((retValKeyElementSetPrivateKey == E_OK) && + (retValKeyElementSetPublicKey == E_OK)) + { + /* #35 Copy public key to output buffer and overwrite local copy if store key was successfully */ + /* [SWS_Crypto_00109] return public key */ + if (*publicValueLengthPtr >= ESL_SIZEOF_X25519_PUBLIC_KEY) + { + Crypto_30_LibCv_CopyData(publicValuePtr, publicKeyBuf, ESL_SIZEOF_X25519_PUBLIC_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_ARRAY_ACCESS_WITH_SIZE_CHECK */ + Crypto_30_LibCv_ClearData(publicKeyBuf, ESL_SIZEOF_X25519_PUBLIC_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_ARRAY_ACCESS_WITH_SIZE_CHECK */ + *publicValueLengthPtr = ESL_SIZEOF_X25519_PUBLIC_KEY; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_WITH_DET_CHECK */ + retVal = E_OK; + } + else + /* #40 If buffer is too small return with error */ + { + retVal = CRYPTO_E_SMALL_BUFFER; + } + } + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519_With_Ws() */ +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X25519_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr) +{ + /* #10 Init Workspace */ + eslt_WorkSpaceEdDH localWsX448; + + /* #20 Call Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448_With_Ws */ + return Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448_With_Ws(cryptoKeyId, publicValuePtr, publicValueLengthPtr, &localWsX448); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448_With_Ws( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2VAR(eslt_WorkSpaceEdDH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsX448) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint8 publicKeyBuf[ESL_SIZEOF_X448_PUBLIC_KEY]; + eslt_Length publicKeyLength = ESL_SIZEOF_X448_PUBLIC_KEY; + uint8 privateKeyBuf[ESL_SIZEOF_X448_PRIVATE_KEY]; + eslt_Length privateKeyLength = ESL_SIZEOF_X448_PRIVATE_KEY; + eslt_ErrorCode eslRet; + Std_ReturnType retValKeyElementSetPrivateKey = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Std_ReturnType retValKeyElementSetPublicKey = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + + /* ----- Implementation ------------------------------------------------- */ + + /* #20 Init Workspace */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))&wsX448->header, ESL_SIZEOF_WS_EDDH, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE_PARAMETER */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_initEdDH(wsX448, ESL_CURVE448); /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* #25 Calculate Keys */ + if (esl_generateEphemeralKeyPairEdDH(wsX448, publicKeyBuf, &publicKeyLength, privateKeyBuf, &privateKeyLength) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_PARAMETER_BUFFER */ + { + /* #30 Store public and private key to key elements if calculation was successful */ + retValKeyElementSetPrivateKey = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_PRIVKEY, (P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))privateKeyBuf, privateKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_WORKSPACE_MEMBER */ + retValKeyElementSetPublicKey = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_OWNPUBKEY, (P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))publicKeyBuf, publicKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + if ((retValKeyElementSetPrivateKey == E_OK) && + (retValKeyElementSetPublicKey == E_OK)) + { + /* #35 Copy public key to output buffer and overwrite local copy if store key was successfully */ + /* [SWS_Crypto_00109] return public key */ + if (*publicValueLengthPtr >= ESL_SIZEOF_X448_PUBLIC_KEY) + { + + Crypto_30_LibCv_CopyData(publicValuePtr, publicKeyBuf, ESL_SIZEOF_X448_PUBLIC_KEY); /* SBSW_CRYPTO_30_LIBCV_ARRAY_ACCESS_WITH_SIZE_CHECK */ + Crypto_30_LibCv_ClearData(publicKeyBuf, ESL_SIZEOF_X448_PUBLIC_KEY); /* SBSW_CRYPTO_30_LIBCV_ARRAY_ACCESS_WITH_SIZE_CHECK */ + Crypto_30_LibCv_ClearData(privateKeyBuf, ESL_SIZEOF_X448_PRIVATE_KEY); /* SBSW_CRYPTO_30_LIBCV_ARRAY_ACCESS_WITH_SIZE_CHECK */ + *publicValueLengthPtr = publicKeyLength; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_WITH_DET_CHECK */ + retVal = E_OK; + } + else + /* #40 If buffer is too small return with error */ + { + retVal = CRYPTO_E_SMALL_BUFFER; + } + } + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448_With_Ws() */ +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) speedUpExtPtr, + uint32 keySize) +{ + /* #10 Init Workspace */ + eslt_WorkSpaceEcP workspace; + + /* #20 Call Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic_With_Ws */ + return Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic_With_Ws(cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + publicValuePtr, + publicValueLengthPtr, + domainPtr, + domainExtPtr, + speedUpExtPtr, + keySize, + &workspace); +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* PRQA S 6050, 6060, 6080 9 */ /* MD_MSR_STCAL, MD_CRYPTO_30_LIBCV_STPAR, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic_With_Ws( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) speedUpExtPtr, + uint32 keySize, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint8 privKey[CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE]; + uint8 pubKey[Crypto_30_LibCv_Math_Mul2(CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE)]; + Std_ReturnType retValKeyElementSetPrivateKey = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Std_ReturnType retValKeyElementSetPublicKey = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + + /* ----- Implementation ------------------------------------------------- */ + if (keySize > CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE) + { + /* The requested key size exceeds the maximum ECC key size (CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE) */ + retVal = E_NOT_OK; + } + else + { + /* Calculate Keys */ + if (Crypto_30_LibCv_Local_Ecc_Calculate_With_Ws(pubKey, privKey, domainPtr, domainExtPtr, speedUpExtPtr, keySize, workspace) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + uint32 doubleKeySize = Crypto_30_LibCv_Math_Mul2(keySize); + + /* Store public and private key to key elements if calculation was successfully */ + retValKeyElementSetPublicKey = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_OWNPUBKEY, pubKey, doubleKeySize); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + retValKeyElementSetPrivateKey = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_PRIVKEY, privKey, keySize); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if ((retValKeyElementSetPrivateKey == E_OK) && + (retValKeyElementSetPublicKey == E_OK)) + { + /* Copy public key to output buffer and overwrite local copy if store key was successfully */ + /* [SWS_Crypto_00109] return public key */ + if (*publicValueLengthPtr >= doubleKeySize) + { + + Crypto_30_LibCv_CopyData(publicValuePtr, pubKey, doubleKeySize); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_ARRAY_ACCESS_WITH_SIZE_CHECK */ + + *publicValueLengthPtr = doubleKeySize; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_WITH_DET_CHECK */ + retVal = E_OK; + } + else + /* If buffer is too small return with error */ + { + retVal = CRYPTO_E_SMALL_BUFFER; + } + } + + /* delete buffer content from RAM */ + Crypto_30_LibCv_ClearData(privKey, keySize); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + Crypto_30_LibCv_ClearData(pubKey, doubleKeySize); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic_With_Ws() */ +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ECBD_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GetPartnerPub() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GetPartnerPub( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_KeyStorageIndexType, AUTOMATIC, AUTOMATIC) leftStorageIndexPtr, + P2VAR(Crypto_30_LibCv_KeyStorageIndexType, AUTOMATIC, AUTOMATIC) rightStorageIndexPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + const uint32 publicKeyLength = esl_getLengthOfEcPpublicKey_comp(EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + + /* predecessor = left neighbor / successor = right neighbor */ + uint32 keyLengthLeft = publicKeyLength * 2u; + uint32 keyLengthRight = publicKeyLength * 2u; + + /* ----- Implementation ------------------------------------------------- */ + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex( /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + cryptoKeyId, + CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY, + leftStorageIndexPtr, + (P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))&keyLengthLeft, + CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL) == E_OK) + { + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex( /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + cryptoKeyId, + CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY_2, + rightStorageIndexPtr, + (P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))&keyLengthRight, + CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL) == E_OK) + { + retVal = E_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GetPartnerPub() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair_Init() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ + +/* PRQA S 6080 3 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair_Init( + P2VAR(Crypto_30_LibCv_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr, + uint32 cryptoKeyId, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcSpeedUpExtPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + uint32 numberDevicesLength = CRYPTO_30_LIBCV_SIZEOF_ECDHE_BD_NUM_ECU_LENGTH; + uint32 deviceIdLength = CRYPTO_30_LIBCV_SIZEOF_ECDHE_BD_ECU_ID_LENGTH; + Crypto_30_LibCv_KeyStorageIndexType numberDevicesIndex; /* limited to uint8 */ + Crypto_30_LibCv_KeyStorageIndexType deviceIdIndex; /* limited to uint8 */ + Std_ReturnType retVal = E_NOT_OK, localRet; + uint8 numEcu, ecuId; + + /* ----- Implementation ------------------------------------------------- */ + /* Get and check ecu id and number. */ + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYEXCHANGE_NUM_ECU, /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + &numberDevicesIndex, + &numberDevicesLength, + CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYEXCHANGE_ECU_ID, /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + &deviceIdIndex, + &deviceIdLength, + CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); + if (localRet == E_OK) + { + numEcu = Crypto_30_LibCv_GetKeyStorage(numberDevicesIndex); + ecuId = Crypto_30_LibCv_GetKeyStorage(deviceIdIndex); + if ((ecuId <= numEcu) && (numEcu >= CRYPTO_30_LIBCV_ECDHE_BD_MIN_NUM_ECU)) + { + wsPtr->ecuNum = numEcu; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + /* Init Workspace */ + if (ESL_ERC_NO_ERROR == esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(wsPtr->wsBD.header), ESL_MAXSIZEOF_WS_ECBD, CRYPTO_30_LIBCV_WATCHDOG_PTR)) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + if (ESL_ERC_NO_ERROR == esl_initECBD(&wsPtr->wsBD, (eslt_Size32)numEcu, (eslt_Size32)ecuId, EcDomainPtr, EcDomainExtPtr, EcSpeedUpExtPtr)) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + { + retVal = E_OK; + } + } + } + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair_Init() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair( + P2VAR(Crypto_30_LibCv_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr, + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcSpeedUpExtPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Std_ReturnType localRet = E_NOT_OK; + uint8 privKey[CRYPTO_30_LIBCV_MAX_SIZEOF_PRIVATE_ECBD_KEY]; + uint8 publicKey[CRYPTO_30_LIBCV_MAX_SIZEOF_PUBLIC_ECBD_KEY_XY]; + + const uint32 privateKeyLength = esl_getLengthOfEcPprivateKey(EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + const uint32 publicKeyLength = esl_getLengthOfEcPpublicKey_comp(EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + const uint32 publicKeyLengthXY = publicKeyLength * 2u; + + /* ----- Implementation ------------------------------------------------- */ + /* Init workspace */ + if (Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair_Init(wsPtr, cryptoKeyId, EcDomainPtr, EcDomainExtPtr, EcSpeedUpExtPtr) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_OF_WORKSPACE */ + { + if (esl_generateEphemeralKeyPairECBD( /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + &wsPtr->wsBD, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))privKey, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))publicKey, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(publicKey[publicKeyLength])) + == ESL_ERC_NO_ERROR) + { + /* Store public and private key to key elements if calculation was successfully */ + localRet = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_OWNPUBKEY, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + publicKey, + publicKeyLengthXY); + localRet |= Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_PRIVKEY, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + privKey, + privateKeyLength); + } + + if (localRet == E_OK) + { + /* Copy public key to output buffer and overwrite local copy if store key was successfully */ + /* [SWS_Crypto_00109] return public key */ + if (*publicValueLengthPtr >= publicKeyLengthXY) + { + Crypto_30_LibCv_CopyData(publicValuePtr, publicKey, publicKeyLengthXY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + *publicValueLengthPtr = publicKeyLengthXY; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + + retVal = E_OK; + } + else + { + /* If buffer is too small return with error */ + retVal = CRYPTO_E_SMALL_BUFFER; + } + + /* delete buffer content from RAM */ + Crypto_30_LibCv_ClearData(privKey, privateKeyLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + Crypto_30_LibCv_ClearData(publicKey, publicKeyLengthXY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + } + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_CalcIntermediate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_CalcIntermediate( + P2VAR(eslt_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr, + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + /* predecessor = left neighbor / successor = right neighbor */ + Crypto_30_LibCv_KeyStorageIndexType leftPublicStorageIndex; + Crypto_30_LibCv_KeyStorageIndexType rightPublicStorageIndex; + + uint8 intermediateKey[CRYPTO_30_LIBCV_MAX_SIZEOF_PUBLIC_ECBD_KEY_XY]; + + const uint32 publicKeyLength = esl_getLengthOfEcPpublicKey_comp(EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + const uint32 publicKeyLengthXY = publicKeyLength * 2u; + + /* ----- Implementation ------------------------------------------------- */ + /* Load partner public values and generate intermediate value.*/ + if (Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GetPartnerPub(cryptoKeyId, &leftPublicStorageIndex, &rightPublicStorageIndex, EcDomainPtr) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + if (esl_calculateIntermediateECBD(wsPtr, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(leftPublicStorageIndex), + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&((Crypto_30_LibCv_GetAddrKeyStorage(leftPublicStorageIndex))[publicKeyLength]), + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(rightPublicStorageIndex), + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&((Crypto_30_LibCv_GetAddrKeyStorage(rightPublicStorageIndex))[publicKeyLength]), + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))intermediateKey, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(intermediateKey[publicKeyLength])) == ESL_ERC_NO_ERROR) + { + if (Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYEXCHANGE_INTERMEDIATE, intermediateKey, publicKeyLengthXY) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + /* Copy intermediate key to output buffer and overwrite local copy if store key was successfully */ + /* [SWS_Crypto_00109] return public key */ + if (*publicValueLengthPtr >= publicKeyLengthXY) + { + Crypto_30_LibCv_CopyData(publicValuePtr, intermediateKey, publicKeyLengthXY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + *publicValueLengthPtr = publicKeyLengthXY; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + + /* delete buffer content from RAM */ + Crypto_30_LibCv_ClearData(intermediateKey, publicKeyLengthXY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + retVal = E_OK; + } + else + { + /* If buffer is too small return with error */ + retVal = CRYPTO_E_SMALL_BUFFER; + } + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_CalcIntermediate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteWorkspace() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ + +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteWorkspace( + Crypto_30_LibCv_SizeOfLongTermWsLockType longWsIdx) +{ + /* Delete workspace. */ + Crypto_30_LibCv_ClearData(&Crypto_30_LibCv_GetLongTermWs(longWsIdx).wsECBD, sizeof(Crypto_30_LibCv_WorkSpaceECBD)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ +} /* Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteWorkspace() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteKeys() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ + +CRYPTO_30_LIBCV_LOCAL FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteKeys( + uint32 cryptoKeyId) +{ + uint8 keyBuf = 0; + /* key element delete need to be enabled */ + + /* Delete required key elements. */ + (void)Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_PRIVKEY, &keyBuf, 0u); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (void)Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_OWNPUBKEY, &keyBuf, 0u); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (void)Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY, &keyBuf, 0u); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (void)Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY_2, &keyBuf, 0u); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (void)Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_CUSTOM_KEYEXCHANGE_INTERMEDIATE, &keyBuf, 0u); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (void)Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_SHAREDVALUE, &keyBuf, 0u); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ +} /* Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteKeys() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcSpeedUpExtPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + P2VAR(Crypto_30_LibCv_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) localWsEcBPPtr = NULL_PTR; + Crypto_30_LibCv_SizeOfLongTermWsLockType longWsIdx; + + /* ----- Implementation ------------------------------------------------- */ + /* Try to lock workspace */ + if (Crypto_30_LibCv_Local_LongWsIsLock(cryptoKeyId, &longWsIdx) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + /* Workspace is already locked. */ + localWsEcBPPtr = (P2VAR(Crypto_30_LibCv_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&Crypto_30_LibCv_GetLongTermWs(longWsIdx).wsECBD; + } + else if (Crypto_30_LibCv_Local_LongWsLockGet(cryptoKeyId, &longWsIdx) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + /* New Locked Workspace. */ + localWsEcBPPtr = (P2VAR(Crypto_30_LibCv_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&Crypto_30_LibCv_GetLongTermWs(longWsIdx).wsECBD; + localWsEcBPPtr->state = CRYPTO_30_LIBCV_ECBD_STATE_CALC_PUBVAL; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + } + else + { + retVal = CRYPTO_E_BUSY; + } + + if (localWsEcBPPtr != NULL_PTR) + { + switch (localWsEcBPPtr->state) + { + /* Calculate own key pair */ + default: /* CRYPTO_30_LIBCV_ECBD_STATE_CALC_PUBVAL */ + { + /* reset state members */ + localWsEcBPPtr->ecuCount = 0u; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + localWsEcBPPtr->ecuNum = 0u; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + /* calculate private and public key */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_GenKeyPair(localWsEcBPPtr, + cryptoKeyId, publicValuePtr, publicValueLengthPtr, + EcDomainPtr, EcDomainExtPtr, EcSpeedUpExtPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + localWsEcBPPtr->state = CRYPTO_30_LIBCV_ECBD_STATE_CALC_INTERMEDIATE; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + break; + } + + /* Calculate intermediate value */ + case CRYPTO_30_LIBCV_ECBD_STATE_CALC_INTERMEDIATE: + { + /* calculate intermediate */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime_CalcIntermediate(&localWsEcBPPtr->wsBD, cryptoKeyId, publicValuePtr, publicValueLengthPtr, EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + localWsEcBPPtr->ecuCount = 1u; /* own intermediate value stored */ /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + localWsEcBPPtr->state = CRYPTO_30_LIBCV_ECBD_STATE_REC_INTERMEDIATE; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + break; + } + } + + /* delete working products if there was a failure */ + if (retVal != E_OK) + { + Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteWorkspace(longWsIdx); + Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteKeys(cryptoKeyId); + Crypto_30_LibCv_Local_LongWsLockRelease(cryptoKeyId, longWsIdx); + } + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchange_CheckDomainKeyLengths() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchange_CheckDomainKeyLengths( + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + const uint32 expectedPrivateKeyLength, + const uint32 expectedPublicKeyLength) +{ + Std_ReturnType retVal = E_NOT_OK; + + /* # Check domain key lengths */ + if (expectedPrivateKeyLength == esl_getLengthOfEcPprivateKey(EcDomainPtr)) /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + { + if (expectedPublicKeyLength == esl_getLengthOfEcPpublicKey_comp(EcDomainPtr)) /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchange_CheckDomainKeyLengths() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_CheckDomainKeyLengthsAndProcessCalc() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_CheckDomainKeyLengthsAndProcessCalc( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerIntermediateValuePtr, + uint32 partnerIntermediateValueLength, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + const uint32 expectedPrivateKeyLength, + const uint32 expectedPublicKeyLength) +{ + Std_ReturnType retVal = E_NOT_OK; + + /* # Check domain key lengths */ + if (Crypto_30_LibCv_Local_KeyExchange_CheckDomainKeyLengths(EcDomainPtr, expectedPrivateKeyLength, expectedPublicKeyLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + { + /* # Calculate shared secret according to ECBD */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime(cryptoKeyId, + partnerIntermediateValuePtr, partnerIntermediateValueLength, + EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_CheckDomainKeyLengthsAndProcessCalc() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_CheckDomainKeyLengthsAndProcessCalc() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_CheckDomainKeyLengthsAndProcessCalc( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcSpeedUpExtPtr, + const uint32 expectedPrivateKeyLength, + const uint32 expectedPublicKeyLength) +{ + Std_ReturnType retVal = E_NOT_OK; + + if (Crypto_30_LibCv_Local_KeyExchange_CheckDomainKeyLengths(EcDomainPtr, expectedPrivateKeyLength, expectedPublicKeyLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + { + /* # Calculate public value (Key pair of private and public) according to ECBD curve p224r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime(cryptoKeyId, publicValuePtr, publicValueLengthPtr, + EcDomainPtr, EcDomainExtPtr, EcSpeedUpExtPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_CheckDomainKeyLengthsAndProcessCalc() */ +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ECBD_ENABLED == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6030, 6050, 6080 4 */ /* MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyStorageType keaIndex; + uint32 keaLength = CRYPTO_30_LIBCV_KEY_EXCHANGE_SIZEOF_ALGORITHM; + + /* ----- Implementation ------------------------------------------------- */ + +# if ((CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) && (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON)) + uint32 partitionIdx = Crypto_30_LibCv_CurrentPartitionIdx(); + +# if (CRYPTO_30_LIBCV_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + if (partitionIdx >= Crypto_30_LibCv_GetSizeOfPartitionIdentifiers()) + { + retVal = E_NOT_OK; + } + else +# endif +# endif + { + +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + { +# if (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) + uint32 defaultRandomKey = Crypto_30_LibCv_GetDefaultRandomKeyOfPartitionInfo(partitionIdx); + + /* Lock read access for the DefaultRandomKey */ + if (Crypto_30_LibCv_Local_KeyReadLockGetNotProtected(defaultRandomKey) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +# endif + { + /* Lock write access for the CryptoKey */ + if (Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else + { + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); +# endif + + /* Read and check algorithm key element. */ + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_ALGORITHM, &keaIndex, &keaLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + { + + } + else + { + switch (Crypto_30_LibCv_GetKeyStorage(keaIndex)) + { +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X25519_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_X25519: + /* execute KEA x25519 / RFC 7748 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519(cryptoKeyId, publicValuePtr, publicValueLengthPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_X448: + /* execute KEA x25519 / RFC 7748 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448(cryptoKeyId, publicValuePtr, publicValueLengthPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_P224R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_P224R1: + /* execute KEA NIST/SECp244r1 */ + /* NISTp224r1 = SECp224r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic(cryptoKeyId, publicValuePtr, publicValueLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP224R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP224R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP224R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PRIVATE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP256R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP256R1: + /* execute KEA SECp256r1 / ANSI X9.63 */ + /* NISTp256r1 = ANSIp256r1 = SECp256r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic(cryptoKeyId, publicValuePtr, publicValueLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_ANSIP256R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_ANSIP256R1: + /* execute KEA ANSIp256r1 / ANSI X9.63 */ + /* NISTp256r1 = ANSIp256r1 = SECp256r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic(cryptoKeyId, publicValuePtr, publicValueLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP384R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP384R1: + /* execute KEA SECp384r1 */ + /* NISTp384r1 = SECp384r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic(cryptoKeyId, publicValuePtr, publicValueLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY_PRIVATE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP521R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP521R1: + /* execute KEA SECp521r1 */ + /* NISTp521r1 = SECp521r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic(cryptoKeyId, publicValuePtr, publicValueLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SPAKE2_PLUS_CIPHERSUITE_8_ENABLED == STD_ON) + /* execute KEA Spake2+ */ + case CRYPTO_30_LIBCV_KEY_EXCHANGE_SPAKE2_PLUS_CIPHERSUITE_8: + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P(cryptoKeyId, publicValuePtr, publicValueLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt, + CRYPTO_30_LIBCV_SPAKE2P_MODE_NORMAL); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + break; + case CRYPTO_30_LIBCV_KEY_EXCHANGE_SPAKE2_PLUS_CIPHERSUITE_8_1: + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P(cryptoKeyId, publicValuePtr, publicValueLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt, + CRYPTO_30_LIBCV_SPAKE2P_MODE_CHANGED_VERIFICATION); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_NISTP224R1_BD_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_NISTP224R1_BD: + /* execute KEA NISTp224r1 BD */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_CheckDomainKeyLengthsAndProcessCalc( + cryptoKeyId, publicValuePtr, publicValueLengthPtr, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + Crypto_30_LibCv_EccCurveNistSecP224R1Domain, /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR */ + Crypto_30_LibCv_EccCurveNistSecP224R1DomainExt, + Crypto_30_LibCv_EccCurveNistSecP224R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PRIVATE, + CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PUBLIC); + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_P256R1_BD_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_P256R1_BD: + /* execute KEA p256r1 BD */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_CheckDomainKeyLengthsAndProcessCalc( + cryptoKeyId, publicValuePtr, publicValueLengthPtr, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain, /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR */ + Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt, + Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PUBLIC); + break; +# endif + default: + /* invalid algorithm */ + break; + } + } + /* Release key write lock. */ +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected(cryptoKeyId); + } +# if (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) + Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected(defaultRandomKey); +# endif + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); +# endif + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcPubVal() */ +#endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X25519_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr) +{ + /* #10 Initialize workspace */ + eslt_WorkSpaceX25519 localWsX25519; + + /* #20 Call Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_With_Ws */ + return Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_With_Ws(cryptoKeyId, partnerPublicValuePtr, &localWsX25519); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_Calculate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_Calculate( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + P2VAR(eslt_WorkSpaceX25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsX25519) +{ + eslt_Length sharedSecretLength_eslt = ESL_SIZEOF_X25519_SHARED_SECRET; + uint8 sharedSecret[ESL_SIZEOF_X25519_SHARED_SECRET]; + + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet = ESL_ERC_ERROR; + + /* #30 generate secret by using public key from key element */ + eslRet = esl_generateSharedSecretECDH(wsX25519, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))partnerPublicValuePtr, sharedSecret, &sharedSecretLength_eslt); /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* #35 Store calculated sharedSecret */ + if (Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_SHAREDVALUE, sharedSecret, (uint32)sharedSecretLength_eslt) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + retVal = E_OK; + } + } + + /* #40 delete buffer content from RAM */ + Crypto_30_LibCv_ClearData(sharedSecret, ESL_SIZEOF_X25519_SHARED_SECRET); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_Calculate() */ +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_With_Ws( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + P2VAR(eslt_WorkSpaceX25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsX25519) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet = ESL_ERC_ERROR; + Crypto_30_LibCv_SizeOfKeyStorageType keyExchangePrivateKeyIndex; + uint32 keyExchangePrivateKeyLength = ESL_SIZEOF_X25519_PRIVATE_KEY; + + /* ----- Implementation ------------------------------------------------- */ + /* #20 Initialize workspace */ + /* initialize Ed25519 */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&wsX25519->header, ESL_SIZEOF_WS_X25519, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_initECDH(wsX25519, ESL_Curve25519); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* #25 Load private key */ + /* copy content of key elements to local buffers */ + Std_ReturnType localRetVal; + + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_PRIVKEY, &keyExchangePrivateKeyIndex, &keyExchangePrivateKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRetVal == E_OK) + { + /* import private key from key elements */ + if (esl_importStaticPrivateKeyECDH(wsX25519, Crypto_30_LibCv_GetAddrKeyStorage(keyExchangePrivateKeyIndex)) == ESL_ERC_NO_ERROR) /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS */ + { + /* #30 generate secret */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_Calculate(cryptoKeyId, partnerPublicValuePtr, wsX25519); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_KEY_PTR */ + } + } + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_With_Ws() */ +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X25519_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr) +{ + /* #10 Initialize workspace */ + eslt_WorkSpaceEdDH localWsX448; + + /* #20 Call Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448_With_Ws */ + return Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448_With_Ws(cryptoKeyId, partnerPublicValuePtr, &localWsX448); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448_With_Ws( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + P2VAR(eslt_WorkSpaceEdDH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsX448) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyStorageType keyExchangePrivateKeyIndex; + uint32 keyExchangePrivateKeyLength = ESL_SIZEOF_X448_PRIVATE_KEY; + uint32 sharedSecretLength = ESL_SIZEOF_X448_SHARED_SECRET; + uint8 sharedSecret[ESL_SIZEOF_X448_SHARED_SECRET]; + + /* ----- Implementation ------------------------------------------------- */ + Std_ReturnType localRetVal; + + /* #10 Load private key */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_PRIVKEY, &keyExchangePrivateKeyIndex, &keyExchangePrivateKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRetVal == E_OK) + { + /* #20 generate secret by using public key from key element */ + localRetVal = Crypto_30_LibCv_Local_Dispatch_EdDH_CalculateSharedSecret_With_Ws( /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER_AND_STACK_BUFFER */ + Crypto_30_LibCv_GetAddrKeyStorage(keyExchangePrivateKeyIndex), + keyExchangePrivateKeyLength, + partnerPublicValuePtr, + ESL_SIZEOF_X448_PUBLIC_KEY, + sharedSecret, + &sharedSecretLength, + wsX448 + ); + + if (localRetVal == E_OK) + { + /* #30 Store calculated sharedSecret */ + if (Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_SHAREDVALUE, sharedSecret, sharedSecretLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + retVal = E_OK; + } + } + + /* #40 Delete buffer content from RAM */ + Crypto_30_LibCv_ClearData(sharedSecret, ESL_SIZEOF_X448_KEY); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448_With_Ws() */ +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength, + uint32 keySize, + uint8 keaId) +{ + /* #10 Init workspace */ + eslt_WorkSpaceEcP workspace; + + /* #20 Call Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic_With_Ws */ + return Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic_With_Ws(cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + partnerPublicValuePtr, + partnerPublicValueLength, + keySize, + keaId, + &workspace); +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* PRQA S 6050, 6060, 6080 7 */ /* MD_MSR_STCAL, MD_CRYPTO_30_LIBCV_STPAR, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic_With_Ws( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength, + uint32 keySize, + uint8 keaId, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyStorageType keyExchangePrivateKeyIndex; + uint32 keyExchangePrivateKeyLength; + uint8 sharedSecret[Crypto_30_LibCv_Math_Mul2(CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE)] = { 0u }; + + /* ----- Implementation ------------------------------------------------- */ + + if (keySize > CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE) + { + /* The requested key size exceeds the maximum ECC key size (CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE) */ + /* return E_NOT_OK */ + } + /* Load private key */ + else if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex( + cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_PRIVKEY, + &keyExchangePrivateKeyIndex, &keyExchangePrivateKeyLength, + CRYPTO_30_LIBCV_LENGTH_CHECK_NONE) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + { + /* return E_NOT_OK */ + } + else + { + /* generate secret by using public key from key element */ + if (Crypto_30_LibCv_Local_Dispatch_EcP_CalculateSharedSecret_With_Ws( + Crypto_30_LibCv_GetAddrKeyStorage(keyExchangePrivateKeyIndex), + keyExchangePrivateKeyLength, + partnerPublicValuePtr, partnerPublicValueLength, + sharedSecret, + keaId, workspace) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + { + /* Try to store calculated sharedSecret as X|Y coordinate */ + Std_ReturnType localRetVal = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_SHAREDVALUE, sharedSecret, Crypto_30_LibCv_Math_Mul2(keySize)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (localRetVal == E_OK) + { + retVal = E_OK; + } + else if (localRetVal == CRYPTO_E_KEY_SIZE_MISMATCH) + { + /* If not enough space in key element, store shared secret as x-coordinate only */ + if (Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_SHAREDVALUE, sharedSecret, keySize) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + retVal = E_OK; + } + else + { + /* retVal remains E_NOT_OK */ + } + } + else + { + /* retVal remains E_NOT_OK */ + } + } + + /* delete buffer content from RAM */ + Crypto_30_LibCv_ClearData(sharedSecret, (uint32)Crypto_30_LibCv_Math_Mul2(keySize)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic_With_Ws() */ +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ECBD_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_First() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_First( + P2VAR(Crypto_30_LibCv_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + + if (esl_initSharedSecretECBD(&wsPtr->wsBD) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_First() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Update() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Update( + P2VAR(eslt_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerIntermediateValuePtr, + uint32 partnerIntermediateValueLength, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + const uint32 publicKeyLength = esl_getLengthOfEcPpublicKey_comp(EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + const uint32 publicKeyLengthXY = publicKeyLength * 2u; + + /* ----- Implementation ------------------------------------------------- */ + /* add intermediate value for ecu x */ + /* EcuId (1Byte) | Partner intermediate value X | Partner intermediate value Y */ + if (partnerIntermediateValueLength == (CRYPTO_30_LIBCV_SIZEOF_ECDHE_BD_ECU_ID_LENGTH + publicKeyLengthXY)) + { + if (esl_updateSharedSecretECBD(wsPtr, /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ + (eslt_Size32)partnerIntermediateValuePtr[0], + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&partnerIntermediateValuePtr[CRYPTO_30_LIBCV_SIZEOF_ECDHE_BD_ECU_ID_LENGTH], + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&partnerIntermediateValuePtr[CRYPTO_30_LIBCV_SIZEOF_ECDHE_BD_ECU_ID_LENGTH + publicKeyLength]) + == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Update() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Finish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Finish( + P2VAR(eslt_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsPtr, + uint32 cryptoKeyId, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + uint8 sharedSecret[CRYPTO_30_LIBCV_MAX_SIZEOF_PUBLIC_ECBD_KEY_XY]; + Std_ReturnType retVal = E_NOT_OK; + const uint32 publicKeyLength = esl_getLengthOfEcPpublicKey_comp(EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + const uint32 publicKeyLengthXY = publicKeyLength * 2u; + + /* ----- Implementation ------------------------------------------------- */ + /* #10 Retrieve shared secret */ + if (esl_retrieveSharedSecretECBD(wsPtr, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))sharedSecret, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&sharedSecret[publicKeyLength]) + == ESL_ERC_NO_ERROR) + { + /* #20 Try to store calculated sharedSecret as X|Y coordinate */ + Std_ReturnType localRetVal = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_SHAREDVALUE, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + sharedSecret, publicKeyLengthXY); + if (localRetVal == E_OK) + { + retVal = E_OK; + } + else if (localRetVal == CRYPTO_E_KEY_SIZE_MISMATCH) + { + /* #30 If not enough space in key element, store sharedSecret as x-coordinate only */ + if (Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_SHAREDVALUE, sharedSecret, publicKeyLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + retVal = E_OK; + } + + } + else + { + /* retVal remains E_NOT_OK */ + } + } + + /* #40 Delete sharedSecret buffer content from RAM */ + Crypto_30_LibCv_ClearData(sharedSecret, publicKeyLengthXY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Finish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerIntermediateValuePtr, + uint32 partnerIntermediateValueLength, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + + Std_ReturnType retVal = E_NOT_OK; + + P2VAR(Crypto_30_LibCv_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) localWsEcBPPtr; + Crypto_30_LibCv_SizeOfLongTermWsLockType longWsIdx; + boolean release = FALSE; + + /* ----- Implementation ------------------------------------------------- */ + /* Is workspace already locked for key */ + if (Crypto_30_LibCv_Local_LongWsIsLock(cryptoKeyId, &longWsIdx) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + localWsEcBPPtr = (P2VAR(Crypto_30_LibCv_WorkSpaceECBD, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&Crypto_30_LibCv_GetLongTermWs(longWsIdx).wsECBD; + + if (localWsEcBPPtr->state == CRYPTO_30_LIBCV_ECBD_STATE_REC_INTERMEDIATE) + { + /* distinguish mode dependent on the number of received ecus */ + /* own value already set by Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_Prime */ + if (localWsEcBPPtr->ecuCount == 1u) + { + /* init workspace at first call */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_First(localWsEcBPPtr); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ + } + else + { + retVal = E_OK; + } + + if (retVal == E_OK) + { + /* Update always workspace with new intermediate value.*/ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Update(&localWsEcBPPtr->wsBD, partnerIntermediateValuePtr, partnerIntermediateValueLength, EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ + } + + if ((retVal == E_OK) && (localWsEcBPPtr->ecuCount == (localWsEcBPPtr->ecuNum - 1u))) /* own value not required */ + { + /* Finalize and generate shared secret, if it is the last intermediate value. */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime_Finish(&localWsEcBPPtr->wsBD, cryptoKeyId, EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ + Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteWorkspace(longWsIdx); + release = TRUE; + } + } + if (retVal != E_OK) + { + /* delete workspace if there was an error */ + Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteWorkspace(longWsIdx); + Crypto_30_LibCv_Local_KeyExchange_BD_Prime_DeleteKeys(cryptoKeyId); + release = TRUE; + } + else + { + /* update for added value */ + localWsEcBPPtr->ecuCount = (uint8)(localWsEcBPPtr->ecuCount + 1u); /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + } + + if (release) + { + /* unlock if necessary */ + Crypto_30_LibCv_Local_LongWsLockRelease(cryptoKeyId, longWsIdx); + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_Prime() */ +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ECBD_ENABLED == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6030, 6050, 6080 4 */ /* MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyStorageType keaIndex; + uint32 keaLength = CRYPTO_30_LIBCV_KEY_EXCHANGE_SIZEOF_ALGORITHM; + + /* Lock write access for the CryptoKey */ +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + if (Crypto_30_LibCv_Local_KeyWriteLockGet(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +# endif + { + /* ----- Implementation ------------------------------------------------- */ + /* Read and check algorithm key element. */ + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_ALGORITHM, &keaIndex, &keaLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + { + + } + else + { + switch (Crypto_30_LibCv_GetKeyStorage(keaIndex)) + { +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X25519_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_X25519: + /* execute KEA x25519 / RFC 7748 */ + if (partnerPublicValueLength == ESL_SIZEOF_X25519_PUBLIC_KEY) + { + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519(cryptoKeyId, partnerPublicValuePtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_X448: + /* execute KEA x25519 / RFC 7748 */ + if (partnerPublicValueLength == ESL_SIZEOF_X448_PUBLIC_KEY) + { + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448(cryptoKeyId, partnerPublicValuePtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_P224R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_P224R1: + /* execute KEA NIST/SEC P224R1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic(cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength, CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PRIVATE, CRYPTO_30_LIBCV_ECDHE_224_ID); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_ANSIP256R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_ANSIP256R1: + /* execute KEA ANSIp256r1 / ANSI X9.63 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic(cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength, CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE, CRYPTO_30_LIBCV_ECDHE_256_ID); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP256R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP256R1: + /* execute KEA SECp256r1 / ANSI X9.63 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic(cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength, CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE, CRYPTO_30_LIBCV_ECDHE_256_ID); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP384R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP384R1: + /* execute KEA SECp384r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic(cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength, CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY_PRIVATE, CRYPTO_30_LIBCV_ECDHE_384_ID); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP521R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP521R1: + /* execute KEA SECp521r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic(cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength, CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE, CRYPTO_30_LIBCV_ECDHE_521_ID); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SPAKE2_PLUS_CIPHERSUITE_8_ENABLED == STD_ON) + /* execute KEA Spake2+ */ + case CRYPTO_30_LIBCV_KEY_EXCHANGE_SPAKE2_PLUS_CIPHERSUITE_8: + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P(cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; + case CRYPTO_30_LIBCV_KEY_EXCHANGE_SPAKE2_PLUS_CIPHERSUITE_8_1: + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P(cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_NISTP224R1_BD_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_NISTP224R1_BD: + /* execute KEA NISTp224r1 BD */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_CheckDomainKeyLengthsAndProcessCalc( + cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + Crypto_30_LibCv_EccCurveNistSecP224R1Domain,/* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR */ + CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PRIVATE, + CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PUBLIC); + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_P256R1_BD_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_EXCHANGE_P256R1_BD: + /* execute KEA p256r1 BD */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_CheckDomainKeyLengthsAndProcessCalc( + cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain,/* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR */ + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PUBLIC); + break; +# endif + default: + /* invalid algorithm */ + break; + } + } +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* Release key write lock. */ + Crypto_30_LibCv_Local_KeyWriteLockRelease(cryptoKeyId); +# endif + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyExchangeCalcSecret() */ +#endif /* CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON */ + +#if ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Dispatch_EdDH_CalculateSharedSecret_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Dispatch_EdDH_CalculateSharedSecret_With_Ws( + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + uint32 partnerPubKeyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) sharedSecretPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) sharedSecretLengthPtr, + P2VAR(eslt_WorkSpaceEdDH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet = ESL_ERC_ERROR; + eslt_Length localSharedSecretLength = (eslt_Length)*sharedSecretLengthPtr; + + /* ----- Implementation ------------------------------------------------- */ + /* #10 Initialize workspace */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_SIZEOF_WS_EDDH, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE_PARAMETER */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_initEdDH(workspace, ESL_CURVE448); /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* #20 Load private key */ + if (esl_importStaticPrivateKeyEdDH(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + privateKeyPtr, + (eslt_Length)privateKeyLength) == ESL_ERC_NO_ERROR) + { + /* #30 generate secret by using public key */ + eslRet = esl_generateSharedSecretEdDH( /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER_AND_PARAMETER_BUFFER */ + workspace, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))partnerPubKeyPtr, + (eslt_Length)partnerPubKeyLength, + sharedSecretPtr, + &localSharedSecretLength); + + if (eslRet == ESL_ERC_NO_ERROR) + { + *sharedSecretLengthPtr = localSharedSecretLength; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + } + } + } + return retVal; +} /* Crypto_30_LibCv_Local_Dispatch_EdDH_CalculateSharedSecret_With_Ws() */ +#endif /* ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Dispatch_EcP_CalculateSharedSecret_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Dispatch_EcP_CalculateSharedSecret_With_Ws( + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + uint32 partnerPubKeyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) sharedSecretPtr, + uint8 keaId, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + Std_ReturnType retValDispatching = E_NOT_OK; + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr = Crypto_30_LibCv_EccCurveEmptyDomain; + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr = Crypto_30_LibCv_EccCurveEmptyDomain; + + switch (keaId) + { +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_P224R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_ECDHE_224_ID: + /* NISTp224r1 = SECp224r1 */ + EcDomainPtr = Crypto_30_LibCv_EccCurveNistSecP224R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistSecP224R1DomainExt; + retValDispatching = E_OK; + break; +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_P224R1_DOMAIN == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_P256R1_DOMAIN == STD_ON) + case CRYPTO_30_LIBCV_ECDHE_256_ID: + /* NISTp256r1 = ANSIp256r1 = SECp256r1 */ + EcDomainPtr = Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt; + retValDispatching = E_OK; + break; +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_P256R1_DOMAIN == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP384R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_ECDHE_384_ID: + /* NISTp384r1 = SECp384r1 */ + EcDomainPtr = Crypto_30_LibCv_EccCurveNistSecP384R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt; + retValDispatching = E_OK; + break; +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP384R1_ENABLED == STD_ON) */ + +# if ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP521R1_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) + case CRYPTO_30_LIBCV_ECDHE_521_ID: + /* NISTp521r1 = SECp521r1 */ + EcDomainPtr = Crypto_30_LibCv_EccCurveNistSecP521R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt; + retValDispatching = E_OK; + break; +# endif /* ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP521R1_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) */ + + default: + /* not reachable, misra only. */ + break; + } + + /* ----- Implementation ----------------------------------------------- */ + if (retValDispatching == E_OK) + { + /* Check key sizes */ + if (privateKeyLength != esl_getLengthOfEcPprivateKey(EcDomainPtr)) /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + { + /* invalid private key length */ + } + else if (partnerPubKeyLength != (uint32)Crypto_30_LibCv_Math_Mul2((uint32)esl_getLengthOfEcPpublicKey_comp(EcDomainPtr))) /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + { + /* invalid partner public key length */ + } + else + { + retVal = Crypto_30_LibCv_Local_EcP_CalculateSharedSecret_With_Ws(privateKeyPtr, + partnerPubKeyPtr, + sharedSecretPtr, + workspace, + EcDomainPtr, + EcDomainExtPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_Dispatch_EcP_CalculateSharedSecret_With_Ws() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_EcP_CalculateSharedSecret_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ + /* PRQA S 6060 8 */ /* MD_CRYPTO_30_LIBCV_STPAR_VSECPRIM */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_EcP_CalculateSharedSecret_With_Ws( + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) sharedSecretPtr, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* #1 init EcP workspaces */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_ECP, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_initGenerateSharedSecretDHEcP_prim((P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, EcDomainPtr, EcDomainExtPtr); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + + /* #2 Verify that the key is valid. */ + /* This is already implemented in actECPointIsOnCurve and is part of esl_generateSharedSecretDHEcP_prim */ + + /* #3 generate shared Secret */ + eslRet = esl_generateSharedSecretDHEcP_prim((P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, /* PRQA S 0310, 0311 */ /* MD_CRYPTO_30_LIBCV_0310, MD_CRYPTO_30_LIBCV_0311 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))privateKeyPtr, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&partnerPubKeyPtr[0], (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&partnerPubKeyPtr[esl_getLengthOfEcPprivateKey(EcDomainPtr)], /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&sharedSecretPtr[0], (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&sharedSecretPtr[esl_getLengthOfEcPsecret_comp(EcDomainPtr)]); /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR_AS_PARAM */ + if (eslRet == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_EcP_CalculateSharedSecret_With_Ws() */ +#endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON)) */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +#if (CRYPTO_30_LIBCV_KEYX25519SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyX25519Secret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyX25519Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceX25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyX25519Secret(Crypto_30_LibCv_GetKeyX25519SecretIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength == ESL_SIZEOF_X25519_PUBLIC_KEY) + { + /* Calculate shared secret according to X25519 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X25519_With_Ws(job->cryptoKeyId, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyX25519Secret() */ +#endif /* Crypto_30_LibCv_Dispatch_KeyX448Secret() */ + +#if (CRYPTO_30_LIBCV_KEYX448SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyX448Secret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyX448Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceEdDH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyX448Secret(Crypto_30_LibCv_GetKeyX448SecretIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength == ESL_SIZEOF_X448_PUBLIC_KEY) + { + /* Calculate shared secret according to X448 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_X448_With_Ws(job->cryptoKeyId, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, workspace); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_GLOBAL_WORKSPACE_AND_CONST_BUFFER */ + } + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyX448Secret() */ +#endif /* Crypto_30_LibCv_Dispatch_KeyX448Secret() */ + +#if (CRYPTO_30_LIBCV_KEYP224R1SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP224R1Secret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP224R1Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyP224R1Secret(Crypto_30_LibCv_GetKeyP224R1SecretIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate shared secret according to ECC curve p224r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic_With_Ws(job->cryptoKeyId, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PRIVATE, CRYPTO_30_LIBCV_ECDHE_224_ID, workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP224R1Secret() */ +#endif /* CRYPTO_30_LIBCV_KEYP224R1SECRET == STD_ON */ + +#if (CRYPTO_30_LIBCV_KEYP256R1SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP256R1Secret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP256R1Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyP256R1Secret(Crypto_30_LibCv_GetKeyP256R1SecretIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate shared secret according to ECC curve p256r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic_With_Ws(job->cryptoKeyId, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE, CRYPTO_30_LIBCV_ECDHE_256_ID, workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP256R1Secret() */ +#endif /* CRYPTO_30_LIBCV_KEYP256R1SECRET */ + +#if (CRYPTO_30_LIBCV_KEYP384R1SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP384R1Secret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP384R1Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyP384R1Secret(Crypto_30_LibCv_GetKeyP384R1SecretIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate shared secret according to ECC curve p384r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic_With_Ws(job->cryptoKeyId, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY_PRIVATE, CRYPTO_30_LIBCV_ECDHE_384_ID, workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP384R1Secret() */ +#endif /* CRYPTO_30_LIBCV_KEYP384R1SECRET */ + +#if (CRYPTO_30_LIBCV_KEYP521R1SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP521R1Secret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP521R1Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyP521R1Secret(Crypto_30_LibCv_GetKeyP521R1SecretIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate shared secret according to ECC curve p521r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Generic_With_Ws(job->cryptoKeyId, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE, CRYPTO_30_LIBCV_ECDHE_521_ID, workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP521R1Secret() */ +#endif /* CRYPTO_30_LIBCV_KEYP521R1SECRET */ + +#if (CRYPTO_30_LIBCV_KEYSPAKE2PSECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySpake2PSecret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySpake2PSecret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT_CONST(objectId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate shared secret according to Spake2+ */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_Spake2P(job->cryptoKeyId, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeySpake2PSecret() */ +#endif /* CRYPTO_30_LIBCV_KEYSPAKE2PSECRET */ + +#if (CRYPTO_30_LIBCV_KEYP224R1BDSECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP224R1BDSecret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP224R1BDSecret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT_CONST(objectId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Check domain key lengths */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_CheckDomainKeyLengthsAndProcessCalc( + job->cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + Crypto_30_LibCv_EccCurveNistSecP224R1Domain, /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR */ + CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PRIVATE, + CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PUBLIC); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP224R1BDSecret() */ +#endif /* CRYPTO_30_LIBCV_KEYP224R1BDSECRET */ + +#if (CRYPTO_30_LIBCV_KEYP256R1BDSECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP256R1BDSecret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP256R1BDSecret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT_CONST(objectId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Check domain key lengths */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret_BD_CheckDomainKeyLengthsAndProcessCalc( + job->cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain, /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR */ + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PUBLIC); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP256R1BDSecret() */ +#endif /* CRYPTO_30_LIBCV_KEYP256R1BDSECRET */ + +#if (CRYPTO_30_LIBCV_KEYX25519PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyX25519PubVal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyX25519PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceX25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyX25519PubVal(Crypto_30_LibCv_GetKeyX25519PubValIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate public value (Key pair of private and public) according to X25519 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X25519_With_Ws( job->cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + workspace); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyX25519PubVal() */ +#endif /* CRYPTO_30_LIBCV_KEYX25519PUBVAL */ + +#if (CRYPTO_30_LIBCV_KEYX448PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyX448PubVal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyX448PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceEdDH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyX448PubVal(Crypto_30_LibCv_GetKeyX448PubValIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate public value (Key pair of private and public) according to X448 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_X448_With_Ws(job->cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_GLOBAL_WORKSPACE_AND_JOB_BUFFER */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + workspace); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyX448PubVal() */ +#endif /* CRYPTO_30_LIBCV_KEYX448PUBVAL */ + +#if (CRYPTO_30_LIBCV_KEYP224R1PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP224R1PubVal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP224R1PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyP224R1PubVal(Crypto_30_LibCv_GetKeyP224R1PubValIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate public value (Key pair of private and public) according to ECC curve p224r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic_With_Ws(job->cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP224R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP224R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP224R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PRIVATE, + workspace); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP224R1PubVal() */ +#endif /* CRYPTO_30_LIBCV_KEYP224R1PUBVAL */ + +#if (CRYPTO_30_LIBCV_KEYP256R1PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP256R1PubVal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP256R1PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyP256R1PubVal(Crypto_30_LibCv_GetKeyP256R1PubValIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate public value (Key pair of private and public) according to ECC curve p256r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic_With_Ws(job->cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE, + workspace); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP256R1PubVal() */ +#endif /* CRYPTO_30_LIBCV_KEYP256R1PUBVAL */ + +#if (CRYPTO_30_LIBCV_KEYP384R1PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP384R1PubVal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP384R1PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyP384R1PubVal(Crypto_30_LibCv_GetKeyP384R1PubValIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate public value (Key pair of private and public) according to ECC curve p384r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic_With_Ws(job->cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY_PRIVATE, + workspace); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP384R1PubVal() */ +#endif /* CRYPTO_30_LIBCV_KEYP384R1PUBVAL */ + +#if (CRYPTO_30_LIBCV_KEYP224R1BDPUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP224R1BDPubVal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP224R1BDPubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT_CONST(objectId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate public value (Key pair of private and public) according to ECBD curve p224r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_CheckDomainKeyLengthsAndProcessCalc( + job->cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + Crypto_30_LibCv_EccCurveNistSecP224R1Domain, /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR */ + Crypto_30_LibCv_EccCurveNistSecP224R1DomainExt, + Crypto_30_LibCv_EccCurveNistSecP224R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PRIVATE, + CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PUBLIC); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP224R1BDPubVal() */ +#endif /* CRYPTO_30_LIBCV_KEYP224R1BDPUBVAL */ + +#if (CRYPTO_30_LIBCV_KEYP256R1BDPUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP256R1BDPubVal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP256R1BDPubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT_CONST(objectId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate public value (Key pair of private and public) according to ECBD curve p256r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_BD_CheckDomainKeyLengthsAndProcessCalc( + job->cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain, /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR */ + Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt, + Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PUBLIC); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP256R1BDPubVal() */ +#endif /* CRYPTO_30_LIBCV_KEYP256R1BDPUBVAL */ + +#if (CRYPTO_30_LIBCV_KEYP521R1PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP521R1PubVal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP521R1PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyP521R1PubVal(Crypto_30_LibCv_GetKeyP521R1PubValIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + /* Calculate public value (Key pair of private and public) according to ECC curve p521r1 */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Generic_With_Ws(job->cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE, + workspace); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyP521R1PubVal() */ +#endif /* CRYPTO_30_LIBCV_KEYP521R1PUBVAL */ + +#if (CRYPTO_30_LIBCV_KEYSPAKE2PPUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySpake2PPubVal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySpake2PPubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT_CONST(objectId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + /* nothing to do. */ + retVal = E_OK; + break; + + case CRYPTO_OPERATIONMODE_FINISH: + { + uint8 spakeMode = (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode == CRYPTO_ALGOMODE_NOT_SET) ? (uint8) CRYPTO_30_LIBCV_SPAKE2P_MODE_NORMAL : (uint8) CRYPTO_30_LIBCV_SPAKE2P_MODE_CHANGED_VERIFICATION; + + /* Calculate public value according to Spake2+ */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal_Spake2P(job->cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt, + spakeMode); + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* unsupported mode */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeySpake2PPubVal() */ +#endif /* CRYPTO_30_LIBCV_KEYSPAKE2PPUBVAL */ + +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeyExchange.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyExchange.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyExchange.h new file mode 100644 index 0000000..6bca183 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyExchange.h @@ -0,0 +1,663 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeyExchange.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for Key Exchange Services. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#ifndef CRYPTO_30_LIBCV_KEYEXCHANGE_H +# define CRYPTO_30_LIBCV_KEYEXCHANGE_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_SIZEOF_ALGORITHM (1u) + + /* ECDHE */ +# define CRYPTO_30_LIBCV_ECDHE_224_ID (0u) +# define CRYPTO_30_LIBCV_ECDHE_256_ID (1u) +# define CRYPTO_30_LIBCV_ECDHE_384_ID (2u) +# define CRYPTO_30_LIBCV_ECDHE_521_ID (3u) + + /* ECBD max key size */ +# if(CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_P256R1_BD_ENABLED == STD_ON) +# define CRYPTO_30_LIBCV_MAX_SIZEOF_PRIVATE_ECBD_KEY (CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE) +# define CRYPTO_30_LIBCV_MAX_SIZEOF_PUBLIC_ECBD_KEY (CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PUBLIC) +# define CRYPTO_30_LIBCV_MAX_SIZEOF_PUBLIC_ECBD_KEY_XY (CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PUBLIC_XY) +# elif(CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_NISTP224R1_BD_ENABLED == STD_ON) +# define CRYPTO_30_LIBCV_MAX_SIZEOF_PRIVATE_ECBD_KEY (CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PRIVATE) +# define CRYPTO_30_LIBCV_MAX_SIZEOF_PUBLIC_ECBD_KEY (CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PUBLIC) +# define CRYPTO_30_LIBCV_MAX_SIZEOF_PUBLIC_ECBD_KEY_XY (CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PUBLIC_XY) +# endif + + /* Key Exchange ECBD */ +# if ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_NISTP224R1_BD_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_P256R1_BD_ENABLED == STD_ON)) +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_ECBD_ENABLED STD_ON +# else +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_ECBD_ENABLED STD_OFF +# endif + + /* Key Exchange Generic */ +# if ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_P224R1_ENABLED == STD_ON) \ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_ANSIP256R1_ENABLED == STD_ON) \ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP256R1_ENABLED == STD_ON) \ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP384R1_ENABLED == STD_ON) \ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP521R1_ENABLED == STD_ON)) +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED STD_ON +# else +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED STD_OFF +# endif + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_KEYX25519SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyX25519Secret() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyX25519Secret job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyX25519Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYX25519SECRET */ + +# if (CRYPTO_30_LIBCV_KEYX448SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyX448Secret() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyX448Secret job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyX448Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYX448SECRET */ + +# if (CRYPTO_30_LIBCV_KEYP224R1SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP224R1Secret() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyP224R1Secret job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP224R1Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP224R1SECRET */ + +# if (CRYPTO_30_LIBCV_KEYP256R1SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP256R1Secret() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyP256R1Secret job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP256R1Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP256R1SECRET */ + +# if (CRYPTO_30_LIBCV_KEYP384R1SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP384R1Secret() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyP384R1Secret job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP384R1Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP384R1SECRET */ + +# if (CRYPTO_30_LIBCV_KEYP521R1SECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP521R1Secret() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyP521R1Secret job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP521R1Secret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP521R1SECRET */ + +# if (CRYPTO_30_LIBCV_KEYSPAKE2PSECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySpake2PSecret() + *********************************************************************************************************************/ +/*! \brief Dispatches the Key Spake2+ Secret job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_Spake2+ + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySpake2PSecret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYSPAKE2PSECRET */ + +# if (CRYPTO_30_LIBCV_KEYP224R1BDSECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP224R1BDSecret() + *********************************************************************************************************************/ +/*! \brief Dispatches the Key P224R1 BD Secret job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_ECBD + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP224R1BDSecret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP224R1BDSECRET */ + +# if (CRYPTO_30_LIBCV_KEYP256R1BDSECRET == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP256R1BDSecret() + *********************************************************************************************************************/ +/*! \brief Dispatches the Key P256R1 BD Secret job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_ECBD + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP256R1BDSecret( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP256R1BDSECRET */ + +# if (CRYPTO_30_LIBCV_KEYX25519PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyX25519PubVal() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyX25519PubVal job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyX25519PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYX25519PUBVAL */ + +# if (CRYPTO_30_LIBCV_KEYX448PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyX448PubVal() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyX448PubVal job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyX448PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYX448PUBVAL */ + +# if (CRYPTO_30_LIBCV_KEYP224R1PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP224R1PubVal() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyP224R1PubVal job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP224R1PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP224R1PUBVAL */ + +# if (CRYPTO_30_LIBCV_KEYP256R1PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP256R1PubVal() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyP256R1PubVal job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP256R1PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP256R1PUBVAL */ + +# if (CRYPTO_30_LIBCV_KEYP384R1PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP384R1PubVal() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyP384R1PubVal job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP384R1PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP384R1PUBVAL */ + +# if (CRYPTO_30_LIBCV_KEYP224R1BDPUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP224R1BDPubVal() + *********************************************************************************************************************/ +/*! \brief Dispatches the Key P224R1 BD PubVal job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_ECBD + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP224R1BDPubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP224R1BDPUBVAL */ + +# if (CRYPTO_30_LIBCV_KEYP256R1BDPUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP256R1BDPubVal() + *********************************************************************************************************************/ +/*! \brief Dispatches the Key P256R1 BD PubVal job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_ECBD + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP256R1BDPubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP256R1BDPUBVAL */ + +# if (CRYPTO_30_LIBCV_KEYP521R1PUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyP521R1PubVal() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeyP521R1PubVal job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyP521R1PubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYP521R1PUBVAL */ + +# if (CRYPTO_30_LIBCV_KEYSPAKE2PPUBVAL == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySpake2PPubVal() + *********************************************************************************************************************/ +/*! \brief Dispatches the Key Spake2+ PubVal job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_Spake2+ + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySpake2PPubVal( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYSPAKE2PPUBVAL */ + +# if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcPubVal() + *********************************************************************************************************************/ +/*! \brief Dispatches the public value calculation. + * \details Dispatches the public value calculation dependent on the given algorithm. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid crypto key. + * publicValuePtr has to be a valid pointer. + * publicValueLengthPtr has to be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcPubVal( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyExchangeCalcSecret() + *********************************************************************************************************************/ +/*! \brief Dispatch the shared secret calculation. + * \details Dispatch the shared secret calculation depending on the given algorithm. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \param[in] partnerPublicValueLength Holds the length of th partner public value. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId has to be a valid crypto key. + * partnerPublicValuePtr has to be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyExchangeCalcSecret( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); +# endif /* (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) */ + +# if ((CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Dispatch_EcP_CalculateSharedSecret_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculate shared secret + * \details Calculate shared secret for ECDHE Prime for the given values. + * \param[in] privateKeyPtr Pointer to the private key array. + * \param[in] privateKeyLength Length of the private key array. + * \param[in] partnerPubKeyPtr Pointer to the partner public key array. + * \param[in] partnerPubKeyLength Length of the partner public key array. + * \param[out] sharedSecretPtr Pointer to the shared secret. + * \param[in] keaId Key exchange algorithm identifier. + * \param[in,out] workspace Contains workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre privateKeyPtr has to be a valid pointer with the length privateKeyLength. + * partnerPubKeyPtr has to be a valid pointer with the length partnerPubKeyLength. + * sharedSecretPtr has to be a valid pointer with the length 2*esl_getLengthOfEcPsecret_comp(EcDomainPtr). + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Dispatch_EcP_CalculateSharedSecret_With_Ws( + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + uint32 partnerPubKeyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) sharedSecretPtr, + uint8 keaId, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +# endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_GENERIC_ENABLED == STD_ON)) */ + +# if ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Dispatch_EdDH_CalculateSharedSecret_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret + * \details Calculates the shared secret key for the key exchange with the key material of the key identified + * by the cryptoKeyId and the partner public key. The shared secret key is stored + * as a key element in the same key. The write access right for the destination key element + * must be less than or equal to WA_INTERNAL_COPY. + * \param[in] privateKeyPtr Holds the private key which shall be used for the key exchange + * protocol. + * \param[in] privateKeyLength The length of the private key which shall be used for the key exchange + * protocol. + * \param[in] partnerPubKeyPtr Holds the partner public key which shall be used for the key exchange + * protocol. + * \param[in] partnerPubKeyLength The length of the partner public key which shall be used for the key exchange + * protocol. + * \param[out] sharedSecretPtr Pointer to the memory location where the calculated shared secret should be stored. + * \param[in,out] sharedSecretLengthPtr Pointer to the memory location where the number of available bytes for the + * shared secret is stored. The memory location will be overwritten by the actual + * stored length of the shared secret. + * \param[in,out] workspace Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Dispatch_EdDH_CalculateSharedSecret_With_Ws( + P2CONST(uint8, AUTOMATIC, AUTOMATIC) privateKeyPtr, + uint32 privateKeyLength, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) partnerPubKeyPtr, + uint32 partnerPubKeyLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) sharedSecretPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) sharedSecretLengthPtr, + P2VAR(eslt_WorkSpaceEdDH, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); +# endif /* ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_X448_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) */ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_KEYEXCHANGE_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeyExchange.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyGenerate.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyGenerate.c new file mode 100644 index 0000000..1a0a13c --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyGenerate.c @@ -0,0 +1,1156 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeyGenerate.c + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Implementation of Key Generate Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_KEYGENERATE_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +#include "Crypto_30_LibCv.h" +#include "Crypto_30_LibCv_Services.h" +#include "Crypto_30_LibCv_KeyGenerate.h" +#include "Crypto_30_LibCv_Curve.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ +#define CRYPTO_30_LIBCV_KEY_GENERATE_SIZEOF_ALGORITHM (1u) + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_DispatchKga() + *********************************************************************************************************************/ +/*! \brief Dispatches the key generation without checking key availability and access. + * \details Dispatches the key value generation dependent on the given algorithm. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key generation + * \param[in] kgaIndex Index in the key storage where the element which holds the kga identifier + * is stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId has to be a valid crypto key. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_DispatchKga(uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyStorageType kgaIndex); +#endif /* (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SYMMETRIC_GENERIC_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_Symmetric() + *********************************************************************************************************************/ +/*! \brief Generation of the symmetric key values + * \details Generates the symmetric key values and stores the key in the memory location pointed to by the key + * value pointer. The write access right for the destination key element must be less than or equal + * to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key generation. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre cryptoKeyId has to be a valid crypto key. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_Symmetric(uint32 cryptoKeyId); +#endif /* CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SYMMETRIC_GENERIC_ENABLED == STD_ON */ + +#if ((CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ANSI_NIST_SEC_P256R1_ENABLED == STD_ON) || \ + (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P384R1_ENABLED == STD_ON) || \ + (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P521R1_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic() + *********************************************************************************************************************/ +/*! \brief Key value generation + * \details Generates the key value for the key generate and stores the key in the memory location pointed + * by the key value pointer. The write access right for the destination key element must be less + * or equal than WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key generation + * \param[in] domainPtr Pointer to domain parameter structure + * \param[in] domainExtPtr Pointer to domain parameter extension structure + * \param[in] speedUpExtPtr Pointer to precomputation structure + * \param[in] keySize Contains the length of the key element in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre cryptoKeyId has to be a valid crypto key. + * all pointers need to be valid. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic( + uint32 cryptoKeyId, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) speedUpExtPtr, + uint32 keySize); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic_With_Ws() + *********************************************************************************************************************/ +/*! \brief Generation of the key value + * \details Generates the key value and stores the public key in the memory location pointed to by the public + * value pointer. The write access right for the destination key element must be less or equal + * than WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key generation + * \param[in] domainPtr Pointer to domain parameter structure + * \param[in] domainExtPtr Pointer to domain parameter extension structure + * \param[in] speedUpExtPtr Pointer to precomputation structure + * \param[in] keySize Contains the length of the key element in bytes. + * \param[in,out] workspace Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre cryptoKeyId has to be a valid crypto key. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic_With_Ws( + uint32 cryptoKeyId, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) speedUpExtPtr, + uint32 keySize, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); +#endif /* ((CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ANSI_NIST_SEC_P256R1_ENABLED == STD_ON) || \ + (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P384R1_ENABLED == STD_ON) || \ + (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P521R1_ENABLED == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ED25519_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_Ed25519() + *********************************************************************************************************************/ +/*! \brief Key value generation + * \details Generates the key values for the Ed25519 key generate algorithm by passing a suitable workspace to + * Crypto_30_LibCv_Local_KeyGenerate_Ed25519_With_Ws and stores the keys in the memory location + * pointed to by the key value pointer. The write access right for the destination key elements must + * be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key generation + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre cryptoKeyId has to be a valid crypto key. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_Ed25519( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_Ed25519_With_Ws() + *********************************************************************************************************************/ +/*! \brief Generation of the key values + * \details Generates the key values according to Ed25519 key generation algorithm and stores the keys in the + * memory location pointed to by the key value pointer. The write access right for the destination + * key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key generation + * \param[in,out] workspace Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre cryptoKeyId has to be a valid crypto key. + * workspace has to be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_Ed25519_With_Ws( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Ed25519_Calculate_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculate Ed25519 key pair + * \details Calculates the private and public Ed25519 key pair. + * \param[in,out] workspace Contains the workspace. + * \param[out] privateValuePtr Contains the pointer to the data where the private value shall be stored. + * \param[in,out] privateValueLengthPtr Contains the pointer to the data where the private length value shall be stored. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Contains the pointer to the data where the public length value shall be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Ed25519_Calculate_With_Ws( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) privateValuePtr, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) privateValueLengthPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr); +#endif /* CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ED25519_ENABLED */ + +#if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SM2P256V1_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1() + *********************************************************************************************************************/ +/*! \brief Key value generation + * \details Generates the key values for the SM2P256V1 key generate algorithm by passing a suitable workspace to + * Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1_With_Ws and stores the keys in the memory location + * pointed to by the key value pointer. The write access right for the destination key elements must + * be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key generation + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre cryptoKeyId has to be a valid crypto key. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1_With_Ws() + *********************************************************************************************************************/ +/*! \brief Generation of the key values + * \details Generates the key values according to SM2P256V1 key generation algorithm and stores the keys in the + * memory location pointed to by the key value pointer. The write access right for the destination + * key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key generation + * \param[in,out] workspace Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre cryptoKeyId has to be a valid crypto key. + * workspace has to be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1_With_Ws( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Sm2P256V1_Calculate_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculate SM2P256V1 key pair + * \details Calculates the private and public SM2P256V1 key pair. + * \param[in,out] workspace Contains the workspace. + * \param[out] privateKey Contains the pointer to the data where the private value shall be stored. + * \param[in,out] privateLength Contains the pointer to the data where the private length value shall be stored. + * \param[out] publicKeyX Contains the pointer to the data where the public x value shall be stored. + * \param[in,out] publicLengthX Contains the pointer to the data where the public x length value shall be stored. + * \param[out] publicKeyY Contains the pointer to the data where the public y value shall be stored. + * \param[in,out] publicLengthY Contains the pointer to the data where the public y length value shall be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Sm2P256V1_Calculate_With_Ws( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) privateKey, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) privateLength, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicKeyX, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicLengthX, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicKeyY, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicLengthY); +#endif /* CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SM2P256V1_ENABLED */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SYMMETRIC_GENERIC_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_Symmetric() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_Symmetric(uint32 cryptoKeyId) +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_ErrorCode getBytesRetVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint32 kgkLength; + uint8 keyBuffer[CRYPTO_30_LIBCV_KEY_GENERATE_MAX_LENGTH]; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex; + + /* ----- Implementation ------------------------------------------------- */ + + /* #10 Search Key Element */ + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, CRYPTO_KE_KEYGENERATE_KEY, &elementIndex) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + kgkLength = Crypto_30_LibCv_GetLengthOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndex)); + + /* #20 Check key length */ + if (kgkLength <= CRYPTO_30_LIBCV_KEY_GENERATE_MAX_LENGTH) + { + /* #30 Generate random values */ + getBytesRetVal = esl_getBytesRNG((eslt_Length)kgkLength, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))keyBuffer); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (getBytesRetVal == E_OK) + { + /* #40 Set random values to the key element */ + retVal = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYGENERATE_KEY, (P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))keyBuffer, kgkLength); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + Crypto_30_LibCv_ClearData(keyBuffer, kgkLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + } + else + { + retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyGenerate_Symmetric() */ +#endif /* CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SYMMETRIC_GENERIC_ENABLED == STD_ON */ + +#if ((CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ANSI_NIST_SEC_P256R1_ENABLED == STD_ON) || \ + (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P384R1_ENABLED == STD_ON) || \ + (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P521R1_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic( + uint32 cryptoKeyId, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) speedUpExtPtr, + uint32 keySize) +{ + /* #10 Init Workspace */ + eslt_WorkSpaceEcP workspace; + + /* #20 Call Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic_With_Ws */ + return Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic_With_Ws( + cryptoKeyId, + domainPtr, + domainExtPtr, + speedUpExtPtr, + keySize, + &workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ +} /* Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_MSR_STPAR */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic_With_Ws( + uint32 cryptoKeyId, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) speedUpExtPtr, + uint32 keySize, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint8 privKey[CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE] = { 0u }; + uint8 pubKey[Crypto_30_LibCv_Math_Mul2(CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE)] = { 0u }; + + /* ----- Implementation ------------------------------------------------- */ + if (keySize > CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE) + { + /* The requested key size exceeds the maximum ECC key size (CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE) */ + retVal = E_NOT_OK; + } + else + { + /* Calculate Keys */ + if (Crypto_30_LibCv_Local_Ecc_Calculate_With_Ws(pubKey, privKey, domainPtr, domainExtPtr, speedUpExtPtr, keySize, workspace) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + uint32 doubleKeySize = Crypto_30_LibCv_Math_Mul2(keySize); + + /* Store public and private key to key elements if calculation was successfully */ + retVal = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_OWNPUBKEY, pubKey, doubleKeySize); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (retVal == E_OK) + { + retVal = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYGENERATE_KEY, privKey, keySize); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + /* delete buffer content from RAM */ + Crypto_30_LibCv_ClearData(privKey, keySize); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + Crypto_30_LibCv_ClearData(pubKey, doubleKeySize); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic_With_Ws() */ +#endif /* ((CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ANSI_NIST_SEC_P256R1_ENABLED == STD_ON) || \ + (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P384R1_ENABLED == STD_ON) || \ + (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P521R1_ENABLED == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ED25519_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_Ed25519() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_Ed25519( + uint32 cryptoKeyId) +{ + /* #10 Init Workspace */ + eslt_WorkSpaceEd25519 workspace; + + /* #20 Call Crypto_30_LibCv_Local_KeyGenerate_Ed25519_With_Ws */ + return Crypto_30_LibCv_Local_KeyGenerate_Ed25519_With_Ws( + cryptoKeyId, + &workspace); /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS */ +} /* Crypto_30_LibCv_Local_KeyGenerate_Ed25519() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_Ed25519_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_Ed25519_With_Ws( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + uint8 privKey[ESL_SIZEOF_Ed25519_SECRET_KEY]; + uint8 pubKey[ESL_SIZEOF_Ed25519_PUBLIC_KEY]; + eslt_Length privKeyLength = ESL_SIZEOF_Ed25519_SECRET_KEY; + eslt_Length pubKeyLength = ESL_SIZEOF_Ed25519_PUBLIC_KEY; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + /* #10 Calculate Keys */ + if (Crypto_30_LibCv_Local_Ed25519_Calculate_With_Ws(workspace, + privKey, + &privKeyLength, + pubKey, + &pubKeyLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + { + /* #11 Store public and private key to key elements if calculation was successfully */ + retVal = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_OWNPUBKEY, pubKey, pubKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (retVal == E_OK) + { + retVal = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYGENERATE_KEY, privKey, privKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + /* #12 delete buffer content from RAM */ + Crypto_30_LibCv_ClearData(privKey, privKeyLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + Crypto_30_LibCv_ClearData(pubKey, pubKeyLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyGenerate_Ed25519_With_Ws() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Ed25519_Calculate_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Ed25519_Calculate_With_Ws( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) privateValuePtr, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) privateValueLengthPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* ----- Implementation ------------------------------------------------- */ + + /* #10 Init Workspace */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_SIZEOF_WS_Ed25519, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_initGenerateKeyPairEdDSA(workspace, ESL_Curve25519); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* #20 Calculate Keys */ + if (esl_generateKeyPairEdDSA(workspace, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))privateValuePtr, + privateValueLengthPtr, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))publicValuePtr, + publicValueLengthPtr) == ESL_ERC_NO_ERROR) /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS */ + { + retVal = E_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_Local_Ed25519_Calculate_With_Ws() */ + +#endif /* CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ED25519_ENABLED */ + +#if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SM2P256V1_ENABLED == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1( + uint32 cryptoKeyId) +{ + /* Init Workspace */ + eslt_WorkSpaceSM2 workspace; + + /* Call Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1_With_Ws */ + return Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1_With_Ws( + cryptoKeyId, + &workspace); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_STACK_WORKSPACE */ +} /* Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1_With_Ws( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + uint8 privKey[CRYPTO_30_LIBCV_SM2_SIZEOF_PRIVATE_KEY]; + uint8 pubKey[CRYPTO_30_LIBCV_SM2_SIZEOF_PUBLIC_KEY]; + eslt_Length privKeyLength = CRYPTO_30_LIBCV_SM2_SIZEOF_PRIVATE_KEY; + eslt_Length pubKeyLengthX = CRYPTO_30_LIBCV_SM2_SIZEOF_PUBLIC_KEY_HALF; + eslt_Length pubKeyLengthY = CRYPTO_30_LIBCV_SM2_SIZEOF_PUBLIC_KEY_HALF; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + /* Calculate Keys. */ + if (Crypto_30_LibCv_Local_Sm2P256V1_Calculate_With_Ws(workspace, + privKey, + &privKeyLength, + pubKey, + &pubKeyLengthX, + &pubKey[pubKeyLengthX], + &pubKeyLengthY) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_OF_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + uint32 pubKeyLength = (uint32)pubKeyLengthX + (uint32)pubKeyLengthX; + + /* Store public and private key to key elements if calculation was successfully. */ + retVal = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYEXCHANGE_OWNPUBKEY, pubKey, pubKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (retVal == E_OK) + { + retVal = Crypto_30_LibCv_Local_KeyElementSet(cryptoKeyId, CRYPTO_KE_KEYGENERATE_KEY, privKey, privKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + /* Delete buffer content from RAM. */ + Crypto_30_LibCv_ClearData(privKey, sizeof(privKey)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + Crypto_30_LibCv_ClearData(pubKey, sizeof(pubKey)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1_With_Ws() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Sm2P256V1_Calculate_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Sm2P256V1_Calculate_With_Ws( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) privateKey, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) privateLength, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicKeyX, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicLengthX, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicKeyY, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicLengthY) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* ----- Implementation ------------------------------------------------- */ + + /* Init Workspace */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_SIZEOF_WS_SM2, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Init SM2 algorithm */ + eslRet = esl_initGenerateKeyPairSM2_ECP(workspace, + Crypto_30_LibCv_EccCurveSm2P256v1Domain, + Crypto_30_LibCv_EccCurveSm2P256v1DomainExt, + Crypto_30_LibCv_EccCurveSm2P256v1SpeedUpExt); /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + /* Calculate Keys */ + if (esl_generateKeyPairSM2_ECP(workspace, + privateKey, privateLength, + publicKeyX, publicLengthX, + publicKeyY, publicLengthY) == ESL_ERC_NO_ERROR)/* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS */ + { + retVal = E_OK; + } + } + } + return retVal; +} /* Crypto_30_LibCv_Local_Sm2P256V1_Calculate_With_Ws() */ + +#endif /* CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SM2P256V1_ENABLED */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +#if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate(uint32 cryptoKeyId) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyStorageType kgaIndex; + uint32 kgaLength = CRYPTO_30_LIBCV_KEY_GENERATE_SIZEOF_ALGORITHM; + + /* ----- Implementation ------------------------------------------------- */ + +# if ((CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) && (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON)) + uint32 partitionIdx = Crypto_30_LibCv_CurrentPartitionIdx(); + +# if (CRYPTO_30_LIBCV_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + if (partitionIdx >= Crypto_30_LibCv_GetSizeOfPartitionIdentifiers()) + { + retVal = E_NOT_OK; + } + else +# endif +# endif + { +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + { +# if (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) + uint32 defaultRandomKey = Crypto_30_LibCv_GetDefaultRandomKeyOfPartitionInfo(partitionIdx); + + /* #5 Lock read access for the DefaultRandomKey */ + if (Crypto_30_LibCv_Local_KeyReadLockGetNotProtected(defaultRandomKey) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +# endif + { + /* #10 Lock write access for the CryptoKey */ + if (Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else + { + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); +# endif + + /* #20 Read and check algorithm key element */ + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_KEYGENERATE_ALGORITHM, &kgaIndex, &kgaLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* Fail to read necessary KeyElement */ + } + else + { + /* #30 Dispatch KGA */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_DispatchKga(cryptoKeyId, kgaIndex); + } + /* #40 Release key write lock */ +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected(cryptoKeyId); + } +# if (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) + Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected(defaultRandomKey); +# endif + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); +# endif + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyGenerate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate_DispatchKga() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate_DispatchKga(uint32 cryptoKeyId, Crypto_30_LibCv_SizeOfKeyStorageType kgaIndex) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + switch (Crypto_30_LibCv_GetKeyStorage(kgaIndex)) + { +# if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SYMMETRIC_GENERIC_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_GENERATE_SYMMETRIC: + /* #10 Execute KGA Symmetric */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_Symmetric(cryptoKeyId); + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ANSI_NIST_SEC_P256R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_GENERATE_P256R1: + /* #20 Execute KGA ANSI_NIST_P256R1 */ + /* NISTp256r1 = ANSIp256r1 = SECp256r1 */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic(cryptoKeyId, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P384R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_GENERATE_P384R1: + /* #30 Execute KGA NIST_SEC_P384R1 */ + /* NISTp384r1 = SECp384r1 */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic(cryptoKeyId, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY_PRIVATE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P521R1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_P521R1: + /* #40 Execute KGA NIST_SEC_P521R1 */ + /* NISTp521 = SECp521r1 */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic(cryptoKeyId, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ED25519_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ED25519: + /* #50 Execute KGA ED25519 */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_Ed25519(cryptoKeyId); + break; +# endif +# if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SM2P256V1_ENABLED == STD_ON) + case CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_SM2P256V1: + /* #60 Execute KGA SM2P256V1 */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1(cryptoKeyId); + break; +# endif + + default: + /* invalid algorithm */ + break; + } + + if (retVal != E_OK) + { + retVal = E_NOT_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyGenerate_DispatchKga() */ +#endif /* CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM == STD_ON */ + +#if ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_USING_KEY_GENERATE_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ANSI_NIST_SEC_P256R1_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P384R1_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P521R1_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Ecc_Calculate_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_MSR_STPAR */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Ecc_Calculate_With_Ws( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) privateValuePtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) speedUpExtPtr, + uint32 keySize, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + + /* ----- Implementation ------------------------------------------------- */ + + /* #10 Init Workspace */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workspace->header, ESL_MAXSIZEOF_WS_ECP, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_initGenerateKeyEcP_prim((P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, domainPtr, domainExtPtr, speedUpExtPtr); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE */ + } + + if (eslRet == ESL_ERC_NO_ERROR) + { + if (esl_getLengthOfEcPprivateKey(domainPtr) == keySize) /* SBSW_CRYPTO_30_LIBCV_ESL_CONST_WORKSPACE */ + { + if (esl_getLengthOfEcPpublicKey_comp(domainPtr) == keySize) /* SBSW_CRYPTO_30_LIBCV_ESL_CONST_WORKSPACE */ + { + /* #20 Calculate Keys */ + if (esl_generateKeyEcP_prim((P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))workspace, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))privateValuePtr, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))publicValuePtr, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(publicValuePtr[keySize])) == ESL_ERC_NO_ERROR) /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS */ + { + retVal = E_OK; + } + } + } + } + return retVal; +} /* Crypto_30_LibCv_Local_Ecc_Calculate_With_Ws() */ +#endif /* ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_USING_KEY_GENERATE_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ANSI_NIST_SEC_P256R1_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P384R1_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P521R1_ENABLED == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_KEYGENSYMGENERIC == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenSymGeneric() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenSymGeneric( uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* #10 Generate symmetric key */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_Symmetric(job->cryptoKeyId); + } + + CRYPTO_30_LIBCV_DUMMY_STATEMENT(objectId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyGenSymGeneric() */ +#endif /* CRYPTO_30_LIBCV_KEYGENSYMGENERIC == STD_ON */ + +#if (CRYPTO_30_LIBCV_KEYGENP256R1 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenP256R1() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenP256R1( uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyGenP256R1(Crypto_30_LibCv_GetKeyGenP256R1IdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* #20 Calculate public value (Key pair of private and public) according to ECC curve p256r1 */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic_With_Ws(job->cryptoKeyId, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE, + workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyGenP256R1() */ +#endif /* CRYPTO_30_LIBCV_KEYGENP256R1 == STD_ON */ + +#if (CRYPTO_30_LIBCV_KEYGENP384R1 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenP384R1() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenP384R1( uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyGenP384R1(Crypto_30_LibCv_GetKeyGenP384R1IdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* #10 Calculate public value (Key pair of private and public) according to ECC curve p384r1 */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic_With_Ws(job->cryptoKeyId, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP384R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY_PRIVATE, + workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyGenP384R1() */ +#endif /* CRYPTO_30_LIBCV_KEYGENP384R1 == STD_ON */ + +#if (CRYPTO_30_LIBCV_KEYGENP521R1 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenP521R1() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenP521R1(uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyGenP521R1(Crypto_30_LibCv_GetKeyGenP521R1IdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* #10 Calculate public value (Key pair of private and public) according to ECC curve p521r1 */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_ECC_Generic_With_Ws(job->cryptoKeyId, + (P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1Domain, + (P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt, + (P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_EccCurveNistSecP521R1SpeedUpExt, + CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE, + workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_WITH_ECC_CURVE_DATA */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyGenP521R1() */ +#endif /* CRYPTO_30_LIBCV_KEYGENP521R1 == STD_ON */ + +#if (CRYPTO_30_LIBCV_KEYGENED25519 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenEd25519() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenEd25519( uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyGenEd25519(Crypto_30_LibCv_GetKeyGenEd25519IdxOfObjectInfo(objectId)); + + /* #10 Calculate Key pair of private and public according to Ed25519 */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_Ed25519_With_Ws(job->cryptoKeyId, workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyGenEd25519() */ +#endif /* CRYPTO_30_LIBCV_KEYGENED25519 == STD_ON */ + +#if (CRYPTO_30_LIBCV_KEYGENSM2P256V1 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenSm2P256V1() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenSm2P256V1(uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyGenSm2P256V1(Crypto_30_LibCv_GetKeyGenSm2P256V1IdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* Calculate public value (Key pair of private and public) according to SM2 with curve Sm2P256v1 */ + retVal = Crypto_30_LibCv_Local_KeyGenerate_Sm2P256V1_With_Ws(job->cryptoKeyId, + workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_OF_WORKSPACE */ + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyGenSm2P256V1() */ +#endif /* CRYPTO_30_LIBCV_KEYGENSM2P256V1 == STD_ON */ + +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeyGenerate.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyGenerate.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyGenerate.h new file mode 100644 index 0000000..15d27e6 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyGenerate.h @@ -0,0 +1,297 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeyGenerate.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for Key Generate Services. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#ifndef CRYPTO_30_LIBCV_KEYGENERATE_H +# define CRYPTO_30_LIBCV_KEYGENERATE_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ +# if ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_P224R1_ENABLED == STD_ON) \ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_ANSIP256R1_ENABLED == STD_ON) \ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP256R1_ENABLED == STD_ON) \ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP384R1_ENABLED == STD_ON) \ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP521R1_ENABLED == STD_ON)) +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_USING_KEY_GENERATE_ENABLED STD_ON +# else +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_USING_KEY_GENERATE_ENABLED STD_OFF +# endif + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGenerate() + *********************************************************************************************************************/ +/*! \brief Checks key availability and access, then dispatches the key generation. + * \details Dispatches the key value generation dependent on the given algorithm. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key generation + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId has to be a valid crypto key. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGenerate(uint32 cryptoKeyId); +# endif /* (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEYGENSYMGENERIC == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenSymGeneric() + *********************************************************************************************************************/ +/*! \brief Dispatches the key generate symmetric Generic job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-265506 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenSymGeneric(uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYGENSYMGENERIC == STD_ON */ + +# if (CRYPTO_30_LIBCV_KEYGENP256R1 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenP256R1() + *********************************************************************************************************************/ +/*! \brief Dispatches the key generate P256R1 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-240342 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenP256R1(uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYGENP256R1 == STD_ON */ + +# if (CRYPTO_30_LIBCV_KEYGENP384R1 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenP384R1() + *********************************************************************************************************************/ +/*! \brief Dispatches the key generate P384R1 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-240342 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenP384R1(uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYGENP384R1 == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEYGENP521R1 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenP521R1() + *********************************************************************************************************************/ +/*! \brief Dispatches the key generate P521R1 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-240342 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenP521R1(uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYGENP521R1 == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEYGENSM2P256V1 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenSm2P256V1() + *********************************************************************************************************************/ +/*! \brief Dispatches the key generate Sm2P256V1 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-240342 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenSm2P256V1(uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYGENSM2P256V1 == STD_ON) */ + +# if (CRYPTO_30_LIBCV_KEYGENED25519 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyGenEd25519() + *********************************************************************************************************************/ +/*! \brief Dispatches the key generate ED25519 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-240342 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyGenEd25519(uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYGENED25519 == STD_ON) */ + +# if ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_USING_KEY_GENERATE_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ANSI_NIST_SEC_P256R1_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P384R1_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P521R1_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Ecc_Calculate_With_Ws() + *********************************************************************************************************************/ +/*! \brief Calculate Ecc + * \details Calculate Ecc for ECDHE for the given values. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * The publicValuePtr contains the x- and y-value pair. + * \param[out] privateValuePtr Contains the pointer to the data where the private value shall be stored. + * \param[in] domainPtr Pointer to domain parameter structure + * \param[in] domainExtPtr Pointer to domain parameter extension structure + * \param[in] speedUpExtPtr Pointer to precomputation structure + * \param[in] keySize Contains the length of the key element in bytes. + * \param[in,out] workspace Contains the workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre privateValuePtr has to be a valid pointer with keySize. + * publicValuePtr has to be a valid pointer with size 2*keySize. + * all pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Ecc_Calculate_With_Ws( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) privateValuePtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) domainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) speedUpExtPtr, + uint32 keySize, + P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +# endif /* ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_USING_KEY_GENERATE_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ANSI_NIST_SEC_P256R1_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P384R1_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P521R1_ENABLED == STD_ON)) */ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_GENERATE_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeyGenerate.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyManagement.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyManagement.c new file mode 100644 index 0000000..83c6326 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyManagement.c @@ -0,0 +1,8444 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeyManagement.c + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Implementation of the MICROSAR Crypto Driver (Crypto) + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ +#define CRYPTO_30_LIBCV_KEYMANAGEMENT_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Crypto_30_LibCv.h" +#include "Crypto_30_LibCv_Services.h" +#include "Crypto_30_LibCv_Curve.h" +#include "Crypto_30_LibCv_RandomSeed.h" +#include "Crypto_30_LibCv_KeyExchange.h" +#include "Crypto_30_LibCv_KeyGenerate.h" +#include "Crypto_30_LibCv_KeyDerive.h" +#include "Crypto_30_LibCv_KeySetValid.h" +#include "Crypto_30_LibCv_KeySetInvalid.h" +#include "Crypto_30_LibCv_InternalApi.h" + +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) +# include "NvM.h" +#endif + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ +#if !defined (CRYPTO_30_LIBCV_LOCAL) /* COV_CRYPTO_30_LIBCV_LOCAL_DEFINE */ +# define CRYPTO_30_LIBCV_LOCAL static +#endif + +#if !defined (CRYPTO_30_LIBCV_LOCAL_INLINE) /* COV_CRYPTO_30_LIBCV_LOCAL_DEFINE */ +# define CRYPTO_30_LIBCV_LOCAL_INLINE LOCAL_INLINE +#endif + +#define Crypto_30_LibCv_GetKeyElementWrittenLength(Index) ((uint32)(((uint32)Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageWrittenLengthStartIdxOfKeyElements((Index))) << 8) | (uint32)Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageWrittenLengthStartIdxOfKeyElements((Index))+1u))) +#define CRYPTO_30_LIBCV_EMPTY_KEY_LENGTH (0u) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_KEY (16u) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_UPDATE_CONSTANT (16u) +#define CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER (CRYPTO_30_LIBCV_SIZEOF_SHE_KEY+ CRYPTO_30_LIBCV_SIZEOF_SHE_UPDATE_CONSTANT) +#define CRYPTO_30_LIBCV_SIZEOF_ENC_BUFFER (CRYPTO_30_LIBCV_SIZEOF_SHE_KEY+ CRYPTO_30_LIBCV_SIZEOF_SHE_UPDATE_CONSTANT) + +#define CRYPTO_30_LIBCV_STARTINDEX_SHE_M1_UID (0u) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID (15u) +#define CRYPTO_30_LIBCV_STARTINDEX_SHE_M1_IDS (CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M1_IDS (1u) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M1 (CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID + CRYPTO_30_LIBCV_SIZEOF_SHE_M1_IDS) + +#define CRYPTO_30_LIBCV_STARTINDEX_SHE_M2 (CRYPTO_30_LIBCV_SIZEOF_SHE_M1) +#define CRYPTO_30_LIBCV_STARTINDEX_SHE_M2_COUNTER (CRYPTO_30_LIBCV_STARTINDEX_SHE_M2) +#define CRYPTO_30_LIBCV_MASK_SHE_M2_COUNTER (0xFFFFFFF0uL) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M2_COUNTER_BIT (28u) +#define CRYPTO_30_LIBCV_STARTINDEX_SHE_M2_KEYFLAG (CRYPTO_30_LIBCV_STARTINDEX_SHE_M2) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M2 (32u) + +#define CRYPTO_30_LIBCV_STARTINDEX_SHE_M3 (CRYPTO_30_LIBCV_STARTINDEX_SHE_M2 + CRYPTO_30_LIBCV_SIZEOF_SHE_M2) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M3 (16u) + +#define CRYPTO_30_LIBCV_STARTINDEX_SHE_M4 (CRYPTO_30_LIBCV_STARTINDEX_SHE_M3 + CRYPTO_30_LIBCV_SIZEOF_SHE_M3) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M4 (32u) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M4_COUNTER_FULL_BYTES (4u) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M4_ENC (16u) + +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M5 (16u) + +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M3 (CRYPTO_30_LIBCV_SIZEOF_SHE_M1 + CRYPTO_30_LIBCV_SIZEOF_SHE_M2 + CRYPTO_30_LIBCV_SIZEOF_SHE_M3) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M4_M5 (CRYPTO_30_LIBCV_SIZEOF_SHE_M4 + CRYPTO_30_LIBCV_SIZEOF_SHE_M5) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M5 (CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M3 + CRYPTO_30_LIBCV_SIZEOF_SHE_M4_M5) + +#define CRYPTO_30_LIBCV_SHE_M1_SECRET_KEY_ID (0u) +#define CRYPTO_30_LIBCV_SHE_M1_ECU_MASTER_KEY_ID (1u) +#define CRYPTO_30_LIBCV_SHE_M1_MAC_KEY_ID (2u) +#define CRYPTO_30_LIBCV_SHE_M1_MAC_ID (3u) +#define CRYPTO_30_LIBCV_SHE_M1_KEY_N_START_ID (4u) +#define CRYPTO_30_LIBCV_SHE_M1_KEY_N_END_ID (13u) +#define CRYPTO_30_LIBCV_SHE_M1_RAM_KEY_ID (14u) +#define CRYPTO_30_LIBCV_SHE_NUM_KEYS (25u) + +#define CRYPTO_30_LIBCV_SHE_TYPE_SECRET_KEY (0u) +#define CRYPTO_30_LIBCV_SHE_TYPE_MASTER_KEY (1u) +#define CRYPTO_30_LIBCV_SHE_TYPE_MAC_KEY (2u) +#define CRYPTO_30_LIBCV_SHE_TYPE_MAC (3u) +#define CRYPTO_30_LIBCV_SHE_TYPE_KEY_N (4u) +#define CRYPTO_30_LIBCV_SHE_TYPE_RAM_KEY (5u) +#define CRYPTO_30_LIBCV_SHE_NUM_KEY_TYPES (6u) + +#define CRYPTO_30_LIBCV_SHE_UID_WILDCARD_VALUE (0x00u) + +#define CRYPTO_30_LIBCV_SHE_PAGE0 (0u) +#define CRYPTO_30_LIBCV_SHE_PAGE1 (1u) + +#define CRYPTO_30_LIBCV_SIZEOF_SHE_CHALLENGE (16u) +#define CRYPTO_30_LIBCV_SIZEOF_CMAC (16u) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_STATUS (1u) +#define CRYPTO_30_LIBCV_SIZEOF_SHE_CMD_GET_ID_OUTPUT (CRYPTO_30_LIBCV_SIZEOF_SHE_STATUS + CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID + CRYPTO_30_LIBCV_SIZEOF_CMAC) + +#define CRYPTO_30_LIBCV_SHE_CLEARED_STATUS (0x00u) /* Cleared status */ +#define CRYPTO_30_LIBCV_SHE_STATUS_BUSY (0x01u) /* Whenever SHE is processing a command. */ +#define CRYPTO_30_LIBCV_SHE_STATUS_SECURE_BOOT (0x02u) /* If the secure booting is activated. */ +#define CRYPTO_30_LIBCV_SHE_STATUS_BOOT_INIT (0x04u) /* If the secure booting has been personalized during the boot sequence. */ +#define CRYPTO_30_LIBCV_SHE_STATUS_BOOT_FINISHED (0x08u) /* When the secure booting has been finished by calling either CMD_BOOT_FAILURE or CMD_BOOT_OK or if CMD_SECURE_BOOT failed in verifying BOOT_MAC. */ +#define CRYPTO_30_LIBCV_SHE_STATUS_BOOT_OK (0x10u) /* If the secure booting (CMD_SECURE_BOOT) succeeded. If CMD_BOOT_FAILURE is called the bit is erased. */ +#define CRYPTO_30_LIBCV_SHE_STATUS_RND_INIT (0x20u) /* If the random number generator has been initialized. */ +#define CRYPTO_30_LIBCV_SHE_STATUS_EXT_DEBUGGER (0x40u) /* If an external debugger is connected to the chip, i.e. it reflects the input for debugger activation. */ +#define CRYPTO_30_LIBCV_SHE_STATUS_INT_DEBUGGER (0x80u) /* If the internal debugging mechanisms of SHE are activated */ + +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +# define CRYPTO_30_LIBCV_SHE_FID_MASK_WRITE_PROTECTION (0x80u) +/* The FID for boot protection is only checked if the feature is enabled. + * Otherwise use 0x00 Mask to ignore boot protection. */ +# if (CRYPTO_30_LIBCV_KEYELEMENTSBOOTPROTECTIONIDXOFSHEPAGE == STD_ON) +# define CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION (0x40u) +# define CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION_INV (0xBFu) +# else +# define CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION (0x00u) +# endif +/* The FID for debugger protection is only checked if the feature is enabled. + * Otherwise use 0x00 Mask to ignore debugger protection. */ +# if (CRYPTO_30_LIBCV_KEYELEMENTSDEBUGGERPROTECTIONIDXOFSHEPAGE == STD_ON) +# define CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION (0x20u) +# define CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION_INV (0xDFu) +# else +# define CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION (0x00u) +# endif +# define CRYPTO_30_LIBCV_SHE_FID_MASK_KEY_USAGE (0x10u) +# define CRYPTO_30_LIBCV_SHE_FID_MASK_WILDCARD (0x08u) +# define CRYPTO_30_LIBCV_SHE_FID_MASK_CMAC_USAGE (0x04u) +# define CRYPTO_30_LIBCV_SHE_FID_MASK_DENIED (0x02u) +# define CRYPTO_30_LIBCV_SHE_FID_MASK_DEFAULT (0x00u) +# endif +#endif + +/* NvM Block Handling */ +/* State: + * 1Byte State: [ Bit7-3 not used | DataCopied | WriteRequested| DataChanged ] + */ +#define CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_DATA_CHANGE (0x01u) +#define CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_WRITE_REQUESTED (0x02u) +#define CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_WRITE_COPIED (0x04u) +#define CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_CLEAR_WRITE_COPIED (0xFBu) +#define CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_CLEAR_WRITE_REQUESTED (0xFDu) + +#define CRYPTO_30_LIBCV_NVBLOCK_STATE_IDLE (0x00u) +#define CRYPTO_30_LIBCV_NVBLOCK_STATE_WRITE_REQ_PENDING (CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_DATA_CHANGE) +#define CRYPTO_30_LIBCV_NVBLOCK_STATE_WRITE_REQ (CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_DATA_CHANGE|CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_WRITE_REQUESTED) +#define CRYPTO_30_LIBCV_NVBLOCK_STATE_COPY_DATA (CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_WRITE_COPIED) +#define CRYPTO_30_LIBCV_NVBLOCK_STATE_REQ_WHILE_PENDING (CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_WRITE_COPIED|CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_DATA_CHANGE) + +/* Nv Header Length and Position */ +#define CRYPTO_30_LIBCV_POS_NVBLOCK_VERSION (0u) +#define CRYPTO_30_LIBCV_SIZEOF_NVBLOCK_VERSION (1u) +#define CRYPTO_30_LIBCV_POS_NVBLOCK_FLAGS (CRYPTO_30_LIBCV_SIZEOF_NVBLOCK_VERSION) +#define CRYPTO_30_LIBCV_SIZEOF_NVBLOCK_FLAGS (1u) +#define CRYPTO_30_LIBCV_POS_NVBLOCK_CRC (CRYPTO_30_LIBCV_POS_NVBLOCK_FLAGS+CRYPTO_30_LIBCV_SIZEOF_NVBLOCK_FLAGS) +#define CRYPTO_30_LIBCV_SIZEOF_NVBLOCK_CRC (4u) +#define CRYPTO_30_LIBCV_SIZEOF_NVBLOCK_HEADER_CRC (CRYPTO_30_LIBCV_POS_NVBLOCK_CRC + CRYPTO_30_LIBCV_SIZEOF_NVBLOCK_CRC) + +/* Nv Version and Flags */ +#define CRYPTO_30_LIBCV_NVBLOCK_VERSION_0 (0u) +#define CRYPTO_30_LIBCV_NVBLOCK_FLAGS_0 (0u) + +/* Nvm Service Id for NvM_WriteBlock */ +#ifndef CRYPTO_30_LIBCV_NVM_WRITE_BLOCK /* COV_CRYPTO_30_LIBCV_COMPATIBILITY_DEFINE */ +# define CRYPTO_30_LIBCV_NVM_WRITE_BLOCK NVM_WRITE_BLOCK /* Service ID NvM_WriteBlock() */ +#endif +/* Nvm Service Id for NvM_WriteBlock */ +#ifndef CRYPTO_30_LIBCV_NVM_WRITE_ALL /* COV_CRYPTO_30_LIBCV_COMPATIBILITY_DEFINE */ +# define CRYPTO_30_LIBCV_NVM_WRITE_ALL NVM_WRITE_ALL /* Service ID NvM_WriteAll() */ +#endif + +/* KeyNvStatus */ +/* State: + * 1Byte State: [ Bit7-5 not used | WRITE_FAILED | KEY_COPIED | NV_WRITE_REQ | KEY_CHANGED | NV_SYNC ] + */ + /* Bit masks */ +#define CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_NV_SYNC (0x01u) +#define CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_KEY_CHANGED (0x02u) +#define CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_NV_WRITE_REQ (0x04u) +#define CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_KEY_COPIED (0x08u) +#define CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_WRITE_FAILED (0x10u) + +/* States */ +#define CRYPTO_30_LIBCV_KEY_NV_STATUS_NOT_NV (0x00u) +#define CRYPTO_30_LIBCV_KEY_NV_STATUS_NV_SYNC (CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_NV_SYNC) +#define CRYPTO_30_LIBCV_KEY_NV_STATUS_KEY_CHANGED (CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_KEY_CHANGED) +#define CRYPTO_30_LIBCV_KEY_NV_STATUS_NV_WRITE_REQ (CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_KEY_CHANGED|CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_NV_WRITE_REQ) +#define CRYPTO_30_LIBCV_KEY_NV_STATUS_KEY_COPIED (CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_KEY_COPIED) +#define CRYPTO_30_LIBCV_KEY_NV_STATUS_WRITE_FAILED (CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_KEY_CHANGED|CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_WRITE_FAILED) + + /********************************************************************************************************************** + * LOCAL FUNCTION MACROS + *********************************************************************************************************************/ + +/* SHE Key Update */ +#define Crypto_30_LibCv_She_M1_GetAuthId(value) ((uint8)((value) & 0x0Fu)) /* Mask authentication id */ +#define Crypto_30_LibCv_She_M1_GetId(value) ((uint8)((value) >> 4)) /* Mask update SHE id */ +#define Crypto_30_LibCv_She_M1_BuildIds(Id, AuthId) (((uint8)(((Id) << 4) & 0xF0u)) | ((uint8)((AuthId) & 0x0Fu)))/* Mask update SHE id */ +#define Crypto_30_LibCv_She_IsDebugCmd(cryptoKeyId, elementId) ((cryptoKeyId == Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate()) && (elementId == CRYPTO_KE_CUSTOM_SHE_DEBUG_CMD)) + +/* Convert Counter from M1 to Store Value */ +#define Crypto_30_LibCv_She_ConvertCounter(value) (((value) & CRYPTO_30_LIBCV_MASK_SHE_M2_COUNTER) >> 4) + +/* Get SHE Constant */ +#define Crypto_30_LibCv_She_GetPtrMacConst(indexOfSheKey) (Crypto_30_LibCv_GetAddrSheConstants(Crypto_30_LibCv_GetSheConstantsMacStartIdxOfShePage(Crypto_30_LibCv_GetShePageIdxOfSheKeys((indexOfSheKey))))) +#define Crypto_30_LibCv_She_GetPtrEncConst(indexOfSheKey) (Crypto_30_LibCv_GetAddrSheConstants(Crypto_30_LibCv_GetSheConstantsEncStartIdxOfShePage(Crypto_30_LibCv_GetShePageIdxOfSheKeys((indexOfSheKey))))) + +/* NvM Block Handling */ +#define Crypto_30_LibCv_GetNvBlockState(blockIdx) (Crypto_30_LibCv_NvBlock_State[blockIdx]) +#define Crypto_30_LibCv_SetNvBlockState(blockIdx, state) ((Crypto_30_LibCv_NvBlock_State[blockIdx]) = (state)) +#define Crypto_30_LibCv_IsNvBlockState(blockIdx, state) ((Crypto_30_LibCv_NvBlock_State[blockIdx]) == (state)) +#define Crypto_30_LibCv_IsNvBlockStateMask(blockIdx, Mask) (((Crypto_30_LibCv_NvBlock_State[blockIdx]) & (Mask)) == (Mask)) +#define Crypto_30_LibCv_SetNvBlockStateMask(blockIdx, Mask) ((Crypto_30_LibCv_NvBlock_State[blockIdx]) = (Crypto_30_LibCv_NvBlock_State_Type)((Crypto_30_LibCv_NvBlock_State[blockIdx]) | (Mask))) +#define Crypto_30_LibCv_ClearNvBlockStateMask(blockIdx, Mask) ((Crypto_30_LibCv_NvBlock_State[blockIdx]) = (Crypto_30_LibCv_NvBlock_State_Type)((Crypto_30_LibCv_NvBlock_State[blockIdx]) & (Mask))) + +#ifndef Crypto_30_LibCv_NvM_WriteBlock /* COV_CRYPTO_30_LIBCV_COMPATIBILITY_DEFINE */ +# define Crypto_30_LibCv_NvM_WriteBlock Crypto_30_LibCv_GetNvWriteBlockFctNameOfNvStorage() +#endif + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/* Typedef for she key type */ +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +typedef uint8 Crypto_30_LibCv_SheKeyTypeType; +#endif + +/* NvM Block Handling */ +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) +typedef uint8 Crypto_30_LibCv_NvBlock_State_Type; +#endif + +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + *********************************************************************************************************************/ +#define CRYPTO_30_LIBCV_START_SEC_CONST_8BIT +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +CRYPTO_30_LIBCV_LOCAL CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_SheKeyCheckFlags[CRYPTO_30_LIBCV_SHE_NUM_KEY_TYPES - 1u] = /* Ram Key is not checked. */ /* PRQA S 3218 */ /* MD_CRYPTO_30_LIBCV_8.7 */ +{ + /* SECRET_KEY */ CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION, + /* ECU_MASTER_KEY */ CRYPTO_30_LIBCV_SHE_FID_MASK_WRITE_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_WILDCARD, + /* BOOT_MAC_KEY */ CRYPTO_30_LIBCV_SHE_FID_MASK_WRITE_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_WILDCARD, + /* BOOT_MAC */ CRYPTO_30_LIBCV_SHE_FID_MASK_WRITE_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_WILDCARD, + /* KEY_N */ CRYPTO_30_LIBCV_SHE_FID_MASK_WRITE_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_KEY_USAGE | CRYPTO_30_LIBCV_SHE_FID_MASK_WILDCARD | CRYPTO_30_LIBCV_SHE_FID_MASK_CMAC_USAGE, +}; + +CRYPTO_30_LIBCV_LOCAL CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_SheKeySetAccessFlags[CRYPTO_30_LIBCV_SHE_NUM_KEY_TYPES - 1u] = /* Ram Key is not checked. */ /* PRQA S 3218 */ /* MD_CRYPTO_30_LIBCV_8.7 */ +{ + /* SECRET_KEY */ CRYPTO_30_LIBCV_SHE_FID_MASK_DENIED, + /* ECU_MASTER_KEY */ CRYPTO_30_LIBCV_SHE_FID_MASK_DENIED, + /* BOOT_MAC_KEY */ CRYPTO_30_LIBCV_SHE_FID_MASK_KEY_USAGE | CRYPTO_30_LIBCV_SHE_FID_MASK_CMAC_USAGE, + /* BOOT_MAC */ CRYPTO_30_LIBCV_SHE_FID_MASK_DENIED, + /* KEY_N */ 0u, +}; + +CRYPTO_30_LIBCV_LOCAL CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_SheKeyServiceFlags[CRYPTO_30_LIBCV_SHE_NUM_SERVICES] = /* PRQA S 3218 */ /* MD_CRYPTO_30_LIBCV_8.7 */ +{ + /* Enc/Decrypt */ CRYPTO_30_LIBCV_SHE_FID_MASK_DENIED | CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_KEY_USAGE, + /* Mac Generate */ CRYPTO_30_LIBCV_SHE_FID_MASK_DENIED | CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_KEY_USAGE | CRYPTO_30_LIBCV_SHE_FID_MASK_CMAC_USAGE, + /* Mac Verify */ CRYPTO_30_LIBCV_SHE_FID_MASK_DENIED | CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_KEY_USAGE, + /* SHE Update Read */ CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION | CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION +}; + +CRYPTO_30_LIBCV_LOCAL CONST(uint8, CRYPTO_30_LIBCV_CONST) Crypto_30_LibCv_SheKeyServiceFlagsResult[CRYPTO_30_LIBCV_SHE_NUM_SERVICES] = /* PRQA S 3218 */ /* MD_CRYPTO_30_LIBCV_8.7 */ +{ + /* Enc/Decrypt */ 0u, + /* Mac Generate */ CRYPTO_30_LIBCV_SHE_FID_MASK_KEY_USAGE, /* Use for Mac */ + /* Mac Verify */ CRYPTO_30_LIBCV_SHE_FID_MASK_KEY_USAGE, /* Use for Mac */ + /* SHE Update Read */ 0u +}; +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) */ +#endif /* (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) */ + +#define CRYPTO_30_LIBCV_STOP_SEC_CONST_8BIT +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define CRYPTO_30_LIBCV_START_SEC_VAR_NOINIT_8BIT +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +# if (CRYPTO_30_LIBCV_SHE_DEBUG_CMD == STD_ON) +/* It is only allowed to access this data if the SheInfoKey is locked */ +CRYPTO_30_LIBCV_LOCAL VAR(uint8, CRYPTO_30_LIBCV_VAR_NOINIT) Crypto_30_LibCv_She_Debug_Cmd_Challenge[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY]; +# endif +#endif + +/* NvM Block Handling */ +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) +CRYPTO_30_LIBCV_LOCAL VAR(Crypto_30_LibCv_NvBlock_State_Type, CRYPTO_30_LIBCV_VAR_NOINIT) Crypto_30_LibCv_NvBlock_State[Crypto_30_LibCv_GetSizeOfNvBlock()]; +#endif + +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +# if (CRYPTO_30_LIBCV_SHE_DEBUG_CMD == STD_ON) +/* It is only allowed to access this data if the SheInfoKey is locked */ +VAR(boolean, CRYPTO_30_LIBCV_VAR_NOINIT) Crypto_30_LibCv_She_Debug_Cmd_ChallengeFlag; +# endif +#endif + +#define CRYPTO_30_LIBCV_STOP_SEC_VAR_NOINIT_8BIT +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementCopy_RightsCheck() + **********************************************************************************************************************/ +/*! \brief Check access rights for copy key element + * \details The key element can only be copied, if the destination key element write access right is less than + * WA_INTERNAL_COPY. + * Additional the read access right of the source must be less than RA_INTERNAL_COPY and the destination + * read access right must be higher or equal than the source read access right. + * \param[in] elementIndexSrc Holds the element index of the source key element. Has to be in bounds. + * \param[in] elementIndexDst Holds the element index of the destination key element. Has to be in bounds. + * \return E_OK Request successful. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * \pre elementIndexSrc has to be a valid element storage index. + * elementIndexDst has to be a valid element storage index. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementCopy_RightsCheck( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexSrc, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexDst); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementCopy() + *********************************************************************************************************************/ +/*! \brief Copy key element + * \details Copies a key element to another key element in the same crypto driver. + * \param[in] elementIndexSrc Holds the element index of the source key element. Has to be in bounds. + * \param[in] elementIndexDst Holds the element index of the destination key element. Has to be in bounds. + * \param[in] dstCryptoKeyId Holds the identifier of the destination key whose key element shall be set. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * \pre elementIndexSrc has to be a valid element storage index. + * elementIndexDst has to be a valid element storage index. + * dstCryptoKeyId has to be a valid key id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementCopy( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexSrc, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexDst, + uint32 dstCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementCopyPartial() + **********************************************************************************************************************/ +/*! \brief Copy key element partial + * \details Copies a key element to another key element in the same crypto driver. The keyElementSourceOffset + * and keyElementCopyLength allows to copy just a part of the source key element into the destination. + * The offset of the target key is also specified with this function. + * The key element can only be copied, if the destination key element write access right is less than + * WA_INTERNAL_COPY. + * Additional the read access right of the source must be less than RA_INTERNAL_COPY and the destination + * read access right must be higher or equal than the source read access right. + * \param[in] elementIndexSrc Holds the element index of the source key element. Has to be in bounds. + * \param[in] elementIndexDst Holds the element index of the destination key element. Has to be in bounds. + * \param[in] dstCryptoKeyId Holds the identifier of the destination key whose key element shall be set. + * \param[in] keyElementSourceOffset Holds the offset of the of the source key element indicating the start index + * of the copy operation. + * \param[in] keyElementTargetOffset Holds the offset of the of the target key element indicating the start index + * of the copy operation. + * \param[in] keyElementCopyLength Holds the number of bytes that shall be copied. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * CRYPTO_E_KEY_EMPTY Request failed, uninitialized source key element. + * \pre elementIndexSrc and elementIndexDst must be valid. + * dstCryptoKeyId has to be a valid key id. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementCopyPartial( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexSrc, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexDst, + uint32 dstCryptoKeyId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyCopy_Internal() + **********************************************************************************************************************/ +/*! \brief Copy each key element of given keys. + * \details Copy key element which matches their key element IDs of given keys. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] targetCryptoKeyId Holds the identifier of the key whose key element shall be the destination + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, at least one key is not available. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * \pre cryptoKeyId and targetCryptoKeyId are valid IDs of non-identical crypto keys, + * cryptoKeyId is read-locked, targetCryptoKeyId is write-locked. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyCopy_Internal( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetLengthCheck() + **********************************************************************************************************************/ +/*! + * \brief Check the length. + * \details Check the length according to lengthCheck (NONE, MAX, EQUAL). + * NONE Provide key always / key length is written to resultLengthPtr. + * MAX Provide key if the stored key length is smaller or equal to resultLengthPtr / key length is written to resultLengthPtr. + * EQUAL Provide key if the stored key length is equal to resultLengthPtr / key length is written to resultLengthPtr. + * \param[in] resultLengthptr Pointer which contains the size of the available buffer. + * \param[in] elementIndex Index of the Key element. + * \param[in] lengthCheck Length check mode. + * \return TRUE Length check passed. + * FALSE Length check failed. + * \pre elementIndex is a valid parameter + * resultIndexPtr need to be valid ptr + * resultLengthPtr need to be valid ptr + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetLengthCheck( + P2CONST(uint32, AUTOMATIC, AUTOMATIC) resultLengthptr, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + Crypto_30_LibCv_LengthCheckType lengthCheck); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGet_Standard() + *********************************************************************************************************************/ +/*! + * \brief Gets content of the key element. + * \details Gets content of the key element from the key storage. + * \param[in,out] resultIndexPtr Holds the identifier of the key element storage index. + * \param[in,out] resultLengthPtr Pointer to a variable which contains the size of the available buffer. + * After calling this function, the parameter contains the number of bytes written to the buffer. + * \param[in] elementIndex Index of the Key element. + * \param[in] lengthCheck Length check mode. + * \return E_OK Request successful. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. / Size mismatch for length check equal. + * \pre elementIndex is a valid parameter + * resultIndexPtr need to be valid ptr + * resultLengthPtr need to be valid ptr + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGet_Standard( + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + Crypto_30_LibCv_LengthCheckType lengthCheck); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeySetValidity() + *********************************************************************************************************************/ +/*! + * \brief Sets the given key to the requested validity. + * \details Sets all key elements of the given key to the requested validity, calls the KeyNvStatus keyChanged + * transition and triggers the key-validity-changed callout. + * \param[in] cryptoKeyId Holds the identifier of the key whose validity shall be set. + * \param[in] requestedValidity Validity to which the key shall be set: Valid (TRUE) or Invalid (FALSE) + * \return TRUE Request NvM Write. + * FALSE No writing necessary. + * \pre cryptoKeyId has to hold a valid identifier of a key + * \context TASK + * \reentrant TRUE, for different cryptoKeyIds + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeySetValidity( + uint32 cryptoKeyId, boolean requestedValidity); + +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyGetSheId() + **********************************************************************************************************************/ +/*! \brief Get SHE Id for element. + * \details - + * \param[in] elementIndex Holds the identifier of the key element + * \param[out] sheIdPtr Holds the pointer to the SHE id + * \pre elementIndex must identify a valid key element for a SHE key + * sheIdPtr has to be a valid ptr + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyGetSheId( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) sheIdPtr); +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyGetSheIndex() + **********************************************************************************************************************/ +/*! \brief Get index of SHE key in SheKeys. + * \details - + * \param[in] elementIndex Holds the identifier of the key element + * \param[out] indexSheKeyPtr Holds the pointer to the sheKeys index + * \return E_OK Request successful, SHE key found. + * E_NOT_OK Request failed. + * \pre elementIndex must identify a valid key element for a SHE key + * indexSheKeyPtr has to be a valid ptr + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyGetSheIndex( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(Crypto_30_LibCv_SizeOfSheKeysType, AUTOMATIC, AUTOMATIC) indexSheKeyPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyGetKeyType() + **********************************************************************************************************************/ +/*! \brief Get SHE key type for SHE Id. + * \details - + * \param[in] sheId Holds the identifier to the SheKeyId. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre sheId must identify a valid key element + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(uint8, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyGetKeyType( + uint8 sheId); + +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyGetElementIndex() + **********************************************************************************************************************/ +/*! \brief Check if the element with the given SheKeyId is present. + * \details - + * \param[in] sheKeyId Holds the identifier to the SheKeyId. + * \param[out] elementIndex Pointer to the element index. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre sheId must identify a valid key element + * All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyGetElementIndex( + uint8 sheKeyId, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) elementIndex); +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetSheCheckFid() + **********************************************************************************************************************/ +/*! \brief Check FID access rights for key usage. + * \details - + * \param[in] elementIndex Holds the identifier of the key element + * \param[in] serviceType Holds the usage service type + * \return TRUE Request successful / Usage allowed. + * FALSE Request failed. + * \pre elementIndex must identify a valid key element + * serviceType must to be a valid service type + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetSheCheckFid( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + Crypto_30_LibCv_ServiceType serviceType); +# endif + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel() + *********************************************************************************************************************/ +/*! \brief The function derives a key from given input data. + * \details The function derives a key from given input data. This is used during the SHE key updated protocol. + * \param[in] dataPtr Pointer to input data from which the key is derived + * \param[in] length Length of input data. + * \param[out] outputPtr Pointer to derived key + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the buffer provided by outputPtr has to be 16 Bytes. + * Length of the buffer provided by dataPtr has to be a multiple of 16. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel( + P2CONST(uint8, AUTOMATIC, AUTOMATIC) dataPtr, + uint32 length, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCmac() + *********************************************************************************************************************/ +/*! \brief Generates Cmac based on given data and given key. + * \details The function calculates the cmac based on the given data and the key. This is used during the SHE key updated protocol. + * \param[in] dataPtr Pointer to data from which the mac is calculated + * \param[in] length Length of input data + * \param[in] keyPtr Pointer to key buffer + * \param[out] outputPtr Pointer to derived key + * \param[out] workspace Pointer to workspace + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the buffer provided by outputPtr has to be 16 Bytes + * Length of the key provided by keyPtr has to be 16 Bytes + * Length of the provided dataPtr has to be a multiple of 16 Bytes. + * workspace has to be a valid pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateCmac( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataPtr, + uint32 length, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) outputPtr, + P2VAR(eslt_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateVerifyAndExtract() + *********************************************************************************************************************/ +/*! \brief Verify and extract key + * \details Verify M3, extract key and generate M4 and M5. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] elementIndex Holds the identifier of the key element which shall be set + * \param[in] m1m2m3 Holds the pointer to the key buffer which shall be used to update the key element with M1M2M3. + * \param[in] indexOfSheKey Index of the update key element in SheKeys + * \param[in] indexOfAuthSheKey Index of the authentication key element in SheKeys + * \param[in] outputElement Index of the destination key element + * \param[in] proofAvailable Holds the value if the proof element is available. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId and outputElement as well as elementIndex must identify a valid key - key element pair + * keyPtr has to be a valid ptr with the length of CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M3 + * indexOfSheKey and indexOfAuthSheKey need to be valid index for SheKeys. + * \context TASK + * \reentrant TRUE, for different crypto keys. + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateVerifyAndExtract( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey, + Crypto_30_LibCv_SizeOfSheKeysType indexOfAuthSheKey, + Crypto_30_LibCv_SizeOfKeyElementsType outputElement, + Std_ReturnType proofAvailable); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdate() + *********************************************************************************************************************/ +/*! \brief Updates key element based on SHE key update mechanism. + * \details Interprets the given key buffer as M1M2M3 of the SHE key update mechanism and extracts relevant + * information for setting the key element. This is used during the SHE key updated protocol. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] elementIndex Holds the identifier of the key element which shall be set + * \param[in] indexOfSheKey Hold the index of the update key in SheKeys. + * \param[in] m1m2m3 Holds the pointer to the key buffer which shall be used to update the key element which holds M1M2M3. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * \pre cryptoKeyId, elementIndex as well as indexOfSheKey must identify a valid key - key element pair + * keyPtr has to be a valid ptr with the length of CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M3 + * \context TASK + * \reentrant TRUE, for different crypto keys. + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdate( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementSetShe() + *********************************************************************************************************************/ +/*! \brief Sets a she key element. + * \details Sets the given key element using she behavior. She key updated for she key and plaintext update for ram key. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] elementIndex Holds the index of the key element which shall be set. + * \param[in] keyPtr Holds the pointer to the key data which shall be set as key element. + * \param[in] keyLength Contains the length of the key element in bytes. + * \param[in] oldRetVal Contains the old return value. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre cryptoKeyId and elementIndex have to be a valid identifiers to a key in the keyStorage. + * The crypto key has to be locked for write access. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementSetShe( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength, + Std_ReturnType oldRetVal); + +# if (CRYPTO_30_LIBCV_RAM_KEY_EXPORT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetShe() + *********************************************************************************************************************/ +/*! \brief Get a she key element. + * \details Get the given key element using she behavior. Only the She ram key can be provided for key export. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be provided. + * \param[in] elementIndex Holds the index of the key element which shall be provided. + * \param[out] resultPtr Holds the pointer to the key data which shall be set as key element. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId and elementIndex have to be a valid identifiers to a key in the keyStorage. + * The crypto key has to be locked for read access. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetShe( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyExport_M1M2M3() + *********************************************************************************************************************/ +/*! \brief Calculate M1M2M3 + * \details Calculate M1M2M3 for She ram key export. + * \param[out] m1m2m3 Pointer to key buffer with M1M2M3 (Sizeof CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M3) + * \param[in,out] KDFbufferPtr Pointer to the key derive function buffer. Size need to be CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER. + * The first 16 bytes contain to be the secret key. + * \param[in,out] encBufferPtr Pointer to the working buffer. Size need to be CRYPTO_30_LIBCV_SIZEOF_ENC_BUFFER. + * \param[in] uid Pointer to the She uid. Size need to be CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID. + * \param[in] ramKey Holds the pointer to the She ram key with sizeof CRYPTO_30_LIBCV_SIZEOF_SHE_KEY. + * \param[in] indexOfSheKey Hold the index of the update key in SheKeys. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre indexOfSheKey have to be a valid identifiers to a key in the keyStorage. + * All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyExport_M1M2M3( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) KDFbufferPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) encBufferPtr, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) uid, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) ramKey, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyExport() + *********************************************************************************************************************/ +/*! \brief She key export calculate M1-M3 or M1-M5 + * \details Calculate M1-M3 or M1-M5 She ram key export. + * (64 Bytes for M1-M3 and 112Bytes for M1-M5) + * \param[in] indexOfSheKey Hold the index of the update key in SheKeys. + * \param[in] indexOfAuthSheKey Hold the index of the authentication key in SheKeys. + * \param[out] resultPtr Holds the pointer to the key data which shall be set as key element. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre indexOfSheKey and indexOfAuthSheKey have to be a valid identifiers to a key in the keyStorage. + * All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyExport( + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey, + Crypto_30_LibCv_SizeOfSheKeysType indexOfAuthSheKey, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr); +# endif /* (CRYPTO_30_LIBCV_RAM_KEY_EXPORT == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateDecrypt() + *********************************************************************************************************************/ +/*! \brief Decrypts data based on given key. + * \details The function decrypts the given data using the provided key. AES128 is used as underlying algorithm. + * This is used during the SHE key updated protocol. + * \param[in] m2m3 Pointer to data which shall be decrypted which hold M2M3. + * \param[in] keyPtr Pointer to key buffer + * \param[out] outputPtr Pointer to buffer where the decrypted data will be copied to + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the buffer provided by dataPtr has to be 32 Bytes + * Length of the key provided by keyPtr has to be 16 Bytes + * Length of the buffer provided by outputPtr has to be 32 Bytes + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateDecrypt( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m2m3, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateEncrypt() + *********************************************************************************************************************/ +/*! \brief Encrypts data based on given key. + * \details The function encrypts the given data using the provided key. AES128 is used as underlying algorithm. + * This is used during the SHE key updated protocol. + * \param[in] dataPtr Pointer to data which shall be encrypted + * \param[in] keyPtr Pointer to key buffer + * \param[out] outputPtr Pointer to buffer where the encrypted data will be copied to + * \param[in] numberOfBlocks Specifies the number of blocks. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the buffer provided by dataPtr has to be numberOfBlocks * 16 Bytes + * Length of the key provided by keyPtr has to be 16 Bytes + * Length of the buffer provided by outputPtr has to be numberOfBlocks * 16 Bytes + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateEncrypt( + P2CONST(uint8, AUTOMATIC, AUTOMATIC) dataPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputPtr, + uint8 numberOfBlocks); + +/********************************************************************************************************************** + * Crypto_30_LibCv_GetSheKey() + **********************************************************************************************************************/ +/*! \brief Get SHE index in SheKeys for the given SHE Id and Page. + * \details - + * \param[in] sheKeyId Holds the SHE key id. + * \param[in] shePage Holds the SHE key page. + * \param[out] indexOfSheKeyPtr Pointer to the Index of the key element in SheKeys. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_GetSheKey( + uint8 sheKeyId, + Crypto_30_LibCv_SizeOfShePageType shePage, + P2VAR(Crypto_30_LibCv_SizeOfSheKeysType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) indexOfSheKeyPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCheckM1Ids() + *********************************************************************************************************************/ +/*! \brief Determines the authentication key element based on M1. + * \details The function checks if the authentication key element should be the element itself + * or the SHE master key. This is done by processing ID byte of M1. + * \param[in] m1m2m3 Pointer to key buffer with M1M2M3 + * \param[in] indexOfSheKey Index of the key element in SheKeys + * \param[out] indexOfAuthSheKeyPtr Pointer to the Index of the authentication key element in SheKeys + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the key provided by keyPtr has to be 16 Bytes + * indexOfSheKey has to be a valid SheKeysIndex. + * All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateCheckM1Ids( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey, + P2VAR(Crypto_30_LibCv_SizeOfSheKeysType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) indexOfAuthSheKeyPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCheckUid() + **********************************************************************************************************************/ +/*! \brief Check M1 UID is valid. + * \details Check if the M1 UID is the wildcard or the ECU UID. + * \param[in] m1m2m3 Pointer to key buffer with M1M2M3. + * \param[in] elementIndex Index of the key element. + * \param[in] sheKeyType Type of the SHE key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the key provided by keyPtr has to be 15 Bytes + * elementIndex has to be a valid index of a key element. + * All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateCheckUid( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + Crypto_30_LibCv_SheKeyTypeType sheKeyType); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateVerifyM3() + *********************************************************************************************************************/ +/*! \brief Verifies M3. + * \details The function verifies the M3. + * \param[in] m1m2m3 Pointer to key buffer with M1M2M3 + * \param[in] indexOfAuthSheKey Index of the authentication key element in SheKeys. + * \param[in] indexOfSheKey Index of the update key element in SheKeys. + * \param[in,out] KDFbufferPtr Pointer to the key derive function buffer + * \param[in] KDFbufferLength Length of the KDF buffer + * \param[in,out] outputBufferPtr pointer to the working buffer. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the buffer provided by outputBufferPtr has to be 32 Bytes. + * Length of the buffer provided by KDFbufferPtr has to be 32 Bytes. + * indexOfSheKey and indexOfAuthSheKey need to be valid sheKeys Index. + * page need to be a valid SHE key page. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateVerifyM3( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfSheKeysType indexOfAuthSheKey, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) KDFbufferPtr, + uint8 KDFbufferLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputBufferPtr); + +# if(CRYPTO_30_LIBCV_SHE_ENABLE_COUNTER == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCheckCounter() + **********************************************************************************************************************/ +/*! \brief Check if the used counter from M1 is valid. + * \details - + * \param[in] elementIndexCounter Index of the counter key element. + * \param[in] decryptedKeyPtr Pointer to key buffer + * \param[in] sheKeyType Holds the type of the SHE key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId must identify a valid key. + * Length of the buffer provided by decryptedKeyPtr has to be 32 Bytes. + * All pointers need to be valid. + * elementIndexCounter need to be a valid element index of a SHE counter. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateCheckCounter( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexCounter, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) decryptedKeyPtr, + Crypto_30_LibCv_SheKeyTypeType sheKeyType); +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_COUNTER == STD_ON) */ + +# if(CRYPTO_30_LIBCV_SHE_ENABLE_COUNTER == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCopyCounter() + **********************************************************************************************************************/ +/*! \brief Save the new counter value. + * \details - + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] elementIndexCounter Index of the counter key element. + * \param[in] decryptedKeyPtr Pointer to key buffer + * \pre Length of the buffer provided by decryptedKeyPtr has to be 32 Bytes. + * All pointers need to be valid. + * elementIndexCounter need to be a valid element index of a SHE counter. + * cryptoKeyId must identify a valid key. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateCopyCounter( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexCounter, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) decryptedKeyPtr); +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_COUNTER == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCopyFid() + **********************************************************************************************************************/ +/*! \brief Convert and save FID from M1. + * \details - + * \param[in] elementIndex Index of the update key element. + * \param[in] decryptedKeyPtr Pointer to key buffer + * \param[in] sheKeyType Holds the type of the SHE key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre Length of the buffer provided by decryptedKeyPtr has to be 32 Bytes. + * All pointers need to be valid. + * elementIndex need to be a valid element index of a SHE key. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateCopyFid( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) decryptedKeyPtr, + Crypto_30_LibCv_SheKeyTypeType sheKeyType); +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateExtractKey() + *********************************************************************************************************************/ +/*! \brief Extracts new Key. + * \details The function provides the new key. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] m1m2m3 Pointer to key buffer with M1M2M3 + * \param[in] elementIndex Index of the key element. + * \param[in,out] KDFbufferPtr Pointer to the key derive function buffer + * \param[in] KDFbufferLength Length of the KDF buffer + * \param[in,out] outputBufferPtr pointer to the working buffer. + * \param[in] indexOfSheKey Index of the update key element in SheKeys. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId must identify a valid key. + * Length of the buffer provided by outputBufferPtr has to be 32 Bytes. + * Length of the buffer provided by KDFbufferPtr has to be 32 Bytes. + * indexOfSheKey need to be valid sheKeys Index. + * sheKeyType need to be a valid SHE key type. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateExtractKey( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) KDFbufferPtr, + uint8 KDFbufferLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputBufferPtr, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateProofM4M5() + *********************************************************************************************************************/ +/*! \brief Calculates M4 and M5 + * \details The function calculate the proof elements M4 and M5. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] m1m2m3 Pointer to key buffer with M1M2M3 + * \param[in] outputElement Index of the destination key element + * \param[in,out] KDFbufferPtr Pointer to the key derive function buffer. Size need to be CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER. + * The first 16 bytes contain to be the ram key. + * \param[in,out] outputBufferPtr pointer to the working buffer. Size need to be CRYPTO_30_LIBCV_SIZEOF_ENC_BUFFER. + * The first 16 bytes contain to be the counter. + * \param[in] indexOfSheKey Hold the index of the update key in SheKeys. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId must identify a valid key. + * Length of the buffer provided by outputBufferPtr has to be 32 Bytes. + * indexOfSheKey need to be a valid index of sheKeys. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateProofM4M5( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfKeyElementsType outputElement, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) KDFbufferPtr, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputBufferPtr, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateGenM4M5() + *********************************************************************************************************************/ +/*! \brief Calculates M4 and M5 + * \details The function calculate the proof elements M4 and M5. + * \param[in] m1m2m3 Pointer to key buffer with M1M2M3 (Sizeof CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M3) + * \param[out] m4m5 Pointer to key buffer for M4M5. (Sizeof CRYPTO_30_LIBCV_SIZEOF_SHE_M4_M5) + * \param[in] uid Pointer to the She uid. Size need to be CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID. + * \param[in,out] KDFbufferPtr Pointer to the key derive function buffer. Size need to be CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER. + * The first 16 bytes contain to be the ram key. + * \param[in,out] encBufferPtr Pointer to the working buffer. Size need to be CRYPTO_30_LIBCV_SIZEOF_ENC_BUFFER. + * The first 16 bytes contain to be the counter. + * \param[in] indexOfSheKey Hold the index of the update key in SheKeys. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointer need to be valid. + * indexOfSheKey need to be a valid index of sheKeys. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateGenM4M5( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m4m5, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) uid, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) KDFbufferPtr, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) encBufferPtr, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateFindProof() + **********************************************************************************************************************/ +/*! \brief Check if the Proof element is available. + * \details Allowed is CRYPTO_KE_MAC_PROOF and CRYPTO_KE_CIPHER_PROOF. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[out] outputElementIndexPtr Ptr to the identifier of the proof key element which shall be set. + * \return E_OK Request successful. + * CRYPTO_E_KEY_NOT_AVAILABLE Request successful no proof element found. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed. + * \pre cryptoKeyId must identify a valid key. + * outputElementIndexPtr need to be a valid ptr. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateFindProof( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_KeyElementsIterType, AUTOMATIC, AUTOMATIC) outputElementIndexPtr); + +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateLockKeys() + **********************************************************************************************************************/ +/*! \brief Lock the info and authentication key for reading. + * \details - + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] authKeyId Holds the identifier of the key which is used for authentication. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as authKeyId must identify a valid key. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateLockKeys( + uint32 cryptoKeyId, + uint32 authKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateUnlockKeys() + **********************************************************************************************************************/ +/*! \brief Release the lock for the info and authentication key. + * \details - + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] authKeyId Holds the identifier of the key which is used for authentication. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as authKeyId must identify a valid key. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateUnlockKeys( + uint32 cryptoKeyId, + uint32 authKeyId); +# endif /* (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SHE_DEBUG_CMD == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_GetChallenge() + *********************************************************************************************************************/ +/*! \brief Provide challenge for She DEBUG_CMD + * \details Provide the challenge required for She DEBUG_CMD and save request. + * \param[out] resultPtr Holds the pointer to the key data which shall be set as key element. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_GetChallenge( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_SetAuthorizationAndLock() + *********************************************************************************************************************/ +/*! \brief Execute She DEBUG_CMD + * \details Set Authorization and verify access. Delete deletion keys on success. + * \param[in] keyPtr Holds the pointer to the key data which shall be set as key element. + * \param[in] keyLength Contains the length of the key element in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_SetAuthorizationAndLock( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_SetAuthorization() + *********************************************************************************************************************/ +/*! \brief Execute She DEBUG_CMD + * \details Set Authorization and verify access. Delete deletion keys on success. + * \param[in] keyPtr Holds the pointer to the key data which shall be set as key element + * with length of CRYPTO_30_LIBCV_SIZEOF_SHE_KEY. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_SetAuthorization( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_DeleteKeys() + *********************************************************************************************************************/ +/*! \brief Delete deletion keys. + * \details Overwrite deletion keys with zero and restore inital values. + * \pre All deletion keys need to be locked for write access. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_DeleteKeys(void); + +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_IsWriteProtected() + *********************************************************************************************************************/ +/*! \brief Is a deletion key write protected? + * \details - + * \return TRUE At least one key is write protected. + * FALSE No key is write protected. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_IsWriteProtected(void); +# endif + +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_Authorization() + *********************************************************************************************************************/ +/*! \brief Verify She DEBUG_CMD Authorization + * \details - + * \param[in] masterKey Holds the pointer to the She master key with sizeof CRYPTO_30_LIBCV_SIZEOF_SHE_KEY. + * \param[in] uid Holds the pointer to the She uid with sizeof CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID. + * \param[in] challenge Holds the pointer to the She challenge with sizeof CRYPTO_30_LIBCV_SIZEOF_SHE_KEY. + * \param[in] authorization Holds the pointer to the She authorization with sizeof CRYPTO_30_LIBCV_SIZEOF_SHE_KEY. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_Authorization( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) masterKey, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) uid, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) challenge, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) authorization); +# endif /* (CRYPTO_30_LIBCV_SHE_DEBUG_CMD == STD_ON) */ +#endif /* (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) */ + +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_Trigger_Write_Req() + **********************************************************************************************************************/ +/*! \brief Trigger write request. + * \details Call NvM_SetRamBlockStatus and NvM_WriteBlock dependent on the block processing + * \param[in] blockIdx Holds the identifier of the nv block. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre blockIdx has to be a valid identifier. + * \context TASK + * \reentrant TRUE, for different blocks. + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_Trigger_Write_Req( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_State_CallbackWrittenToBlock() + **********************************************************************************************************************/ +/*!\brief Write Block request finished Block callback routine. + * \details Block specific callback routine which is called by NvM in order to notify the Crypto driver that an + * asynchronous single block request has been finished. + * \param[in] blockIdx The internal identifier of the NvM block. + * \pre blockIdx need to be valid. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_State_CallbackWrittenToBlock( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_State_WrittenToBlock() + **********************************************************************************************************************/ +/*!\brief Update State for WrittenToBlock + * \details - + * \param[in] blockIdx The internal identifier of the NvM block. + * \pre blockIdx need to be valid. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_State_WrittenToBlock( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_WriteToBlock_Copy() + **********************************************************************************************************************/ +/*!\brief Copy data to NvMBufferPtr + * \details Copy header and data. + * \param[in] blockIdx The internal identifier of the NvM block. + * \param[out] NvMBufferPtr RAM mirror where Ram block data shall be written to. + * \pre blockIdx need to be valid. + * NvMBufferPtr need to be a valid pointer. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_WriteToBlock_Copy( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) NvMBufferPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_CheckLengthOfGivenKeyElement() + **********************************************************************************************************************/ +/*!\brief Check if lengths of given key element is valid + * \details Check if configured key element length is equal or greater than key element length read from NvM data + * \param[out] validLengthsPtr Pointer where the result of lengths check is written (TRUE: all lengths valid, + FALSE: at least one length invalid + * \param[in] blockIdx The internal identifier of the NvM block. + * \param[in] NvMBufferPtr RAM mirror where Ram block data can be read from. + * \param[in] dataStartPos Start position of data as NvMBufferPtr index. + * \pre blockIdx and dataStartPos need to be valid. + * NvMBufferPtr and validLengthsPtr need to be a valid pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_CheckLengthOfGivenKeyElement( + P2VAR(boolean, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) validLengthsPtr, + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + Crypto_30_LibCv_KeyElementsIterType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) NvMBufferPtr, + Crypto_30_LibCv_SizeOfKeyStorageType dataStartPos); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_CheckKeyElementLengths() + **********************************************************************************************************************/ +/*!\brief Check if key element lengths are valid + * \details Get keyIdx matching the blockIdx and check key element lengths of key + * \param[in] blockIdx The internal identifier of the NvM block. + * \param[in] NvMBufferPtr RAM mirror where Ram block data can be read from. + * \param[in] dataStartPos Start position of data as NvMBufferPtr index. + * \return E_OK Data was either copied from buffer or restored. + * \pre blockIdx and dataStartPos need to be valid. + * NvMBufferPtr need to be a valid pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_CheckKeyElementLengths( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) NvMBufferPtr, + Crypto_30_LibCv_SizeOfKeyStorageType dataStartPos); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_ReadFromBlock_Copy() + **********************************************************************************************************************/ +/*!\brief Read from Block callback routine. + * \details Block specific callback routine which is called by NvM in order to let the Crypto driver copy data from + * NvM RAM mirror to Crypto RAM block. + * \param[in] blockIdx The internal identifier of the NvM block. + * \param[in] NvMBuffer RAM mirror where Ram block data can be read from. + * \return E_OK Data was either copied from buffer or restored. + * \pre blockIdx need to be valid. + * NvMBufferPtr need to be a valid pointer. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_ReadFromBlock_Copy( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) NvMBufferPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_ReadFromBlock_HeaderCrc() + **********************************************************************************************************************/ +/*!\brief Check Header for CRC + * \details - + * \param[in] blockIdx The internal identifier of the NvM block. + * \param[in] NvMBufferPtr RAM mirror where Ram block data can be read from. + * \return TRUE Header valid. + * \return FALSE Header not valid. + * \pre blockIdx need to be valid. + * NvMBufferPtr need to be a valid pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_ReadFromBlock_HeaderCrc( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) NvMBufferPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_WriteToBlock_HeaderCrc() + **********************************************************************************************************************/ +/*!\brief Copy Header for CRC + * \details - + * \param[in] blockIdx The internal identifier of the NvM block. + * \param[out] NvMBufferPtr RAM mirror where Ram block data shall be written to. + * \param[out] writtenLengthPtr Pointer where written Length shall be written to. + * \pre blockIdx need to be valid. + * All pointers need to be a valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_WriteToBlock_HeaderCrc( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) NvMBufferPtr, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) writtenLengthPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_ReadFromBlock_Restore() + **********************************************************************************************************************/ +/*!\brief Restore data for the given block. + * \details - + * \param[in] blockIdx The internal identifier of the NvM block. + * \pre blockIdx need to be valid. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_ReadFromBlock_Restore( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_IsKeyUpdatedByNvm() + *********************************************************************************************************************/ +/*! \brief Reports if the given cryptoKey is currently updated by NvM. + * \details This function returns true if the KeyNvState of the given key is in one of the following states: + * NV_WRITE_REQ, KEY_COPIED, WRITE_FAILED. Else false. + * \param[in] cryptoKeyId Holds the identifier of the key for which the key state shall be returned. + * \pre cryptoKeyId has to be a valid identifier to a cryptoKey. + * \return TRUE The key with the given cryptoKeyId is currently updated by NvM. + * FALSE The key is currently not updated. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_IsKeyUpdatedByNvm( + uint32 cryptoKeyId); +#endif /* (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) */ + +#if(CRYPTO_30_LIBCV_SHECMDGETID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_She_Cmd_Get_Status() + *********************************************************************************************************************/ +/*! \brief Get the current she status + * \details - + * \param[out] statusPtr Holds the pointer to the current she status. + * \return E_OK Request successful. + * \return E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_Cmd_Get_Status( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) statusPtr); +#endif /* (CRYPTO_30_LIBCV_SHECMDGETID == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_BinarySearchCryptoKeyId() + *********************************************************************************************************************/ +/*! \brief Binary search for the key index. + * \details Binary search for the key Index of the given elementIndex in the global key list. + * \param[in] elementIndex Holds the identifier of the keyElement in the keyStorage. + * \param[out] cryptoKeyId Will hold the identifier of the key after it has been found. + * \return E_OK Request successful. + * E_NOT_OK Request failed, key not found. + * \pre elementIndex has to be a valid identifier to a keyElement in the keyStorage. + * cryptoKeyId pointer need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_BinarySearchCryptoKeyId( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGet() + *********************************************************************************************************************/ +/*! \brief This interface shall be used to get a key element of the key identified by the cryptoKeyId and store + * the key element in the memory location pointed to by the result pointer. + * \details The key element can only be provided, if the read access right is RA_ALLOWED. If the key element + * is configured to allow partial access, resultLengthPtr contains the amount of data which should + * be read from the key element. + * The behavior for partial access can be switched on or off in the configuration. + * If the read access right is RA_ENCRYPTED the She ram key can be exported. + * (64 Bytes for M1-M3 and 112Bytes for M1-M5) + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] keyElementId Holds the identifier of the key element which shall be set. + * \param[out] resultPtr Holds the pointer to the key data which shall be set as key element. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \param[out] errorIdPtr Holds the pointer to the error id. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId needs to be a valid key id. + * keyElementId needs to be a valid key element id. + * resultPtr pointer needs to be valid. + * resultLengthPtr pointer needs to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) errorIdPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetNoShe() + *********************************************************************************************************************/ +/*! \brief Stores the key element identified by the provided elementIndex in the in the memory location + * pointed to by the result pointer. + * \details If the key element has partial access enabled, also only parts of the key element can be stored. + * This behavior depends on the available buffer and on the configuration. + * \param[in] elementIndex Holds the identifier of the keyElement in the keyStorage. + * \param[out] resultPtr Holds the pointer to the key data which shall be set as key element. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed, key not found. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre elementIndex has to be a valid identifier to a keyElement in the keyStorage. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetNoShe( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGetStatus() + *********************************************************************************************************************/ +/*! \brief Reports the status of the given cryptoKey. + * \details Reports UPDATE_IN_PROGRESS if the key has changed and is currently updated by the NVM. Otherwise + * is reports the validity of the key. + * \param[in] cryptoKeyId Holds the identifier of the key for which the key state shall be returned. + * \param[out] keyStatusPtr Contains the pointer to the data where the status of the key shall be stored. + * \pre cryptoKeyId has to be a valid identifier to a cryptoKey. + * keyStatusPtr has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGetStatus( + uint32 cryptoKeyId, + P2VAR(Crypto_KeyStatusType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyStatusPtr); + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SetKeyElementWrittenLength() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SetKeyElementWrittenLength( + Crypto_30_LibCv_SizeOfKeyElementsType keyElementIndex, + uint32 keyElementLength) +{ + /* #10 Set high- and low-byte for keyElement written length */ +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_OFF) + volatile P2VAR(Crypto_30_LibCv_KeyStorageType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) lowBytePtr = + &Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageWrittenLengthStartIdxOfKeyElements(keyElementIndex)); + volatile P2VAR(Crypto_30_LibCv_KeyStorageType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) highBytePtr = + &Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageWrittenLengthStartIdxOfKeyElements(keyElementIndex) + 1u); + + *lowBytePtr = 0u; /* SBSW_CRYPTO_30_LIBCV_VOLATILE_KEY_STORAGE_VIA_KEY_ELEMENT */ + *highBytePtr = 0u; /* SBSW_CRYPTO_30_LIBCV_VOLATILE_KEY_STORAGE_VIA_KEY_ELEMENT */ +#endif + Crypto_30_LibCv_SetKeyStorage(Crypto_30_LibCv_GetKeyStorageWrittenLengthStartIdxOfKeyElements(keyElementIndex), (uint8)((keyElementLength >> 8) & 0xFFu)); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + Crypto_30_LibCv_SetKeyStorage(Crypto_30_LibCv_GetKeyStorageWrittenLengthStartIdxOfKeyElements(keyElementIndex) + 1u, (uint8)(keyElementLength & 0xFFu)); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ +} /* Crypto_30_LibCv_SetKeyElementWrittenLength() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyIdSearch() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyIdSearch( + Crypto_30_LibCv_SizeOfKeyElementsType keyElementIndex, + uint32 keyElementLength) +{ + Std_ReturnType retVal = E_NOT_OK; + uint32 cryptoKeyId = 0u; + + /* #10 Search the Crypto Key Id if the functionality is enabled and trigger that the key value is changed */ + retVal = Crypto_30_LibCv_Local_BinarySearchCryptoKeyId(keyElementIndex, &cryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (retVal == E_OK) + { + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(cryptoKeyId, keyElementIndex, keyElementLength); + } + + return retVal; +} /* Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyIdSearch() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType keyElementIndex, + uint32 keyElementLength) +{ + + /* #10 Set high- and low-byte for keyElement written length */ + Crypto_30_LibCv_SetKeyElementWrittenLength(keyElementIndex, keyElementLength); + +#if(CRYPTO_30_LIBCV_KEYVALUECHANGEDCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + /* #20 Call the callout if the functionality is enabled and trigger that the key value is changed */ + Crypto_30_LibCv_GetKeyValueChangedCalloutFctNameOfConfigurableCallouts()(cryptoKeyId, Crypto_30_LibCv_GetIdOfKeyElements(keyElementIndex)); +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif +#if(CRYPTO_30_LIBCV_NVBLOCK == STD_ON) +/* Call KeyNvStatus KeyChanged transition */ + Crypto_30_LibCv_KeyNvStatus_KeyChanged(cryptoKeyId, keyElementIndex); +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + +} /* Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_SetKeyElementStateWritten() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_SetKeyElementStateWritten( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex) +{ + /* ----- Local Variables ------------------------------------------------ */ + /* ----- Implementation ------------------------------------------------- */ + /* Clear Key Flags and set write once if required. */ + Crypto_30_LibCv_ClearKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_CLEAR_NORMAL_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + if (Crypto_30_LibCv_IsKeyElementWriteOnce(elementIndex)) + { + Crypto_30_LibCv_SetKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + } +} /* Crypto_30_LibCv_Local_SetKeyElementStateWritten() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeySetValidity() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeySetValidity( + uint32 cryptoKeyId, boolean requestedValidity) +{ + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex; + boolean writeReq = FALSE; + + /* Set key state for all key elements */ + + /* Loop over all elements of the given key */ + for (elementIndex = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(cryptoKeyId); elementIndex < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(cryptoKeyId); elementIndex++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + if (requestedValidity) + { + /* Set key element to valid */ + + /* Check if key element is invalid */ + if (!Crypto_30_LibCv_IsKeyElementValid(elementIndex)) + { + /* Set validity bit */ + Crypto_30_LibCv_SetKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + if (Crypto_30_LibCv_IsKeyElementPersist(elementIndex)) + { + writeReq = TRUE; + Crypto_30_LibCv_KeyNvStatus_KeyChanged(cryptoKeyId, elementIndex); + } +#endif + } + } + else + { + /* Set key element to invalid */ + + /* Clear validity bit */ + Crypto_30_LibCv_ClearKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_INV_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + if (Crypto_30_LibCv_IsKeyElementPersist(elementIndex)) + { + writeReq = TRUE; + /* Even though the key may not actually change, it shall always be written by NVM if KeySetInvalid is called, thus mark it as changed to comply the KeyNvStatus statemachine */ + Crypto_30_LibCv_KeyNvStatus_KeyChanged(cryptoKeyId, elementIndex); + } +#endif + } + } + + /* Call the callout if the functionality is enabled and trigger that the key is set to the requested validity */ +#if(CRYPTO_30_LIBCV_KEYVALIDITYSETCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + Crypto_30_LibCv_GetKeyValiditySetCalloutFctNameOfConfigurableCallouts()(cryptoKeyId, requestedValidity); +#endif + + return writeReq; +} /* Crypto_30_LibCv_Local_KeySetValidity() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Internal_KeySetValid() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Internal_KeySetValid( + uint32 cryptoKeyId) +{ + return Crypto_30_LibCv_Local_KeySetValidity(cryptoKeyId, TRUE); +} /* Crypto_30_LibCv_Internal_KeySetValid() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Internal_KeySetInvalid() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Internal_KeySetInvalid( + uint32 cryptoKeyId) +{ + return Crypto_30_LibCv_Local_KeySetValidity(cryptoKeyId, FALSE); +} /* Crypto_30_LibCv_Internal_KeySetInvalid() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementCopy_RightsCheck() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 3 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementCopy_RightsCheck( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexSrc, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexDst) +{ + Std_ReturnType retVal = E_OK; + /* #10 Check if the access flags are matching the conditions to copy a key element */ + /* Read != DENIED and Destination Protection >= Source Protection */ + if (((Crypto_30_LibCv_GetReadOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndexSrc))) == CRYPTO_30_LIBCV_RA_DENIED) || + ((Crypto_30_LibCv_GetReadOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndexSrc))) > (Crypto_30_LibCv_GetReadOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndexDst))))) + { + retVal = CRYPTO_E_KEY_READ_FAIL; + } + /* WRITE <= Internal Copy */ + else if ((Crypto_30_LibCv_GetWriteOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndexDst))) == CRYPTO_30_LIBCV_WA_DENIED) + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + } + /* #20 Check if it is a write once key which is written already. */ + else if (Crypto_30_LibCv_IsKeyElementStateByMask(elementIndexDst, CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_MASK)) + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + } + else + { + /* #30 Check She key rights */ +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) + if (Crypto_30_LibCv_IsSheKey(elementIndexSrc)) + { + retVal = CRYPTO_E_KEY_READ_FAIL; + } + else if (Crypto_30_LibCv_IsSheKey(elementIndexDst)) + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + } + else + { + /* Success */ + } +#endif + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementCopy_RightsCheck() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementCopy() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6030, 6080 3 */ /* MD_MSR_STCYC, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementCopy( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexSrc, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexDst, + uint32 dstCryptoKeyId) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + Crypto_30_LibCv_KeyStorageIterType keyStorageIndexSrc; + Crypto_30_LibCv_KeyStorageIterType keyStorageIndexDst; + + /* ----- Implementation ------------------------------------------------- */ + + /* #10 Check if the access flags are matching the conditions to copy a key element */ + retVal = Crypto_30_LibCv_Local_KeyElementCopy_RightsCheck(elementIndexSrc, elementIndexDst); + if (retVal == E_OK) + { + retVal = E_NOT_OK; /* PRQA S 2982 */ /* MD_MSR_RetVal */ + { + /* Check if the available data is not bigger than the maximum size of the destination element */ + /* #35 Copy key element data if the size is matching */ + if ((Crypto_30_LibCv_GetKeyElementWrittenLength(elementIndexSrc) == Crypto_30_LibCv_GetKeyElementLength(elementIndexDst)) || + ((Crypto_30_LibCv_IsKeyElementPartial(elementIndexDst) == TRUE) && + (Crypto_30_LibCv_GetKeyElementWrittenLength(elementIndexSrc) <= Crypto_30_LibCv_GetKeyElementLength(elementIndexDst)))) + { + keyStorageIndexSrc = Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(elementIndexSrc); + keyStorageIndexDst = Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(elementIndexDst); + /* Copy the source element to the destination element */ + Crypto_30_LibCv_CopyData(Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndexDst), Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndexSrc), Crypto_30_LibCv_GetKeyElementWrittenLength(elementIndexSrc)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + + /* store the written length in the destination element */ + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(dstCryptoKeyId, elementIndexDst, Crypto_30_LibCv_GetKeyElementWrittenLength(elementIndexSrc)); + Crypto_30_LibCv_Local_SetKeyElementStateWritten(elementIndexDst); + + retVal = E_OK; + } + else + { + /* The destination element is to short to store the available data of the source element */ + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementCopy() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementCopyPartial() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +/* PRQA S 6030, 6060, 6080 6 */ /* MD_MSR_STCYC, MD_CRYPTO_30_LIBCV_STPAR_ASR, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementCopyPartial( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexSrc, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexDst, + uint32 dstCryptoKeyId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + Crypto_30_LibCv_KeyStorageIterType keyStorageIndexSrc, keyStorageIndexDst; + uint32 writtenLengthSrc, writtenLengthDst; + + /* ----- Implementation ------------------------------------------------- */ + + /* #10 Check if the access flags are matching the conditions to copy a key element */ + retVal = Crypto_30_LibCv_Local_KeyElementCopy_RightsCheck(elementIndexSrc, elementIndexDst); + if (retVal == E_OK) + { + retVal = E_NOT_OK; /* PRQA S 2982 */ /* MD_MSR_RetVal */ + { + writtenLengthSrc = Crypto_30_LibCv_GetKeyElementWrittenLength(elementIndexSrc); + writtenLengthDst = Crypto_30_LibCv_GetKeyElementWrittenLength(elementIndexDst); + + if (writtenLengthSrc == CRYPTO_30_LIBCV_EMPTY_KEY_LENGTH) + { + retVal = CRYPTO_E_KEY_EMPTY; + } + else if ( + (Crypto_30_LibCv_IsKeyElementPartial(elementIndexDst) == TRUE) && + /* [SWS_Crypto_00207] readLength */ + ((keyElementSourceOffset + keyElementCopyLength) <= writtenLengthSrc) && + ((Crypto_30_LibCv_IsUint32Overflow(keyElementSourceOffset, keyElementCopyLength)) == FALSE) && + /* [SWS_Crypto_00208] writeLength */ + ((keyElementTargetOffset + keyElementCopyLength) <= Crypto_30_LibCv_GetKeyElementLength(elementIndexDst)) && + ((Crypto_30_LibCv_IsUint32Overflow(keyElementTargetOffset, keyElementCopyLength)) == FALSE)) + { + keyStorageIndexSrc = Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(elementIndexSrc); + keyStorageIndexDst = Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(elementIndexDst); + + /* If there is a gap between offset and written length, clear it. */ + if (writtenLengthDst < keyElementTargetOffset) + { + Crypto_30_LibCv_ClearData(Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndexDst + writtenLengthDst), (uint32)(keyElementTargetOffset - writtenLengthDst)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + } + + /* Copy the source element to the destination element */ + Crypto_30_LibCv_CopyData(Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndexDst + keyElementTargetOffset), Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndexSrc + keyElementSourceOffset), keyElementCopyLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + + /* store the written length in the destination element */ + /* [SWS_Crypto_00210], [SWS_Crypto_00211] */ + if (writtenLengthDst < (keyElementTargetOffset + keyElementCopyLength)) + { + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(dstCryptoKeyId, elementIndexDst, (keyElementTargetOffset + keyElementCopyLength)); + } + Crypto_30_LibCv_Local_SetKeyElementStateWritten(elementIndexDst); + + retVal = E_OK; + } + else + { + /* The destination element is too short to store the available data of the source element */ + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementCopyPartial() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyCopy_Internal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyCopy_Internal( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + Std_ReturnType retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + Std_ReturnType retValBuf = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexSrc; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexDst = 0u; + + /* #1 Loop over all elements of the source key */ + for (elementIndexSrc = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(cryptoKeyId); elementIndexSrc < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(cryptoKeyId); elementIndexSrc++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + /* #2 Loop over all elements of the destination key to find a matching element for the current source element */ + if (Crypto_30_LibCv_Local_KeyElementSearch(targetCryptoKeyId, Crypto_30_LibCv_GetIdOfKeyElements(elementIndexSrc), &elementIndexDst) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* #3 copy key element with Crypto_30_LibCv_Local_KeyElementCopy */ + retValBuf = Crypto_30_LibCv_Local_KeyElementCopy((Crypto_30_LibCv_SizeOfKeyElementsType)elementIndexSrc, elementIndexDst, targetCryptoKeyId); + if (retVal != E_OK) + { + /* #4 Return E_OK if at least one keyElement has been successfully copied [SWS_CryIf_00121] */ + retVal = retValBuf; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_KeyCopy_Internal() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetLengthCheck() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetLengthCheck( + P2CONST(uint32, AUTOMATIC, AUTOMATIC) resultLengthptr, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + Crypto_30_LibCv_LengthCheckType lengthCheck) +{ + boolean retVal = FALSE; + + switch (lengthCheck) + { + case CRYPTO_30_LIBCV_LENGTH_CHECK_NONE: + retVal = TRUE; + break; + + case CRYPTO_30_LIBCV_LENGTH_CHECK_MAX: + if (Crypto_30_LibCv_GetKeyElementWrittenLength(elementIndex) <= *resultLengthptr) + { + retVal = TRUE; + } + break; + + case CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL: + if (Crypto_30_LibCv_GetKeyElementWrittenLength(elementIndex) == *resultLengthptr) + { + retVal = TRUE; + } + break; + + case CRYPTO_30_LIBCV_LENGTH_CHECK_MIN: + if (Crypto_30_LibCv_GetKeyElementWrittenLength(elementIndex) >= *resultLengthptr) + { + retVal = TRUE; + } + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementGetLengthCheck() */ + +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyGetSheId() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyGetSheId( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) sheIdPtr) +{ + Crypto_30_LibCv_SheKeysIterType i; + + /* Get key SHE id of SHE key list. */ + for (i = 0u; i < Crypto_30_LibCv_GetSizeOfSheKeys(); i++) + { + if (Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(i) == elementIndex) + { + *sheIdPtr = Crypto_30_LibCv_GetSheIdOfSheKeys(i); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + break; + } + } +} /* Crypto_30_LibCv_SheKeyGetSheId() */ +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyGetSheIndex() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyGetSheIndex( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(Crypto_30_LibCv_SizeOfSheKeysType, AUTOMATIC, AUTOMATIC) indexSheKeyPtr) +{ + Crypto_30_LibCv_SheKeysIterType i; + Std_ReturnType retVal = E_NOT_OK; + + /* Get index of SHE key in list. */ + for (i = 0u; i < Crypto_30_LibCv_GetSizeOfSheKeys(); i++) + { + if (Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(i) == elementIndex) + { + *indexSheKeyPtr = (Crypto_30_LibCv_SizeOfSheKeysType)i; /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + retVal = E_OK; + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyGetSheIndex() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyGetKeyType() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(uint8, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyGetKeyType( + uint8 sheId) +{ + uint8 keyType; + /* Get key type for SHE key. */ + if (sheId == CRYPTO_30_LIBCV_SHE_M1_RAM_KEY_ID) + { + keyType = CRYPTO_30_LIBCV_SHE_TYPE_RAM_KEY; + } + else if (sheId >= CRYPTO_30_LIBCV_SHE_M1_KEY_N_START_ID) + { + keyType = CRYPTO_30_LIBCV_SHE_TYPE_KEY_N; + } + else + { + keyType = sheId; + } + return keyType; +} /* Crypto_30_LibCv_SheKeyGetKeyType() */ + +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyGetElementIndex() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyGetElementIndex( + uint8 sheKeyId, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) elementIndex) +{ + Std_ReturnType found = E_NOT_OK; + + Crypto_30_LibCv_SheKeysIterType i; + + /* Check if the element with the given SheKeyId is present. */ + for (i = 0u; i < Crypto_30_LibCv_GetSizeOfSheKeys(); i++) + { + if (Crypto_30_LibCv_GetSheIdOfSheKeys(i) == sheKeyId) + { + *elementIndex = Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(i); /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + found = E_OK; + break; + } + } + + return found; +} /* Crypto_30_LibCv_SheKeyGetElementIndex() */ +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetSheCheckFid() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetSheCheckFid( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + Crypto_30_LibCv_ServiceType serviceType) +{ + boolean retVal = FALSE; + uint8 fid, keyType, sheId = 0u; + Crypto_30_LibCv_SizeOfKeyElementsType localElementIndex = 0u; + + /* Get SHE id for element */ + Crypto_30_LibCv_SheKeyGetSheId(elementIndex, &sheId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + keyType = Crypto_30_LibCv_SheKeyGetKeyType(sheId); + + /* Ram key usage is always allowed. */ + if (keyType != CRYPTO_30_LIBCV_SHE_TYPE_RAM_KEY) + { + + if (keyType == CRYPTO_30_LIBCV_SHE_TYPE_SECRET_KEY) + { + /* If it is the secret key load FID from master key. */ + if (Crypto_30_LibCv_SheKeyGetElementIndex(CRYPTO_30_LIBCV_SHE_M1_ECU_MASTER_KEY_ID, &localElementIndex) == E_OK) /* COV_CRYPTO_30_LIBCV_SHE_ECU_MASTER_KEY */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + fid = Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageExtensionIdxOfKeyElements(localElementIndex)); + } + else + { + /* Use default values if there is no master key. */ + fid = CRYPTO_30_LIBCV_SHE_FID_MASK_DEFAULT; + } + } + else + { + /* load FID */ + fid = Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageExtensionIdxOfKeyElements(elementIndex)); + } + + fid &= Crypto_30_LibCv_SheKeyCheckFlags[keyType]; /* clear flags which not need to be checked according to key type */ + fid |= Crypto_30_LibCv_SheKeySetAccessFlags[keyType]; /* set additional flags for access protection according to key type */ + fid &= Crypto_30_LibCv_SheKeyServiceFlags[serviceType]; /* clear flags which not need to be checked according to service type */ + + /* Check Boot Protection */ +# if (CRYPTO_30_LIBCV_KEYELEMENTSBOOTPROTECTIONIDXOFSHEPAGE == STD_ON) + localElementIndex = Crypto_30_LibCv_GetKeyElementsBootProtectionIdxOfShePage(CRYPTO_30_LIBCV_SHE_PAGE0); + if ((Crypto_30_LibCv_IsModuleBootProtected(Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(localElementIndex)))) && + (Crypto_30_LibCv_GetKeyElementWrittenLength(localElementIndex) == 1u)) + { + /* If Boot is passed clear bit to allow access. */ + fid &= CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION_INV; + } +# endif + + /* Check Debugger Protection */ +# if (CRYPTO_30_LIBCV_KEYELEMENTSDEBUGGERPROTECTIONIDXOFSHEPAGE == STD_ON) + localElementIndex = Crypto_30_LibCv_GetKeyElementsDebuggerProtectionIdxOfShePage(CRYPTO_30_LIBCV_SHE_PAGE0); + if ((Crypto_30_LibCv_IsModuleDebuggerProtected(Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(localElementIndex)))) && + (Crypto_30_LibCv_GetKeyElementWrittenLength(localElementIndex) == 1u)) + { + /* If no Debugger is attached clear bit to allow access. */ + fid &= CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION_INV; + } +# endif + + /* Check Result */ + if (fid == Crypto_30_LibCv_SheKeyServiceFlagsResult[serviceType]) + { + retVal = TRUE; + } + } + else + { + retVal = TRUE; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementGetSheCheckFid() */ +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) */ +#endif /* (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGet_Standard() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGet_Standard( + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + Crypto_30_LibCv_LengthCheckType lengthCheck) +{ + Std_ReturnType retVal; + + if (Crypto_30_LibCv_Local_KeyElementGetLengthCheck(resultLengthPtr, elementIndex, lengthCheck) == TRUE) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + { + *resultIndexPtr = Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(elementIndex); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + /* [SWS_Crypto_00092] */ + *resultLengthPtr = Crypto_30_LibCv_GetKeyElementWrittenLength(elementIndex); /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_WITH_DET_CHECK */ + retVal = E_OK; + } + else + { + /* [SWS_Crypto_00093] */ + retVal = CRYPTO_E_SMALL_BUFFER; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementGet_Standard() */ + +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel( + P2CONST(uint8, AUTOMATIC, AUTOMATIC) dataPtr, + uint32 length, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputPtr) +{ + /* + AES-MP(x i): OUT_i = ENC_(ECB, OUT_i-1) (x i) XOR x_i XOR OUT_i-1; i > 0; OUT_0 = 0; + */ + eslt_WorkSpaceAES128Block workSpaceAes128Block; + Std_ReturnType retVal = E_NOT_OK; + uint32 currentOffset = 0u; + uint8_least i; + uint8 Out[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY]; + uint8 Out_last[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY]; + uint8 tempCalcByte; + eslt_ErrorCode eslRetVal = ESL_ERC_ERROR; + + /* #10 initialize all parameters */ + /* Init Out_i-1 (Out_last) */ + Crypto_30_LibCv_ClearData(Out, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + Crypto_30_LibCv_ClearData(Out_last, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + + /* #15 initialize workspace */ + if (esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workSpaceAes128Block.header, /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + ESL_MAXSIZEOF_WS_AES128, + CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) + { + /* #20 Calculate Block-Hash until data size is reached */ + for(currentOffset = 0u; currentOffset < length; currentOffset += CRYPTO_30_LIBCV_SIZEOF_SHE_KEY) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND */ + { + /* Set Key */ + /* #25 Set old Hash as round Key */ + eslRetVal = esl_initEncryptAES128Block((P2VAR(eslt_WorkSpaceAES128Block, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workSpaceAes128Block, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Out_last); /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS */ + + /* Encrypt */ + /* #30 Calculate new Hash */ + if (eslRetVal == ESL_ERC_NO_ERROR) + { + eslRetVal = esl_encryptAES128Block((P2VAR(eslt_WorkSpaceAES128Block, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workSpaceAes128Block, + &dataPtr[currentOffset], + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Out); /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS_AND_PTR_AS_PARAMETER */ + } + + if (eslRetVal == ESL_ERC_NO_ERROR) + { + /* #35 Exor new and old hash */ + for (i = 0u; i < CRYPTO_30_LIBCV_SIZEOF_SHE_KEY; i++) + { + /* Calculate Out and Out_last */ + tempCalcByte = (uint8)(Out_last[i] ^ Out[i] ^ dataPtr[currentOffset + i]); + Out_last[i] = tempCalcByte; /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + Out[i] = tempCalcByte; /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + } + } + else + { + break; + } + } + } + + /* #40 Save Result if compression was successful */ + if (eslRetVal == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + + Crypto_30_LibCv_CopyData(outputPtr, Out, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCmac() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC( Std_ReturnType, CRYPTO_30_LIBCV_CODE ) Crypto_30_LibCv_SheKeyUpdateCmac( + P2CONST( uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR ) dataPtr, + uint32 length, + P2CONST( uint8, AUTOMATIC, AUTOMATIC ) keyPtr, + P2VAR( uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR ) outputPtr, + P2VAR(eslt_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + Std_ReturnType retVal = E_NOT_OK; + + /* #10 Init work space */ + if (esl_initWorkSpaceHeader(&workspace->header, /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + ESL_MAXSIZEOF_WS_CMACAES, + CRYPTO_30_LIBCV_WATCHDOG_PTR ) == ESL_ERC_NO_ERROR) + { + /* #15 Init CMAC */ + if (esl_initCMACAES128( workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_KEY_PTR */ + CRYPTO_30_LIBCV_CMACAES128_KEY_SIZE, + (P2CONST( eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR ))keyPtr ) == ESL_ERC_NO_ERROR) + { + + /* #25 Update Calculation */ + if (esl_updateCMACAES128(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_DATA_PTR */ + (eslt_Length)length, + (P2CONST( eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR ))dataPtr ) == ESL_ERC_NO_ERROR) + { + /* Finalize */ + if (esl_finalizeCMACAES128(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_OUTPUT_PTR */ + outputPtr ) == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + } + } + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateCmac() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateDecrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateDecrypt( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m2m3, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputPtr) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_WorkSpaceAES128 workSpaceAes128; + eslt_ErrorCode eslRet; + eslt_Length outLength = 2u * CRYPTO_30_LIBCV_AES_BLOCK_SIZE; + eslt_Length written; + + /* #10 Init work space */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workSpaceAes128.header, + ESL_MAXSIZEOF_WS_AES128, + CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + + /* #15 Init AES decryption */ + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_initDecryptAES128((P2VAR(eslt_WorkSpaceAES128, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workSpaceAes128, /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_KEY_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))keyPtr, + ESL_BM_CBC, + ESL_PM_OFF, + NULL_PTR); + } + + /* #20 Decrypt data */ + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_decryptAES128((P2VAR(eslt_WorkSpaceAES128, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workSpaceAes128, + (eslt_Length)2u * CRYPTO_30_LIBCV_AES_BLOCK_SIZE, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))m2m3, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))outputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_DATA_OUTPUT */ + } + + written = outLength; + outLength = (eslt_Length)(((eslt_Length)(2u * CRYPTO_30_LIBCV_AES_BLOCK_SIZE)) - written); + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_finalizeDecryptAES128((P2VAR(eslt_WorkSpaceAES128, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workSpaceAes128, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputPtr[written]); + } + + written = (eslt_Length)(written + outLength); + + if ((eslRet == ESL_ERC_NO_ERROR) && + (written == (2u * CRYPTO_30_LIBCV_AES_BLOCK_SIZE))) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateDecrypt() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateEncrypt() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateEncrypt( + P2CONST(uint8, AUTOMATIC, AUTOMATIC) dataPtr, + P2CONST(uint8, AUTOMATIC, AUTOMATIC) keyPtr, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputPtr, + uint8 numberOfBlocks) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode eslRet; + eslt_WorkSpaceAES128 workSpaceAes128; + eslt_Length outLength = (eslt_Length)((eslt_Length)(numberOfBlocks) * CRYPTO_30_LIBCV_AES_BLOCK_SIZE); + eslt_Length written; + + /* #10 Init work space */ + eslRet = esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(workSpaceAes128.header), /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_STACK_WORKSPACE */ + ESL_MAXSIZEOF_WS_AES128, + CRYPTO_30_LIBCV_WATCHDOG_PTR); + + /* #15 Init AES encryption */ + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_initEncryptAES128((P2VAR(eslt_WorkSpaceAES128, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workSpaceAes128, /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_KEY_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))keyPtr, + ESL_BM_CBC, + ESL_PM_OFF, + NULL_PTR); + } + + /* #20 encrypt data */ + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_encryptAES128((P2VAR(eslt_WorkSpaceAES128, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workSpaceAes128, /* SBSW_CRYPTO_30_LIBCV_ESL_STACK_WORKSPACE_WITH_DATA_OUTPUT */ + (eslt_Length)((eslt_Length)(numberOfBlocks) * CRYPTO_30_LIBCV_AES_BLOCK_SIZE), + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))dataPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))&outLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))outputPtr); + } + + written = outLength; + outLength = (eslt_Length)(((eslt_Length)numberOfBlocks * CRYPTO_30_LIBCV_AES_BLOCK_SIZE) - written); + + if (eslRet == ESL_ERC_NO_ERROR) + { + eslRet = esl_finalizeEncryptAES128((P2VAR(eslt_WorkSpaceAES128, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workSpaceAes128, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputPtr[written]); + } + + written = (eslt_Length)(written + outLength); + + if ((eslRet == ESL_ERC_NO_ERROR) && + (written == ((eslt_Length)numberOfBlocks * CRYPTO_30_LIBCV_AES_BLOCK_SIZE))) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateEncrypt() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_GetSheKey() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_GetSheKey( + uint8 sheKeyId, + Crypto_30_LibCv_SizeOfShePageType shePage, + P2VAR(Crypto_30_LibCv_SizeOfSheKeysType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) indexOfSheKeyPtr) +{ + Std_ReturnType found = E_NOT_OK; + Crypto_30_LibCv_SheKeysIterType i; + + /* Get SHE index in SheKeys for the given SHE Id and Page. */ + for (i = 0u; i < Crypto_30_LibCv_GetSizeOfSheKeys(); i++) + { + if ((Crypto_30_LibCv_GetSheIdOfSheKeys(i) == sheKeyId) && + (Crypto_30_LibCv_GetShePageIdxOfSheKeys(i) == shePage)) + { + *indexOfSheKeyPtr = (Crypto_30_LibCv_SizeOfSheKeysType)i; /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + found = E_OK; + break; + } + } + + return found; +} /* Crypto_30_LibCv_GetSheKey() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCheckM1Ids() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6030, 6080 4 */ /* MD_MSR_STCYC, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateCheckM1Ids( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey, + P2VAR(Crypto_30_LibCv_SizeOfSheKeysType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) indexOfAuthSheKeyPtr) +{ + Std_ReturnType retVal = E_NOT_OK; + uint8 m1AuthId, m1SheId; + Crypto_30_LibCv_SizeOfShePageType authPage; + boolean loadAuthKey = FALSE; + + m1AuthId = Crypto_30_LibCv_She_M1_GetAuthId(m1m2m3[CRYPTO_30_LIBCV_STARTINDEX_SHE_M1_IDS]); + m1SheId = Crypto_30_LibCv_She_M1_GetId(m1m2m3[CRYPTO_30_LIBCV_STARTINDEX_SHE_M1_IDS]); + + /* Secret key */ + if (m1SheId == CRYPTO_30_LIBCV_SHE_M1_SECRET_KEY_ID) + { + /* not possible */ + } + /* check if keyId matches configured key elementId */ + else if (m1SheId == Crypto_30_LibCv_GetSheIdOfSheKeys(indexOfSheKey)) + { + /* set default page to 0 */ + authPage = CRYPTO_30_LIBCV_SHE_PAGE0; + + /* master key, mac key and key_ */ + if ((m1SheId != CRYPTO_30_LIBCV_SHE_M1_MAC_ID) && + (m1SheId <= CRYPTO_30_LIBCV_SHE_M1_KEY_N_END_ID)) + { + /* Master key authentication */ + if (m1AuthId == CRYPTO_30_LIBCV_SHE_M1_ECU_MASTER_KEY_ID) /* COV_CRYPTO_30_LIBCV_SHE_KEY_CONFIGURATION */ + { + loadAuthKey = TRUE; + } + /* Self update */ + else if (m1AuthId == m1SheId) + { + /* Use index from update key to refer to all required information e.g. SHE page */ + *indexOfAuthSheKeyPtr = indexOfSheKey; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + retVal = E_OK; + } + else + { + /* not valid */ + } + } + /* mac */ + else if (m1SheId == CRYPTO_30_LIBCV_SHE_M1_MAC_ID) + { + /* Master key authentication */ + if (m1AuthId == CRYPTO_30_LIBCV_SHE_M1_ECU_MASTER_KEY_ID) /* COV_CRYPTO_30_LIBCV_SHE_KEY_CONFIGURATION */ + { + loadAuthKey = TRUE; + } + /* Mac key authentication */ + else if (m1AuthId == CRYPTO_30_LIBCV_SHE_M1_MAC_KEY_ID) /* COV_CRYPTO_30_LIBCV_SHE_KEY_CONFIGURATION */ + { + loadAuthKey = TRUE; + } + else + { + /* not valid */ + } + } + /* ram key */ + else + { + /* Secret key authentication */ + if (m1AuthId == CRYPTO_30_LIBCV_SHE_M1_SECRET_KEY_ID) + { + loadAuthKey = TRUE; + } + /* KEY_N authentication on the same page */ + else if ((m1AuthId >= CRYPTO_30_LIBCV_SHE_M1_KEY_N_START_ID) && + (m1AuthId <= CRYPTO_30_LIBCV_SHE_M1_KEY_N_END_ID)) + { + loadAuthKey = TRUE; + authPage = Crypto_30_LibCv_GetShePageIdxOfSheKeys(indexOfSheKey); + } + else + { + /* retVal is already set */ + } + } + + if (loadAuthKey == TRUE) + { + retVal = Crypto_30_LibCv_GetSheKey(m1AuthId, authPage, indexOfAuthSheKeyPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + } + else + { + /* not possible */ + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateCheckM1Ids() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCheckUid() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 4 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateCheckUid( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + Crypto_30_LibCv_SheKeyTypeType sheKeyType) +{ + uint8 i; + Std_ReturnType retVal = E_NOT_OK; + boolean verified; + uint32 uidLength = CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID; + Crypto_30_LibCv_SizeOfKeyStorageType uIdStorageIndex; + + verified = TRUE; + /* Check if the value is wildcard */ + for (i = 0u; i < CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID; i++) + { + if (m1m2m3[i] != CRYPTO_30_LIBCV_SHE_UID_WILDCARD_VALUE) + { + verified = FALSE; + break; + } + } + + /* check UID if the wildcard is not matching. */ + if (verified == FALSE) + { + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex(Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate(), CRYPTO_KE_CUSTOM_SHE_UID, &uIdStorageIndex, &uidLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MIN) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + verified = TRUE; + for (i = 0u; i < CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID; i++) + { + if (m1m2m3[i] != Crypto_30_LibCv_GetKeyStorage(uIdStorageIndex + i)) + { + verified = FALSE; + break; + } + } + } + } + else + { +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) + /* If the wildcard is valid, check if it is valid to use the wildcard. */ + if ((Crypto_30_LibCv_IsKeyElementExtensionByMask(elementIndex, CRYPTO_30_LIBCV_SHE_FID_MASK_WILDCARD)) && + (sheKeyType != CRYPTO_30_LIBCV_SHE_TYPE_RAM_KEY)) + { + verified = FALSE; + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(sheKeyType); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(elementIndex); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + } + + if (verified == TRUE) + { + retVal = E_OK; + } + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateCheckUid() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateVerifyM3() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060, 6080 8 */ /* MD_CRYPTO_30_LIBCV_STPAR, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateVerifyM3( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfSheKeysType indexOfAuthSheKey, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) KDFbufferPtr, + uint8 KDFbufferLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputBufferPtr) +{ + Std_ReturnType retVal = E_NOT_OK; + uint8_least i; + /* Buffer */ + uint8 key[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY]; /* K2 */ + uint32 authKeyLength = CRYPTO_30_LIBCV_SIZEOF_SHE_KEY; + Crypto_30_LibCv_SizeOfKeyStorageType keyStorageIndex; + eslt_WorkSpaceCMACAES workSpaceCmacAes; + + if (Crypto_30_LibCv_IsKeyElementValid(Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(indexOfAuthSheKey))) + { + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic( Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(indexOfAuthSheKey), &keyStorageIndex, &authKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL, CRYPTO_30_LIBCV_SHE_SERVICE_KEY_SERVICE) == E_OK) /* COV_CRYPTO_30_LIBCV_SHE_KEY_CONFIGURATION_2 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + /* Set constant for SHE page handling */ + /* Set Key_Update_Mac_C constant */ + Crypto_30_LibCv_CopyData(&KDFbufferPtr[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY], Crypto_30_LibCv_She_GetPtrMacConst(indexOfSheKey), CRYPTO_30_LIBCV_SIZEOF_SHE_UPDATE_CONSTANT); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + /* #10 Generate K2 */ + /* KDF AuthKey|Key_Update_Mac_C */ + Crypto_30_LibCv_CopyData(KDFbufferPtr, Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndex), CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + if (Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel(KDFbufferPtr, KDFbufferLength, key) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_AND_KEY */ + { + + /* #15 Calculate M3 / CMAC and verify */ + /* M3 proof: M3* = outputBufferPtr */ + if (Crypto_30_LibCv_SheKeyUpdateCmac(m1m2m3, CRYPTO_30_LIBCV_STARTINDEX_SHE_M3, key, outputBufferPtr, (P2VAR(eslt_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&workSpaceCmacAes) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR_KEY_OUTPUT */ + { + retVal = E_OK; + /* Check (M3 = M3*) */ + for (i = 0u; i < CRYPTO_30_LIBCV_SIZEOF_SHE_M3; i++) + { + if (m1m2m3[i + CRYPTO_30_LIBCV_STARTINDEX_SHE_M3] != outputBufferPtr[i]) + { + retVal = E_NOT_OK; + } + } + } + } + } + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateVerifyM3() */ + +# if(CRYPTO_30_LIBCV_SHE_ENABLE_COUNTER == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCheckCounter() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateCheckCounter( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexCounter, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) decryptedKeyPtr, + Crypto_30_LibCv_SheKeyTypeType sheKeyType) +{ + uint32 oldCounter, newCounter; + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyStorageType keyStorage; + uint32 counterLength = CRYPTO_30_LIBCV_SIZEOF_SHE_M4_COUNTER_FULL_BYTES; + + if (sheKeyType == CRYPTO_30_LIBCV_SHE_TYPE_RAM_KEY) + { + /* no counter check for ram key */ + retVal = E_OK; + } + else + { + /* There is a validation that there need to be a counter */ + (void)Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic( elementIndexCounter, &keyStorage, &counterLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL, CRYPTO_30_LIBCV_SHE_SERVICE_KEY_SERVICE);/* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&oldCounter, Crypto_30_LibCv_GetAddrKeyStorage(keyStorage));/* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&newCounter, decryptedKeyPtr);/* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + newCounter = Crypto_30_LibCv_She_ConvertCounter(newCounter); + + /* check if new counter is bigger */ + if ((newCounter) > (oldCounter)) + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateCheckCounter() */ +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_COUNTER == STD_ON) */ + +# if(CRYPTO_30_LIBCV_SHE_ENABLE_COUNTER == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCopyCounter() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateCopyCounter( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexCounter, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) decryptedKeyPtr) +{ + uint32 newCounter; + uint8 counterValue[CRYPTO_30_LIBCV_SIZEOF_SHE_M4_COUNTER_FULL_BYTES]; + + /* Save the new counter value. */ + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&newCounter, decryptedKeyPtr); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + newCounter = Crypto_30_LibCv_She_ConvertCounter(newCounter); + Crypto_30_LibCv_Local_Uint32ToUint8ArrayBigEndian(counterValue, newCounter);/* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + Crypto_30_LibCv_KeyElementSetInternalStandardWithCryptoKeyId(cryptoKeyId, elementIndexCounter, counterValue, CRYPTO_30_LIBCV_SIZEOF_SHE_M4_COUNTER_FULL_BYTES);/* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ +} /* Crypto_30_LibCv_SheKeyUpdateCopyCounter() */ +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_COUNTER == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateCopyFid() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateCopyFid( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) decryptedKeyPtr, + Crypto_30_LibCv_SheKeyTypeType sheKeyType) +{ + uint8 fid; + + /* Convert FID */ + fid = (uint8)(((uint8)(decryptedKeyPtr[3] << 4)) | ((uint8)(decryptedKeyPtr[4] >> 4) & 0x0Cu)); + + /* Add flag for SHE key identification. */ + fid |= CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_SHE_KEY_MASK; + Crypto_30_LibCv_SetKeyStorage(Crypto_30_LibCv_GetKeyStorageExtensionIdxOfKeyElements(elementIndex), fid); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + + /* Add write once flag in key element state. */ + if ((Crypto_30_LibCv_Uint8CheckMask(fid, CRYPTO_30_LIBCV_SHE_FID_MASK_WRITE_PROTECTION)) && + (sheKeyType != CRYPTO_30_LIBCV_SHE_TYPE_RAM_KEY)) + { + Crypto_30_LibCv_SetKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + } + else + { + Crypto_30_LibCv_ClearKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_INV_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + } +} /* Crypto_30_LibCv_SheKeyUpdateCopyFid() */ +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateExtractKey() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateExtractKey( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) KDFbufferPtr, + uint8 KDFbufferLength, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputBufferPtr, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey) +{ + Std_ReturnType retVal = E_NOT_OK; + uint8_least i; + /* Buffer */ + uint8 key[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY]; + Crypto_30_LibCv_KeyStorageIterType keyStorageIndex = Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(elementIndex); + /* #10 Generate K1 */ + /* Set Key_Update_Enc_C constant */ + Crypto_30_LibCv_CopyData(&KDFbufferPtr[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY], Crypto_30_LibCv_She_GetPtrEncConst(indexOfSheKey), CRYPTO_30_LIBCV_SIZEOF_SHE_UPDATE_CONSTANT); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + if (Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel(KDFbufferPtr, KDFbufferLength, key) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_AND_KEY */ + { + Crypto_30_LibCv_ClearData(outputBufferPtr, CRYPTO_30_LIBCV_SIZEOF_SHE_M2); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + /* #15 Decrypt C,K,F */ + if (Crypto_30_LibCv_SheKeyUpdateDecrypt(&m1m2m3[CRYPTO_30_LIBCV_STARTINDEX_SHE_M2], key, outputBufferPtr) == E_OK) /* SBSW_CRYPTO_30_LIBCV_KEY_OUTPUT_BUFFER_PARAMETER_KEY_STACK */ + { + /* check counter */ +# if(CRYPTO_30_LIBCV_SHE_ENABLE_COUNTER == STD_ON) + Crypto_30_LibCv_SheKeyTypeType sheKeyType; + sheKeyType = Crypto_30_LibCv_SheKeyGetKeyType(Crypto_30_LibCv_GetSheIdOfSheKeys(indexOfSheKey)); + if (Crypto_30_LibCv_SheKeyUpdateCheckCounter(Crypto_30_LibCv_GetKeyElementsCounterIdxOfSheKeys(indexOfSheKey), outputBufferPtr, sheKeyType) == E_OK) /* SBSW_CRYPTO_30_LIBCV_KEY_OUTPUT_BUFFER_PARAMETER_KEY_STACK */ +# endif + { + /* #20 Store new Key and key length. */ + for (i = 0u; i < CRYPTO_30_LIBCV_SIZEOF_SHE_KEY; i++) + { + Crypto_30_LibCv_SetKeyStorage(keyStorageIndex + i, outputBufferPtr[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY + i]); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + + /* KDF Key|Key_Update_Enc_C */ + KDFbufferPtr[i] = outputBufferPtr[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY + i]; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } + + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(cryptoKeyId, elementIndex, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); + retVal = E_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateExtractKey() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateGenM4M5() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateGenM4M5( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m4m5, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) uid, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) KDFbufferPtr, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) encBufferPtr, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey) +{ + Std_ReturnType retVal = E_NOT_OK; + /* Buffer */ + uint8 key[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY]; /* Key3 and Key4 */ + eslt_WorkSpaceCMACAES workSpaceCmacAes; + + /* Set Key_Update_Enc_C constant */ + Crypto_30_LibCv_CopyData(&KDFbufferPtr[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY], Crypto_30_LibCv_She_GetPtrEncConst(indexOfSheKey), CRYPTO_30_LIBCV_SIZEOF_SHE_UPDATE_CONSTANT); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + /* # Generate K3 */ + if (Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel(KDFbufferPtr, CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER, key) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_AND_KEY */ + { + /* # Generate M4* */ + /* counter(28bits) | "1" | "0" ... "0"x99 (=128 bit) */ + encBufferPtr[CRYPTO_30_LIBCV_SIZEOF_SHE_M4_COUNTER_FULL_BYTES - 1u] |= 0x08u; /* Add leading one for padding ENC(ECB,K3) */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + encBufferPtr[CRYPTO_30_LIBCV_SIZEOF_SHE_M4_COUNTER_FULL_BYTES - 1u] &= 0xF8u; /* Add leading zero for padding ENC(ECB,K3) */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + /* Add padding */ + Crypto_30_LibCv_ClearData(&(encBufferPtr[4]), CRYPTO_30_LIBCV_SIZEOF_SHE_M4_ENC - CRYPTO_30_LIBCV_SIZEOF_SHE_M4_COUNTER_FULL_BYTES); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + /* # Copy UID of M4 */ + Crypto_30_LibCv_CopyData(m4m5, uid, CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + + /* # Copy Ids of M4 */ + Crypto_30_LibCv_CopyData(&m4m5[CRYPTO_30_LIBCV_STARTINDEX_SHE_M1_IDS], &m1m2m3[CRYPTO_30_LIBCV_STARTINDEX_SHE_M1_IDS], CRYPTO_30_LIBCV_SIZEOF_SHE_M1_IDS); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + + /* # Generate and store second block of M4 */ + if (Crypto_30_LibCv_SheKeyUpdateEncrypt(encBufferPtr, key, &m4m5[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY], 1u) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR_KEY_OUTPUT */ + { + /* Set Key_Update_Mac_C constant */ + Crypto_30_LibCv_CopyData(&KDFbufferPtr[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY], Crypto_30_LibCv_She_GetPtrMacConst(indexOfSheKey), CRYPTO_30_LIBCV_SIZEOF_SHE_UPDATE_CONSTANT); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + /* # Generate K4 */ + if (Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel(KDFbufferPtr, CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER, key) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_AND_KEY */ + { + /* Generate M5 */ + retVal = Crypto_30_LibCv_SheKeyUpdateCmac(m4m5, 32u, key, &m4m5[32], &workSpaceCmacAes); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + } + } + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateGenM4M5() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateProofM4M5() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateProofM4M5( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfKeyElementsType outputElement, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) KDFbufferPtr, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) outputBufferPtr, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey) +{ + Std_ReturnType retVal = E_NOT_OK; + uint32 uidLength = CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID; + Crypto_30_LibCv_SizeOfKeyStorageType uIdStorageIndex; + /* Buffer */ + uint8 m4m5[CRYPTO_30_LIBCV_SIZEOF_SHE_M4_M5]; + + /* # Copy UID of M4 */ + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex(Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate(), CRYPTO_KE_CUSTOM_SHE_UID, &uIdStorageIndex, &uidLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MIN) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + + /* # Build M4 and M5 */ + retVal = Crypto_30_LibCv_SheKeyUpdateGenM4M5(m1m2m3, m4m5, Crypto_30_LibCv_GetAddrKeyStorage(uIdStorageIndex), KDFbufferPtr, outputBufferPtr, indexOfSheKey); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_KEY_OUTPUTBUFFER */ + if (retVal == E_OK) + { + /* # Copy M4 & M5 */ + Crypto_30_LibCv_CopyData(Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(outputElement), m4m5, CRYPTO_30_LIBCV_SIZEOF_SHE_M4_M5); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + + /* # Store written length */ + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(cryptoKeyId, outputElement, CRYPTO_30_LIBCV_SIZEOF_SHE_M4_M5); + } + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateProofM4M5() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateFindProof() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateFindProof( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_KeyElementsIterType, AUTOMATIC, AUTOMATIC) outputElementIndexPtr) +{ + Std_ReturnType retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + Crypto_30_LibCv_KeyElementsIterType outputElement; + + /* Determine proof output slot */ + for (outputElement = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(cryptoKeyId); /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + outputElement < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(cryptoKeyId); + outputElement++) + { + if ((Crypto_30_LibCv_GetIdOfKeyElements(outputElement) == CRYPTO_KE_MAC_PROOF)|| + (Crypto_30_LibCv_GetIdOfKeyElements(outputElement) == CRYPTO_KE_CIPHER_PROOF)) + { + if ((Crypto_30_LibCv_GetKeyStorageEndIdxOfKeyElements(outputElement) - Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(outputElement)) >= (uint16)CRYPTO_30_LIBCV_SIZEOF_SHE_M4_M5) + { + *outputElementIndexPtr = outputElement; /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + retVal = E_OK; + } + else + { + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateFindProof() */ + +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateLockKeys() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateLockKeys( + uint32 cryptoKeyId, + uint32 authKeyId) +{ + Std_ReturnType retVal = E_NOT_OK; + uint32 sheInfoKeyId; + + sheInfoKeyId = Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate(); + /* check if SHE info need to be locked */ + if (Crypto_30_LibCv_Local_KeyReadLockGet(sheInfoKeyId) == E_OK) + { + /* check if SHE info need to be locked */ + if (authKeyId != cryptoKeyId) + { + if (Crypto_30_LibCv_Local_KeyReadLockGet(authKeyId) == E_OK) + { + retVal = E_OK; + } + else + { + Crypto_30_LibCv_Local_KeyReadLockRelease(sheInfoKeyId); + } + } + else + { + retVal = E_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateLockKeys() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateUnlockKeys() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateUnlockKeys( + uint32 cryptoKeyId, + uint32 authKeyId) +{ + uint32 sheInfoKeyId; + + sheInfoKeyId = Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate(); + + Crypto_30_LibCv_Local_KeyReadLockRelease(sheInfoKeyId); + + if (authKeyId != cryptoKeyId) + { + Crypto_30_LibCv_Local_KeyReadLockRelease(authKeyId); + } +} /* Crypto_30_LibCv_SheKeyUpdateUnlockKeys() */ +# endif /* (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdateVerifyAndExtract() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdateVerifyAndExtract( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey, + Crypto_30_LibCv_SizeOfSheKeysType indexOfAuthSheKey, + Crypto_30_LibCv_SizeOfKeyElementsType outputElement, + Std_ReturnType proofAvailable) +{ + /* # Init KDF Parameters */ + /* KDF Buffer */ + uint8 KDFbuffer[CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER]; + + /* # Init Workspace */ + /* Working Buffers */ + uint8 encBuffer[CRYPTO_30_LIBCV_SIZEOF_ENC_BUFFER]; + + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SheKeyTypeType sheKeyType = Crypto_30_LibCv_SheKeyGetKeyType(Crypto_30_LibCv_GetSheIdOfSheKeys(indexOfSheKey)); + + /* # Verify M3 */ + if (Crypto_30_LibCv_SheKeyUpdateVerifyM3(m1m2m3, indexOfAuthSheKey, indexOfSheKey, KDFbuffer, CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER, encBuffer) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_KEY_OUTPUTBUFFER */ + { + /* # check UID */ + if (Crypto_30_LibCv_SheKeyUpdateCheckUid(m1m2m3, elementIndex, sheKeyType) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + { + /* # Extract Key */ + retVal = Crypto_30_LibCv_SheKeyUpdateExtractKey(cryptoKeyId, m1m2m3, elementIndex, KDFbuffer, CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER, encBuffer, indexOfSheKey); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_KEY_OUTPUTBUFFER */ + + if (retVal == E_OK) + { + /* store FID and Counter */ +# if(CRYPTO_30_LIBCV_SHE_ENABLE_COUNTER == STD_ON) + /* RAM key has no counter */ + if (Crypto_30_LibCv_IsKeyElementsCounterUsedOfSheKeys(indexOfSheKey)) + { + Crypto_30_LibCv_SheKeyUpdateCopyCounter(cryptoKeyId, Crypto_30_LibCv_GetKeyElementsCounterIdxOfSheKeys(indexOfSheKey), encBuffer); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + } +# endif +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) + Crypto_30_LibCv_SheKeyUpdateCopyFid(elementIndex, encBuffer, sheKeyType); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ +# else + Crypto_30_LibCv_ClearKeyElementExtensionByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_SHE_CLEAR_PLAIN_KEY_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ +# endif + + /* # Generate M4 & M5, if proof slot is available */ + if (proofAvailable == E_OK) + { + retVal = Crypto_30_LibCv_SheKeyUpdateProofM4M5(cryptoKeyId, m1m2m3, (Crypto_30_LibCv_SizeOfKeyElementsType)outputElement, KDFbuffer, encBuffer, indexOfSheKey); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_KEY_OUTPUTBUFFER */ + } + } + } + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdateVerifyAndExtract() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyUpdate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 5 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyUpdate( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3) +{ + Std_ReturnType retVal = E_NOT_OK; + Std_ReturnType proofAvailable; + Crypto_30_LibCv_KeyElementsIterType outputElement = 0u; + Crypto_30_LibCv_SizeOfSheKeysType indexOfAuthSheKey = 0u; + + /* # Determine proof output slot */ + proofAvailable = Crypto_30_LibCv_SheKeyUpdateFindProof(cryptoKeyId, &outputElement); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if ((proofAvailable == E_OK) || + (proofAvailable == CRYPTO_E_KEY_NOT_AVAILABLE)) + { + /*# Check key ID */ + if (Crypto_30_LibCv_SheKeyUpdateCheckM1Ids(m1m2m3, indexOfSheKey, &indexOfAuthSheKey) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + retVal = Crypto_30_LibCv_SheKeyUpdateLockKeys(cryptoKeyId, Crypto_30_LibCv_GetKeyIdxOfSheKeys(indexOfAuthSheKey)); + + if (retVal == E_OK) + { +# endif + /* # Verify M3, Extract Key and Generate M4 & M5, if proof slot is available */ + retVal = Crypto_30_LibCv_SheKeyUpdateVerifyAndExtract(cryptoKeyId, elementIndex, m1m2m3, indexOfSheKey, indexOfAuthSheKey, (Crypto_30_LibCv_SizeOfKeyElementsType)outputElement, proofAvailable); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_SheKeyUpdateUnlockKeys(cryptoKeyId, Crypto_30_LibCv_GetKeyIdxOfSheKeys(indexOfAuthSheKey)); + } + else + { + retVal = CRYPTO_E_BUSY; + } +# endif + } + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementSetShe() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6080 6 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementSetShe( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength, + Std_ReturnType oldRetVal) +{ + Std_ReturnType retVal = oldRetVal; + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey; + + /* Check if it is a write once key which is written already. */ + if (Crypto_30_LibCv_IsKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_MASK)) + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + } + /* Key update using SHE key update protocol */ + else if ((keyLength == CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M3) && + (Crypto_30_LibCv_GetKeyElementLength(elementIndex) == CRYPTO_30_LIBCV_SIZEOF_SHE_KEY)) + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + if (Crypto_30_LibCv_SheKeyGetSheIndex(elementIndex, &indexOfSheKey) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + if ((CRYPTO_30_LIBCV_WA_ENCRYPTED == Crypto_30_LibCv_GetWriteOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndex))) || + ((CRYPTO_30_LIBCV_WA_ALLOWED == Crypto_30_LibCv_GetWriteOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndex))) && + (Crypto_30_LibCv_GetSheIdOfSheKeys(indexOfSheKey) == CRYPTO_30_LIBCV_SHE_M1_RAM_KEY_ID))) + { + /* She Key Protocol */ + retVal = Crypto_30_LibCv_SheKeyUpdate(cryptoKeyId, elementIndex, indexOfSheKey, keyPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + } + } + } + /* Set plaintext ram key */ + else if (keyLength == CRYPTO_30_LIBCV_SIZEOF_SHE_KEY) + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + if (CRYPTO_30_LIBCV_WA_ALLOWED == Crypto_30_LibCv_GetWriteOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndex))) + { + /* Is the given key a she key and is it a ram key. */ + if (Crypto_30_LibCv_SheKeyGetSheIndex(elementIndex, &indexOfSheKey) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + if (Crypto_30_LibCv_GetSheIdOfSheKeys(indexOfSheKey) == CRYPTO_30_LIBCV_SHE_M1_RAM_KEY_ID) + { + /* Set ram key as plaintext. */ + retVal = Crypto_30_LibCv_Local_KeyElementSetInternal(cryptoKeyId, elementIndex, keyPtr, keyLength, CRYPTO_30_LIBCV_WA_ENCRYPTED); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + + if (retVal == E_OK) + { + Crypto_30_LibCv_SetKeyElementExtensionByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_SHE_PLAIN_KEY_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + } + } + } + } + } + else + { + /* nothing to do */ + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementSetShe() */ + +# if (CRYPTO_30_LIBCV_RAM_KEY_EXPORT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetShe() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +/* PRQA S 6080 5 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetShe( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr) +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey, indexOfAuthSheKey = 0u; + /* Is it a she key */ + if (Crypto_30_LibCv_SheKeyGetSheIndex(elementIndex, &indexOfSheKey) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* Is it the ram key */ + if (Crypto_30_LibCv_GetSheIdOfSheKeys(indexOfSheKey) == CRYPTO_30_LIBCV_SHE_M1_RAM_KEY_ID) + { + if (*resultLengthPtr >= CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M3) + { + /* Get Secret Key, find key can be voided because secret key must be available for ram key */ + (void)Crypto_30_LibCv_GetSheKey(CRYPTO_30_LIBCV_SHE_M1_SECRET_KEY_ID, CRYPTO_30_LIBCV_SHE_PAGE0, &indexOfAuthSheKey); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* Lock Keys */ + retVal = Crypto_30_LibCv_SheKeyUpdateLockKeys(cryptoKeyId, (uint32)Crypto_30_LibCv_GetKeyIdxOfSheKeys(indexOfAuthSheKey)); + + if (retVal == E_OK) + { +# endif + /* export key */ + retVal = Crypto_30_LibCv_SheKeyExport(indexOfSheKey, indexOfAuthSheKey, resultPtr, resultLengthPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* Unlock Keys */ + Crypto_30_LibCv_SheKeyUpdateUnlockKeys(cryptoKeyId, Crypto_30_LibCv_GetKeyIdxOfSheKeys(indexOfAuthSheKey)); + } + else + { + retVal = CRYPTO_E_BUSY; + } +# endif + } + else + { + retVal = CRYPTO_E_SMALL_BUFFER; + } + } + else + { + retVal = CRYPTO_E_KEY_READ_FAIL; + } + } + else + { + retVal = CRYPTO_E_KEY_READ_FAIL; + } + +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_OFF) + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementGetShe() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyExport_M1M2M3() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyExport_M1M2M3( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) m1m2m3, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) KDFbufferPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) encBufferPtr, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) uid, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) ramKey, + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey) +{ + Std_ReturnType retVal = E_NOT_OK; + uint8 key[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY]; + eslt_WorkSpaceCMACAES workSpaceCmacAes; + + /* M1 */ + Crypto_30_LibCv_CopyData(m1m2m3, uid, CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + m1m2m3[CRYPTO_30_LIBCV_STARTINDEX_SHE_M1_IDS] = Crypto_30_LibCv_She_M1_BuildIds(CRYPTO_30_LIBCV_SHE_M1_RAM_KEY_ID, CRYPTO_30_LIBCV_SHE_M1_SECRET_KEY_ID); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + /* M2 */ + /* Generate K1 */ + /* Set AuthKey|Key_Update_Enc_C constant */ + Crypto_30_LibCv_CopyData(&KDFbufferPtr[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY], Crypto_30_LibCv_She_GetPtrEncConst(indexOfSheKey), CRYPTO_30_LIBCV_SIZEOF_SHE_UPDATE_CONSTANT); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + if (Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel(KDFbufferPtr, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY + CRYPTO_30_LIBCV_SIZEOF_SHE_UPDATE_CONSTANT, key) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_AND_KEY */ + { + + /* Encrypt C,K,F */ + Crypto_30_LibCv_ClearData(encBufferPtr, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + Crypto_30_LibCv_CopyData(&encBufferPtr[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY], ramKey, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + if (Crypto_30_LibCv_SheKeyUpdateEncrypt(encBufferPtr, key, &m1m2m3[CRYPTO_30_LIBCV_STARTINDEX_SHE_M2], 2u) == E_OK) /* SBSW_CRYPTO_30_LIBCV_KEY_OUTPUT_BUFFER_PARAMETER_KEY_STACK */ + { + /* M3 */ + /* Generate K2 */ + /* KDF AuthKey|Key_Update_Mac_C */ + Crypto_30_LibCv_CopyData(&KDFbufferPtr[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY], Crypto_30_LibCv_She_GetPtrMacConst(indexOfSheKey), CRYPTO_30_LIBCV_SIZEOF_SHE_UPDATE_CONSTANT); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + if (Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel(KDFbufferPtr, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY + CRYPTO_30_LIBCV_SIZEOF_SHE_UPDATE_CONSTANT, key) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_AND_KEY */ + { + + /* Calculate M3 CMAC */ + if (Crypto_30_LibCv_SheKeyUpdateCmac(m1m2m3, CRYPTO_30_LIBCV_STARTINDEX_SHE_M3, key, &m1m2m3[CRYPTO_30_LIBCV_STARTINDEX_SHE_M3], &workSpaceCmacAes) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR_KEY_OUTPUT */ + { + retVal = E_OK; + } + } + } + + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyExport_M1M2M3() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_SheKeyExport() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +/* PRQA S 6080 5 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SheKeyExport( + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey, + Crypto_30_LibCv_SizeOfSheKeysType indexOfAuthSheKey, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr) +{ + Std_ReturnType retVal = E_NOT_OK, localRet; + uint8 m1m5[CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M5]; + uint8 kdfBuffer[CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER]; + uint8 encBuffer[CRYPTO_30_LIBCV_SIZEOF_ENC_BUFFER]; + uint32 writtenLength = CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M3; + + Crypto_30_LibCv_SizeOfKeyStorageType uIdStorageIndex, keyStorageIndex, authKeyStorageIndex; + uint32 length; + + /* Get UID */ + length = CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID; + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate(), CRYPTO_KE_CUSTOM_SHE_UID, &uIdStorageIndex, &length, CRYPTO_30_LIBCV_LENGTH_CHECK_MIN); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* Get SecretKey */ + if (localRet == E_OK) + { + length = CRYPTO_30_LIBCV_SIZEOF_SHE_KEY; + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic( Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(indexOfAuthSheKey), &authKeyStorageIndex, &length, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL, CRYPTO_30_LIBCV_SHE_SERVICE_KEY_SERVICE); /* COV_CRYPTO_30_LIBCV_SHE_KEY_CONFIGURATION_2 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + if (!Crypto_30_LibCv_IsKeyElementValid(Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(indexOfAuthSheKey))) + { + localRet = E_NOT_OK; + } + + /* Get RamKey */ + if (localRet == E_OK) + { + length = CRYPTO_30_LIBCV_SIZEOF_SHE_KEY; + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic( Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(indexOfSheKey), &keyStorageIndex, &length, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL, CRYPTO_30_LIBCV_SHE_SERVICE_KEY_SERVICE); /* COV_CRYPTO_30_LIBCV_SHE_KEY_CONFIGURATION_2 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* Check if Ram key is written as plaintext */ + if (localRet == E_OK) + { + if (!Crypto_30_LibCv_IsKeyElementExtensionByMask(Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(indexOfSheKey), CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_SHE_PLAIN_KEY_MASK)) + { + retVal = CRYPTO_E_KEY_READ_FAIL; + localRet = E_NOT_OK; + } + + if (localRet == E_OK) + { + /* Calculate m1-m3 */ + Crypto_30_LibCv_CopyData(kdfBuffer, Crypto_30_LibCv_GetAddrKeyStorage(authKeyStorageIndex), CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + retVal = Crypto_30_LibCv_SheKeyExport_M1M2M3(m1m5, kdfBuffer, encBuffer, Crypto_30_LibCv_GetAddrKeyStorage(uIdStorageIndex), Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndex), indexOfSheKey); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_KEY_OUTPUTBUFFER */ + + /* Calculate m4-m5 if required */ + if ((retVal == E_OK) && + (*resultLengthPtr >= CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M5)) + { + Crypto_30_LibCv_CopyData(kdfBuffer, Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndex), CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + retVal = Crypto_30_LibCv_SheKeyUpdateGenM4M5(m1m5, &m1m5[CRYPTO_30_LIBCV_STARTINDEX_SHE_M4], Crypto_30_LibCv_GetAddrKeyStorage(uIdStorageIndex), kdfBuffer, encBuffer, indexOfSheKey); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KDFBUFFER_KEY_OUTPUTBUFFER */ + writtenLength = CRYPTO_30_LIBCV_SIZEOF_SHE_M1_M5; + } + + /* Copy key Export to the given Buffer. */ + if (retVal == E_OK) + { + Crypto_30_LibCv_CopyData(resultPtr, m1m5, writtenLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_ARRAY_ACCESS_WITH_SIZE_CHECK */ + *resultLengthPtr = writtenLength; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + } + } + } + } + + return retVal; +} /* Crypto_30_LibCv_SheKeyExport() */ +# endif /* (CRYPTO_30_LIBCV_RAM_KEY_EXPORT == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SHE_DEBUG_CMD == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_Authorization() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_Authorization( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) masterKey, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) uid, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) challenge, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) authorization) +{ + Std_ReturnType retVal = E_NOT_OK; + const uint8 debugKeyC[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY] = { 0x01U, 0x03U, 0x53U, 0x48U, 0x45U, 0x00U, 0x80U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xB0U }; + + uint8 key[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY]; + uint8 result[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY]; + uint8 buffer[CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER]; + uint8_least i; + eslt_WorkSpaceCMACAES workSpaceCmacAes; + + /* K = KDF(KEYMASTER_ECU_KEY, DEBUG_KEY_C) */ + Crypto_30_LibCv_CopyData(buffer, masterKey, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + Crypto_30_LibCv_CopyData(&buffer[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY], debugKeyC, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + if (Crypto_30_LibCv_SheKeyUpdateMiyaguchiPreneel(buffer, CRYPTO_30_LIBCV_SIZEOF_KDF_BUFFER, key) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + /* AUTHORIZATION = CMAC(CHALLENGE | UID) with K */ + Crypto_30_LibCv_CopyData(buffer, challenge, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + Crypto_30_LibCv_CopyData(&buffer[CRYPTO_30_LIBCV_SIZEOF_SHE_KEY], uid, CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + if (Crypto_30_LibCv_SheKeyUpdateCmac(buffer, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY + CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID, key, result, &workSpaceCmacAes) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + /* Check (authorization = authorization*) */ + retVal = E_OK; + for (i = 0u; i < CRYPTO_30_LIBCV_SIZEOF_SHE_KEY; i++) + { + if (authorization[i] != result[i]) + { + retVal = E_NOT_OK; + } + } + } + } + + return retVal; +} /* Crypto_30_LibCv_She_DebugCmd_Authorization() */ + +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_IsWriteProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_IsWriteProtected(void) +{ + boolean writeProtection = FALSE; + Crypto_30_LibCv_KeyIterType keyIdx; + Crypto_30_LibCv_KeyElementsIterType elementIdx; + + /* Check if a key is write protected. */ + for (keyIdx = 0u; keyIdx < Crypto_30_LibCv_GetSizeOfKey(); keyIdx++) + { + if (Crypto_30_LibCv_IsDebugDeletionOfKey(keyIdx)) + { + /* Iterate over all elements in the key */ + for (elementIdx = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(keyIdx); elementIdx < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(keyIdx); elementIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + if (Crypto_30_LibCv_IsKeyElementStateByMask(elementIdx, CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_MASK)) + { + writeProtection = TRUE; + break; + } + } + } + } + + return writeProtection; +} /* Crypto_30_LibCv_She_DebugCmd_IsWriteProtected() */ +# endif /* (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_DeleteKeys() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_DeleteKeys(void) +{ + Crypto_30_LibCv_SizeOfKeyType keyIdx; + Crypto_30_LibCv_SheKeysIterType sheKeyIndex; + Crypto_30_LibCv_SizeOfKeyElementsType elementIdx; + + /* Set keys to initial state. */ + for (keyIdx = 0u; keyIdx < Crypto_30_LibCv_GetSizeOfKey(); keyIdx++) + { + if (Crypto_30_LibCv_IsDebugDeletionOfKey(keyIdx)) + { + for (elementIdx = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(keyIdx); elementIdx < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(keyIdx); elementIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + /* Delete old value */ + Crypto_30_LibCv_ClearData(Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(elementIdx), Crypto_30_LibCv_GetKeyElementLength(elementIdx)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + + /* init key again */ + Crypto_30_LibCv_Init_Key(elementIdx, FALSE); + +# if(CRYPTO_30_LIBCV_KEYVALUECHANGEDCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + /* Call the callout if the functionality is enabled and trigger that the key value is changed. */ + Crypto_30_LibCv_GetKeyValueChangedCalloutFctNameOfConfigurableCallouts()(keyIdx, Crypto_30_LibCv_GetIdOfKeyElements(elementIdx)); +# endif +# if(CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + /* Call KeyNvStatus KeyChanged transition */ + Crypto_30_LibCv_KeyNvStatus_KeyChanged(keyIdx, elementIdx); +# endif + } + } + } + + for (sheKeyIndex = 0u; sheKeyIndex < Crypto_30_LibCv_GetSizeOfSheKeys(); sheKeyIndex++) + { + elementIdx = Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(sheKeyIndex); + Crypto_30_LibCv_Init_KeySheAdditional(elementIdx); + } + +# if(CRYPTO_30_LIBCV_KEYVALIDITYSETCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + /* Call the callout if the functionality is enabled and trigger that the key is set to valid */ + { + boolean isValid; + + for (keyIdx = 0u; keyIdx < Crypto_30_LibCv_GetSizeOfKey(); keyIdx++) + { + isValid = TRUE; + + if (Crypto_30_LibCv_IsDebugDeletionOfKey(keyIdx)) + { + for (elementIdx = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(keyIdx); elementIdx < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(keyIdx); elementIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + if (!Crypto_30_LibCv_IsKeyElementValid(elementIdx)) + { + isValid = FALSE; + break; + } + } + + if (isValid == TRUE) + { + Crypto_30_LibCv_GetKeyValiditySetCalloutFctNameOfConfigurableCallouts()(keyIdx, TRUE); + } + } + } + } +# endif +} /* Crypto_30_LibCv_She_DebugCmd_DeleteKeys() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_GetChallenge() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_GetChallenge( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr) +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + eslt_ErrorCode localRet; + /* Check length */ + if (*resultLengthPtr >= CRYPTO_30_LIBCV_SIZEOF_SHE_KEY) + { + /* Check write protection */ +# if (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON) + if (!Crypto_30_LibCv_She_DebugCmd_IsWriteProtected()) +# endif + { + /* Provide RNG as challenge */ + localRet = esl_getBytesRNG( CRYPTO_30_LIBCV_SIZEOF_SHE_KEY, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))Crypto_30_LibCv_She_Debug_Cmd_Challenge ); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + if (localRet == E_OK) + { + Crypto_30_LibCv_CopyData(resultPtr, Crypto_30_LibCv_She_Debug_Cmd_Challenge, CRYPTO_30_LIBCV_SIZEOF_SHE_KEY); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_ARRAY_ACCESS_WITH_SIZE_CHECK */ + *resultLengthPtr = CRYPTO_30_LIBCV_SIZEOF_SHE_KEY; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + Crypto_30_LibCv_She_Debug_Cmd_ChallengeFlag = TRUE; + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + } + else + { + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + + return retVal; +} /* Crypto_30_LibCv_She_DebugCmd_GetChallenge() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_SetAuthorization() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_SetAuthorization( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr) +{ + Std_ReturnType retVal = E_NOT_OK, localRet; + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheKey = 0u; + Crypto_30_LibCv_SizeOfKeyStorageType uIdStorageIndex, keyStorageIndex = 0u; + uint32 length; + + Crypto_30_LibCv_She_Debug_Cmd_ChallengeFlag = FALSE; + /* Get Master Key She Idx */ + localRet = Crypto_30_LibCv_GetSheKey(CRYPTO_30_LIBCV_SHE_M1_ECU_MASTER_KEY_ID, CRYPTO_30_LIBCV_SHE_PAGE0, &indexOfSheKey); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + /* Get UID */ + length = CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID; + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate(), CRYPTO_KE_CUSTOM_SHE_UID, &uIdStorageIndex, &length, CRYPTO_30_LIBCV_LENGTH_CHECK_MIN); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* Get Master Key */ + if (localRet == E_OK) + { + length = CRYPTO_30_LIBCV_SIZEOF_SHE_KEY; + localRet = Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic(Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(indexOfSheKey), &keyStorageIndex, &length, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL, CRYPTO_30_LIBCV_SHE_SERVICE_KEY_SERVICE); /* COV_CRYPTO_30_LIBCV_SHE_KEY_CONFIGURATION_2 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (localRet == E_OK) + { + /* Check Authorization */ + retVal = Crypto_30_LibCv_She_DebugCmd_Authorization(Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndex), Crypto_30_LibCv_GetAddrKeyStorage(uIdStorageIndex), Crypto_30_LibCv_She_Debug_Cmd_Challenge, keyPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + if (retVal == E_OK) + { + /* Delete keys */ + Crypto_30_LibCv_She_DebugCmd_DeleteKeys(); + } + } + } + + return retVal; +} /* Crypto_30_LibCv_She_DebugCmd_SetAuthorization() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_She_DebugCmd_SetAuthorizationAndLock() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* PRQA S 6010, 6030, 6080 3 */ /* MD_MSR_STPTH , MD_MSR_STCYC , MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_DebugCmd_SetAuthorizationAndLock( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength) +{ +# if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + Crypto_30_LibCv_KeyElementsIterType elementIdx; + boolean persist; +# endif + Std_ReturnType retVal = E_NOT_OK; + + /* Is it a valid request */ + if ((keyLength == CRYPTO_30_LIBCV_SIZEOF_SHE_KEY) && + Crypto_30_LibCv_She_Debug_Cmd_ChallengeFlag) + { +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_KeyIterType lockedKeyIdx; + + /* Lock keys for write access. */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + for (lockedKeyIdx = 0u; lockedKeyIdx < Crypto_30_LibCv_GetSizeOfKey(); lockedKeyIdx++) + { + if (Crypto_30_LibCv_IsDebugDeletionOfKey(lockedKeyIdx)) + { + if (Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected((uint32)lockedKeyIdx) != E_OK) + { + retVal = CRYPTO_E_BUSY; + break; + } + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + + if (retVal != CRYPTO_E_BUSY) +# endif + { + retVal = Crypto_30_LibCv_She_DebugCmd_SetAuthorization(keyPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + } + +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + { + Crypto_30_LibCv_KeyIterType releaseKeyIdx; + + /* Release keys for write access. */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + for (releaseKeyIdx = 0; releaseKeyIdx < lockedKeyIdx; releaseKeyIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND_STATIC_GENDATA */ + { + if (Crypto_30_LibCv_IsDebugDeletionOfKey(releaseKeyIdx)) + { + Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected((uint32)releaseKeyIdx); + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + } +# endif + +# if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + if (retVal == E_OK) + { + Crypto_30_LibCv_KeyIterType persistKeyIdx; + /* Trigger write block. */ + for (persistKeyIdx = 0; persistKeyIdx < Crypto_30_LibCv_GetSizeOfKey(); persistKeyIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND_STATIC_GENDATA */ + { + persist = FALSE; + + if (Crypto_30_LibCv_IsDebugDeletionOfKey(persistKeyIdx)) + { + for (elementIdx = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(persistKeyIdx); elementIdx < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(persistKeyIdx); elementIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + if (Crypto_30_LibCv_IsKeyElementPersist(elementIdx)) + { + persist = TRUE; + } + } + if (persist == TRUE) + { + Crypto_30_LibCv_NvBlock_Write_Req(Crypto_30_LibCv_GetNvBlockIdxOfKey(persistKeyIdx)); + } + } + } + } +# endif + } + else + { + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + + return retVal; +} /* Crypto_30_LibCv_She_DebugCmd_SetAuthorizationAndLock() */ +# endif /* (CRYPTO_30_LIBCV_SHE_DEBUG_CMD == STD_ON) */ +#endif /* CRYPTO_30_LIBCV_SHEKEYS == STD_ON */ + +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_Trigger_Write_Req() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_Trigger_Write_Req( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, localRet = E_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + /* ----- Implementation ------------------------------------------------- */ + + /* Set Ram Block Status */ +# if (CRYPTO_30_LIBCV_NVM_ENABLE_SET_RAM_BLOCK_STATUS == STD_ON) + localRet = NvM_SetRamBlockStatus((NvM_BlockIdType)Crypto_30_LibCv_GetDescriptorOfNvBlock(blockIdx), TRUE); + if (localRet == E_OK) +# endif + { + /* Trigger write request if it is a IMMEDIATE block. */ + if ((Crypto_30_LibCv_GetProcessingOfNvBlock(blockIdx) == CRYPTO_30_LIBCV_NV_PROCESSING_IMMEDIATE)) + { + localRet = Crypto_30_LibCv_NvM_WriteBlock((NvM_BlockIdType)Crypto_30_LibCv_GetDescriptorOfNvBlock(blockIdx), NULL_PTR); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_NULL_PTR */ + } + } + + /* If an error occurred clear write requested bit mask in state. */ + if (localRet == E_OK) + { + retVal = E_OK; + } + else + { + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + Crypto_30_LibCv_ClearNvBlockStateMask(blockIdx, CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_CLEAR_WRITE_REQUESTED); /* SBSW_CRYPTO_30_LIBCV_CSL02_NV_BLOCK */ + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + } + return retVal; +} /* Crypto_30_LibCv_NvBlock_Trigger_Write_Req() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_MainFunction() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_MainFunction(void) +{ + /* ----- Local Variables ------------------------------------------------ */ + Crypto_30_LibCv_NvBlockIterType blockIdx; + + /* ----- Implementation ------------------------------------------------- */ + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* Check if write request need to be triggered for any block. */ + for (blockIdx = 0u; blockIdx < Crypto_30_LibCv_GetSizeOfNvBlock(); blockIdx++) + { + if (Crypto_30_LibCv_GetNvBlockState(blockIdx) == CRYPTO_30_LIBCV_NVBLOCK_STATE_WRITE_REQ_PENDING) + { + Crypto_30_LibCv_SetNvBlockState(blockIdx, CRYPTO_30_LIBCV_NVBLOCK_STATE_WRITE_REQ); /* SBSW_CRYPTO_30_LIBCV_CSL02_NV_BLOCK */ + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + (void)Crypto_30_LibCv_NvBlock_Trigger_Write_Req((Crypto_30_LibCv_SizeOfNvBlockType)blockIdx); + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +} /* Crypto_30_LibCv_NvBlock_MainFunction() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_Write_Req() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_Write_Req( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx) +{ +# if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS > 1u) + if (GetApplicationID() == Crypto_30_LibCv_MainApplicationId) +# endif + { + /* ----- Local Variables ------------------------------------------------ */ + + boolean setBlockStatus = FALSE; + /* ----- Implementation ------------------------------------------------- */ + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* If idle trigger new request */ + if (Crypto_30_LibCv_IsNvBlockState(blockIdx, CRYPTO_30_LIBCV_NVBLOCK_STATE_IDLE)) + { + Crypto_30_LibCv_SetNvBlockState(blockIdx, CRYPTO_30_LIBCV_NVBLOCK_STATE_WRITE_REQ); /* SBSW_CRYPTO_30_LIBCV_CSL02_NV_BLOCK */ + setBlockStatus = TRUE; + } + /* Otherwise set only flag for changed data .*/ + else + { + Crypto_30_LibCv_SetNvBlockStateMask(blockIdx, CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_DATA_CHANGE); /* SBSW_CRYPTO_30_LIBCV_CSL02_NV_BLOCK */ + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + /* Update KeyNvStatus of the keys of this block */ + Crypto_30_LibCv_KeyNvStatus_NvWriteReq(blockIdx); + + if (setBlockStatus) + { + (void)Crypto_30_LibCv_NvBlock_Trigger_Write_Req(blockIdx); + } + } +} /* Crypto_30_LibCv_NvBlock_Write_Req() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_State_CallbackWrittenToBlock() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_State_CallbackWrittenToBlock( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx) +{ + /* ----- Local Variables ------------------------------------------------ */ + /* ----- Implementation ------------------------------------------------- */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* Update state */ + Crypto_30_LibCv_ClearNvBlockStateMask(blockIdx, CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_CLEAR_WRITE_COPIED); /* SBSW_CRYPTO_30_LIBCV_CSL02_NV_BLOCK */ + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +} /* Crypto_30_LibCv_NvBlock_State_CallbackWrittenToBlock() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_State_WrittenToBlock() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_State_WrittenToBlock( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx) +{ + /* ----- Local Variables ------------------------------------------------ */ + /* ----- Implementation ------------------------------------------------- */ + /* Update state if data is marked as changed. */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + if (Crypto_30_LibCv_IsNvBlockStateMask(blockIdx, CRYPTO_30_LIBCV_NVBLOCK_STATE_MASK_DATA_CHANGE)) + { + Crypto_30_LibCv_SetNvBlockState(blockIdx, CRYPTO_30_LIBCV_NVBLOCK_STATE_COPY_DATA); /* SBSW_CRYPTO_30_LIBCV_CSL02_NV_BLOCK */ + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +} /* Crypto_30_LibCv_NvBlock_State_WrittenToBlock() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_WriteToBlock_Copy() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_WriteToBlock_Copy( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) NvMBufferPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Crypto_30_LibCv_SizeOfKeyStorageType length, writtenLength = 0u; + + /* ----- Development Error Checks ------------------------------------- */ + + /* ----- Implementation ------------------------------------------------- */ + + /* Update State */ + Crypto_30_LibCv_NvBlock_State_WrittenToBlock(blockIdx); + + /* Set header */ + if (Crypto_30_LibCv_GetConsistencyLevelOfNvBlock(blockIdx) == CRYPTO_30_LIBCV_NV_CONSISTENCY_LEVEL_DETECT) + { + Crypto_30_LibCv_NvBlock_WriteToBlock_HeaderCrc(blockIdx, NvMBufferPtr, &writtenLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER */ + } + else + { + /* CRYPTO_30_LIBCV_NV_STORAGE_KIND_NONE */ + } + + /* Data */ + length = (Crypto_30_LibCv_SizeOfKeyStorageType)(Crypto_30_LibCv_GetKeyStorageEndIdxOfNvBlock(blockIdx) - Crypto_30_LibCv_GetKeyStorageStartIdxOfNvBlock(blockIdx)); + /* Copy Key Storage to Buffer */ + Crypto_30_LibCv_CopyData(&NvMBufferPtr[writtenLength], Crypto_30_LibCv_GetAddrKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfNvBlock(blockIdx)), length); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER */ + writtenLength = (Crypto_30_LibCv_SizeOfKeyStorageType)(writtenLength + length); + /* Clear remaining Bytes of Buffer to have a specified value */ + Crypto_30_LibCv_ClearData(&NvMBufferPtr[writtenLength], (Crypto_30_LibCv_SizeOfKeyStorageType)(Crypto_30_LibCv_GetLengthOfNvBlock(blockIdx) - (writtenLength))); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER */ +} /* Crypto_30_LibCv_NvBlock_WriteToBlock_Copy() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_CheckLengthOfGivenKeyElement() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_CheckLengthOfGivenKeyElement( + P2VAR(boolean, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) validLengthsPtr, + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + Crypto_30_LibCv_KeyElementsIterType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) NvMBufferPtr, + Crypto_30_LibCv_SizeOfKeyStorageType dataStartPos) +{ + if (Crypto_30_LibCv_IsKeyElementPersist(elementIndex)) + { + /* Check if configured key element length is equal or greater than key element length read from NvM data */ + uint32 nvmKeyElementWrittenLengthOffset = dataStartPos + + ((uint32)Crypto_30_LibCv_GetKeyStorageWrittenLengthStartIdxOfKeyElements(elementIndex)) - + Crypto_30_LibCv_GetKeyStorageStartIdxOfNvBlock(blockIdx); + + uint32 keyElementNvmLength = ((uint32)NvMBufferPtr[nvmKeyElementWrittenLengthOffset] << 8) | (uint32)NvMBufferPtr[nvmKeyElementWrittenLengthOffset + 1u]; + + if (keyElementNvmLength > Crypto_30_LibCv_GetKeyElementLength(elementIndex)) + { + *validLengthsPtr = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + } +} /* Crypto_30_LibCv_NvBlock_CheckLengthOfGivenKeyElement() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_CheckKeyElementLengths() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_CheckKeyElementLengths( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) NvMBufferPtr, + Crypto_30_LibCv_SizeOfKeyStorageType dataStartPos) +{ + Std_ReturnType retVal = E_NOT_OK; + boolean validLengths = TRUE; + Crypto_30_LibCv_KeyIterType keyIdx; + Crypto_30_LibCv_KeyElementsIterType elementIndex; + + for (keyIdx = 0u; keyIdx < Crypto_30_LibCv_GetSizeOfKey(); keyIdx++) + { + if (Crypto_30_LibCv_GetNvBlockIdxOfKey(keyIdx) == blockIdx) + { + for (elementIndex = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(keyIdx); elementIndex < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(keyIdx); elementIndex++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + Crypto_30_LibCv_NvBlock_CheckLengthOfGivenKeyElement(&validLengths, blockIdx, elementIndex, NvMBufferPtr, dataStartPos); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_AND_ACCESS_TO_NVBUFFER */ + } + } + } + + if (validLengths == TRUE) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_NvBlock_CheckKeyElementLengths() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_ReadFromBlock_Copy() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_ReadFromBlock_Copy( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) NvMBufferPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + boolean validHeader = TRUE; + boolean dataCopiedFromNvM = FALSE; + Crypto_30_LibCv_SizeOfKeyStorageType length, dataStartPos = 0u; + + /* ----- Development Error Checks ------------------------------------- */ + + /* ----- Implementation ------------------------------------------------- */ + + /* Set header */ + Crypto_30_LibCv_NvBlock_State_Init(blockIdx); + + /* Check header */ + if ((Crypto_30_LibCv_GetConsistencyLevelOfNvBlock(blockIdx) == CRYPTO_30_LIBCV_NV_CONSISTENCY_LEVEL_DETECT)) + { + validHeader = Crypto_30_LibCv_NvBlock_ReadFromBlock_HeaderCrc(blockIdx, NvMBufferPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER */ + dataStartPos = (Crypto_30_LibCv_SizeOfKeyStorageType)CRYPTO_30_LIBCV_SIZEOF_NVBLOCK_HEADER_CRC; + } + + if (validHeader) + { + /* Check if key element lengths are valid */ + if(Crypto_30_LibCv_NvBlock_CheckKeyElementLengths(blockIdx, NvMBufferPtr, dataStartPos) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER */ + { + /* Copy data to Key Storage */ + length = (Crypto_30_LibCv_SizeOfKeyStorageType)(Crypto_30_LibCv_GetKeyStorageEndIdxOfNvBlock(blockIdx) - Crypto_30_LibCv_GetKeyStorageStartIdxOfNvBlock(blockIdx)); + Crypto_30_LibCv_CopyData(Crypto_30_LibCv_GetAddrKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfNvBlock(blockIdx)), &NvMBufferPtr[dataStartPos], length); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_KEY_STORAGE_ACCESS_NV */ + dataCopiedFromNvM = TRUE; + /* Update KeyNvStatus of keys of NvBlock. */ + Crypto_30_LibCv_KeyNvStatus_ReadFromBlock(blockIdx); + } + } + + /* Restore data in Key Storage */ + if(dataCopiedFromNvM == FALSE) + { + Crypto_30_LibCv_NvBlock_ReadFromBlock_Restore(blockIdx); + } + + return E_OK; +} /* Crypto_30_LibCv_NvBlock_ReadFromBlock_Copy() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_ReadFromBlock_HeaderCrc() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_ReadFromBlock_HeaderCrc( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) NvMBufferPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + boolean validHeader = TRUE; + uint32 crc; + + /* ----- Implementation ------------------------------------------------- */ + /* Header */ + /* Version */ + if (NvMBufferPtr[CRYPTO_30_LIBCV_POS_NVBLOCK_VERSION] != CRYPTO_30_LIBCV_NVBLOCK_VERSION_0) + { + validHeader = FALSE; + } + /* Flags */ + if (NvMBufferPtr[CRYPTO_30_LIBCV_POS_NVBLOCK_FLAGS] != CRYPTO_30_LIBCV_NVBLOCK_FLAGS_0) + { + validHeader = FALSE; + } + /* Check Structure Crc */ + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&crc, &NvMBufferPtr[CRYPTO_30_LIBCV_POS_NVBLOCK_CRC]); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER */ + if (crc != Crypto_30_LibCv_GetCrcOfNvBlock(blockIdx)) + { + validHeader = FALSE; + } + + return validHeader; +} /* Crypto_30_LibCv_NvBlock_ReadFromBlock_HeaderCrc() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_WriteToBlock_HeaderCrc() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_WriteToBlock_HeaderCrc( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) NvMBufferPtr, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) writtenLengthPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + /* ----- Implementation ------------------------------------------------- */ + /* Header */ + /* Version */ + NvMBufferPtr[CRYPTO_30_LIBCV_POS_NVBLOCK_VERSION] = CRYPTO_30_LIBCV_NVBLOCK_VERSION_0; /* SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER */ + + /* Flags */ + NvMBufferPtr[CRYPTO_30_LIBCV_POS_NVBLOCK_FLAGS] = CRYPTO_30_LIBCV_NVBLOCK_FLAGS_0; /* SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER */ + + /* Copy Structure Crc */ + Crypto_30_LibCv_Local_Uint32ToUint8ArrayBigEndian(&NvMBufferPtr[CRYPTO_30_LIBCV_POS_NVBLOCK_CRC], Crypto_30_LibCv_GetCrcOfNvBlock(blockIdx)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER */ + *writtenLengthPtr = (Crypto_30_LibCv_SizeOfKeyStorageType)(*writtenLengthPtr + CRYPTO_30_LIBCV_SIZEOF_NVBLOCK_HEADER_CRC); /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ +} /* Crypto_30_LibCv_NvBlock_WriteToBlock_HeaderCrc() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_ReadFromBlock_Restore() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_ReadFromBlock_Restore( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx) +{ + /* ----- Local Variables ------------------------------------------------ */ + /* ----- Implementation ------------------------------------------------- */ + /* Restore new init values for the given block. */ + (void)Crypto_30_LibCv_NvBlock_Init(blockIdx); +} /* Crypto_30_LibCv_NvBlock_ReadFromBlock_Restore() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_IsKeyUpdatedByNvm() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_IsKeyUpdatedByNvm( + uint32 cryptoKeyId) { + boolean retVal = FALSE; + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + Crypto_30_LibCv_KeyNvStatusType currentStatus = Crypto_30_LibCv_GetKeyNvStatus(cryptoKeyId); + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + if ((currentStatus == CRYPTO_30_LIBCV_KEY_NV_STATUS_NV_WRITE_REQ) || + (currentStatus == CRYPTO_30_LIBCV_KEY_NV_STATUS_KEY_COPIED) || + (currentStatus == CRYPTO_30_LIBCV_KEY_NV_STATUS_WRITE_FAILED)) + { + retVal = TRUE; + } + return retVal; +} /* Crypto_30_LibCv_KeyNvStatus_IsKeyUpdatedByNvm() */ +#endif /* (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) */ + +#if(CRYPTO_30_LIBCV_SHECMDGETID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_She_Cmd_Get_Status() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_She_Cmd_Get_Status( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) statusPtr) +{ + Std_ReturnType retVal; + Crypto_30_LibCv_SizeOfKeyStorageType bootProtectionElementIndexPtr = 0u; + Crypto_30_LibCv_SizeOfKeyStorageType debuggerProtectionElementIndexPtr = 0u; + uint32 elementLength = 1u; + + /* Init status */ + *statusPtr = CRYPTO_30_LIBCV_SHE_CLEARED_STATUS; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + + /* Get BOOT_PROTECTION and DEBUGGER_PROTECTION element id */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate(), CRYPTO_KE_CUSTOM_SHE_BOOT_PROTECTION, &bootProtectionElementIndexPtr, &elementLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + retVal |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate(), CRYPTO_KE_CUSTOM_SHE_DEBUGGER_PROTECTION, &debuggerProtectionElementIndexPtr, &elementLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* Check boot protection */ + if (*(Crypto_30_LibCv_GetAddrKeyStorage(bootProtectionElementIndexPtr)) == 1u) + { + *statusPtr |= CRYPTO_30_LIBCV_SHE_STATUS_BOOT_FINISHED; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + *statusPtr |= CRYPTO_30_LIBCV_SHE_STATUS_BOOT_OK; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + + /* Check debugger protection */ + if (*(Crypto_30_LibCv_GetAddrKeyStorage(debuggerProtectionElementIndexPtr)) == 0u) + { + *statusPtr |= CRYPTO_30_LIBCV_SHE_STATUS_EXT_DEBUGGER; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + } + else + { + retVal = E_NOT_OK; + } + + return retVal; +} /* Crypto_30_LibCv_She_Cmd_Get_Status() */ +#endif /* (CRYPTO_30_LIBCV_SHECMDGETID == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGet() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* [SWS_Crypto_91006] */ +/* PRQA S 6080 5 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) errorIdPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex = 0u; + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* Try to get read lock */ + if (Crypto_30_LibCv_Local_KeyReadLockGet(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +#endif + { +#if (CRYPTO_30_LIBCV_SHE_DEBUG_CMD == STD_ON) + /* Check if it is She DEBUG_CMD */ + if (Crypto_30_LibCv_She_IsDebugCmd(cryptoKeyId, keyElementId)) + { +# if (CRYPTO_30_LIBCV_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + if (GetApplicationID() == Crypto_30_LibCv_MainApplicationId) +# endif + { + retVal = Crypto_30_LibCv_She_DebugCmd_GetChallenge(resultPtr, resultLengthPtr); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + } + } + else +#endif + /* Search Key Element */ + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, keyElementId, &elementIndex) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* [SWS_Crypto_00087] Check that keyElementId is in valid range */ + *errorIdPtr = CRYPTO_E_PARAM_HANDLE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_INLINE_STACK */ + /* Info: This return value is according to the Spec although CRYPTO_E_KEY_NOT_AVAILABLE would make more sense */ + retVal = E_NOT_OK; + } + else + { + /* Check if the Key element is valid */ + if (FALSE == Crypto_30_LibCv_IsKeyElementValid(elementIndex)) + { + /* [SWS_Crypto_00039] */ + /* Info: This return value is according to the Spec although CRYPTO_E_KEY_NOT_VALID would make more sense */ + retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + } + else + { + /* Check if read access is allowed */ + if (CRYPTO_30_LIBCV_RA_ALLOWED == (Crypto_30_LibCv_GetReadOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndex)))) + { + retVal = Crypto_30_LibCv_Local_KeyElementGetNoShe(elementIndex, resultPtr, resultLengthPtr); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + } +#if (CRYPTO_30_LIBCV_RAM_KEY_EXPORT == STD_ON) + /* She key */ + else if (CRYPTO_30_LIBCV_RA_ENCRYPTED == (Crypto_30_LibCv_GetReadOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndex)))) + { + retVal = Crypto_30_LibCv_Local_KeyElementGetShe(cryptoKeyId, elementIndex, resultPtr, resultLengthPtr); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + } +#endif + else + { + retVal = CRYPTO_E_KEY_READ_FAIL; + } + } + } + } +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyReadLockRelease(cryptoKeyId); +#endif + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementGet() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetNoShe() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* [SWS_Crypto_91006] */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetNoShe( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr) +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_LibCv_SizeOfKeyStorageType resultIndex; + Crypto_30_LibCv_LengthCheckType lengthCheck; + uint32 writtenKeyLength = 0u; + +#if (CRYPTO_30_LIBCV_STRICT_LENGTH_CHECK_FOR_KEY_ELEMENT_GET == STD_OFF) + /* If the Key Element has partial access allowed, length check should not be strict */ + if (Crypto_30_LibCv_IsKeyElementPartial(elementIndex) == TRUE) + { + lengthCheck = CRYPTO_30_LIBCV_LENGTH_CHECK_NONE; + } + else +#endif + { + lengthCheck = CRYPTO_30_LIBCV_LENGTH_CHECK_MAX; + } + + writtenKeyLength = *resultLengthPtr; + + /* Get SHE key always if ra is allowed */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic(elementIndex, &resultIndex, &writtenKeyLength, lengthCheck, CRYPTO_30_LIBCV_SHE_SERVICE_KEY_SERVICE); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + +#if (CRYPTO_30_LIBCV_STRICT_LENGTH_CHECK_FOR_KEY_ELEMENT_GET == STD_OFF) + if (Crypto_30_LibCv_IsKeyElementPartial(elementIndex) == TRUE) + { + /* Check if written length is less than requested length */ + if (writtenKeyLength < *resultLengthPtr) + { + /* Use written length of key */ + *resultLengthPtr = writtenKeyLength; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_WITH_DET_CHECK */ + } + else + { + /* Use requested length of the key (already set). This will result in a partial copy. */ + } + } + else +#endif + { + /* Use written length of key */ + *resultLengthPtr = writtenKeyLength; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_WITH_DET_CHECK */ + } + + /* Copy key element if access is allowed */ + if (retVal == E_OK) + { + Crypto_30_LibCv_CopyData(resultPtr, Crypto_30_LibCv_GetAddrKeyStorage(resultIndex), *resultLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementGetNoShe() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_BinarySearchCryptoKeyId() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_BinarySearchCryptoKeyId( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) cryptoKeyId) +{ + Std_ReturnType retVal = E_NOT_OK; + + /* Check if the found crypto key ID is smaller than the key element end index. */ + if (elementIndex < Crypto_30_LibCv_GetSizeOfKeyElements()) + { + Crypto_30_LibCv_SizeOfKeyType minKey = 0u; + Crypto_30_LibCv_SizeOfKeyType maxKey = (Crypto_30_LibCv_SizeOfKeyType)(Crypto_30_LibCv_GetSizeOfKey()); + Crypto_30_LibCv_SizeOfKeyType middleKey = 0u; + + /* Iterate through the list to find a key whose value is less than the Key Element End Index and + greater than or equal to Key Element Start Index. The element index is less than the maximum element + index and there is no gap between them, so we find the CryptoKeyId and exit the loop. */ + while (minKey < maxKey) /* COV_CRYPTO_30_LIBCV_BINARYSEARCH */ /* FETA_CRYPTO_30_LIBCV_BINARY_SEARCH */ + { + /* Start at the middle and check if the elementIndex is smaller or larger than the beginning of the middle key index. + If it is smaller, set the new middle key value to the middle between 0 and the old middle key. + If it is larger, set the new middle key value to the middle between the old middle key value and the maximum key size. */ + middleKey = (Crypto_30_LibCv_SizeOfKeyType)Crypto_30_LibCv_Math_CalcMiddle(minKey, maxKey); + + if (Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(middleKey) > elementIndex) + { + /* cryptoKeyId must be lower than the middle */ + maxKey = (Crypto_30_LibCv_SizeOfKeyType)(middleKey); + } + else if (Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(middleKey) <= elementIndex) + { + /* cryptoKeyId must be higher than the middle */ + minKey = (Crypto_30_LibCv_SizeOfKeyType)(middleKey + 1u); + } + else + { + *cryptoKeyId = middleKey; /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + retVal = E_OK; + /* Key has been found. Leave loop. */ + break; + } + } + + /* If key couldn't be found, retVal is already set to E_NOT_OK */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_BinarySearchCryptoKeyId() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyGetStatus() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyGetStatus( + uint32 cryptoKeyId, + P2VAR(Crypto_KeyStatusType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyStatusPtr) +{ +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + /* Check if NVM is currently updating the given cryptoKey */ + if (Crypto_30_LibCv_KeyNvStatus_IsKeyUpdatedByNvm(cryptoKeyId)) + { + /* Report update in progress */ + /* [SWS_Crypto_00245] */ + *keyStatusPtr = CRYPTO_KEYSTATUS_UPDATE_IN_PROGRESS; /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } + else +#endif + { + Crypto_KeyStatusType localKeyStatus = CRYPTO_KEYSTATUS_VALID; + /* Check if any key element of the given cryptoKey is invalid */ + for (Crypto_30_LibCv_KeyElementsIterType elementIndex = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(cryptoKeyId); elementIndex < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(cryptoKeyId); elementIndex++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + /* Check if current KeyElement is invalid */ + if (!Crypto_30_LibCv_IsKeyElementValid(elementIndex)) + { + localKeyStatus = CRYPTO_KEYSTATUS_INVALID; + break; + } + } + /* Report validity of key */ + /* [SWS_Crypto_00235] */ + *keyStatusPtr = localKeyStatus; /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } +} /* Crypto_30_LibCv_Local_KeyGetStatus() */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +#if (CRYPTO_30_LIBCV_USE_VSTD_LIB == STD_OFF) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_CopyData_Implementation() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_CopyData_Implementation( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) targetData, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) sourceData, + uint32 dataLength) +{ + uint32_least byteIdx; + /* #10 Copy data bytewise to the target buffer */ + for (byteIdx = 0u; byteIdx < dataLength; byteIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND */ + { + targetData[byteIdx] = sourceData[byteIdx]; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } +} /* Crypto_30_LibCv_Local_CopyData_Implementation() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_SetData_Implementation() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_SetData_Implementation( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) dataBuf, + uint8 pattern, + uint32 dataLength) +{ + uint32_least byteIdx; + /* #10 Set data bytewise */ + for (byteIdx = 0u; byteIdx < dataLength; byteIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND */ + { + dataBuf[byteIdx] = pattern; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } +} /* Crypto_30_LibCv_Local_SetData_Implementation() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_ClearData_Implementation() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_ClearData_Implementation( + P2VAR(uint8, AUTOMATIC, AUTOMATIC) dataBuf, + uint32 dataLength) +{ + /* #10 Clear data bytewise */ + Crypto_30_LibCv_Local_SetData_Implementation(dataBuf, 0x00u, dataLength); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ +} /* Crypto_30_LibCv_Local_ClearData_Implementation() */ +#endif /* (CRYPTO_30_LIBCV_USE_VSTD_LIB == STD_OFF) */ + +#if ((CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_CompareData_IsSmaller() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_CompareData_IsSmaller( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) targetData, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) referenceData, + uint32 dataLength) +{ + uint32_least byteIdx; + Std_ReturnType retVal = E_NOT_OK; + /* #10 Compare data bytewise. */ + for (byteIdx = 0u; byteIdx < dataLength; byteIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND */ + { + if (targetData[byteIdx] < referenceData[byteIdx]) + { + retVal = E_OK; + break; + } + } + return retVal; +} /* Crypto_30_LibCv_Local_CompareData_IsSmaller() */ +#endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyReadLockGetNotProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyReadLockGetNotProtected( + uint32 cryptoKeyId) +{ + Std_ReturnType retVal = E_NOT_OK; + + if ((Crypto_30_LibCv_GetKeyLock(cryptoKeyId) >= CRYPTO_30_LIBCV_KEY_LOCK_FREE) && (Crypto_30_LibCv_GetKeyLock(cryptoKeyId) < CRYPTO_30_LIBCV_KEY_LOCK_READ_MAX)) + { + Crypto_30_LibCv_IncKeyLock(cryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyReadLockGetNotProtected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected( + uint32 cryptoKeyId) +{ + if (Crypto_30_LibCv_GetKeyLock(cryptoKeyId) > CRYPTO_30_LIBCV_KEY_LOCK_FREE) /* COV_CRYPTO_30_LIBCV_KEY_LOCKING_RELEASE */ + { + Crypto_30_LibCv_DecKeyLock(cryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } +} /* Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected( + uint32 cryptoKeyId) +{ + Std_ReturnType retVal = E_NOT_OK; + + if (Crypto_30_LibCv_GetKeyLock(cryptoKeyId) == CRYPTO_30_LIBCV_KEY_LOCK_FREE) + { + Crypto_30_LibCv_SetKeyLock(cryptoKeyId, CRYPTO_30_LIBCV_KEY_LOCK_WRITE); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected( + uint32 cryptoKeyId) +{ + if (Crypto_30_LibCv_GetKeyLock(cryptoKeyId) == CRYPTO_30_LIBCV_KEY_LOCK_WRITE) /* COV_CRYPTO_30_LIBCV_KEY_LOCKING_RELEASE */ + { + Crypto_30_LibCv_SetKeyLock(cryptoKeyId, CRYPTO_30_LIBCV_KEY_LOCK_FREE); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } +} /* Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyReadLockGet() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyReadLockGet( + uint32 cryptoKeyId) +{ + Std_ReturnType retVal; + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + retVal = Crypto_30_LibCv_Local_KeyReadLockGetNotProtected(cryptoKeyId); + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + + return retVal; +} /* Crypto_30_LibCv_Local_KeyReadLockGet() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyReadLockRelease() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyReadLockRelease( + uint32 cryptoKeyId) +{ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected(cryptoKeyId); + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); +} /* Crypto_30_LibCv_Local_KeyReadLockRelease() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyWriteLockGet() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyWriteLockGet( + uint32 cryptoKeyId) +{ + Std_ReturnType retVal; + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + retVal = Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected(cryptoKeyId); + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + + return retVal; +} /* Crypto_30_LibCv_Local_KeyWriteLockGet() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyWriteLockRelease() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyWriteLockRelease( + uint32 cryptoKeyId) +{ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected(cryptoKeyId); + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); +} /* Crypto_30_LibCv_Local_KeyWriteLockRelease() */ +#endif /* (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementSearch() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +/* [SWS_Crypto_91006] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementSearch( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) elementIndex) +{ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_KeyElementsIterType elementIdx; + + /* #10 Iterate over all elements in the key to find a matching key element */ + for (elementIdx = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(cryptoKeyId); elementIdx < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(cryptoKeyId); elementIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + if (keyElementId == Crypto_30_LibCv_GetIdOfKeyElements(elementIdx)) + { + retVal = E_OK; + *elementIndex = (Crypto_30_LibCv_SizeOfKeyElementsType)elementIdx; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementSearch() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementIdsGet() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +/* PRQA S 6080 4 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementIdsGet( + uint32 cryptoKeyId, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyElementIdsPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyElementIdsLengthPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00161] */ + errorId = CRYPTO_E_UNINIT; + } + /* #15 Check plausibility of parameters */ + else if (keyElementIdsPtr == NULL_PTR) + { + /* [SWS_Crypto_00162] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else if (keyElementIdsLengthPtr == NULL_PTR) + { + errorId = CRYPTO_E_PARAM_HANDLE; + } + else +#endif + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00162] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else + { + /* ----- Implementation ------------------------------------------------- */ + Crypto_30_LibCv_KeyElementsIterType elementIndex; + uint32 writeIdx = 0u; + retVal = E_OK; + + /* #20 Iterate over all Key Element Ids */ + for(elementIndex = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(cryptoKeyId); elementIndex < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(cryptoKeyId); elementIndex++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + /* #25 Copy Key Element Id, if the buffer is to small return with error */ + if (writeIdx < *(keyElementIdsLengthPtr)) + { + keyElementIdsPtr[writeIdx] = Crypto_30_LibCv_GetIdOfKeyElements(elementIndex); /* SBSW_CRYPTO_30_LIBCV_ARRAY_ACCESS_WITH_SIZE_CHECK */ + } + else + { + /* provided array is too small to store all element ids */ + retVal = CRYPTO_E_SMALL_BUFFER; + /* [SWS_Crypto_00164] Check that provided buffer is big enough */ + errorId = CRYPTO_E_SMALL_BUFFER; + break; + } + + writeIdx++; + } + + /* #30 save written data length */ + *keyElementIdsLengthPtr = writeIdx; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS_WITH_DET_CHECK */ + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #40 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_ELEMENT_IDS_GET, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_KeyElementIdsGet() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyCopy() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 3 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyCopy( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00156] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif + /* #15 Check plausibility of parameters */ + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00157] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else if (targetCryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00158] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + /* #16 Check if source and target key IDs are the same */ + else if (cryptoKeyId == targetCryptoKeyId) + { + /* Source and target shall not be the same, retVal remains on E_NOT_OK. */ + } + else + /* ----- Implementation ------------------------------------------------- */ + { +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* #17 Lock write access for the target CryptoKey */ + if (Crypto_30_LibCv_Local_KeyWriteLockGet(targetCryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +#endif + { +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* #18 Lock read access for the source CryptoKey */ + if (Crypto_30_LibCv_Local_KeyReadLockGet(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +#endif + { + /* #19 Copy keys internally */ + retVal = Crypto_30_LibCv_KeyCopy_Internal(cryptoKeyId, targetCryptoKeyId); + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyReadLockRelease(cryptoKeyId); +#endif + } +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyWriteLockRelease(targetCryptoKeyId); +#endif + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #40 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_COPY, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_KeyCopy() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementCopy() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ + /* PRQA S 6080 5 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementCopy( + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 targetCryptoKeyId, + uint32 targetKeyElementId) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexSrc = 0u; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexDst = 0u; + uint8 errorId = CRYPTO_E_PARAM_HANDLE; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00149] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif + /* #15 Check plausibility of parameters */ + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00150] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else if (targetCryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00151] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else + { + /* #20 Find source element. Otherwise return with Error. */ + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, keyElementId, &elementIndexSrc) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* ----- Implementation ------------------------------------------------- */ + /* [SWS_Crypto_00152] if keyElementId is out of valid range return E_NOT_OK */ + /* [SWS_Crypto_00153] if targetKeyElementId is out of valid range return E_NOT_OK */ + retVal = E_NOT_OK; + } + else + { + /* ----- Implementation ------------------------------------------------- */ + /* #25 Find destination element. Otherwise return with Error. */ + if (Crypto_30_LibCv_Local_KeyElementSearch(targetCryptoKeyId, targetKeyElementId, &elementIndexDst) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* [SWS_Crypto_00152] Check that keyElementId is in valid range */ + /* [SWS_Crypto_00153] Check that targetKeyElementId is in valid range */ + errorId = CRYPTO_E_NO_ERROR; + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* #30 Lock write access for the target CryptoKey */ + if (Crypto_30_LibCv_Local_KeyWriteLockGet(targetCryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +#endif + { + /* #35 Lock read access for the source CryptoKey if necessary */ + /* #40 copy key element with Crypto_30_LibCv_Local_KeyElementCopy */ + if (cryptoKeyId == targetCryptoKeyId) + { + retVal = Crypto_30_LibCv_Local_KeyElementCopy(elementIndexSrc, elementIndexDst, targetCryptoKeyId); + } +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + else if (Crypto_30_LibCv_Local_KeyReadLockGet(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } +#endif + else + { + retVal = Crypto_30_LibCv_Local_KeyElementCopy(elementIndexSrc, elementIndexDst, targetCryptoKeyId); +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyReadLockRelease(cryptoKeyId); +#endif + } +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyWriteLockRelease(targetCryptoKeyId); +#endif + } + } + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #50 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_ELEMENT_COPY, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + return retVal; +} /* Crypto_30_LibCv_KeyElementCopy() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementCopyPartial() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6060, 6080 8 */ /* MD_MSR_STPAR, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementCopyPartial( + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetCryptoKeyId, + uint32 targetKeyElementId) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexSrc = 0u; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndexDst = 0u; + uint8 errorId = CRYPTO_E_PARAM_HANDLE; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00205] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif + /* #15 Check plausibility of parameters */ + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00206] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else if (targetCryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00206] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else + { + /* #20 Find source element. Otherwise return with Error. */ + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, keyElementId, &elementIndexSrc) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* ----- Implementation ------------------------------------------------- */ + /* [SWS_Crypto_00206] if keyElementId is out of valid range return E_NOT_OK */ + /* [SWS_Crypto_00206] if targetKeyElementId is out of valid range return E_NOT_OK */ + } + else + { + /* ----- Implementation ------------------------------------------------- */ + /* #25 Find destination element. Otherwise return with Error. */ + if (Crypto_30_LibCv_Local_KeyElementSearch(targetCryptoKeyId, targetKeyElementId, &elementIndexDst) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* [SWS_Crypto_00206] Check that keyElementId is in valid range */ + /* [SWS_Crypto_00206] Check that targetKeyElementId is in valid range */ + errorId = CRYPTO_E_NO_ERROR; + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* #30 Lock write access for the target CryptoKey */ + if (Crypto_30_LibCv_Local_KeyWriteLockGet(targetCryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +#endif + { + /* #35 Lock read access for the source CryptoKey if necessary */ + /* #40 copy key element with Crypto_30_LibCv_Local_KeyElementCopyPartial */ + if (cryptoKeyId == targetCryptoKeyId) + { + retVal = Crypto_30_LibCv_Local_KeyElementCopyPartial(elementIndexSrc, elementIndexDst, targetCryptoKeyId, keyElementSourceOffset, keyElementTargetOffset, keyElementCopyLength); /* PRQA S 2963, 2982 */ /* MD_CRYPTO_30_LIBCV_2963, MD_MSR_RetVal */ + } +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + else if (Crypto_30_LibCv_Local_KeyReadLockGet(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } +#endif + else + { + retVal = Crypto_30_LibCv_Local_KeyElementCopyPartial(elementIndexSrc, elementIndexDst, targetCryptoKeyId, keyElementSourceOffset, keyElementTargetOffset, keyElementCopyLength); +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyReadLockRelease(cryptoKeyId); +#endif + } +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyWriteLockRelease(targetCryptoKeyId); +#endif + } + } + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #50 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_ELEMENT_COPY_PARTIAL, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + return retVal; +} /* Crypto_30_LibCv_KeyElementCopyPartial() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementSetInternalStandard() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementSetInternalStandard( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength) +{ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_KeyStorageIterType keyStorageIndex; + uint32 maxLength = Crypto_30_LibCv_GetKeyElementLength(elementIndex); + + keyStorageIndex = Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(elementIndex); + /* #10 Copy keyPtr to key storage. */ + + Crypto_30_LibCv_CopyData(Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndex), keyPtr, keyLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + /* #15 If the new written length is shorter than the old, delete the rest of the old key. */ + if (maxLength > keyLength) + { + Crypto_30_LibCv_ClearData(Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndex + keyLength), (uint32)(maxLength - keyLength)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + } + + retVal = Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyIdSearch(elementIndex, keyLength); + + return retVal; +} /* Crypto_30_LibCv_KeyElementSetInternalStandard() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementSetInternalStandardWithCryptoKeyId() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementSetInternalStandardWithCryptoKeyId( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength) +{ + Crypto_30_LibCv_KeyStorageIterType keyStorageIndex; + uint32 maxLength = Crypto_30_LibCv_GetKeyElementLength(elementIndex); + + keyStorageIndex = Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(elementIndex); + /* #10 Copy keyPtr to key storage. */ + + Crypto_30_LibCv_CopyData(Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndex), keyPtr, keyLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + /* #15 If the new written length is shorter than the old, delete the rest of the old key. */ + if (maxLength > keyLength) + { + Crypto_30_LibCv_ClearData(Crypto_30_LibCv_GetAddrKeyStorage(keyStorageIndex + keyLength), (uint32)(maxLength - keyLength)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + } + + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(cryptoKeyId, elementIndex, keyLength); +} /* Crypto_30_LibCv_KeyElementSetInternalStandardWithCryptoKeyId() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementSetInternal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementSetInternal( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength, + Crypto_30_LibCv_WriteOfKeyElementInfoType writeAccess) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + + /* ----- Implementation ------------------------------------------------- */ +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) + if ((writeAccess != CRYPTO_30_LIBCV_WA_ENCRYPTED) && + Crypto_30_LibCv_IsSheKey(elementIndex)) + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + } + else +#endif + { + { + /* #10 Check if it is a write once key which is written already. */ + if (Crypto_30_LibCv_IsKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_MASK)) + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + } + /* #20 Copy data if there is enough free space */ + /* Check if the available data is not bigger than the maximum size of the destination element */ + else if ((keyLength == Crypto_30_LibCv_GetKeyElementLength(elementIndex)) || + ((Crypto_30_LibCv_IsKeyElementPartial(elementIndex) == TRUE) && + (keyLength <= Crypto_30_LibCv_GetKeyElementLength(elementIndex)))) + { + if (writeAccess >= (Crypto_30_LibCv_GetWriteOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(elementIndex)))) + { + Crypto_30_LibCv_KeyElementSetInternalStandardWithCryptoKeyId(cryptoKeyId, elementIndex, keyPtr, keyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + retVal = E_OK; + } + else + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + } + } + else + { + /* Key length is to large */ + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; /* [SWS_Crypto_00146] */ + } + } + } + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementSetInternal() */ + +#if ((CRYPTO_30_LIBCV_KEY_DERIVE_ALGORITHM == STD_ON) || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementSet() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* [SWS_Crypto_91004] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementSet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex = 0u; + + /* ----- Implementation ------------------------------------------------- */ + + /* #10 Find key element, otherwise return with Error */ + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, keyElementId, &elementIndex) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + } + else + { + /* #15 Set Key Element internally */ + retVal = Crypto_30_LibCv_Local_KeyElementSetInternal(cryptoKeyId, elementIndex, keyPtr, keyLength, CRYPTO_30_LIBCV_WA_INTERNAL_COPY); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (retVal == E_OK) + { + Crypto_30_LibCv_Local_SetKeyElementStateWritten(elementIndex); + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementSet() */ +#endif /* ((CRYPTO_30_LIBCV_KEY_DERIVE_ALGORITHM == STD_ON) || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON)) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementSet() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* [SWS_Crypto_91004] */ +/* PRQA S 6030, 6050, 6080 5 */ /* MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementSet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + errorId = CRYPTO_E_UNINIT; /* [SWS_Crypto_00075] */ + } + /* #15 Check plausibility of parameters */ + else if (keyPtr == NULL_PTR) + { + errorId = CRYPTO_E_PARAM_POINTER; /* [SWS_Crypto_00078] */ + } + else +# if (CRYPTO_30_LIBCV_KEY_ELEMENT_DELETE == STD_OFF) + if (keyLength == 0u) + { + errorId = CRYPTO_E_PARAM_VALUE; /* [SWS_Crypto_00079] */ + } + else +# endif +#endif + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + errorId = CRYPTO_E_PARAM_HANDLE; /* [SWS_Crypto_00076] */ + } + else + { + /* ----- Implementation ------------------------------------------------- */ + /* ----- Local Variables ------------------------------------------------ */ + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex = 0u; + + /* ----- Implementation ------------------------------------------------- */ + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* #20 Lock write access for the CryptoKey */ + if (Crypto_30_LibCv_Local_KeyWriteLockGet(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +#endif + { +#if (CRYPTO_30_LIBCV_SHE_DEBUG_CMD == STD_ON) + /* Check if it is She DEBUG_CMD */ + if (Crypto_30_LibCv_She_IsDebugCmd(cryptoKeyId, keyElementId)) + { +# if (CRYPTO_30_LIBCV_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + if (GetApplicationID() == Crypto_30_LibCv_MainApplicationId) +# endif + { + retVal = Crypto_30_LibCv_She_DebugCmd_SetAuthorizationAndLock(keyPtr, keyLength); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + } + } + else +#endif + /* #23 Find key element, otherwise return with Error */ + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, keyElementId, &elementIndex) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* [SWS_Crypto_00077] check if keyElementId is in valid range */ + errorId = CRYPTO_E_PARAM_HANDLE; + retVal = E_NOT_OK; + } + else + { + /* #25 Set Key Element internally */ + retVal = Crypto_30_LibCv_Local_KeyElementSetInternal(cryptoKeyId, elementIndex, keyPtr, keyLength, CRYPTO_30_LIBCV_WA_ALLOWED); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ +#if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +# if (CRYPTO_30_LIBCV_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + if (GetApplicationID() == Crypto_30_LibCv_MainApplicationId) +# endif + { + if ((retVal == CRYPTO_E_KEY_SIZE_MISMATCH) || + (retVal == CRYPTO_E_KEY_WRITE_FAIL)) + { + /* [SWS_Crypto_00146] */ + /* #30 Else: if key size matching update using SHE key update protocol */ + retVal = Crypto_30_LibCv_Local_KeyElementSetShe(cryptoKeyId, elementIndex, keyPtr, keyLength, retVal); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + } + } +#endif + + if (retVal == E_OK) + { + /* Keep write once flag this can be set with M1M2M3. */ + Crypto_30_LibCv_ClearKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_CLEAR_NORMAL_MASK | CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + if (Crypto_30_LibCv_IsKeyElementWriteOnce(elementIndex)) + { + Crypto_30_LibCv_SetKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + } + } + } +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyWriteLockRelease(cryptoKeyId); +#endif + } + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #40 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_ELEMENT_SET, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_KeyElementSet() */ + +#if ((CRYPTO_30_LIBCV_KEY_DERIVE_ALGORITHM == STD_ON) || (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess( /* PRQA S 3219 */ /* MD_CRYPTO_30_LIBCV_3219_1 */ + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) elementIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) keyLengthPtr, + Crypto_30_LibCv_WriteOfKeyElementInfoType writeAccess) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + + /* ----- Implementation ----------------------------------------------- */ + /* Check if keyElementId is available */ + retVal = Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, keyElementId, elementIndexPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal != E_OK) + { + /* Parse return value */ + retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + } + else +# if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) + if (Crypto_30_LibCv_IsSheKey(*elementIndexPtr)) + { + /* Access not allowed due to she key */ + retVal = CRYPTO_E_KEY_WRITE_FAIL; + } + else +# endif + /* Check if it is a write once key which is written already. */ + if (Crypto_30_LibCv_IsKeyElementStateByMask(*elementIndexPtr, CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_MASK)) + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + } + else if (writeAccess >= (Crypto_30_LibCv_GetWriteOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(*elementIndexPtr)))) + { + /* Access allowed due to access permission check */ + /* Get configured key element length */ + *keyLengthPtr = Crypto_30_LibCv_GetKeyElementLength(*elementIndexPtr); /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + } + else + { + retVal = CRYPTO_E_KEY_WRITE_FAIL; + } + + return retVal; +} /* Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccessAndLength() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccessAndLength( /* PRQA S 3219 */ /* MD_CRYPTO_30_LIBCV_3219_1 */ + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) elementIndexPtr, + uint32 requestedKeyLength, + Crypto_30_LibCv_WriteOfKeyElementInfoType writeAccess) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + uint32 keyLength; + + /* ----- Implementation ----------------------------------------------- */ + /* Check if keyElementId is available */ + retVal = Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess(cryptoKeyId, /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + keyElementId, + elementIndexPtr, + &keyLength, + writeAccess); + + if (retVal == E_OK) + { + if (keyLength < requestedKeyLength) + { + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + else if ((keyLength > requestedKeyLength) && (Crypto_30_LibCv_IsKeyElementPartial(*elementIndexPtr) == FALSE)) + { + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + else + { + /* retVal is already set */ + } + } + + return retVal; +} /* Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccessAndLength() */ +#endif /* ((CRYPTO_30_LIBCV_KEY_DERIVE_ALGORITHM == STD_ON) || (CRYPTO_30_LIBCV_KEYWRAP == STD_ON)) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeySetValid() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* [SWS_Crypto_91014] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeySetValid( + uint32 cryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; + boolean writeBlock; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + errorId = CRYPTO_E_UNINIT; /* [SWS_Crypto_00196] 4.3.1, [SWS_Crypto_00082] 4.3.0 */ + } + else +#endif + /* #15 Check plausibility of parameters */ + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + errorId = CRYPTO_E_PARAM_HANDLE; /* [SWS_Crypto_00197] 4.3.1, [SWS_Crypto_00083] 4.3.0 */ + } + else + { + /* ----- Implementation ------------------------------------------------- */ +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* #17 Lock write access for the CryptoKey */ + if (Crypto_30_LibCv_Local_KeyWriteLockGet(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +#endif + { + /* #20 Set the given KeyId valid */ + writeBlock = Crypto_30_LibCv_Internal_KeySetValid(cryptoKeyId); + +#if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) + Crypto_30_LibCv_ClearObjectWorkspaceForChangedKey(cryptoKeyId); +#endif +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyWriteLockRelease(cryptoKeyId); +#endif + +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + if (writeBlock) + { + Crypto_30_LibCv_NvBlock_Write_Req(Crypto_30_LibCv_GetNvBlockIdxOfKey(cryptoKeyId)); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(writeBlock); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + retVal = E_OK; + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #25 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_SET_VALID, /* == CRYPTO_30_LIBCV_SID_KEY_VALID_SET */ + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_KeySetValid() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyValidSet() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ + /* [SWS_Crypto_91014] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyValidSet( + uint32 cryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + retVal = Crypto_30_LibCv_KeySetValid(cryptoKeyId); + + return retVal; +} /* Crypto_30_LibCv_KeyValidSet() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeySetInvalid() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ + /* [SWS_Crypto_91020] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeySetInvalid( + uint32 cryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; + boolean writeBlock; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + errorId = CRYPTO_E_UNINIT; /* [SWS_Crypto_00236] */ + } + else +#endif + /* Check plausibility of parameters */ + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + errorId = CRYPTO_E_PARAM_HANDLE; /* [SWS_Crypto_00237] */ + } + else + { + /* ----- Implementation ------------------------------------------------- */ +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* Lock write access for the CryptoKey */ + if (Crypto_30_LibCv_Local_KeyWriteLockGet(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +#endif + { + /* [SWS_Crypto_00238] */ + /* Set the given KeyId invalid */ + writeBlock = Crypto_30_LibCv_Internal_KeySetInvalid(cryptoKeyId); + +#if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) + Crypto_30_LibCv_ClearObjectWorkspaceForChangedKey(cryptoKeyId); +#endif +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyWriteLockRelease(cryptoKeyId); +#endif + +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + if (writeBlock) + { + Crypto_30_LibCv_NvBlock_Write_Req(Crypto_30_LibCv_GetNvBlockIdxOfKey(cryptoKeyId)); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(writeBlock); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + retVal = E_OK; + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_SET_INVALID, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_KeySetInvalid() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* [SWS_Crypto_91006] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck, + Crypto_30_LibCv_ServiceType serviceType) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + + /* ----- Implementation ------------------------------------------------- */ +#if ((CRYPTO_30_LIBCV_SHEKEYS == STD_ON) && (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON)) + /* Check if we are allowed to access the key regarding SHE */ + boolean access = FALSE; + /* If the key element is not SHE: allowed */ + if (!Crypto_30_LibCv_IsSheKey(elementIndex)) + { + access = TRUE; + } + else + { + /* If the key element is SHE and we are accessing with a SHE service: Check the FID */ + if (serviceType != CRYPTO_30_LIBCV_SHE_SERVICE_OTHER) + { + access = Crypto_30_LibCv_Local_KeyElementGetSheCheckFid(elementIndex, serviceType); + } + } + + if (access == FALSE) + { + retVal = CRYPTO_E_KEY_READ_FAIL; + } + else +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(serviceType); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + { + { + /* Get storage index of the key element */ + retVal = Crypto_30_LibCv_Local_KeyElementGet_Standard(resultIndexPtr, (P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))resultLengthPtr, elementIndex, lengthCheck); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* [SWS_Crypto_91006] */ +/* PRQA S 6060 7 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck, + Crypto_30_LibCv_ServiceType serviceType) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex = 0u; + + /* ----- Implementation ------------------------------------------------- */ + /* #10 Search Key Element */ + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, keyElementId, &elementIndex) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + retVal = CRYPTO_E_KEY_NOT_AVAILABLE; + } + /* #15 Check if the Key element is valid */ + else if (FALSE == Crypto_30_LibCv_IsKeyElementValid(elementIndex)) + { + /* [SWS_Crypto_00039] */ + retVal = CRYPTO_E_KEY_NOT_VALID; + } + else + { + /* #20 Get Key Element */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic(elementIndex, resultIndexPtr, resultLengthPtr, lengthCheck, serviceType); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetStorageIndex() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +/* [SWS_Crypto_91006] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetStorageIndex( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + + /* # Get key element storage index. */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended(cryptoKeyId, keyElementId, resultIndexPtr, resultLengthPtr, lengthCheck, CRYPTO_30_LIBCV_SHE_SERVICE_OTHER); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementGetStorageIndex() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + + /* # Get key element storage index. */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended(cryptoKeyId, keyElementId, resultIndexPtr, resultLengthPtr, lengthCheck, CRYPTO_30_LIBCV_SHE_SERVICE_OTHER); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* # Parse allowed return values for job processing. */ + if (retVal == E_OK) + { + + } + else if (retVal == CRYPTO_E_KEY_NOT_VALID) + { + + } + else if (retVal == CRYPTO_E_SMALL_BUFFER) + { + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + else + { + retVal = E_NOT_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + + /* # Get key element storage index. */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended(cryptoKeyId, keyElementId, resultIndexPtr, resultLengthPtr, lengthCheck, CRYPTO_30_LIBCV_SHE_SERVICE_OTHER); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* # Parse allowed return values for job processing. */ + if (retVal == E_OK) + { + + } + else if (retVal == CRYPTO_E_KEY_NOT_VALID) + { + + } + else if (retVal == CRYPTO_E_KEY_NOT_AVAILABLE) + { + + } + else + { + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + + return retVal; +} /* Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_GetElementsIndexJob() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* [SWS_Crypto_91006] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_GetElementsIndexJob( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_KeyElementGetType, AUTOMATIC, AUTOMATIC) keyElements, + Crypto_30_LibCv_KeyElementGetSizeType numberOfElements, + Crypto_30_LibCv_LengthCheckType lengthCheck + ) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_KeyElementGetSizeType i; + + /* Iterate over the given number of key elements */ + for (i = 0; i < numberOfElements; i++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND */ + { + /* Get the storage index for each key element*/ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(cryptoKeyId, keyElements[i].keyElementId, &keyElements[i].keyElementIndex, &keyElements[i].keyElementLength, lengthCheck); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + if (retVal != E_OK) + { + break; + } + } + return retVal; +} /* Crypto_30_LibCv_Local_GetElementsIndexJob() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_ElementGetterSetId() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +/* [SWS_Crypto_91006] */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_ElementGetterSetId( + P2VAR(Crypto_30_LibCv_KeyElementGetType, AUTOMATIC, AUTOMATIC) keyElements, + Crypto_30_LibCv_KeyElementGetSizeType elementNumber, + uint32 keyElementId) +{ + keyElements[elementNumber].keyElementId = keyElementId; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ +} /* Crypto_30_LibCv_Local_ElementGetterSetId() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_ElementGetterSetIdAndLength() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +/* [SWS_Crypto_91006] */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_ElementGetterSetIdAndLength( + P2VAR(Crypto_30_LibCv_KeyElementGetType, AUTOMATIC, AUTOMATIC) keyElements, + Crypto_30_LibCv_KeyElementGetSizeType elementNumber, + uint32 keyElementId, + uint32 keyLength) +{ + keyElements[elementNumber].keyElementId = keyElementId; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + keyElements[elementNumber].keyElementLength = keyLength; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ +} /* Crypto_30_LibCv_Local_ElementGetterSetIdAndLength() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementGet() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* [SWS_Crypto_91006] */ +/* PRQA S 6080 5 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementGet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00085] */ + errorId = CRYPTO_E_UNINIT; + } + /* #15 Check plausibility of parameters */ + else if (resultPtr == NULL_PTR) + { + /* [SWS_Crypto_00088] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (resultLengthPtr == NULL_PTR) + { + /* [SWS_Crypto_00089] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (*resultLengthPtr == 0u) + { + /* [SWS_Crypto_00090] */ + errorId = CRYPTO_E_PARAM_VALUE; + } + else +#endif + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00086] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else + { + retVal = Crypto_30_LibCv_Local_KeyElementGet(cryptoKeyId, keyElementId, resultPtr, resultLengthPtr, &errorId); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #90 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_ELEMENT_GET, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_KeyElementGet() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RandomSeed() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* [SWS_Crypto_91013] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RandomSeed( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00128] */ + errorId = CRYPTO_E_UNINIT; + } + /* #15 Check plausibility of parameters */ + else if (entropyPtr == NULL_PTR) + { + /* [SWS_Crypto_00130] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (entropyLength == 0u) + { + /* [SWS_Crypto_00131] */ + errorId = CRYPTO_E_PARAM_VALUE; + } + else +#endif + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00129] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else + { +#if ((CRYPTO_30_LIBCV_FIPS186 == STD_ON) || (CRYPTO_30_LIBCV_DRBGAES == STD_ON) || (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON)) + retVal = Crypto_30_LibCv_Local_RandomSeed(cryptoKeyId, entropyPtr, entropyLength); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ +#else + retVal = E_NOT_OK; + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(entropyPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(entropyLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #25 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_RANDOM_SEED, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_RandomSeed() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyGenerate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ + +/* [SWS_Crypto_91007] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyGenerate( + uint32 cryptoKeyId) +{ + /* ----- Local Variables ------------------------------------------------ */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00094] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif + /* #15 Check plausibility of parameters */ + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00095] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else + { + /* ----- Implementation ------------------------------------------------- */ +#if (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM == STD_ON) + retVal = Crypto_30_LibCv_Local_KeyGenerate(cryptoKeyId); +#else + retVal = E_NOT_OK; + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #20 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_GENERATE, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_KeyGenerate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyDerive() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +/* [SWS_Crypto_91008] */ +/* PRQA S 6080 3 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyDerive( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00097] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif + /* #15 Check plausibility of parameters */ + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00098] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else if (targetCryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00180] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else + { + /* ----- Implementation ------------------------------------------------- */ +#if (CRYPTO_30_LIBCV_KEY_DERIVE_ALGORITHM == STD_ON) + boolean writeBlock = FALSE; +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* #30 Lock write access for the target CryptoKey */ + if (Crypto_30_LibCv_Local_KeyWriteLockGet(targetCryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +# endif + { + /* #35 Lock read access for the source CryptoKey if necessary */ + /* #40 derive key element with Crypto_30_LibCv_Local_KeyDerive */ + if (cryptoKeyId == targetCryptoKeyId) + { + retVal = Crypto_30_LibCv_Local_KeyDerive(cryptoKeyId, targetCryptoKeyId, &writeBlock); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + } +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + else if (Crypto_30_LibCv_Local_KeyReadLockGet(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } +# endif + else + { + retVal = Crypto_30_LibCv_Local_KeyDerive(cryptoKeyId, targetCryptoKeyId, &writeBlock); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyReadLockRelease(cryptoKeyId); +# endif + } + +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyWriteLockRelease(targetCryptoKeyId); +# endif + +# if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + if (writeBlock) + { + Crypto_30_LibCv_NvBlock_Write_Req(Crypto_30_LibCv_GetNvBlockIdxOfKey(targetCryptoKeyId)); + } +# endif + } +#else + retVal = E_NOT_OK; + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(targetCryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #80 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, CRYPTO_30_LIBCV_INSTANCE_ID, CRYPTO_30_LIBCV_SID_KEY_DERIVE, errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_KeyDerive() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyExchangeCalcPubVal() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* [SWS_Crypto_91009] */ +/* PRQA S 6080 4 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyExchangeCalcPubVal( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_API_REQUIREMENT */ + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_API_REQUIREMENT */ +{ + /* ----- Local Variables ------------------------------------------------ */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00103] */ + errorId = CRYPTO_E_UNINIT; + } + /* #15 Check plausibility of parameters */ + else if (publicValuePtr == NULL_PTR) + { + /* [SWS_Crypto_00105] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (publicValueLengthPtr == NULL_PTR) + { + /* [SWS_Crypto_00106] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (*publicValueLengthPtr == 0u) + { + /* [SWS_Crypto_00107] */ + errorId = CRYPTO_E_PARAM_VALUE; + } + else +#endif + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00104] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + /* The retVal is already captured in the methods body. */ + /* [SWS_Crypto_00110] */ + else + { + /* ----- Implementation ------------------------------------------------- */ + +#if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) + /* #20 Calculate Public Value */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcPubVal(cryptoKeyId, publicValuePtr, publicValueLengthPtr); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + +# if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + if (retVal == CRYPTO_E_SMALL_BUFFER) + { + /* [SWS_Crypto_00110] */ + errorId = CRYPTO_E_PARAM_VALUE; + } +# endif +#else + retVal = E_NOT_OK; + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(publicValuePtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(publicValueLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #30 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_EXCHANGE_CALC_PUB_VAL, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_KeyExchangeCalcPubVal() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyExchangeCalcSecret() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* [SWS_Crypto_91010] */ +/* PRQA S 6080 4 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyExchangeCalcSecret( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00111] */ + errorId = CRYPTO_E_UNINIT; + } + /* #15 Check plausibility of parameters */ + else if (partnerPublicValuePtr == NULL_PTR) + { + /* [SWS_Crypto_00113] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (partnerPublicValueLength == 0u) + { + /* [SWS_Crypto_00115] */ + errorId = CRYPTO_E_PARAM_VALUE; + } + else +#endif + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00112] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else + { + /* ----- Runtime Error Check ------------------------------------------------- */ +#if (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) + /* #20 Calculate Secret Value */ + retVal = Crypto_30_LibCv_Local_KeyExchangeCalcSecret(cryptoKeyId, partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ +#else + retVal = E_NOT_OK; + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(partnerPublicValuePtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(partnerPublicValueLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #45 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_EXCHANGE_CALC_SECRET, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_KeyExchangeCalcSecret() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_CertificateParse() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_CertificateParse( + uint32 cryptoKeyId) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00168] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif + /* #15 Check plausibility of parameters */ + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00169] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else + { + /* ----- Implementation ------------------------------------------------- */ + + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #20 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_CERTIFICATE_PARSE, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_CertificateParse() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_CertificateVerify() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ + +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_CertificateVerify( + uint32 cryptoKeyId, + uint32 verifyCryptoKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) verifyPtr) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_2 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + /* [SWS_Crypto_00172] */ + errorId = CRYPTO_E_UNINIT; + } + /* #15 Check plausibility of parameters */ + else if (verifyPtr == NULL_PTR) + { + /* [SWS_Crypto_00175] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else +#endif + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00173] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else if (verifyCryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + /* [SWS_Crypto_00174] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else + { + /* ----- Implementation ------------------------------------------------- */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(verifyCryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(verifyPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #20 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_CERTIFICATE_VERIFY, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_CertificateVerify() */ + +#if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_State_Init() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_State_Init( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx) +{ + /* ----- Local Variables ------------------------------------------------ */ + /* ----- Implementation ------------------------------------------------- */ + Crypto_30_LibCv_SetNvBlockState(blockIdx, CRYPTO_30_LIBCV_NVBLOCK_STATE_IDLE); /* SBSW_CRYPTO_30_LIBCV_CSL02_NV_BLOCK */ +} /* Crypto_30_LibCv_NvBlock_State_Init() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_ReadFromBlock() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6080 3 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_ReadFromBlock( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2CONST(void, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) NvMBuffer) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) NvMBufferPtr = (P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))NvMBuffer; /* PRQA S 0316 */ /* MD_CRYPTO_30_LIBCV_0316 */ + uint8 errorId = CRYPTO_E_NO_ERROR; + +# if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + errorId = CRYPTO_E_UNINIT; + } + else if (NvMBuffer == NULL_PTR) + { + errorId = CRYPTO_E_PARAM_POINTER; + } + else +# endif + { +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_KeyIterType lockedKeyIdx; + boolean locked = FALSE; + + /* Lock keys for write access. */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + for (lockedKeyIdx = 0u; lockedKeyIdx < Crypto_30_LibCv_GetSizeOfKey(); lockedKeyIdx++) + { + if (Crypto_30_LibCv_GetNvBlockIdxOfKey(lockedKeyIdx) == blockIdx) + { + locked = TRUE; + if (Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected((uint32)lockedKeyIdx) != E_OK) + { + locked = FALSE; + break; + } + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + + if (locked == TRUE) +# endif + { + /* Copy Buffer to Key Storage */ + retVal = Crypto_30_LibCv_NvBlock_ReadFromBlock_Copy(blockIdx, NvMBufferPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER */ + } + +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + { + Crypto_30_LibCv_KeyIterType releaseKeyIdx; + /* Release keys for write access. */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + for (releaseKeyIdx = 0; releaseKeyIdx < lockedKeyIdx; releaseKeyIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND_STATIC_GENDATA */ + { + if (Crypto_30_LibCv_GetNvBlockIdxOfKey(releaseKeyIdx) == blockIdx) + { + Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected((uint32)releaseKeyIdx); + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + } +# endif + } +# if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_NVBLOCK_READFROMBLOCK, + errorId); + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + + return retVal; +} /* Crypto_30_LibCv_NvBlock_ReadFromBlock() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_WriteToBlock() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 3 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_WriteToBlock( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2VAR(void, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) NvMBuffer) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) NvMBufferPtr = (P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))NvMBuffer; /* PRQA S 0316 */ /* MD_CRYPTO_30_LIBCV_0316 */ + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + errorId = CRYPTO_E_UNINIT; + } + else if (NvMBuffer == NULL_PTR) + { + errorId = CRYPTO_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ------------------------------------------------- */ +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_KeyIterType lockedKeyIdx; + boolean locked = FALSE; + + /* Lock keys for read access. */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + for (lockedKeyIdx = 0u; lockedKeyIdx < Crypto_30_LibCv_GetSizeOfKey(); lockedKeyIdx++) + { + if (Crypto_30_LibCv_GetNvBlockIdxOfKey(lockedKeyIdx) == blockIdx) + { + locked = TRUE; + if (Crypto_30_LibCv_Local_KeyReadLockGetNotProtected((uint32)lockedKeyIdx) != E_OK) + { + locked = FALSE; + break; + } + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + + if (locked == TRUE) +# endif + { + /* Copy Key Storage to Buffer. */ + Crypto_30_LibCv_NvBlock_WriteToBlock_Copy(blockIdx, NvMBufferPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_AND_ACCESS_TO_NVBUFFER */ + /* Update KeyNvStatus of keys of NvBlock */ + Crypto_30_LibCv_KeyNvStatus_NvCopied(blockIdx); + retVal = E_OK; + } + +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + { + Crypto_30_LibCv_KeyIterType releaseKeyIdx; + /* Release keys for read access. */ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + for (releaseKeyIdx = 0; releaseKeyIdx < lockedKeyIdx; releaseKeyIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND_STATIC_GENDATA */ + { + if (Crypto_30_LibCv_GetNvBlockIdxOfKey(releaseKeyIdx) == blockIdx) + { + Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected((uint32)releaseKeyIdx); + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1(); + } +# endif + } +# if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_NVBLOCK_WRITETOBLOCK, + errorId); + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + + return retVal; +} /* Crypto_30_LibCv_NvBlock_WriteToBlock() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_Init() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6080 2 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_Init( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + + Crypto_30_LibCv_KeyIterType keyIdx; + Crypto_30_LibCv_KeyElementsIterType elementIndex; +# if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) + Crypto_30_LibCv_SheKeysIterType sheKeyIndex; +# endif + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + errorId = CRYPTO_E_UNINIT; + } + else +# endif + { + /* ----- Implementation ------------------------------------------------- */ + retVal = E_OK; + Crypto_30_LibCv_NvBlock_State_Init(blockIdx); + + /* Initialize keys */ + for (keyIdx = 0u; keyIdx < Crypto_30_LibCv_GetSizeOfKey(); keyIdx++) + { + if (Crypto_30_LibCv_GetNvBlockIdxOfKey(keyIdx) == blockIdx) + { + for (elementIndex = Crypto_30_LibCv_GetKeyElementsStartIdxOfKey(keyIdx); elementIndex < Crypto_30_LibCv_GetKeyElementsEndIdxOfKey(keyIdx); elementIndex++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA */ + { + if (Crypto_30_LibCv_IsKeyElementPersist(elementIndex)) + { + Crypto_30_LibCv_Init_Key(elementIndex, TRUE); + } + } + } + } + + /* Initialize she keys */ +# if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) + for (sheKeyIndex = 0u; sheKeyIndex < Crypto_30_LibCv_GetSizeOfSheKeys(); sheKeyIndex++) + { + keyIdx = Crypto_30_LibCv_GetKeyIdxOfSheKeys(sheKeyIndex); + if (Crypto_30_LibCv_GetNvBlockIdxOfKey(keyIdx) == blockIdx) + { + elementIndex = Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(sheKeyIndex); + if (Crypto_30_LibCv_IsKeyElementPersist(elementIndex)) + { + Crypto_30_LibCv_Init_KeySheAdditional(elementIndex); + } + } + } +# endif + } +# if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_NVBLOCK_INIT, + errorId); + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + + return retVal; +} /* Crypto_30_LibCv_NvBlock_Init() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_Callback() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_Callback( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + uint8 ServiceId, + NvM_RequestResultType JobResult) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + errorId = CRYPTO_E_UNINIT; + } + else +# endif + { + /* ----- Implementation ------------------------------------------------- */ + retVal = E_OK; + switch (ServiceId) + { + case CRYPTO_30_LIBCV_NVM_WRITE_BLOCK: +# if (CRYPTO_30_LIBCV_NVM_WRITE_BLOCK != CRYPTO_30_LIBCV_NVM_WRITE_ALL) /* For compatibility to ASR 20-11 */ + case CRYPTO_30_LIBCV_NVM_WRITE_ALL: +# endif + { + Crypto_30_LibCv_NvBlock_State_CallbackWrittenToBlock(blockIdx); + Crypto_30_LibCv_KeyNvStatus_NvBlockCallback(blockIdx, JobResult); + break; + } + + default: + /* Service not handled. */ + break; + } + /* ----- Development Error Report --------------------------------------- */ + } +# if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_NVBLOCK_CALLBACK, + errorId); + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + + return retVal; +} /* Crypto_30_LibCv_NvBlock_Callback() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_InitKey() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_InitKey(uint32 cryptoKeyId) +{ + /* Set KeyNvStatus of current key to NV_SYNC */ + Crypto_30_LibCv_SetKeyNvStatus(cryptoKeyId, CRYPTO_30_LIBCV_KEY_NV_STATUS_NOT_NV); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ +} /* Crypto_30_LibCv_KeyNvStatus_InitKey() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_ReadFromBlock() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_ReadFromBlock(Crypto_30_LibCv_SizeOfNvBlockType blockIdx) +{ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* Loop through all cryptoKeys */ + for (uint32 keyIdx = 0u; keyIdx < Crypto_30_LibCv_GetSizeOfKeyNvStatus(); keyIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND_STATIC_GENDATA */ + { + /* Check if current key is referenced to the given NvBlock */ + if (Crypto_30_LibCv_GetNvBlockIdxOfKey(keyIdx) == blockIdx) + { + /* Set KeyNvStatus of current key to NV_SYNC */ + Crypto_30_LibCv_SetKeyNvStatus(keyIdx, CRYPTO_30_LIBCV_KEY_NV_STATUS_NV_SYNC); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +} /* Crypto_30_LibCv_KeyNvStatus_ReadFromBlock() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_KeyChanged_Unprotected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_KeyChanged_Unprotected(uint32 cryptoKeyId, Crypto_30_LibCv_SizeOfKeyElementsType elementIdx) +{ + /* If key is referenced to a NvBlock */ + if (Crypto_30_LibCv_IsKeyElementPersist(elementIdx)) + { + /* Check if key is in NV_WRITE_REQ */ + if (Crypto_30_LibCv_GetKeyNvStatus(cryptoKeyId) == CRYPTO_30_LIBCV_KEY_NV_STATUS_NV_WRITE_REQ) + { + /* Stay in this state */ + } + else + { + /* Set KEY_CHANGED state */ + Crypto_30_LibCv_SetKeyNvStatus(cryptoKeyId, CRYPTO_30_LIBCV_KEY_NV_STATUS_KEY_CHANGED); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } + } +} /* Crypto_30_LibCv_KeyNvStatus_KeyChanged_Unprotected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_KeyChanged() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_KeyChanged(uint32 cryptoKeyId, Crypto_30_LibCv_SizeOfKeyElementsType elementIdx) +{ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + Crypto_30_LibCv_KeyNvStatus_KeyChanged_Unprotected(cryptoKeyId, elementIdx); + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +} /* Crypto_30_LibCv_KeyNvStatus_KeyChanged() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_NvWriteReq() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_NvWriteReq(Crypto_30_LibCv_SizeOfNvBlockType blockIdx) +{ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* Loop through all cryptoKeys */ + for (uint32 keyIdx = 0u; keyIdx < Crypto_30_LibCv_GetSizeOfKeyNvStatus(); keyIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND_STATIC_GENDATA */ + { + /* Check if current key is referenced to the given NvBlock */ + if (Crypto_30_LibCv_GetNvBlockIdxOfKey(keyIdx) == blockIdx) + { + /* Check if key has changed by checking the KEY_CHANGED bit */ + if ((Crypto_30_LibCv_GetKeyNvStatus(keyIdx) & CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_KEY_CHANGED) == CRYPTO_30_LIBCV_KEY_NV_STATUS_MASK_KEY_CHANGED) + { + /* Set KeyNvStatus of current key to NV_WRITE_REQ */ + Crypto_30_LibCv_SetKeyNvStatus(keyIdx, CRYPTO_30_LIBCV_KEY_NV_STATUS_NV_WRITE_REQ); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +} /* Crypto_30_LibCv_KeyNvStatus_NvWriteReq() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_NvCopied() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_NvCopied(Crypto_30_LibCv_SizeOfNvBlockType blockIdx) +{ + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* Loop through all cryptoKeys */ + for (uint32 keyIdx = 0u; keyIdx < Crypto_30_LibCv_GetSizeOfKeyNvStatus(); keyIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND_STATIC_GENDATA */ + { + /* Check if current key is referenced to the given NvBlock */ + if (Crypto_30_LibCv_GetNvBlockIdxOfKey(keyIdx) == blockIdx) + { + /* Check if key is in state NV_WRITE_REQ or KEY_CHANGED */ + /* All keys of a block are copied when writing. This means that a key that has only changed is also updated by the NvM. */ + if ((Crypto_30_LibCv_GetKeyNvStatus(keyIdx) == CRYPTO_30_LIBCV_KEY_NV_STATUS_NV_WRITE_REQ) || + (Crypto_30_LibCv_GetKeyNvStatus(keyIdx) == CRYPTO_30_LIBCV_KEY_NV_STATUS_KEY_CHANGED)) + { + /* Set KeyNvStatus of current key to KEY_COPIED */ + Crypto_30_LibCv_SetKeyNvStatus(keyIdx, CRYPTO_30_LIBCV_KEY_NV_STATUS_KEY_COPIED); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +} /* Crypto_30_LibCv_KeyNvStatus_NvCopied() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_NvBlockCallback() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_NvBlockCallback(Crypto_30_LibCv_SizeOfNvBlockType blockIdx, NvM_RequestResultType jobResult) +{ + /* Define the next state depending on the job result of the callback */ + Crypto_30_LibCv_KeyNvStatusType nextState = (jobResult == NVM_REQ_OK) ? CRYPTO_30_LIBCV_KEY_NV_STATUS_NV_SYNC : CRYPTO_30_LIBCV_KEY_NV_STATUS_WRITE_FAILED; + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* Loop through all cryptoKeys */ + for (uint32 keyIdx = 0u; keyIdx < Crypto_30_LibCv_GetSizeOfKeyNvStatus(); keyIdx++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_UNCHANGED_UPPER_BOUND_STATIC_GENDATA */ + { + /* Check if current key is referenced to the given NvBlock */ + if (Crypto_30_LibCv_GetNvBlockIdxOfKey(keyIdx) == blockIdx) + { + /* Check if key is in state KEY_COPIED */ + if (Crypto_30_LibCv_GetKeyNvStatus(keyIdx) == CRYPTO_30_LIBCV_KEY_NV_STATUS_KEY_COPIED) + { + /* Set KeyNvStatus of current key to NV_SYNC or WRITE_FAIL depending on jobResult */ + Crypto_30_LibCv_SetKeyNvStatus(keyIdx, nextState); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); +} /* Crypto_30_LibCv_KeyNvStatus_NvBlockCallback() */ + +#endif /* (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) */ + +#if(CRYPTO_30_LIBCV_KEYSETVALIDJOB == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySetValidJob() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +/* [SWS_Crypto_91014] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySetValidJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* #10 Set the given KeyId valid */ + Crypto_30_LibCv_SetProcessJob_Trigger_Write(objectId, Crypto_30_LibCv_Internal_KeySetValid(job->cryptoKeyId)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + } + return E_OK; +} /* Crypto_30_LibCv_Dispatch_KeySetValidJob() */ +#endif /* (CRYPTO_30_LIBCV_KEYSETVALIDJOB == STD_ON) */ + +#if(CRYPTO_30_LIBCV_KEYSETINVALIDJOB == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySetInvalidJob() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* [SWS_Crypto_91014] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySetInvalidJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + /* Set key invalid */ + /* Foward write request */ + Crypto_30_LibCv_SetProcessJob_Trigger_Write(objectId, Crypto_30_LibCv_Internal_KeySetInvalid(job->cryptoKeyId)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + return E_OK; +} /* Crypto_30_LibCv_Dispatch_KeySetInvalidJob() */ +#endif /* (CRYPTO_30_LIBCV_KEYSETINVALIDJOB == STD_ON) */ + +#if(CRYPTO_30_LIBCV_SHECMDGETID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SheCmdGetId() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6050,6080 4 */ /* MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SheCmdGetId( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + Std_ReturnType retVal = E_NOT_OK, localRet; + Crypto_30_LibCv_SizeOfSheKeysType indexOfSheMasterKey = 0u; + Crypto_30_LibCv_SizeOfKeyStorageType uIdStorageIndex, masterKeyStorageIndex; + uint32 length; + uint8 result[CRYPTO_30_LIBCV_SIZEOF_CMAC]; + uint8 buffer[CRYPTO_30_LIBCV_SIZEOF_SHE_CMD_GET_ID_OUTPUT]; + uint8 status; + + if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_SINGLECALL)) + { + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + P2VAR(eslt_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfSheCmdGetId(Crypto_30_LibCv_GetSheCmdGetIdIdxOfObjectInfo(objectId)); + + /* #10 Get Master Key She Idx */ + /* Find key can be voided because master key must be available for cmd get id */ + (void)Crypto_30_LibCv_GetSheKey(CRYPTO_30_LIBCV_SHE_M1_ECU_MASTER_KEY_ID, CRYPTO_30_LIBCV_SHE_PAGE0, &indexOfSheMasterKey); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + /* #20 The input must have a length of 16 bytes, the crypto key must be set to the master key and must also be valid */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength == CRYPTO_30_LIBCV_SIZEOF_SHE_CHALLENGE) && + (Crypto_30_LibCv_GetKeyIdxOfSheKeys(indexOfSheMasterKey) == job->cryptoKeyId) && + (Crypto_30_LibCv_IsKeyElementValid(Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(indexOfSheMasterKey)))) + { +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* #30 Lock key for reading */ + if (Crypto_30_LibCv_Local_KeyReadLockGet(Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate()) == E_OK) +# endif + { + /* #40 Get she status */ + localRet = Crypto_30_LibCv_She_Cmd_Get_Status(&status); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + /* #50 Get UID */ + length = CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID; + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndex(Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate(), CRYPTO_KE_CUSTOM_SHE_UID, &uIdStorageIndex, &length, CRYPTO_30_LIBCV_LENGTH_CHECK_MIN); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + /* #60 Get Master Key */ + length = CRYPTO_30_LIBCV_SIZEOF_SHE_KEY; + localRet |= Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic(Crypto_30_LibCv_GetKeyElementsKeyIdxOfSheKeys(indexOfSheMasterKey), &masterKeyStorageIndex, &length, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL, CRYPTO_30_LIBCV_SHE_SERVICE_KEY_SERVICE); /* COV_CRYPTO_30_LIBCV_SHE_KEY_CONFIGURATION_2 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (localRet == E_OK) + { + /* MAC = CMAC[ 16 bytes CHALLENGE | 15 bytes UID | 1 byte STATUS ] with Master K */ + Crypto_30_LibCv_CopyData(buffer, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, CRYPTO_30_LIBCV_SIZEOF_SHE_CHALLENGE); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + Crypto_30_LibCv_CopyData(&buffer[CRYPTO_30_LIBCV_SIZEOF_SHE_CHALLENGE], Crypto_30_LibCv_GetAddrKeyStorage(uIdStorageIndex), CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + Crypto_30_LibCv_CopyData(&buffer[CRYPTO_30_LIBCV_SIZEOF_SHE_CHALLENGE + CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID], &status, CRYPTO_30_LIBCV_SIZEOF_SHE_STATUS); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + + /* #70 Calculate Mac */ + if (Crypto_30_LibCv_SheKeyUpdateCmac(buffer, CRYPTO_30_LIBCV_SIZEOF_ENC_BUFFER, Crypto_30_LibCv_GetAddrKeyStorage(masterKeyStorageIndex), result, workspace) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { + /* Output = [ 15 bytes UID | 1 byte STATUS | 16 bytes CMAC ] */ + Crypto_30_LibCv_CopyData(buffer, Crypto_30_LibCv_GetAddrKeyStorage(uIdStorageIndex), CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + Crypto_30_LibCv_CopyData(&buffer[CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID], &status, CRYPTO_30_LIBCV_SIZEOF_SHE_STATUS); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + Crypto_30_LibCv_CopyData(&buffer[CRYPTO_30_LIBCV_SIZEOF_SHE_M1_UID + CRYPTO_30_LIBCV_SIZEOF_SHE_STATUS], result, CRYPTO_30_LIBCV_SIZEOF_CMAC); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + + /* Adapt output size */ + if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr > CRYPTO_30_LIBCV_SIZEOF_ENC_BUFFER) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = CRYPTO_30_LIBCV_SIZEOF_ENC_BUFFER; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* #80 Copy result to output buffer */ + Crypto_30_LibCv_CopyData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, buffer, *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + + retVal = E_OK; + } + } +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* #90 Unlock Key */ + Crypto_30_LibCv_Local_KeyReadLockRelease(Crypto_30_LibCv_GetSheInfoKeyRefOfSheKeyUpdate()); +# endif + } + } + } + else + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_SheCmdGetId() */ +#endif /* (CRYPTO_30_LIBCV_SHECMDGETID == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_GetKeyFlags() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6010, 6030 3 */ /* MD_MSR_STPTH, MD_MSR_STCYC */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_GetKeyFlags( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_KeyFlagType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyFlagsPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex = 0u; + + /* ----- Implementation ------------------------------------------------- */ + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + retVal = E_NOT_OK; + } + else + { + /* Get elementIndex, keyElementId is checked implicitly */ + retVal = Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, keyElementId, &elementIndex); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + } + + if (retVal == E_OK) + { + /* Set correct Flags */ + /* TRUE: Key is valid + FALSE: Key is invalid */ + if (Crypto_30_LibCv_IsKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_MASK)) + { + keyFlagsPtr->isKeyValid = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + else + { + keyFlagsPtr->isKeyValid = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + + /* TRUE: Rewriting and erasing disabled + FALSE: Rewriting and erasing enabled */ + if (Crypto_30_LibCv_IsKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_MASK)) + { + keyFlagsPtr->write_protection = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + else + { + keyFlagsPtr->write_protection = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + { +#if ((CRYPTO_30_LIBCV_SHEKEYS == STD_ON) && (CRYPTO_30_LIBCV_SHE_ENABLE_FID == STD_ON)) + uint8 sheExtensions; + sheExtensions = Crypto_30_LibCv_GetKeyElementExtension(elementIndex); + + /* TRUE: Key is an SHE Key + FALSE: Key is not a SHE Key */ + if (Crypto_30_LibCv_IsSheKey(elementIndex)) + { + keyFlagsPtr->isSheKey = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + +# if (CRYPTO_30_LIBCV_KEYELEMENTSBOOTPROTECTIONIDXOFSHEPAGE == STD_ON) + /* TRUE: usage is limited + FALSE: Key usage is not limited according to result of secure boot */ + if (Crypto_30_LibCv_Uint8CheckMask(sheExtensions, CRYPTO_30_LIBCV_SHE_FID_MASK_BOOT_PROTECTION)) + { + keyFlagsPtr->boot_protection = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + else +# endif + { + keyFlagsPtr->boot_protection = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + +# if (CRYPTO_30_LIBCV_KEYELEMENTSDEBUGGERPROTECTIONIDXOFSHEPAGE == STD_ON) + /* TRUE: key can not be used if debugger is attached + FALSE: Use of a debug interface does not impose a limitation on key usage */ + if (Crypto_30_LibCv_Uint8CheckMask(sheExtensions, CRYPTO_30_LIBCV_SHE_FID_MASK_DEBUGGER_PROTECTION)) + { + keyFlagsPtr->debugger_protection = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + else +# endif + { + keyFlagsPtr->debugger_protection = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + + /* TRUE: key can be used for CMAC generate/verify + FALSE: Key can be used for AES ECB+CBC encrypt/decrypt */ + if (Crypto_30_LibCv_Uint8CheckMask(sheExtensions, CRYPTO_30_LIBCV_SHE_FID_MASK_KEY_USAGE)) + { + keyFlagsPtr->key_usage = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + else + { + keyFlagsPtr->key_usage = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + + /* TRUE: Key update by wildcard is disabled + FALSE: Key update by wildcard UID is enabled */ + if (Crypto_30_LibCv_Uint8CheckMask(sheExtensions, CRYPTO_30_LIBCV_SHE_FID_MASK_WILDCARD)) + { + keyFlagsPtr->disable_wildcard = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + else + { + keyFlagsPtr->disable_wildcard = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + + /* TRUE: Key can not be used to execute CMAC generate but only for CMAC verify + FALSE: Key can be used to execute CMAC generate */ + if (Crypto_30_LibCv_Uint8CheckMask(sheExtensions, CRYPTO_30_LIBCV_SHE_FID_MASK_CMAC_USAGE)) + { + keyFlagsPtr->cmac_usage = TRUE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + else + { + keyFlagsPtr->cmac_usage = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + } + else +#endif + { + keyFlagsPtr->isSheKey = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + keyFlagsPtr->boot_protection = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + keyFlagsPtr->debugger_protection = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + keyFlagsPtr->key_usage = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + keyFlagsPtr->disable_wildcard = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + keyFlagsPtr->cmac_usage = FALSE; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + } + } + } + return retVal; +} /* Crypto_30_LibCv_Api_GetKeyFlags() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyElementGetStorageIndex() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 6 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyElementGetStorageIndex( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck, + Crypto_30_LibCv_ServiceType serviceType) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + retVal = E_NOT_OK; + } + else + { + /* Call Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended( + cryptoKeyId, + keyElementId, + resultIndexPtr, + resultLengthPtr, + lengthCheck, + serviceType); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } + + return retVal; +} /* Crypto_30_LibCv_Api_KeyElementGetStorageIndex() */ + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyReadLockGetNotProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyReadLockGetNotProtected( + uint32 cryptoKeyId) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + retVal = E_NOT_OK; + } + else + { + /* Call Crypto_30_LibCv_Local_KeyReadLockGetNotProtected */ + retVal = Crypto_30_LibCv_Local_KeyReadLockGetNotProtected(cryptoKeyId); + } + + return retVal; +} /* Crypto_30_LibCv_Api_KeyReadLockGetNotProtected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyReadLockReleaseNotProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyReadLockReleaseNotProtected( + uint32 cryptoKeyId) +{ + Std_ReturnType retVal = E_NOT_OK; + + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + retVal = E_NOT_OK; + } + else + { + /* Call Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected */ + Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected(cryptoKeyId); + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Api_KeyReadLockReleaseNotProtected() */ +#endif /* (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyElementSearch() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyElementSearch( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) elementIndex) +{ + Std_ReturnType retVal = E_NOT_OK; + + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + retVal = E_NOT_OK; + } + else + { + retVal = Crypto_30_LibCv_Local_KeyElementSearch( /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + cryptoKeyId, + keyElementId, + elementIndex); + } + + return retVal; +} /* Crypto_30_LibCv_Api_KeyElementSearch() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyWriteLockGetNotProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyWriteLockGetNotProtected( + uint32 cryptoKeyId) +{ + Std_ReturnType retVal = E_NOT_OK; + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + retVal = E_NOT_OK; + } + else + { + retVal = Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected(cryptoKeyId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_LibCv_Api_KeyWriteLockGetNotProtected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyWriteLockReleaseNotProtected() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyWriteLockReleaseNotProtected( + uint32 cryptoKeyId) +{ + Std_ReturnType retVal = E_NOT_OK; + +#if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + retVal = E_NOT_OK; + } + else + { + Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected(cryptoKeyId); + retVal = E_OK; + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_LibCv_Api_KeyWriteLockReleaseNotProtected() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Api_KeyElementSetInternalStandard() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Api_KeyElementSetInternalStandard( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength) +{ + Std_ReturnType retVal = E_NOT_OK; + + if (elementIndex >= Crypto_30_LibCv_GetSizeOfKeyElements()) + { + retVal = E_NOT_OK; + } + else + { + retVal = Crypto_30_LibCv_KeyElementSetInternalStandard(elementIndex, keyPtr, keyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + } + + return retVal; +} /* Crypto_30_LibCv_Api_KeyElementSetInternalStandard() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyGetStatus() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* [SWS_Crypto_91019] */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyGetStatus( + uint32 cryptoKeyId, + P2VAR(Crypto_KeyStatusType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyStatusPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + /* Check initialization state of the component */ + if (Crypto_30_LibCv_IsModuleSharedNotInitialized()) + { + errorId = CRYPTO_E_UNINIT; /* [SWS_Crypto_00232] */ + } + /* Check validity of keyStatusPtr */ + else if (keyStatusPtr == NULL_PTR) + { + errorId = CRYPTO_E_PARAM_POINTER; /* [SWS_Crypto_00234] */ + } + else +#endif + /* Check plausibility of cryptoKeyId */ + if (cryptoKeyId >= Crypto_30_LibCv_GetSizeOfKey()) + { + errorId = CRYPTO_E_PARAM_HANDLE; /* [SWS_Crypto_00233] */ + } + else + { + /* ----- Implementation ------------------------------------- */ + Crypto_30_LibCv_Local_KeyGetStatus(cryptoKeyId, keyStatusPtr); /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + retVal = E_OK; + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_KEY_GET_STATUS, + errorId); + } +#else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif + + return retVal; +} /* Crypto_30_LibCv_KeyGetStatus() */ + +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeyManagement.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyManagement.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyManagement.h new file mode 100644 index 0000000..3aa9d81 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyManagement.h @@ -0,0 +1,667 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeyManagement.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Internal header file for service key management function prototypes + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#ifndef CRYPTO_30_LIBCV_KEYMANAGEMENT_H +# define CRYPTO_30_LIBCV_KEYMANAGEMENT_H +# include "Csm_Types.h" +# include "Crypto_30_LibCv_Cfg.h" + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyCopy() + *********************************************************************************************************************/ +/*! \brief Copy the key + * \details Copies a key with all its elements to another key in the same crypto driver. + * The key element can only be copied, if the destination key element write access right is less than + * WA_INTERNAL_COPY. + * Additional the read access right of the source must be less than RA_INTERNAL_COPY and the destination + * read access right must be higher or equal than the source read access right. + * The function returns E_OK if at least one keyElement has been successfully copied. + * cryptoKeyId and targetCryptoKeyId shall not be identical, otherwise the function returns E_NOT_OK. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] targetCryptoKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \return E_OK Request successful, at least one keyElement was successfully copied. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-131140 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyCopy( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementCopy() + *********************************************************************************************************************/ +/*! \brief Copy key element + * \details Copies a key element to another key element in the same crypto driver. + * The key element can only be copied, if the destination key element write access right is less than + * WA_INTERNAL_COPY. + * Additional the read access right of the source must be less than RA_INTERNAL_COPY and the destination + * read access right must be higher or equal than the source read access right. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for the + * copy operation. + * \param[in] targetCryptoKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination for + * the copy operation. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-131141 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementCopy( + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 targetCryptoKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementCopyPartial() + **********************************************************************************************************************/ +/*! \brief Copy key element partial + * \details Copies a key element to another key element in the same crypto driver. The keyElementSourceOffset + * and keyElementCopyLength allows to copy just a part of the source key element into the destination. + * The offset of the target key is also specified with this function. + * The target key element needs to have partial access. + * The key element can only be copied, if the destination key element write access right is less than + * WA_INTERNAL_COPY. + * Additional the read access right of the source must be less than RA_INTERNAL_COPY and the destination + * read access right must be higher or equal than the source read access right. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for the + * copy operation. + * \param[in] keyElementSourceOffset Holds the offset of the of the source key element indicating the start index + * of the copy operation. + * \param[in] keyElementTargetOffset Holds the offset of the of the target key element indicating the start index + * of the copy operation. + * \param[in] keyElementCopyLength Holds the number of bytes that shall be copied. + * \param[in] targetCryptoKeyId Holds the identifier of the key whose key element shall be the + * destination element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination for + * the copy operation. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * CRYPTO_E_KEY_EMPTY Request failed, uninitialized source key element. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-174489 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementCopyPartial( + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetCryptoKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementIdsGet() + *********************************************************************************************************************/ +/*! \brief Used to retrieve information which key elements are available in a given key. + * \details The service provides a list of key element which are available in the given key. + * \param[in] cryptoKeyId Holds the identifier of the key whose available element ids shall be exported. + * \param[out] keyElementIdsPtr Contains the pointer to the array where the ids of the key + * elements shall be stored. + * \param[out] keyElementIdsLengthPtr Holds a pointer to the memory location in which the number of key element + * in the given key is stored. On calling this function, this parameter + * shall contain the size of the buffer provided by keyElementIdsPtr. When the + * request has finished, the actual number of key elements is stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-131139 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementIdsGet( + uint32 cryptoKeyId, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyElementIdsPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyElementIdsLengthPtr); + +/* [SWS_Crypto_91004] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementSet() + *********************************************************************************************************************/ +/*! \brief Sets a key element + * \details Sets the given key element bytes to the key identified by cryptoKeyId. + * The key element can only be set, if the write access right is WA_ALLOWED or WA_ENCRYPTED. + * The access right need to be WA_ALLOWED for normal key, WA_ENCRYPTED for She key and WA_ALLOWED for She ram key. + * If keyLength is zero the old value is deleted. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] keyElementId Holds the identifier of the key element which shall be set. + * \param[in] keyPtr Holds the pointer to the key data which shall be set as key element. + * \param[in] keyLength Contains the length of the key element in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-131144 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementSet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength); + +# if ((CRYPTO_30_LIBCV_KEY_DERIVE_ALGORITHM == STD_ON) || (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess() + **********************************************************************************************************************/ +/*! \brief Checks the availability of the key element, the write access and determines the configured key element length + * \details - + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] keyElementId Holds the id of the key element which shall be set. + * \param[out] elementIndexPtr Holds the index of the key element which shall be set. + * \param[out] keyLengthPtr Contains the length of the key element in bytes. + * \param[in] writeAccess Hold the max write access right which could be accessed. + * \return E_OK Request successful. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * \pre cryptoKeyId has to be a valid identifier. + * The crypto key has to be locked for write access. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccess( /* PRQA S 3219 */ /* MD_CRYPTO_30_LIBCV_3219_1 */ + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) elementIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) keyLengthPtr, + Crypto_30_LibCv_WriteOfKeyElementInfoType writeAccess); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccessAndLength() + **********************************************************************************************************************/ +/*! \brief Checks the availability of the key element, the write access, determines and checks the configured key element length + * \details - + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] keyElementId Holds the id of the key element which shall be set. + * \param[out] elementIndexPtr Holds the index of the key element which shall be set. + * \param[in] requestedKeyLength Contains the length of the key element in bytes. + * \param[in] writeAccess Hold the max write access right which could be accessed. + * \return E_OK Request successful. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * \pre cryptoKeyId has to be a valid identifier. + * The crypto key has to be locked for write access. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccessAndLength( /* PRQA S 3219 */ /* MD_CRYPTO_30_LIBCV_3219_1 */ + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) elementIndexPtr, + uint32 requestedKeyLength, + Crypto_30_LibCv_WriteOfKeyElementInfoType writeAccess); +# endif + +/* [SWS_Crypto_91005] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyValidSet() + *********************************************************************************************************************/ +/*! \brief Sets the key state of the key identified by cryptoKeyId to valid. + * \details Sets all key elements of the given cryptoKey to valid. If the key contains at least one invalid + * persistent key element when called, the NvM is requested to write the block to which the cryptoKey + * refers. This API is an alias for KeySetValid() and does not differ in functionality, but is used + * for compliance with AUTOSAR 4.3.0 in terms of naming. + * \param[in] cryptoKeyId Holds the identifier of the key whose key elements shall be set to valid. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-131143 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyValidSet( + uint32 cryptoKeyId); + +/* [SWS_Crypto_91014] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_KeySetValid() + *********************************************************************************************************************/ +/*! \brief Sets the key state of the key identified by cryptoKeyId to valid. + * \details Sets all key elements of the given cryptoKey to valid. If the key contains at least one invalid + * persistent key element when called, the NvM is requested to write the block to which the cryptoKey + * refers. This API is an alias for KeyValidSet() and does not differ in functionality, but is used + * for compliance with AUTOSAR 4.3.1 (and higher) in terms of naming. + * \param[in] cryptoKeyId Holds the identifier of the key whose key elements shall be set to valid. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-131143 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeySetValid( + uint32 cryptoKeyId); + +/* [SWS_Crypto_91020] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_KeySetInvalid() + *********************************************************************************************************************/ +/*! \brief Sets invalid for the status of the key identified by cryptoKeyId. + * \details Sets all key elements of the given cryptoKey to invalid. If the key has at least one persistent + * key element, the NvM is requested to write the block to which the cryptoKey refers. + * \param[in] cryptoKeyId Holds the identifier of the key for which the status shall be set to invalid. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-Crypto-KeySetInvalid + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeySetInvalid( + uint32 cryptoKeyId); + +/* [SWS_Crypto_91006] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementGet() + *********************************************************************************************************************/ +/*! \brief This interface shall be used to get a key element of the key identified by the cryptoKeyId and store + * the key element in the memory location pointed to by the result pointer. + * \details The key element can only be provided, if the read access right is RA_ALLOWED. If the key element + * is configured to allow partial access, resultLengthPtr contains the amount of data which should + * be read from the key element. + * The behavior for partial access can be switched on or off in the configuration. + * If the read access right is RA_ENCRYPTED the She ram key can be exported. + * (64 Bytes for M1-M3 and 112Bytes for M1-M5) + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be returned. + * \param[in] keyElementId Holds the identifier of the key element which shall be returned. + * \param[out] resultPtr Holds the pointer of the buffer for the returned key element. + * \param[in,out] resultLengthPtr Holds a pointer to a memory location in which the length + * information is stored. On calling this function this parameter shall + * contain the size of the buffer provided by resultPtr. If the key + * element is configured to allow partial access, this parameter + * contains the amount of data which should be read from the key + * element. The size may not be equal to the size of the provided + * buffer anymore. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-131142 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementGet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr); + +/* [SWS_Crypto_91013] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_RandomSeed() + *********************************************************************************************************************/ +/*! \brief Initialize the seed + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-131137 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RandomSeed( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength); + +/* [SWS_Crypto_91007] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyGenerate() + *********************************************************************************************************************/ +/*! \brief Generates a key + * \details This function shall dispatch the key generate function to the configured crypto driver object. + * \param[in] cryptoKeyId Holds the identifier of the key which is to be updated with the generated + * value. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyGenerate( + uint32 cryptoKeyId); + +/* [SWS_Crypto_91008] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyDerive() + *********************************************************************************************************************/ +/*! \brief Derives a key + * \details Derives a new key by using the key elements in the given key identified by the cryptoKeyId. + * The key derivation function supports different algorithm which are specified by the + * algorithm key element(CRYPTO_KE_KEYDERIVATION_ALGORITHM). + * - For CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256 and + * CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB: + * The given key must contain the key elements for the password (CRYPTO_KE_KEYDERIVATION_PASSWORD), + * salt (CRYPTO_KE_KEYDERIVATION_SALT), algorithm (CRYPTO_KE_KEYDERIVATION_ALGORITHM) and the custom + * element label(CRYPTO_KE_CUSTOM_KEYDERIVATION_LABEL). The number of iterations is automatically + * determined by the needed key length. The derived key is stored in the key element with id 1 of the + * given key identified by targetCryptoKeyId. The write access right for the destination key element + * must be less than or equal to WA_INTERNAL_COPY. + * - For CRYPTO_30_LIBCV_KDF_ALGO_KDF_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256: The KDF reads the algorithm + * configuration from the cryptoKeyId key elements. The KDF requires the following key elements: the private key + * (CRYPTO_KE_KEYDERIVATION_PASSWORD), the public key (CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY) and the other + * Information (CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO). Other Information is only supported up to a length + * of 5 bytes. + * The derived key is set at the target key element (CRYPTO_KE_KEYDERIVATION_PASSWORD). + * - For CRYPTO_30_LIBCV_KDF_ALGO_KDF_ISO_15118_CERTIFICATE_HANDLING: + * For certificate installation the cryptoKeyId need to be the root certificate. + * For certificate update the cryptoKeyId and targetCryptoKeyId need to be the same key Id. + * The KDF is reads the algorithm configuration from the cryptoKeyId key elements. The KDF requires + * the following key element the private key (CRYPTO_KE_KEYDERIVATION_PASSWORD). + * The following key elements need to be set at the targetCryptoKeyId: + * the contract/new public key (CRYPTO_KE_CUSTOM_SCC_CONTRACT_PUBLIC_KEY), + * the IV and encrypted private key (CRYPTO_KE_CUSTOM_SCC_IV_AND_ENCRYPTED_PRIVATE_KEY) and + * the public key (CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY). + * The derived key is set at the target key element (CRYPTO_KE_KEYDERIVATION_PASSWORD). + * - For CRYPTO_30_LIBCV_KDF_ALGO_KDF_ISO_15118_20_CERTIFICATE_HANDLING: + * The KDF reads the algorithm configuration from the cryptoKeyId key elements. + * The following key element need to be set at the cryptoKeyId: + * the private key of the provision certificate (CRYPTO_KE_KEYDERIVATION_PASSWORD). + * The following key elements need to be set at the targetCryptoKeyId: + * the contract public key (CRYPTO_KE_CUSTOM_SCC_CONTRACT_PUBLIC_KEY), + * the IV, encrypted private key and tag (CRYPTO_KE_CUSTOM_SCC_IV_AND_ENCRYPTED_PRIVATE_KEY), + * the PCID and SKI (CRYPTO_KE_CUSTOM_SCC_CONTRACT_AAD) and + * the public key needed for ECDH (CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY). + * The derived key is set at the target key element (CRYPTO_KE_KEYDERIVATION_PASSWORD). + * - For CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA256 and CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA512: + * Derives a key according to KDF X9.63 with the given CRYPTO_KE_KEYDERIVATION_PASSWORD(Secret) + * and optional CRYPTO_KE_KEYDERIVATION_SALT(Seed). + * - For CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA1 and CRYPTO_30_LIBCV_KDF_ALGO_PBKDF2_HMAC_SHA256: + * The given key must contain the key elements for the password (CRYPTO_KE_KEYDERIVATION_PASSWORD), + * salt (CRYPTO_KE_KEYDERIVATION_SALT), algorithm (CRYPTO_KE_KEYDERIVATION_ALGORITHM) + * and the iteration element (CRYPTO_KE_KEYDERIVATION_ITERATIONS). + * The number of iterations is determined by the CRYPTO_KE_KEYDERIVATION_ITERATIONS + * element and must always be set with 4 bytes. The derived key is stored + * in the key element with id 1 of the given key identified by targetCryptoKeyId. + * The write access right for the destination key element must be less than or equal to WA_INTERNAL_COPY. + * - For CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA256 and CRYPTO_30_LIBCV_KDF_ALGO_HKDF_HMAC_SHA384: + * The given key must contain the key elements for the password (CRYPTO_KE_KEYDERIVATION_PASSWORD), + * salt (CRYPTO_KE_KEYDERIVATION_SALT), algorithm (CRYPTO_KE_KEYDERIVATION_ALGORITHM) + * iteration element (CRYPTO_KE_KEYDERIVATION_ITERATIONS) and optionally + * CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO (additional information). + * The iteration element specifies whether the one-step or two-step variant is to be used. + * The derived key is stored in the key element with id 1 of the given key identified by targetCryptoKeyId. + * The write access right for the destination key element must be less than or equal to WA_INTERNAL_COPY. + * - For CRYPTO_KDF_ALGO_HKDF_EXPAND_HMAC_SHA256 and CRYPTO_KDF_ALGO_HKDF_EXPAND_HMAC_SHA384: + * The given key must contain the key elements for the password (CRYPTO_KE_KEYDERIVATION_PASSWORD) and optionally + * CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO (additional information). + * The derived key is stored in the key element with id 1 of the given key identified by targetCryptoKeyId. + * The write access right for the destination key element must be less than or equal to WA_INTERNAL_COPY. + * - For CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA256 and CRYPTO_30_LIBCV_KDF_ALGO_HKDF_OPTION1_SHA512: + * The given key must contain the key elements for the password (CRYPTO_KE_KEYDERIVATION_PASSWORD), + * algorithm (CRYPTO_KE_KEYDERIVATION_ALGORITHM) and optionally CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO (additional information). + * The Algorithm element specifies which hash variant is to be used. + * The derived key is stored in the key element with id 1 of the given key identified by targetCryptoKeyId. + * The write access right for the destination key element must be less than or equal to WA_INTERNAL_COPY. + * - For CRYPTO_30_LIBCV_KDF_ALGO_SPAKE2_PLUS_P256R1: + * The given key must contain the key element for the password (CRYPTO_KE_KEYDERIVATION_PASSWORD). + * The derived key is stored in the key element with id 1 of the given key identified by targetCryptoKeyId. + * The write access right for the destination key element must be less than or equal to WA_INTERNAL_COPY. + * - For CRYPTO_30_LIBCV_KDF_ALGO_KDF_NIST_800_108_CTR_CMAC_AES: + * The given key must contain key elements for the password (CRYPTO_KE_KEYDERIVATION_PASSWORD) and + * algorithm (CRYPTO_KE_KEYDERIVATION_ALGORITHM). Optional additional inputs are label + * (CRYPTO_KE_CUSTOM_KEYDERIVATION_LABEL) and context (CRYPTO_KE_CUSTOM_KEYDERIVATION_CONTEXT). + * The password length defines the CMAC cipher: 16 Bytes (AES128) or 32 Bytes (AES256). + * The derived key is stored in the key element with id 1 of the given key identified by targetCryptoKeyId. + * The write access right for the destination key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyDerive( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/* [SWS_Crypto_91009] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyExchangeCalcPubVal() + *********************************************************************************************************************/ +/*! \brief Calculation of the public value + * \details Calculates the public value for the key exchange and stores the public key in the + * memory location pointed to by the public value pointer. The write access right for the destination + * key element must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-132409 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyExchangeCalcPubVal( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) publicValueLengthPtr); + +/* [SWS_Crypto_91010] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyExchangeCalcSecret() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret + * \details Calculates the shared secret key for the key exchange with the key material of the key identified + * by the cryptoKeyId and the partner public key. The shared secret key is stored + * as a key element in the same key. The write access right for the destination key element + * must be less than or equal to WA_INTERNAL_COPY. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \param[in] partnerPublicValueLength Contains the length of the partners public value in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-132408 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyExchangeCalcSecret( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_CertificateParse() + *********************************************************************************************************************/ +/*! \brief Parse stored certificate + * \details Parses the certificate data stored in the key element CRYPTO_KE_CERT_DATA and fills the key elements + * CRYPTO_KE_CERT_SIGNEDDATA, CRYPTO_KE_CERT_PARSEDPUBLICKEY and CRYPTO_KE_CERT_SIGNATURE + * \param[in] cryptoKeyId Holds the identifier of the key slot in which the certificate has been + * stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_CertificateParse( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_CertificateVerify() + *********************************************************************************************************************/ +/*! \brief Certificate verification + * \details Verifies the certificate stored in the key referenced by verifyCryptoKeyId with the + * certificate stored in the key referenced by cryptoKeyId. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used to validate the + * certificate. + * \param[in] verifyCryptoKeyId Holds the identifier of the key containing the certificate, which shall be + * verified. + * \param[out] verifyPtr Holds a pointer to the memory location which will contain the result of the + * certificate verification. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_CertificateVerify( + uint32 cryptoKeyId, + uint32 verifyCryptoKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) verifyPtr); + +# if(CRYPTO_30_LIBCV_SHECMDGETID == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SheCmdGetId() + *********************************************************************************************************************/ +/*! \brief Dispatches the She Cmd Get Id job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SheCmdGetId( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_SHECMDGETID == STD_ON) */ + +/* [SWS_Crypto_91019] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyGetStatus() + *********************************************************************************************************************/ +/*! \brief Returns the key state of the key identified by cryptoKeyId. + * \details This function reports the validity of a key. If the key is currently written by + * the NVM e.g. KeyElementSet() followed by KeySetValid(), it reports UPDATE_IN_PROGRESS + * until the key was successfully written by the NVM. If the update was not successful + * the status remains on UPDATE_IN_PROGRESS. The reported state reflects the state + * of the last initiated update routine. Which means if the key is changed again during + * the NVM update, the UPDATE_IN_PROGRESS is no longer reported. + * + * \param[in] cryptoKeyId Holds the identifier of the key for which the key state shall be returned. + * \param[out] keyStatusPtr Contains the pointer to the data where the status of the key shall be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-DrvCrypto_Libcv_KeyNvStatus + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyGetStatus( + uint32 cryptoKeyId, + P2VAR(Crypto_KeyStatusType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyStatusPtr); + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_KEYMANAGEMENT_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeyManagement.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeySetInvalid.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeySetInvalid.h new file mode 100644 index 0000000..cf11192 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeySetInvalid.h @@ -0,0 +1,73 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeySetInvalid.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for key set valid service. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#ifndef CRYPTO_30_LIBCV_KEYSETINVALID_H +# define CRYPTO_30_LIBCV_KEYSETINVALID_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if(CRYPTO_30_LIBCV_KEYSETINVALIDJOB == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySetInvalidJob() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeySetInvalid job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySetInvalidJob(uint32 objectId, P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYSETINVALIDJOB */ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_KEYSETINVALID_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeySetInvalid.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeySetValid.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeySetValid.h new file mode 100644 index 0000000..725357a --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeySetValid.h @@ -0,0 +1,74 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeySetValid.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for key set valid service. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#ifndef CRYPTO_30_LIBCV_KEYSETVALID_H +# define CRYPTO_30_LIBCV_KEYSETVALID_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if(CRYPTO_30_LIBCV_KEYSETVALIDJOB == STD_ON) +/* [SWS_Crypto_91014] */ +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySetValidJob() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeySetValid job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySetValidJob(uint32 objectId, P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYSETVALID */ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_KEYSETVALID_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeySetValid.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyUnwrap.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyUnwrap.h new file mode 100644 index 0000000..1618393 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyUnwrap.h @@ -0,0 +1,79 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeyUnwrap.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for KeyWrap Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_KEYUNWRAP_H) +# define CRYPTO_30_LIBCV_KEYUNWRAP_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyUnwrapAes() + *********************************************************************************************************************/ +/*! \brief Dispatches the key unwrap job to the lower layer. + * \details Dispatch the key unwrapping. Only available in single call mode + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-KeyUnwrapAes + * \note key wrap and unwrap have the same init-API + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyUnwrapAes( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON) */ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_KEYUNWRAP_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeyUnwrap.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyWrap.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyWrap.c new file mode 100644 index 0000000..4662933 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyWrap.c @@ -0,0 +1,556 @@ +/*********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------ + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------ + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/*! \file Crypto_30_LibCv_KeyWrap.c + * \brief MICROSAR Crypto Driver (Crypto) + * \details Implementation for key wrapping and unwrapping services + **********************************************************************************************************************/ + + /*********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------ + * Refer to the module's header file. + * + * FILE VERSION + * ------------------------------------------------------------------------------------------------------------------ + * Refer to the VERSION CHECK below. + **********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_KEYWRAP_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ +#include "Crypto_30_LibCv.h" +#include "Crypto_30_LibCv_Services.h" +#include "Crypto_30_LibCv_KeyUnwrap.h" +#include "Crypto_30_LibCv_KeyWrap.h" + +/*********************************************************************************************************************** + * LOCAL CONSTANT MACROS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL FUNCTION MACROS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if ((CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON) || (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyWrappingAesStart() + *********************************************************************************************************************/ +/*! + * \brief This function dispatches and executes the Key Wrap/Unwrap Aes init function. + * \details This function initializes the vSecPrim workspace, gets the key encryption key and determines the + * Aes variant according to the key length. + * Supported variants are: + * - Key Wrap/Unwrap Aes 128 + * - Key Wrap/Unwrap Aes 192 + * - Key Wrap/Unwrap Aes 256 + * \param[in,out] workspace Pointer to the vSecPrim key wrap/unwrap workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in] mode Mode of the start function - it determines whether the start is used for a key wrap + * or a key unwrap. The supported modes are: + * - ESL_KEYWRAP_WRAP_MODE + * - ESL_KEYWRAP_UNWRAP_MODE + * \return E_OK Dispatching was successful. + * \return E_NOT_OK Dispatching failed. + * \return CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \return CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyWrappingAesStart( + P2VAR(eslt_WorkspaceAESKeyWrap, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, eslt_Mode mode); +#endif /* ((CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON) || (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyWrapAesFinish() + *********************************************************************************************************************/ +/*! + * \brief This function dispatches and executes the Key Wrap Aes finish function. + * \details This function gets the key to wrap, checks its length and calls the underlying vSecPrim function + * \param[in,out] workspace Pointer to the vSecPrim workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * \return E_NOT_OK Dispatching failed. + * \return CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * \return CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyWrapAesFinish( + P2VAR(eslt_WorkspaceAESKeyWrap, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyUnwrapAesFinish() + *********************************************************************************************************************/ +/*! + * \brief This function dispatches and executes the Key Unwrap Aes finish function. + * \details This function checks the length of the input ptr: + * \param[in,out] workspace Pointer to the vSecPrim hash workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * \pre job has to be a pointer to a valid job object. + * inputPtrLength must be at least 3 * ESL_SIZEOF_AES_SEMIBLOCK and + * a multiple of ESL_SIZEOF_AES_SEMIBLOCK + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyUnwrapAesFinish( + P2VAR(eslt_WorkspaceAESKeyWrap, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint32 objectId); +#endif /* (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#if ((CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON) || (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyWrappingAesStart() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyWrappingAesStart( + P2VAR(eslt_WorkspaceAESKeyWrap, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, eslt_Mode mode) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Initialize workspace header. */ + retValCv = esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_AESKEYWRAP, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + eslt_Mode cipher = 0u; + + /* get key encryption/wrapping key */ + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyEncryptionKey = NULL_PTR; + Crypto_30_LibCv_SizeOfKeyStorageType indexOfkeyEncryptionKey = 0u; + uint32 keyEncryptionKeyLength = ESL_SIZEOF_AES128_KEY; /* key must be at least 16 bytes for key wrapping with AES128, it must be larger for other AES variants */ + + /* get index of key to encrypt */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(job->cryptoKeyId, CRYPTO_KE_CIPHER_KEY, &indexOfkeyEncryptionKey, &keyEncryptionKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MIN); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + keyEncryptionKey = Crypto_30_LibCv_GetAddrKeyStorage(indexOfkeyEncryptionKey); + + /* length check to get ID of the used cipher */ + switch (keyEncryptionKeyLength) + { + case ESL_SIZEOF_AES128_KEY: + { + cipher = ESL_KEYWRAP_AES128; + break; + } + + case ESL_SIZEOF_AES192_KEY: + { + cipher = ESL_KEYWRAP_AES192; + break; + } + + case ESL_SIZEOF_AES256_KEY: + { + cipher = ESL_KEYWRAP_AES256; + break; + } + + default: + { + /* Kek is invalid */ + retVal = E_NOT_OK; + break; + } + } + } + + if (retVal == E_OK) + { + retValCv = esl_initAESKeyWrap(workspace, keyEncryptionKey, (eslt_Length)keyEncryptionKeyLength, cipher, mode); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyWrappingAesStart() */ +#endif + +#if (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyWrapAesFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyWrapAesFinish( + P2VAR(eslt_WorkspaceAESKeyWrap, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* get key to wrap */ + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) plaintextKey = NULL_PTR; + Crypto_30_LibCv_SizeOfKeyStorageType indexOfPlaintextKey = 0u; + uint32 plaintextKeyLength = ESL_SIZEOF_AES_BLOCK; /* key must be at least 16 bytes */ + + /* get index of the plaintext key and check if the key element is big enough */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(job->targetCryptoKeyId, CRYPTO_KE_KEYWRAP_KEY, &indexOfPlaintextKey, &plaintextKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MIN); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + plaintextKey = Crypto_30_LibCv_GetAddrKeyStorage(indexOfPlaintextKey); + + /* the plaintext key must be a multiple of ESL_SIZEOF_AES_SEMIBLOCK */ + if ((plaintextKeyLength % ESL_SIZEOF_AES_SEMIBLOCK) != 0u) + { + retVal = E_NOT_OK; + } + /* the buffer for wrapped key must be at least plaintextKeyLength + ESL_SIZEOF_AES_SEMIBLOCK */ + else if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr < (plaintextKeyLength + ESL_SIZEOF_AES_SEMIBLOCK)) + { + retVal = E_NOT_OK; + } + else + { + eslt_Length outputLength = (eslt_Length)*(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* call vSecPrim key wrap function */ + retValCv = esl_wrapAESKeyWrap(workspace, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) plaintextKey, + (eslt_Length)plaintextKeyLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = (uint32)outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyWrapAesFinish() */ + +#endif /* (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyUnwrapAesFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 3 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyUnwrapAesFinish( + P2VAR(eslt_WorkspaceAESKeyWrap, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint32 objectId) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr) = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* length check - input length must be at least 3u * ESL_SIZEOF_AES_SEMIBLOCK bytes */ + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength < (uint32)(3u * ESL_SIZEOF_AES_SEMIBLOCK)) + { + retVal = E_NOT_OK; + } + /* length of the input must be a multiple of ESL_SIZEOF_AES_SEMIBLOCK */ + else if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength % ESL_SIZEOF_AES_SEMIBLOCK) != 0u) + { + retVal = E_NOT_OK; + } + else + { + /* get index of key where the plaintext key should be stored */ + P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) plaintextKey = NULL_PTR; + Crypto_30_LibCv_SizeOfKeyElementsType indexOfPlaintextKey = 0u; + eslt_Length plaintextKeyLength = (eslt_Length) (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength - ESL_SIZEOF_AES_SEMIBLOCK); + + retVal = Crypto_30_LibCv_KeyElementSet_PreCheckWriteAccessAndLength(job->targetCryptoKeyId, CRYPTO_KE_KEYWRAP_KEY, &indexOfPlaintextKey, plaintextKeyLength, CRYPTO_30_LIBCV_WA_INTERNAL_COPY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + plaintextKey = Crypto_30_LibCv_GetAddrKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(indexOfPlaintextKey)); + eslt_Length inputLen = (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength; + + retValCv = esl_unwrapAESKeyWrap(workspace, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + inputLen, plaintextKey, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) &plaintextKeyLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* Update key element. */ + Crypto_30_LibCv_Local_SetKeyElementStateWritten(indexOfPlaintextKey); + Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId(job->targetCryptoKeyId, indexOfPlaintextKey, plaintextKeyLength); + + /* set key to valid */ + Crypto_30_LibCv_SetProcessJob_Trigger_Write(objectId, Crypto_30_LibCv_Internal_KeySetValid(job->targetCryptoKeyId)); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr) = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + retVal = E_OK; + } + else if (retValCv == ESL_ERC_VERIFICATION_FAILED) + { + /* verification ptr has already been set to CRYPTO_E_VER_NOT_OK */ + retVal = E_OK; + } + else + { + /* verification ptr has already been set to CRYPTO_E_VER_NOT_OK */ + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyUnwrapAesFinish() */ + +#endif /* (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON) */ + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +#if (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON) +/*********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyWrapAes() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyWrapAes( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ----------------------------------------------- */ + /* job is single call only */ + if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_SINGLECALL)) + { + P2VAR(eslt_WorkspaceAESKeyWrap, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyWrapAes(Crypto_30_LibCv_GetKeyWrapAesIdxOfObjectInfo(objectId)); + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + /* note: key wrap and unwrap have the same init-API */ + retVal = Crypto_30_LibCv_Dispatch_KeyWrappingAesStart(workspace, job, ESL_KEYWRAP_WRAP_MODE); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + retVal = E_OK; + break; + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + retVal = Crypto_30_LibCv_Dispatch_KeyWrapAesFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyWrapAes() */ +#endif /* (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON) +/*********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyUnwrapAes() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyUnwrapAes( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + + /* job is single call only */ + if (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_SINGLECALL)) + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(eslt_WorkspaceAESKeyWrap, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeyUnwrapAes(Crypto_30_LibCv_GetKeyUnwrapAesIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkspaceAESKeyWrap)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + /* note: key wrap and unwrap have the same init-API */ + retVal = Crypto_30_LibCv_Dispatch_KeyWrappingAesStart(workspace, job, ESL_KEYWRAP_UNWRAP_MODE); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + retVal = E_OK; + break; + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + retVal = Crypto_30_LibCv_Dispatch_KeyUnwrapAesFinish(workspace, job, objectId); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeyUnwrapAes() */ +#endif /* (CRYPTO_30_LIBCV_KEYUNWRAPAES == STD_ON) */ + +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeyWrap.c + **********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyWrap.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyWrap.h new file mode 100644 index 0000000..6d109c0 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_KeyWrap.h @@ -0,0 +1,78 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_KeyWrap.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for Key Wrap Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_KEYWRAP_H) +# define CRYPTO_30_LIBCV_KEYWRAP_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeyWrapAes() + *********************************************************************************************************************/ +/*! \brief Dispatches the key wrap job to the lower layer. + * \details Dispatch the key wrapping. Only available in single call mode. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-KeyWrapAes + * \note key wrap and unwrap have the same init-API + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeyWrapAes( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_KEYWRAPAES == STD_ON) */ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_KEYWRAP_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_KeyWrap.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Mac.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Mac.c new file mode 100644 index 0000000..eff8c94 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Mac.c @@ -0,0 +1,3202 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Mac.c + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Implementation for MAC Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_MAC_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Crypto_30_LibCv.h" +#include "Crypto_30_LibCv_Services.h" +#include "Crypto_30_LibCv_MacGenerate.h" +#include "Crypto_30_LibCv_MacVerify.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL_CONSTANT MACROS + *********************************************************************************************************************/ +#define CRYPTO_30_LIBCV_MODULO_8(x) ((x) & (8u - 1u)) +#define CRYPTO_30_LIBCV_SIP_HASH_KEY_LENGTH (16u) +#define CRYPTO_30_LIBCV_SIPHASH_MAC_SIZE (8u) +#define CRYPTO_30_LIBCV_SHA2_256_KEY_LENGTH (32u) +#define CRYPTO_30_LIBCV_GMAC_MAX_OUT_TAG_SIZE (16u) + +#define CRYPTO_30_LIBCV_CMAC_AES_MODE_128 (0u) +#define CRYPTO_30_LIBCV_CMAC_AES_MODE_256 (1u) + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_LIBCV_SERVICE_MAC_VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_CompareMac() + *********************************************************************************************************************/ +/*! \brief Compares two MACs + * \details This function compares two MAC values from MSB to LSB. + * \param[in] mac1 Holds a pointer to the first mac + * \param[in] mac2 Holds a pointer to the second mac + * \param[in] lengthInBit Number of bits which shall be compared from MSB to LSB. + * \return CRYPTO_E_VER_NOT_OK Macs are not similar + * CRYPTO_E_VER_OK Macs are similar + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Crypto_VerifyResultType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_CompareMac( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) mac1, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) mac2, + uint32 lengthInBit); +#endif /* (CRYPTO_30_LIBCV_SERVICE_MAC_VERIFY == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_CMACAESVERIFY == STD_ON) || (CRYPTO_30_LIBCV_CMACAESGENERATE == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAes_Init_CalculateKey() + *********************************************************************************************************************/ +/*! \brief Initializes the CMAC AES algorithm including calculate the round keys. + * \details Depending on the AES key size, 128bit or 256bit AES CMAC is initialized. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] sheService Holds the service for SHE key usage. + * \return E_OK Init was successful. + * E_NOT_OK Init failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided key has no proper size. + * \pre workspace has to be valid. + * job has to be a valid job object handle. + * sheService hast be be a valid SHE service. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAes_Init_CalculateKey( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + Crypto_30_LibCv_ServiceType sheService); + +# if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAes_Init_ReuseKey() + *********************************************************************************************************************/ +/*! \brief Initializes the CMAC AES algorithm by reusing the round keys. + * \details Call esl_initExpandedCMACAES128/256 with NULL_PTR and length=0 as expanded key and key length so + * that vSecPrim reuses the previously generated expanded key. + * \param[in,out] workspace Pointer to the esl workspace. + * \return E_OK Init was successful. + * E_NOT_OK Init failed. + * \pre workspace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAes_Init_ReuseKey( + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace); +# endif /* (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAes_Start() + *********************************************************************************************************************/ +/*! \brief Handles operation mode START. + * \details If round key reuse is activated, the function checks if the round keys need to be recalculated or + * or can be reused and initializes the CMAC AES. If not, it just initializes the AES CMAC algorithm. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in] sheService Holds the service for SHE key usage. + * \return E_OK Init was successful. + * E_NOT_OK Init failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided key has no proper size. + * \pre workspace has to be valid. + * objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * sheService hast be be a valid SHE service. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAes_Start( + uint32 objectId, + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_30_LibCv_ServiceType sheService); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAes_Update() + *********************************************************************************************************************/ +/*! \brief Handles operation mode UPDATE. + * \details Forwards the plain text data to the underlying crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Request was successful. + * E_NOT_OK Request failed. + * \pre workspace has to be valid. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAes_Update( + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAes_CalcFullMac() + *********************************************************************************************************************/ +/*! \brief Calculates the full-sized AES CMAC. + * \details Calls the suitable function of the underlaying crypto library based on round key reuse and AES mode. + * Checks if the calculated MAC has a proper size of CRYPTO_30_LIBCV_CMACAES_MAC_SIZE (16 bytes). + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] macBuffer Pointer to a buffer where the AES CMAC shall be stored. + * \param[in,out] macLength Pointer to a length variable providing the length of the macBuffer. + * \return E_OK Request was successful. + * E_NOT_OK Request failed. + * \pre workspace has to be valid. + * macBuffer has to be a valid buffer with a length of CRYPTO_30_LIBCV_CMACAES_MAC_SIZE (16 bytes). + * macLength hat to be a valid pointer providing the length of macBuffer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAes_CalcFullMac( + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) macBuffer, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) macLength); +#endif /* ((CRYPTO_30_LIBCV_CMACAESVERIFY == STD_ON) || (CRYPTO_30_LIBCV_CMACAESGENERATE == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_HMACSHA1GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA1VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA1ModeStart() + *********************************************************************************************************************/ +/*!\brief Handles operation mode START. + * \details This function initializes both the workspace header and algorithm. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Start operation was successful. + * E_NOT_OK Start operation failed. + * \pre workSpace has to be valid. + * job has to be a job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA1ModeStart( + P2VAR(eslt_WorkSpaceHMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA1ModeUpdate() + *********************************************************************************************************************/ +/*!\brief Handles operation mode UPDATE. + * \details This function processes the input data. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Update operation was successful. + * E_NOT_OK Update operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA1ModeUpdate( + P2VAR(eslt_WorkSpaceHMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA1GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA1VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA1GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA1GenerateModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers, adapts the output size of the tag value and + * copies the data to the output location. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA1GenerateModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA1GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA256GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA256VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA256ModeStart() + *********************************************************************************************************************/ +/*!\brief Handles operation mode START. + * \details This function initializes both the workspace header and algorithm. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Start operation was successful. + * E_NOT_OK Start operation failed. + * \pre workSpace has to be valid. + * job has to be a job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA256ModeStart( + P2VAR(eslt_WorkSpaceHMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA256ModeUpdate() + *********************************************************************************************************************/ +/*!\brief Handles operation mode UPDATE. + * \details This function processes the input data. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Update operation was successful. + * E_NOT_OK Update operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA256ModeUpdate( + P2VAR(eslt_WorkSpaceHMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA256GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA256VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA256GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA256GenerateModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers, adapts the output size of the tag value and + * copies the data to the output location. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA256GenerateModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA256GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA384GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA384VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA384ModeStart() + *********************************************************************************************************************/ +/*!\brief Handles operation mode START. + * \details This function initializes both the workspace header and algorithm. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Start operation was successful. + * E_NOT_OK Start operation failed. + * \pre workSpace has to be valid. + * job has to be a job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA384ModeStart( + P2VAR(eslt_WorkSpaceHMACSHA384, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA384ModeUpdate() + *********************************************************************************************************************/ +/*!\brief Handles operation mode UPDATE. + * \details This function processes the input data. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Update operation was successful. + * E_NOT_OK Update operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA384ModeUpdate( + P2VAR(eslt_WorkSpaceHMACSHA384, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA384GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA384VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA384GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA384GenerateModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers, adapts the output size of the tag value and + * copies the data to the output location. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA384GenerateModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA384, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA384GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA512GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA512VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA512ModeStart() + *********************************************************************************************************************/ +/*!\brief Handles operation mode START. + * \details This function initializes both the workspace header and algorithm. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Start operation was successful. + * E_NOT_OK Start operation failed. + * \pre workSpace has to be valid. + * job has to be a job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA512ModeStart( + P2VAR(eslt_WorkSpaceHMACSHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA512ModeUpdate() + *********************************************************************************************************************/ +/*!\brief Handles operation mode UPDATE. + * \details This function processes the input data. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Update operation was successful. + * E_NOT_OK Update operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA512ModeUpdate( + P2VAR(eslt_WorkSpaceHMACSHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA512GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA512VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA512GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA512GenerateModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers, adapts the output size of the tag value and + * copies the data to the output location. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA512GenerateModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA512GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA1VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA1VerifyModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers and checks if verification was successful. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA1VerifyModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA1VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA256VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA256VerifyModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers and checks if verification was successful. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA256VerifyModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA256VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA384VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA384VerifyModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers and checks if verification was successful. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA384VerifyModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA384, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA384VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA512VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA512VerifyModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers and checks if verification was successful. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA512VerifyModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACSHA512VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_GMACAESGENERATE == STD_ON) || (CRYPTO_30_LIBCV_GMACAESVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchGmacAesModeStart() + *********************************************************************************************************************/ +/*!\brief Handles operation mode START. + * \details This function initializes both the workspace header and algorithm. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Start operation was successful. + * E_NOT_OK Start operation failed. + * \pre workSpace has to be valid. + * job has to be a job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchGmacAesModeStart( + P2VAR(eslt_WorkSpaceGMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchGmacAesModeUpdate() + *********************************************************************************************************************/ +/*!\brief Handles operation mode UPDATE. + * \details This function processes the input data. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Update operation was successful. + * E_NOT_OK Update operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchGmacAesModeUpdate( + P2VAR(eslt_WorkSpaceGMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_GMACAESGENERATE == STD_ON) || (CRYPTO_30_LIBCV_GMACAESVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_GMACAESGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchGmacAesGenerateModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers, adapts the output size of the tag value and + * copies the data to the output location. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchGmacAesGenerateModeFinish( + P2VAR(eslt_WorkSpaceGMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_GMACAESGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_GMACAESVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchGmacAesVerifyModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers and checks if verification was successful. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchGmacAesVerifyModeFinish( + P2VAR(eslt_WorkSpaceGMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_GMACAESVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACRIPEMD160GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACRIPEMD160VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacRipeMd160ModeStart() + *********************************************************************************************************************/ +/*!\brief Handles operation mode START. + * \details This function initializes both the workspace header and algorithm. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Start operation was successful. + * E_NOT_OK Start operation failed. + * \pre workSpace has to be valid. + * job has to be a job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacRipeMd160ModeStart( + P2VAR(eslt_WorkSpaceHMACRIPEMD160, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacRipeMd160ModeUpdate() + *********************************************************************************************************************/ +/*!\brief Handles operation mode UPDATE. + * \details This function processes the input data. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Update operation was successful. + * E_NOT_OK Update operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacRipeMd160ModeUpdate( + P2VAR(eslt_WorkSpaceHMACRIPEMD160, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACRIPEMD160GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACRIPEMD160VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACRIPEMD160GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacRipeMd160GenerateModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers, adapts the output size of the tag value and + * copies the data to the output location. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacRipeMd160GenerateModeFinish( + P2VAR(eslt_WorkSpaceHMACRIPEMD160, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACRIPEMD160GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACRIPEMD160VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacRipeMd160VerifyModeFinish() + *********************************************************************************************************************/ +/*!\brief Handles operation mode FINISH. + * \details This function writes the results in output buffers and checks if verification was successful. + * \param[in] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Finish operation was successful. + * E_NOT_OK Finish operation failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacRipeMd160VerifyModeFinish( + P2VAR(eslt_WorkSpaceHMACRIPEMD160, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_HMACRIPEMD160VERIFY == STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#if (CRYPTO_30_LIBCV_SERVICE_MAC_VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_CompareMac() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Crypto_VerifyResultType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_CompareMac( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) mac1, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) mac2, + uint32 lengthInBit) +{ + Crypto_VerifyResultType result = CRYPTO_E_VER_OK; + const uint32 numberOfFullBytesInMac = Crypto_30_LibCv_Bit2Byte(lengthInBit); + uint32 numberBitsInLastByte; + uint8 verifyBitMask; + + uint32 i = 0u; + + /* # Compare full bytes of both MACs. */ + /* # No use of VStdLib_MemCmp, so that the for-loop steps through all bytes in order to achieve a constant function runtime (security measure). */ + for (i = 0u; i < (numberOfFullBytesInMac); i++) /* FETA_CRYPTO_30_LIBCV_MONOTONIC_LOOP_UP_WITH_PARAMETER_DEPENDENT_UPPER_BOUND */ + { + if (mac1[i] != mac2[i]) + { + /* Verification does not match */ + result = CRYPTO_E_VER_NOT_OK; + } + } + + /* # Compare remaining bits. */ + /* Compute number of bits to verify in the last byte */ + numberBitsInLastByte = CRYPTO_30_LIBCV_MODULO_8(lengthInBit); /* Calculate modulo */ + if (numberBitsInLastByte != 0u) + { + /* Generate bitmask which contains all bits to be verified */ + verifyBitMask = (uint8)~((1u << (8u - numberBitsInLastByte)) - 1u); + + /* Verify the last masked byte */ + if ((mac1[numberOfFullBytesInMac] & verifyBitMask) + != (mac2[numberOfFullBytesInMac] & verifyBitMask)) + { + result = CRYPTO_E_VER_NOT_OK; + } + } + + return result; +} /* Crypto_30_LibCv_CompareMac() */ +#endif /* (CRYPTO_30_LIBCV_SERVICE_MAC_VERIFY == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_CMACAESVERIFY == STD_ON) || (CRYPTO_30_LIBCV_CMACAESGENERATE == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAes_Init_CalculateKey() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAes_Init_CalculateKey( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + Crypto_30_LibCv_ServiceType sheService) +{ + uint32 cmacAesKeyLength; + Crypto_30_LibCv_SizeOfKeyStorageType cmacAesKeyIndex; + + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* Get MAC key */ + Std_ReturnType localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended(job->cryptoKeyId, CRYPTO_KE_MAC_KEY, + &cmacAesKeyIndex, &cmacAesKeyLength, + CRYPTO_30_LIBCV_LENGTH_CHECK_NONE, sheService); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (localRetVal == E_OK) + { + /* Initialize workspace header. */ + retValCv = esl_initWorkSpaceHeader(&(workspace->wsCMACAES.header), ESL_MAXSIZEOF_WS_CMACAES, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* Distinguish AES CMAC mode based on AES key size. */ + switch (cmacAesKeyLength) + { + case CRYPTO_30_LIBCV_CMACAES128_KEY_SIZE: + { + /* Init CMAC AES128 */ + workspace->mode = CRYPTO_30_LIBCV_CMAC_AES_MODE_128; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + retValCv = esl_initCMACAES128( + &workspace->wsCMACAES, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)cmacAesKeyLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(cmacAesKeyIndex)); + break; + } + case CRYPTO_30_LIBCV_CMACAES256_KEY_SIZE: + { + /* Init CMAC AES256 */ + workspace->mode = CRYPTO_30_LIBCV_CMAC_AES_MODE_256; /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + retValCv = esl_initCMACAES256( + &workspace->wsCMACAES, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)cmacAesKeyLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(cmacAesKeyIndex)); + break; + } + default: + { + /* MAC key has no proper size. */ + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + retValCv = ESL_ERC_ERROR; + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + } + else if (localRetVal == CRYPTO_E_KEY_NOT_VALID) + { + retVal = CRYPTO_E_KEY_NOT_VALID; + } + else + { + /* retVal remains on E_NOT_OK */ + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_CmacAes_Init_CalculateKey() */ + +# if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAes_Init_ReuseKey() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAes_Init_ReuseKey( + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* Get the AES CMAC mode from the workspace mode which was written in the previous AES CMAC round. */ + switch (workspace->mode) + { + case CRYPTO_30_LIBCV_CMAC_AES_MODE_128: + { + retValCv = esl_initExpandedCMACAES128(&workspace->wsCMACAES, NULL_PTR, (eslt_Length) 0u); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } + case CRYPTO_30_LIBCV_CMAC_AES_MODE_256: + { + retValCv = esl_initExpandedCMACAES256(&workspace->wsCMACAES, NULL_PTR, (eslt_Length) 0u); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported mode. */ + /* retValCv remains error. */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_CmacAes_Init_ReuseKey() */ +# endif /* (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAes_Start() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080, 6030 5 */ /* MD_MSR_STMIF, MD_MSR_STCYC */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAes_Start( + uint32 objectId, + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_30_LibCv_ServiceType sheService) +{ + Std_ReturnType retVal = E_NOT_OK; + + /* Load key element from storage and initialize algorithm with keys. Dependent on roundkey feature, either the roundkey is loaded as key or the original key. */ +# if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE== STD_ON) + Crypto_30_LibCv_SizeOfKeyElementsType macElementId = 0u; + boolean reCalculate = FALSE; + + Std_ReturnType localRetVal = Crypto_30_LibCv_Local_KeyElementSearch(job->cryptoKeyId, CRYPTO_KE_MAC_KEY, &macElementId); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + /* Check if MAC key has changed */ + if ((localRetVal != E_OK) || (!Crypto_30_LibCv_IsKeyElementStateByMask(macElementId, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALUE_USED_MASK))) + { + reCalculate = TRUE; + } + /* Check if job is last job / workspace has changed */ + if (Crypto_30_LibCv_ObjectWorkspaceHasChanged(objectId, job) == TRUE) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + { + reCalculate = TRUE; + } + + if (reCalculate == TRUE) +# endif + { + retVal = Crypto_30_LibCv_Dispatch_CmacAes_Init_CalculateKey(job, workspace, sheService); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + +# if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) + /* Set flag that roundkeys are calculated */ + if (retVal == E_OK) + { + Crypto_30_LibCv_SetKeyElementStateByMask(macElementId, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALUE_USED_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + } + } + else + { + retVal = Crypto_30_LibCv_Dispatch_CmacAes_Init_ReuseKey(workspace); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_OF_WORKSPACE */ + +# else /* !(CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE== STD_ON) */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(objectId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_CmacAes_Start() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAes_Update() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAes_Update( + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* Distinguish between 128bit or 256bit based on workspace mode. */ + switch(workspace->mode) + { + case CRYPTO_30_LIBCV_CMAC_AES_MODE_128: + { + retValCv = esl_updateCMACAES128(&workspace->wsCMACAES, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + break; + } + + case CRYPTO_30_LIBCV_CMAC_AES_MODE_256: + { + retValCv = esl_updateCMACAES256(&workspace->wsCMACAES, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported mode. */ + /* retValCv remains error. */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_CmacAes_Update() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAes_CalcFullMac() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAes_CalcFullMac( + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) macBuffer, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) macLength) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + switch (workspace->mode) + { +# if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) + case CRYPTO_30_LIBCV_CMAC_AES_MODE_128: + { + retValCv = esl_finalizeKeepStateCMACAES128(&workspace->wsCMACAES, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))macBuffer, + macLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_PARAMETER_BUFFER */ + break; + } + case CRYPTO_30_LIBCV_CMAC_AES_MODE_256: + { + retValCv = esl_finalizeKeepStateCMACAES256(&workspace->wsCMACAES, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))macBuffer, + macLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_PARAMETER_BUFFER */ + break; + } +# else /* !(CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) */ + case CRYPTO_30_LIBCV_CMAC_AES_MODE_128: + { + retValCv = esl_finalizeCMACAES128(&workspace->wsCMACAES, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))macBuffer); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + break; + } + case CRYPTO_30_LIBCV_CMAC_AES_MODE_256: + { + retValCv = esl_finalizeCMACAES256(&workspace->wsCMACAES, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))macBuffer, + macLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_PARAMETER_BUFFER */ + + break; + } +# endif /* !(CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) */ + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported mode. */ + /* retValCv remains error. */ + break; + } + } + + /* Check if MAC was fully generated */ + if ((retValCv == ESL_ERC_NO_ERROR) && (*macLength == CRYPTO_30_LIBCV_CMACAES_MAC_SIZE)) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_CmacAes_CalcFullMac() */ +#endif /* ((CRYPTO_30_LIBCV_CMACAESVERIFY == STD_ON) || (CRYPTO_30_LIBCV_CMACAESGENERATE == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_CMACAESGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAesGenerate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAesGenerate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + Std_ReturnType retVal = E_NOT_OK; + + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfCmacAesGenerate(Crypto_30_LibCv_GetCmacAesGenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(Crypto_30_LibCv_WorkSpaceCMACAES)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* Distinguish modes. */ + switch (mode) + { + /* Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + /* Init CMAC AES. */ + retVal = Crypto_30_LibCv_Dispatch_CmacAes_Start(objectId, workspace, job, CRYPTO_30_LIBCV_SHE_SERVICE_MAC_GENERATE); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + /* Process plaintext data. */ + retVal = Crypto_30_LibCv_Dispatch_CmacAes_Update(workspace, job); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + /* Create local buffer to store the full MAC */ + uint8 macBuffer[CRYPTO_30_LIBCV_CMACAES_MAC_SIZE]; + eslt_Length macLength = CRYPTO_30_LIBCV_CMACAES_MAC_SIZE; + + /* Calculate full MAC (16 bytes) */ + if(Crypto_30_LibCv_Dispatch_CmacAes_CalcFullMac(workspace, macBuffer, &macLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + { + /* Get local job output ptrs to shorten the variable names */ + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) outputPtr = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr; + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) outputLengthPtr = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr; + + /* Limit job output length to default AES CMAC size (16 bytes). */ + if (*outputLengthPtr > CRYPTO_30_LIBCV_CMACAES_MAC_SIZE) + { + *outputLengthPtr = CRYPTO_30_LIBCV_CMACAES_MAC_SIZE; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* Copy calculated MAC into output buffer with given outputLengthPtr (truncation possible). */ + Crypto_30_LibCv_CopyData(outputPtr, macBuffer, *outputLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + retVal = E_OK; + } + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_CmacAesGenerate() */ +#endif /* (CRYPTO_30_LIBCV_CMACAESGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_CMACAESVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAesVerify() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAesVerify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(Crypto_30_LibCv_WorkSpaceCMACAES, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfCmacAesVerify(Crypto_30_LibCv_GetCmacAesVerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(Crypto_30_LibCv_WorkSpaceCMACAES)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + /* Init CMAC AES. */ + retVal = Crypto_30_LibCv_Dispatch_CmacAes_Start(objectId, workspace, job, CRYPTO_30_LIBCV_SHE_SERVICE_MAC_VERIFY); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + /* Process plaintext data. */ + retVal = Crypto_30_LibCv_Dispatch_CmacAes_Update(workspace, job); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + /* Create local buffer to store the full MAC */ + uint8 macBuffer[CRYPTO_30_LIBCV_CMACAES_MAC_SIZE]; + eslt_Length macLength = CRYPTO_30_LIBCV_CMACAES_MAC_SIZE; + + /* Check if input length is not to large. */ + /* Size is given in bits. */ + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength <= (Crypto_30_LibCv_Byte2Bit(CRYPTO_30_LIBCV_CMACAES_MAC_SIZE))) + { + /* Calculate full MAC (16 bytes) */ + if (Crypto_30_LibCv_Dispatch_CmacAes_CalcFullMac(workspace, macBuffer, &macLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + { + macLength = (eslt_Length) job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength; + + /* Verify the input MAC by comparing it with the calculated MAC. */ + /* Only the given length is compared to enable truncation. */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr) = /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + Crypto_30_LibCv_CompareMac(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, macBuffer, (uint32) macLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + + retVal = E_OK; + } + } + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_CmacAesVerify() */ +#endif /* (CRYPTO_30_LIBCV_CMACAESVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SIPHASHGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SipHashGenerate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SipHashGenerate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceSipHash, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfSipHashGenerate(Crypto_30_LibCv_GetSipHashGenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceSipHash)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_MAC_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_SIPHASH, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initSipHash(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex)); + } + } + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + + /* # Process plaintext data */ + retValCv = esl_updateSipHash(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + + break; + } + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + eslt_Byte macBuffer[CRYPTO_30_LIBCV_SIPHASH_MAC_SIZE]; + + retValCv = esl_finalizeSipHash(workspace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))macBuffer); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Adapt output size. */ + if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr > CRYPTO_30_LIBCV_SIPHASH_MAC_SIZE) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = CRYPTO_30_LIBCV_SIPHASH_MAC_SIZE; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Write results in output buffers. */ + Crypto_30_LibCv_CopyData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, macBuffer, *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_SipHashGenerate() */ +#endif /* (CRYPTO_30_LIBCV_SIPHASHGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SIPHASHVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SipHashVerify() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SipHashVerify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceSipHash, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfSipHashVerify(Crypto_30_LibCv_GetSipHashVerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceSipHash)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_MAC_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_SIPHASH, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initSipHash(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex)); + } + } + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + /* # Process plaintext data */ + retValCv = esl_updateSipHash(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + eslt_Byte macBuffer[CRYPTO_30_LIBCV_SIPHASH_MAC_SIZE]; + uint32 macLength; + retValCv = esl_finalizeSipHash(workspace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))macBuffer); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Check if input length is not to large. */ + macLength = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength; + if (macLength <= (CRYPTO_30_LIBCV_SIPHASH_MAC_SIZE << 3u)) + { + + /* # Check if verification was successful. */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr) = /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + Crypto_30_LibCv_CompareMac(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, macBuffer, macLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + } + else + { + retValCv = ESL_ERC_ERROR; + } + } + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_SipHashVerify() */ +#endif /* (CRYPTO_30_LIBCV_SIPHASHVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA1GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA1VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA1ModeStart() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA1ModeStart( + P2VAR(eslt_WorkSpaceHMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* # Initialize workspace header. */ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Std_ReturnType retVal = E_NOT_OK; + + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_MAC_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (esl_initWorkSpaceHeader(&(workSpace->header), ESL_MAXSIZEOF_WS_HMACSHA1, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initHashMACSHA1(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex)); + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchHmacSHA1ModeStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA1ModeUpdate() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA1ModeUpdate( + P2VAR(eslt_WorkSpaceHMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + eslt_ErrorCode retValCv; + + /* Update HMAC Calculation */ + /* # Process input data. */ + retValCv = esl_updateHashMACSHA1(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA1ModeUpdate() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA1GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA1VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA1GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA1GenerateModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA1GenerateModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + uint8 macBuffer[ESL_SIZEOF_SHA1_DIGEST]; + + if (esl_finalizeHashMACSHA1(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) macBuffer) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + { + /* # Adapt output size. */ + if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr > ESL_SIZEOF_SHA1_DIGEST) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = ESL_SIZEOF_SHA1_DIGEST; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Write results in output buffers. */ + Crypto_30_LibCv_CopyData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, macBuffer, *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* Set return value */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = 0u; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA1GenerateModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha1Generate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha1Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceHMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfHmacSha1Generate(Crypto_30_LibCv_GetHmacSha1GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceHMACSHA1)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchHmacSHA1ModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA1ModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA1GenerateModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_HmacSha1Generate() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA1GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA256GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA256VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA256ModeStart() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA256ModeStart( + P2VAR(eslt_WorkSpaceHMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* # Initialize workspace header. */ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Std_ReturnType retVal = E_NOT_OK; + + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_MAC_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (esl_initWorkSpaceHeader(&(workSpace->header), ESL_MAXSIZEOF_WS_HMACSHA256, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initHashMACSHA256(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex)); + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchHmacSHA256ModeStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA256ModeUpdate() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA256ModeUpdate( + P2VAR(eslt_WorkSpaceHMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + eslt_ErrorCode retValCv; + + /* Update HMAC Calculation */ + /* # Process input data. */ + retValCv = esl_updateHashMACSHA256(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA256ModeUpdate() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA256GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA256VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA256GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA256GenerateModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA256GenerateModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + uint8 macBuffer[ESL_SIZEOF_SHA256_DIGEST]; + + if (esl_finalizeHashMACSHA256(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) macBuffer) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + { + /* # Adapt output size. */ + if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr > ESL_SIZEOF_SHA256_DIGEST) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = ESL_SIZEOF_SHA256_DIGEST; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Write results in output buffers. */ + Crypto_30_LibCv_CopyData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, macBuffer, *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* Set return value */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = 0u; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA256GenerateModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha256Generate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha256Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceHMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfHmacSha256Generate(Crypto_30_LibCv_GetHmacSha256GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceHMACSHA256)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchHmacSHA256ModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA256ModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA256GenerateModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_HmacSha256Generate() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA256GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA384GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA384VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA384ModeStart() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA384ModeStart( + P2VAR(eslt_WorkSpaceHMACSHA384, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* # Initialize workspace header. */ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Std_ReturnType retVal = E_NOT_OK; + + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_MAC_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (esl_initWorkSpaceHeader(&(workSpace->header), ESL_MAXSIZEOF_WS_HMACSHA384, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initHashMACSHA384(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex)); + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchHmacSHA384ModeStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA384ModeUpdate() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA384ModeUpdate( + P2VAR(eslt_WorkSpaceHMACSHA384, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + eslt_ErrorCode retValCv; + + /* Update HMAC Calculation */ + /* # Process input data. */ + retValCv = esl_updateHashMACSHA384(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA384ModeUpdate() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA384GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA384VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA384GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA384GenerateModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA384GenerateModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA384, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + uint8 macBuffer[ESL_SIZEOF_SHA384_DIGEST]; + + if (esl_finalizeHashMACSHA384(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) macBuffer) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + { + /* # Adapt output size. */ + if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr > ESL_SIZEOF_SHA384_DIGEST) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = ESL_SIZEOF_SHA384_DIGEST; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Write results in output buffers. */ + Crypto_30_LibCv_CopyData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, macBuffer, *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* Set return value */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = 0u; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA384GenerateModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha384Generate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha384Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceHMACSHA384, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfHmacSha384Generate(Crypto_30_LibCv_GetHmacSha384GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceHMACSHA384)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchHmacSHA384ModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA384ModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA384GenerateModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_HmacSha384Generate() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA384GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA512GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA512VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA512ModeStart() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA512ModeStart( + P2VAR(eslt_WorkSpaceHMACSHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* # Initialize workspace header. */ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Std_ReturnType retVal = E_NOT_OK; + + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_MAC_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (esl_initWorkSpaceHeader(&(workSpace->header), ESL_MAXSIZEOF_WS_HMACSHA512, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initHashMACSHA512(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex)); + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchHmacSHA512ModeStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA512ModeUpdate() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA512ModeUpdate( + P2VAR(eslt_WorkSpaceHMACSHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + eslt_ErrorCode retValCv; + + /* Update HMAC Calculation */ + /* # Process input data. */ + retValCv = esl_updateHashMACSHA512(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA512ModeUpdate() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA512GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACSHA512VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA512GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA512GenerateModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA512GenerateModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + uint8 macBuffer[ESL_SIZEOF_SHA512_DIGEST]; + eslt_Length macLength = sizeof(macBuffer); + + if (esl_finalizeHashMACSHA512(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) macBuffer, (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&macLength) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_PARAMETER_BUFFER */ + { + /* # Adapt output size. */ + if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr > ESL_SIZEOF_SHA512_DIGEST) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = ESL_SIZEOF_SHA512_DIGEST; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Write results in output buffers. */ + Crypto_30_LibCv_CopyData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, macBuffer, *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* Set return value */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = 0u; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA512GenerateModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha512Generate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha512Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceHMACSHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfHmacSha512Generate(Crypto_30_LibCv_GetHmacSha512GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceHMACSHA512)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchHmacSHA512ModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA512ModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA512GenerateModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_HmacSha512Generate() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA512GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA1VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA1VerifyModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA1VerifyModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + eslt_ErrorCode retValCv; + uint8 macBuffer[ESL_SIZEOF_SHA1_DIGEST]; + + retValCv = esl_finalizeHashMACSHA1(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) macBuffer); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Check if input length is not to large. */ + /* size is given in bits */ + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength <= Crypto_30_LibCv_Byte2Bit(ESL_SIZEOF_SHA1_DIGEST)) + { + /* # Check if verification was successful. */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr) = /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + Crypto_30_LibCv_CompareMac(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, macBuffer, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + } + else + { + retValCv = ESL_ERC_ERROR; + } + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA1VerifyModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha1Verify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha1Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceHMACSHA1, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfHmacSha1Verify(Crypto_30_LibCv_GetHmacSha1VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceHMACSHA1)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchHmacSHA1ModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA1ModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA1VerifyModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_HmacSha1Verify() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA1VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA256VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA256VerifyModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA256VerifyModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + eslt_ErrorCode retValCv; + uint8 macBuffer[ESL_SIZEOF_SHA256_DIGEST]; + + retValCv = esl_finalizeHashMACSHA256(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) macBuffer); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Check if input length is not to large. */ + /* size is given in bits */ + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength <= Crypto_30_LibCv_Byte2Bit(ESL_SIZEOF_SHA256_DIGEST)) + { + /* # Check if verification was successful. */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr) = /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + Crypto_30_LibCv_CompareMac(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, macBuffer, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + } + else + { + retValCv = ESL_ERC_ERROR; + } + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA256VerifyModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha256Verify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha256Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceHMACSHA256, AUTOMATIC, CRYPTO_30_LIBCV_VAR_NOINIT) workspace = Crypto_30_LibCv_GetWorkspaceOfHmacSha256Verify(Crypto_30_LibCv_GetHmacSha256VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceHMACSHA256)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchHmacSHA256ModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA256ModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA256VerifyModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_HmacSha256Verify() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA256VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA384VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA384VerifyModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA384VerifyModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA384, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + eslt_ErrorCode retValCv; + uint8 macBuffer[ESL_SIZEOF_SHA384_DIGEST]; + + retValCv = esl_finalizeHashMACSHA384(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) macBuffer); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Check if input length is not to large. */ + /* size is given in bits */ + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength <= Crypto_30_LibCv_Byte2Bit(ESL_SIZEOF_SHA384_DIGEST)) + { + /* # Check if verification was successful. */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr) = /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + Crypto_30_LibCv_CompareMac(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, macBuffer, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + } + else + { + retValCv = ESL_ERC_ERROR; + } + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA384VerifyModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha384Verify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha384Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceHMACSHA384, AUTOMATIC, CRYPTO_30_LIBCV_VAR_NOINIT) workspace = Crypto_30_LibCv_GetWorkspaceOfHmacSha384Verify(Crypto_30_LibCv_GetHmacSha384VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceHMACSHA384)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchHmacSHA384ModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA384ModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA384VerifyModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_HmacSha384Verify() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA384VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACSHA512VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacSHA512VerifyModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacSHA512VerifyModeFinish( + P2VAR(eslt_WorkSpaceHMACSHA512, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + eslt_ErrorCode retValCv; + uint8 macBuffer[ESL_SIZEOF_SHA512_DIGEST]; + eslt_Length macLength = sizeof(macBuffer); + + retValCv = esl_finalizeHashMACSHA512(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))macBuffer, (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&macLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_PARAMETER_BUFFER */ + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Check if input length is not to large. */ + /* size is given in bits */ + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength <= Crypto_30_LibCv_Byte2Bit(ESL_SIZEOF_SHA512_DIGEST)) + { + /* # Check if verification was successful. */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr) = /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + Crypto_30_LibCv_CompareMac(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, macBuffer, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + } + else + { + retValCv = ESL_ERC_ERROR; + } + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacSHA512VerifyModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha512Verify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha512Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceHMACSHA512, AUTOMATIC, CRYPTO_30_LIBCV_VAR_NOINIT) workspace = Crypto_30_LibCv_GetWorkspaceOfHmacSha512Verify(Crypto_30_LibCv_GetHmacSha512VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceHMACSHA512)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchHmacSHA512ModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA512ModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchHmacSHA512VerifyModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_HmacSha512Verify() */ +#endif /* (CRYPTO_30_LIBCV_HMACSHA512VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_GMACAESGENERATE == STD_ON) || (CRYPTO_30_LIBCV_GMACAESVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchGmacAesModeStart() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchGmacAesModeStart( + P2VAR(eslt_WorkSpaceGMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* # Initialize workspace header. */ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Std_ReturnType retVal = E_NOT_OK; + + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CIPHER_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CIPHER_IV); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (esl_initWorkSpaceHeader(&(workSpace->header), ESL_MAXSIZEOF_WS_GMAC, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initGMAC(workSpace, + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (eslt_Length)keyElements[1u].keyElementLength, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1u].keyElementIndex)); + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchGmacAesModeStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchGmacAesModeUpdate() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchGmacAesModeUpdate( + P2VAR(eslt_WorkSpaceGMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + eslt_ErrorCode retValCv; + + /* Update GMAC Calculation */ + /* # Process input data. */ + retValCv = esl_updateGMAC(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + + return retValCv; +} /* Crypto_30_LibCv_DispatchGmacAesModeUpdate() */ +#endif /* (CRYPTO_30_LIBCV_GMACAESGENERATE == STD_ON) || (CRYPTO_30_LIBCV_GMACAESVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_GMACAESGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchGmacAesGenerateModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchGmacAesGenerateModeFinish( + P2VAR(eslt_WorkSpaceGMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* buffer holding Auth Tag */ + eslt_Byte authTagTempBuffer[CRYPTO_30_LIBCV_GMAC_MAX_OUT_TAG_SIZE] = { 0u }; + + /* # Write results in output buffer. */ + if (esl_finalizeGMAC(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&authTagTempBuffer[0]) /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + == ESL_ERC_NO_ERROR) + { + /* # Adapt output size of auth tag. */ + if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr > CRYPTO_30_LIBCV_GMAC_MAX_OUT_TAG_SIZE) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = CRYPTO_30_LIBCV_GMAC_MAX_OUT_TAG_SIZE; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + /* # Copy auth tag to output buffer. */ + Crypto_30_LibCv_CopyData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, authTagTempBuffer, *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + retValCv = ESL_ERC_NO_ERROR; + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchGmacAesGenerateModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_GmacAesGenerate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6030 4 */ /* MD_MSR_STCYC */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_GmacAesGenerate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceGMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfGmacAesGenerate(Crypto_30_LibCv_GetGmacAesGenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceGMAC)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchGmacAesModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchGmacAesModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchGmacAesGenerateModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_GmacAesGenerate() */ +#endif /* (CRYPTO_30_LIBCV_GMACAESGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_GMACAESVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchGmacAesVerifyModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchGmacAesVerifyModeFinish( + P2VAR(eslt_WorkSpaceGMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* buffer holding Auth Tag */ + eslt_Byte authTagTempBuffer[CRYPTO_30_LIBCV_GMAC_MAX_OUT_TAG_SIZE] = { 0u }; + uint32 authTagTempBufferLength; + + /* # Write results in output buffer. */ + if (esl_finalizeGMAC(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&authTagTempBuffer[0]) /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + == ESL_ERC_NO_ERROR) + { + /* # Check if input length is not to large. */ + authTagTempBufferLength = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength; + /* size is given in bits */ + if (authTagTempBufferLength <= (CRYPTO_30_LIBCV_GMAC_MAX_OUT_TAG_SIZE << 3u)) + { + + /* # Check if verification was successful. */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr) = /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + Crypto_30_LibCv_CompareMac(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, authTagTempBuffer, authTagTempBufferLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + retValCv = ESL_ERC_ERROR; + } + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchGmacAesVerifyModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_GmacAesVerify() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6030 4 */ /* MD_MSR_STCYC */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_GmacAesVerify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceGMAC, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfGmacAesVerify(Crypto_30_LibCv_GetGmacAesVerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceGMAC)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchGmacAesModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchGmacAesModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchGmacAesVerifyModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_GmacAesVerify() */ +#endif /* (CRYPTO_30_LIBCV_GMACAESVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACRIPEMD160GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACRIPEMD160VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacRipeMd160ModeStart() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacRipeMd160ModeStart( + P2VAR(eslt_WorkSpaceHMACRIPEMD160, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* # Initialize workspace header. */ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Std_ReturnType retVal = E_NOT_OK; + + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_MAC_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (esl_initWorkSpaceHeader(&(workSpace->header), ESL_MAXSIZEOF_WS_HMACRIPEMD160, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* # Initialize algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initHashMACRIPEMD160(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex)); + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchHmacRipeMd160ModeStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacRipeMd160ModeUpdate() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacRipeMd160ModeUpdate( + P2VAR(eslt_WorkSpaceHMACRIPEMD160, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + eslt_ErrorCode retValCv; + + /* Update HMAC Calculation */ + /* # Process input data. */ + retValCv = esl_updateHashMACRIPEMD160(workSpace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacRipeMd160ModeUpdate() */ +#endif /* (CRYPTO_30_LIBCV_HMACRIPEMD160GENERATE == STD_ON) || (CRYPTO_30_LIBCV_HMACRIPEMD160VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACRIPEMD160GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacRipeMd160GenerateModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacRipeMd160GenerateModeFinish( + P2VAR(eslt_WorkSpaceHMACRIPEMD160, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + uint8 macBuffer[ESL_SIZEOF_SHA1_DIGEST]; + + if (esl_finalizeHashMACRIPEMD160(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) macBuffer) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + { + /* # Adapt output size. */ + if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr > ESL_SIZEOF_RIPEMD160_DIGEST) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = ESL_SIZEOF_RIPEMD160_DIGEST; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + /* # Write results in output buffers. */ + Crypto_30_LibCv_CopyData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, macBuffer, *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* Set return value */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = 0u; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacRipeMd160GenerateModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacRipeMd160Generate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacRipeMd160Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceHMACRIPEMD160, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfHmacRipeMd160Generate(Crypto_30_LibCv_GetHmacRipeMd160GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceHMACRIPEMD160)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchHmacRipeMd160ModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchHmacRipeMd160ModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchHmacRipeMd160GenerateModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_HmacRipeMd160Generate() */ +#endif /* (CRYPTO_30_LIBCV_HMACRIPEMD160GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_HMACRIPEMD160VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchHmacRipeMd160VerifyModeFinish() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ + +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchHmacRipeMd160VerifyModeFinish( + P2VAR(eslt_WorkSpaceHMACRIPEMD160, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + eslt_ErrorCode retValCv; + uint8 macBuffer[ESL_SIZEOF_RIPEMD160_DIGEST]; + + retValCv = esl_finalizeHashMACRIPEMD160(workSpace, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) macBuffer); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER_NOLENGTHGIVEN */ + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Check if input length is not to large. */ + /* size is given in bits */ + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength <= Crypto_30_LibCv_Byte2Bit(ESL_SIZEOF_RIPEMD160_DIGEST)) + { + /* # Check if verification was successful. */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr) = /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + Crypto_30_LibCv_CompareMac(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, macBuffer, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER_AND_PARAMETER_BUFFER */ + } + else + { + retValCv = ESL_ERC_ERROR; + } + } + + return retValCv; +} /* Crypto_30_LibCv_DispatchHmacRipeMd160VerifyModeFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacRipeMd160Verify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacRipeMd160Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceHMACRIPEMD160, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfHmacRipeMd160Verify(Crypto_30_LibCv_GetHmacRipeMd160VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceHMACRIPEMD160)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchHmacRipeMd160ModeStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retValCv = Crypto_30_LibCv_DispatchHmacRipeMd160ModeUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retValCv = Crypto_30_LibCv_DispatchHmacRipeMd160VerifyModeFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_HmacRipeMd160Verify() */ +#endif /* (CRYPTO_30_LIBCV_HMACRIPEMD160VERIFY == STD_ON) */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Mac.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_MacGenerate.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_MacGenerate.h new file mode 100644 index 0000000..1763b5d --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_MacGenerate.h @@ -0,0 +1,261 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_MacGenerate.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for MAC Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_MACGENERATE_H) +# define CRYPTO_30_LIBCV_MACGENERATE_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_CMACAESGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAesGenerate() + *********************************************************************************************************************/ +/*! \brief Dispatches the CmacAesGenerate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided key has no proper size. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-DrvCrypto_LibCv_AesCmacGeneration + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAesGenerate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_CMACAESGENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SIPHASHGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SipHashGenerate() + *********************************************************************************************************************/ +/*! \brief Dispatches the SipHashGenerate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-139106 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SipHashGenerate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_SIPHASHGENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_HMACSHA1GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha1Generate() + *********************************************************************************************************************/ +/*! \brief Dispatches the HmacSha1Generate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-142966 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha1Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_HMACSHA1GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_HMACSHA256GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha256Generate() + *********************************************************************************************************************/ +/*! \brief Dispatches the HmacSha256Generate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-139112 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha256Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_HMACSHA256GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_HMACSHA384GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha384Generate() + *********************************************************************************************************************/ +/*! \brief Dispatches the HmacSha384Generate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-182647 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha384Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_HMACSHA384GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_HMACSHA512GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha512Generate() + *********************************************************************************************************************/ +/*! \brief Dispatches the HmacSha512Generate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-HMACSHA512Generate + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha512Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_HMACSHA512GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_GMACAESGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_GmacAesGenerate() + *********************************************************************************************************************/ +/*! \brief Dispatches the GmacAesGenerate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-180786 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_GmacAesGenerate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_GMACAESGENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_HMACRIPEMD160GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacRipeMd160Generate() + *********************************************************************************************************************/ +/*! \brief Dispatches the Hmac RIPEMD160 generate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-242493 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacRipeMd160Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_HMACRIPEMD160GENERATE == STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CRYPTO_30_LIBCV_MACGENERATE_H) */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_MacGenerate.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_MacVerify.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_MacVerify.h new file mode 100644 index 0000000..f556662 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_MacVerify.h @@ -0,0 +1,261 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_MacVerify.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for MAC Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_MACVERIFY_H) +# define CRYPTO_30_LIBCV_MACVERIFY_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_CMACAESVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_CmacAesVerify() + *********************************************************************************************************************/ +/*! \brief Dispatches the CmacAesVerify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided key has no proper size. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-DrvCrypto_LibCv_AesCmacVerification + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_CmacAesVerify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_CMACAESVERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SIPHASHVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SipHashVerify() + *********************************************************************************************************************/ +/*! \brief Dispatches the SipHashVerify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-139105 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SipHashVerify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_SIPHASHVERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_HMACSHA1VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha1Verify() + *********************************************************************************************************************/ +/*! \brief Dispatches the HmacSha1Verify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-142967 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha1Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_HMACSHA1VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_HMACSHA256VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha256Verify() + *********************************************************************************************************************/ +/*! \brief Dispatches the HmacSha256verify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-143359 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha256Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_HMACSHA256VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_HMACSHA384VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha384Verify() + *********************************************************************************************************************/ +/*! \brief Dispatches the HmacSha384verify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-182646 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha384Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_HMACSHA384VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_HMACSHA512VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacSha512Verify() + *********************************************************************************************************************/ +/*! \brief Dispatches the HmacSha512verify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-HMACSHA512Verify + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacSha512Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_HMACSHA512VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_GMACAESVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_GmacAesVerify() + *********************************************************************************************************************/ +/*! \brief Dispatches the GcmAesEncrypt job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-180787 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_GmacAesVerify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_GMACAESVERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_HMACRIPEMD160VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_HmacRipeMd160Verify() + *********************************************************************************************************************/ +/*! \brief Dispatches the Hmac RIPEMD160 verify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-242494 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_HmacRipeMd160Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_HMACRIPEMD160VERIFY == STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CRYPTO_30_LIBCV_MACVERIFY_H) */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_MacVerify.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Random.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Random.c new file mode 100644 index 0000000..478c637 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Random.c @@ -0,0 +1,3303 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Random.c + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Implementation for RANDOM Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_RANDOM_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Crypto_30_LibCv.h" +#include "Crypto_30_LibCv_Services.h" +#include "Crypto_30_LibCv_RandomGenerate.h" +#include "Crypto_30_LibCv_RandomSeed.h" + +#include "ESLib_types.h" +#if (CRYPTO_30_LIBCV_FIPS186 == STD_ON) +# include "actFIPS186.h" +#endif + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_RANDOM_SEED_SIZEOF_ALGORITHM (1u) + +/* FIPS */ +#define CRYPTO_30_LIBCV_FIPS_SEED_LENGTH (20u) + +/* Reseed Interval */ +#define CRYPTO_30_LIBCV_RANDOM_RESEED_COUNTER_LEN (CRYPTO_30_LIBCV_SIZEOF_UINT32) /* (sizeof(uint32)) */ + +/* HASHDRBG SHA512 SEED LEN */ +#define CRYPTO_30_LIBCV_RANDOM_HASH_INTERNAL_STATE_BUFFER_LEN (2u * ESL_HASHDRBG_SHA512_SEED_LEN) + +/********************************************************************************************************************** + * LOCAL FUNCTION MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_LIBCV_FIPS186 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomFips186Finish() + *********************************************************************************************************************/ +/*! \brief Dispatches the RandomFips186 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomFips186Finish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed_Fips() + *********************************************************************************************************************/ +/*! \brief Initialize the seed for FIPS 186.2 + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] seedStateElementIndex Holds the identifier of the key element which shall be set + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \param[out] writeBlock Determines if the block need to be written. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as elementIndex must identify a valid key - key element pair + * entropyPtr need to be a valid pointer + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-139102 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed_Fips( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock); +#endif /* CRYPTO_30_LIBCV_FIPS186 == STD_ON */ + +#if (CRYPTO_30_LIBCV_DRBGAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_AesCtrDrbgSeedFirst() + **********************************************************************************************************************/ +/*! \brief Initial Seed for NIST800-90A DRBG AES128 + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[out] wsDRBG Pointer to the DRBG workspace + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \param[in] modeDRBG Contains the DRBG mode. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as elementIndex must identify a valid key - key element pair + * wsDRBG has to be initialized and a valid eslt_WorkSpaceCTRDRBG pointer. + * entropyPtr need to be a valid pointer with at least the length of entropyLength + * modeDRBG has to be a valid + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_AesCtrDrbgSeedFirst( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsDRBG, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + eslt_DRBGMode modeDRBG); + +/********************************************************************************************************************** + * Crypto_30_LibCv_AesCtrDrbgReseed() + **********************************************************************************************************************/ +/*! \brief Reseed for NIST800-90A DRBG AES128 + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[out] wsDRBG Pointer to the DRBG workspace + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \param[in] modeDRBG indication which AES size the DRBG shall be based on and whether the seeding and + * generating functions shall use a derivation function or not + * \return E_OK Request was successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as elementIndex must identify a valid key - key element pair + * wsDRBG has to be initialized and a valid eslt_WorkSpaceCTRDRBG pointer. + * entropyPtr need to be a valid pointer with at least the length of entropyLength + * modeDRBG has to be a valid + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_AesCtrDrbgReseed( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsDRBG, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + eslt_DRBGMode modeDRBG); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomNistDrbgAesGeneratePrepare() + **********************************************************************************************************************/ +/*! \brief Prepare Nist 800-90A DRBG Aes execution for esl_getBytesRng. + * \details Check input parameter and prepare generation. + * \param[out] ws Pointer to the workspace. + * \param[in] cryptoKeyId Identifier of the crypto key. + * \param[out] keyElements Struct to get element informations. + * \param[out] seedStateElementIndexPtr Holds the element index for Seed state. + * \param[out] seedCounterElementIndexPtr Holds the element index for Seed counter. + * \param[out] persistPtr Determines if the block needs to be written. + * \param[in] seedLength Contains the seed length. + * \param[in] modeDRBG Contains the DRBG mode. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy exhausted, random seed need to be called. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre all pointers need to be valid. + * cryptoKeyId has to be a valid key id. + * seedLength has to be a valid length. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomNistDrbgAesGeneratePrepare( + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) ws, + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_KeyElementGetType, AUTOMATIC, AUTOMATIC) keyElements, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) seedStateElementIndexPtr, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) seedCounterElementIndexPtr, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) persistPtr, + uint32 seedLength, + eslt_DRBGMode modeDRBG); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes() + **********************************************************************************************************************/ +/*! \brief Initialize the seed for NIST800-90A DRBG AES128 + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] seedStateElementIndex Holds the identifier of the key element which shall be set + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \param[out] writeBlock Determines if the block need to be written. + * \param[in] modeDRBG Contains the DRBG mode. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as elementIndex must identify a valid key - key element pair + * entropyPtr need to be a valid pointer with at least the length of entropyLength + * seedStateElementIndex need to be a valid index. + * modeDRBG has to be a valid + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-149660 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock, + eslt_DRBGMode modeDRBG); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes_With_Ws() + **********************************************************************************************************************/ +/*! \brief Initialize the seed for NIST800-90A DRBG AES128 + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] seedStateElementIndex Holds the identifier of the key element which shall be set + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \param[out] writeBlock Determines if the block need to be written. + * \param[in] modeDRBG Contains the DRBG mode. + * \param[in,out] wsDRBG Pointer to the DRBG workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as elementIndex must identify a valid key - key element pair + * entropyPtr need to be a valid pointer with at least the length of entropyLength + * seedStateElementIndex need to be a valid index. + * modeDRBG has to be a valid + * wsDRBG has to be initialized and a valid eslt_WorkSpaceCTRDRBG pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes_With_Ws( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock, + eslt_DRBGMode modeDRBG, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG); + +/********************************************************************************************************************** + * Crypto_30_LibCv_AesCtrDrbgSeed_With_Ws() + **********************************************************************************************************************/ +/*! \brief Seed for NIST800-90A DRBG AES128 + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] seedStateElementIndex Holds the index of the seed state + * \param[in] reseedCtElementIndex Holds the index of the reseed counter + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \param[in] modeDRBG Contains the DRBG mode. + * \param[in,out] wsDRBG Pointer to the DRBG workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as elementIndex must identify a valid key - key element pair + * seedStateElementIndex need to be a valid index. + * reseedCtElementIndex need to be a valid index. + * entropyPtr need to be a valid pointer with at least the length of entropyLength + * modeDRBG has to be a valid + * wsDRBG has to be initialized and a valid eslt_WorkSpaceCTRDRBG pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_AesCtrDrbgSeed_With_Ws( + uint32 cryptoKeyId, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType reseedCtElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + eslt_DRBGMode modeDRBG, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG); + +# if (CRYPTO_30_LIBCV_RANDOM_SOURCE_DRBG_AES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_GetRandomNistDrbgAes() + **********************************************************************************************************************/ +/*! \brief Nist 800-90A DRBG Aes execution for esl_getBytesRng. + * \details Generate random number. This includes a retry mechanism for generation collision. + * \param[in] partitionIdx The index of the currently active partition. + * \param[in] cryptoKeyId Identifier of the crypto key. + * \param[out] requestBuffer Buffer to safe the generated data. + * \param[in] requestLength Length of the requested random data. + * \param[out] persistPtr Determines if the block needs to be written. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy exhausted, random seed need to be called. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre All pointers need to be valid. + * cryptoKeyId has to be a valid key id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_GetRandomNistDrbgAes( + uint32 partitionIdx, + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) requestBuffer, + uint32 requestLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) persistPtr); /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +# endif + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomNistDrbgAesFinishGenerate() + **********************************************************************************************************************/ +/*! \brief Generate random number with Nist 800-90A DRBG Aes. + * \details Manage seed state and generate via esl_getBytesCTRDRBG. + * \param[in,out] workspace Pointer to the DRBG workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[out] persistPtr Pointer to a variable to report if the key shall be written. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy exhausted, random seed need to be called. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre workspace pointer has to be a valid. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomNistDrbgAesFinishGenerate( + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2VAR(boolean, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) persistPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomNistDrbgAesFinish() + **********************************************************************************************************************/ +/*! \brief Prepare Nist 800-90A DRBG Aes execution. + * \details Check input parameter and prepare generation. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomNistDrbgAesFinish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Generate_NistDrbgAes() + **********************************************************************************************************************/ +/*! \brief Generate random number. + * \details Check input parameter and prepare generation. + * \param[in] cryptoKeyId Identifier of the crypto key. + * \param[out] requestBuffer Buffer to safe the generated data. + * \param[in] requestLength Length of the requested random data. + * \param[in,out] wsDRBG Pointer to the DRBG workspace. + * \return All return values of esl_getBytesCTRDRBG. + * \pre All pointers need to be valid. + * cryptoKeyId has to be a valid key id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Generate_NistDrbgAes( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) requestBuffer, + uint32 requestLength, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG); /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Get_And_Set_NistDrbgAesState() + **********************************************************************************************************************/ +/*! \brief Get and set NistDrbgAes state. + * \details Get state parameter and set seed status. + * \param[in] cryptoKeyId Holds the identifier of the key containing the key elements. + * \param[in] seedStateElementIndex Holds the identifier of the key element which shall be set + * \param[in] seedCounterElementIndex Holds the identifier of the key element which shall be set + * \param[in,out] wsDRBG Pointer to the DRBG workspace. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Get_And_Set_NistDrbgAesState( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType seedCounterElementIndex, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG); /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RandomNistDrbgAes_Set_Mode_And_SeedLength() + **********************************************************************************************************************/ +/*! \brief Set NistDrbgAes mode and seed length. + * \details Get correct data from the cryptoKeyId and set NistDrbgAes mode and seed length. + * \param[in] cryptoKeyId Identifier of the crypto key. + * \param[in,out] modeDRBG Contains the DRBG mode. + * \param[in,out] seedLength Contains the seed length. + * \return E_OK Request was successful. + * E_NOT_OK Request failed. + * \pre All pointers need to be valid. + * cryptoKeyId has to be a valid key id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RandomNistDrbgAes_Set_Mode_And_SeedLength( + uint32 cryptoKeyId, + P2VAR(eslt_DRBGMode, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) modeDRBG, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) seedLength); /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +#endif /* CRYPTO_30_LIBCV_DRBGAES == STD_ON */ + +#if (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_HashDrbgSeedFirst() + **********************************************************************************************************************/ +/*! \brief Initial Seed for NIST800-90A DRBG HASH SHA2-512 + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[out] wsDRBG Pointer to the DRBG workspace + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as elementIndex must identify a valid key - key element pair + * wsDRBG has to be initialized and a valid eslt_WorkSpaceHASHDRBG pointer. + * entropyPtr need to be a valid pointer with at least the length of entropyLength + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_HashDrbgSeedFirst( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsDRBG, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_HashDrbgReseed() + **********************************************************************************************************************/ +/*! \brief Reseed for NIST800-90A DRBG HASH SHA2-512 + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[out] wsDRBG Pointer to the DRBG workspace + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \return E_OK Request was successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as elementIndex must identify a valid key - key element pair + * wsDRBG has to be initialized and a valid eslt_WorkSpaceHASHDRBG pointer. + * reseedCnt has to be a valid pointer with the length CRYPTO_30_LIBCV_RANDOM_RESEED_COUNTER_LEN. + * entropyPtr need to be a valid pointer with at least the length of entropyLength + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_HashDrbgReseed( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsDRBG, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash() + **********************************************************************************************************************/ +/*! \brief Initialize the seed for NIST800-90A DRBG HASH SHA2-512 + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] seedStateElementIndex Holds the identifier of the key element which shall be set + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \param[out] writeBlock Determines if the block need to be written. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as elementIndex must identify a valid key - key element pair + * entropyPtr need to be a valid pointer with at least the length of entropyLength + * seedStateElementIndex need to be a valid index. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-149660 + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash_With_Ws() + **********************************************************************************************************************/ +/*! \brief Initialize the seed for NIST800-90A DRBG HASH SHA2-512 + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] seedStateElementIndex Holds the identifier of the key element which shall be set + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \param[out] writeBlock Determines if the block need to be written. + * \param[in,out] wsDRBG Pointer to the DRBG workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as elementIndex must identify a valid key - key element pair + * entropyPtr need to be a valid pointer with at least the length of entropyLength + * seedStateElementIndex need to be a valid index. + * wsDRBG has to be initialized and a valid eslt_WorkSpaceHASHDRBG pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash_With_Ws( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG); + +/********************************************************************************************************************** + * Crypto_30_LibCv_HashDrbgSeed_With_Ws() + **********************************************************************************************************************/ +/*! \brief Seed for NIST800-90A DRBG HASH SHA2-512 + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] seedStateElementIndex Holds the index of the seed state + * \param[in] reseedCtElementIndex Holds the index of the reseed counter + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \param[in,out] wsDRBG Pointer to the DRBG workspace. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre cryptoKeyId as well as elementIndex must identify a valid key - key element pair + * entropyPtr need to be a valid pointer with at least the length of entropyLength + * seedStateElementIndex need to be a valid index. + * reseedCtElementIndex need to be a valid index. + * wsDRBG has to be initialized and a valid eslt_WorkSpaceHASHDRBG pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_HashDrbgSeed_With_Ws( + uint32 cryptoKeyId, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType reseedCtElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Get_And_Set_NistDrbgHashState() + **********************************************************************************************************************/ +/*! \brief Get and set NistDrbgHash state. + * \details Get state parameter and set seed status. + * \param[in] cryptoKeyId Holds the identifier of the key containing the key elements. + * \param[in] seedStateElementIndex Holds the identifier of the key element which shall be set + * \param[in] seedCounterElementIndex Holds the identifier of the key element which shall be set + * \param[in,out] wsDRBG Pointer to the DRBG workspace. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre All pointers need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Get_And_Set_NistDrbgHashState( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType seedCounterElementIndex, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG); /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomNistDrbgHashFinish() + **********************************************************************************************************************/ +/*! \brief Prepare Nist 800-90A DRBG Hash execution. + * \details Check input parameter and prepare generation. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomNistDrbgHashFinish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomNistDrbgHashGeneratePrepare() + **********************************************************************************************************************/ +/*! \brief Prepare Nist 800-90A DRBG Hash execution for esl_getBytesHASHDRBG. + * \details Check input parameter and prepare generation. + * \param[out] ws Pointer to the workspace. + * \param[in] cryptoKeyId Identifier of the crypto key. + * \param[out] keyElements Struct to get element informations. + * \param[out] seedStateElementIndexPtr Holds the element index for Seed state. + * \param[out] seedCounterElementIndexPtr Holds the element index for Seed counter. + * \param[out] persistPtr Determines if the block needs to be written. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy exhausted, random seed need to be called. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre all pointers need to be valid. + * cryptoKeyId has to be a valid key id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomNistDrbgHashGeneratePrepare( + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) ws, + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_KeyElementGetType, AUTOMATIC, AUTOMATIC) keyElements, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) seedStateElementIndexPtr, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) seedCounterElementIndexPtr, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) persistPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Generate_NistDrbgHash() + **********************************************************************************************************************/ +/*! \brief Generate random number. + * \details Check input parameter and prepare generation. + * \param[in] cryptoKeyId Identifier of the crypto key. + * \param[out] requestBuffer Buffer to safe the generated data. + * \param[in] requestLength Length of the requested random data. + * \param[in,out] wsDRBG Pointer to the DRBG workspace. + * \return All return values of esl_getBytesHASHDRBG. + * \pre All pointers need to be valid. + * cryptoKeyId has to be a valid key id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Generate_NistDrbgHash( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) requestBuffer, + uint32 requestLength, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG); /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + +# if (CRYPTO_30_LIBCV_RANDOM_SOURCE_DRBG_HASH == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_GetRandomNistDrbgHash() + **********************************************************************************************************************/ +/*! \brief Nist 800-90A DRBG Hash execution for esl_getBytesRng. + * \details Generate random number. This includes a retry mechanism for generation collision. + * \param[in] partitionIdx The index of the currently active partition. + * \param[in] cryptoKeyId Identifier of the crypto key. + * \param[out] requestBuffer Buffer to safe the generated data. + * \param[in] requestLength Length of the requested random data. + * \param[out] persistPtr Determines if the block needs to be written. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy exhausted, random seed need to be called. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre All pointers need to be valid. + * cryptoKeyId has to be a valid key id. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_GetRandomNistDrbgHash( + uint32 partitionIdx, + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) requestBuffer, + uint32 requestLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) persistPtr); /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +# endif +#endif /* CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON */ + +#if ((CRYPTO_30_LIBCV_DRBGAES == STD_ON) || (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Random_Check_For_Write_Once() + *********************************************************************************************************************/ +/*! \brief Check the key element for write once + * \details This function checks the key element for write once + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] seedStateElementIndex Holds the identifier of the key element which shall be set + * \param[in,out] reseedCtElementIndex Holds the identifier of the key element which shall be set + * \return TRUE Write once inactive. + * FALSE Write once active. + * \pre cryptoKeyId must identify a valid key + * seedStateElementIndex need to be a valid index. + * reseedCtElementIndex need to be a valid pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Random_Check_For_Write_Once( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) reseedCtElementIndex); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Set_NistDrbgState() + *********************************************************************************************************************/ +/*! \brief Set the key element state and the reseed counter + * \details This function sets the key element state and the reseed counter + * \param[in] cryptoKeyId Holds the identifier of the key containing the key elements. + * \param[in] seedStateElementIndex Holds the identifier of the key element which shall be set + * \param[in] seedCounterElementIndex Holds the identifier of the key element which shall be set + * \param[in] retValCv Holds the return value + * \param[in] seedLength Holds the seed length + * \param[in] expectedSeedLength Holds the expected seed length + * \param[in] reseedCntBuf Holds the reseed counter + * \param[in] seedStatus Holds the current seed status + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre seedStateElementIndex need to be a valid index. + * reseedCtElementIndex need to be a valid index. + * retValCv need to be a valid value. + * seedLength need to be a valid length. + * expectedSeedLength need to be a valid length. + * reseedCntBuf need to be a valid buffer. + * seedStatus need to be a valid status. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Set_NistDrbgState( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType seedCounterElementIndex, + eslt_ErrorCode retValCv, + eslt_Length seedLength, + eslt_Length expectedSeedLength, + uint32 reseedCntBuf, + eslt_DRBGSeedStatusType seedStatus); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Check_Random_KeyElement_Persist() + *********************************************************************************************************************/ +/*! \brief Check the key element for persist + * \details This function checks the key element for persist + * \param[in] seedStateElementIndex Holds the identifier of the key element which shall be set + * \param[in] seedCounterElementIndex Holds the identifier of the key element which shall be set + * \param[out] persistPtr Holds the return value + * \pre seedStateElementIndex need to be a valid index. + * reseedCtElementIndex need to be a valid index. + * persist need to be a valid pointer. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Check_Random_KeyElement_Persist( + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType seedCounterElementIndex, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) persistPtr); +#endif /* ((CRYPTO_30_LIBCV_DRBGAES == STD_ON) || (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_IsRngCalculationValid() + **********************************************************************************************************************/ +/*! \brief Check if the Rng Calculation is valid. + * \details Check if the Rng counter has the expected value. + * \param[in] localCount holds the start counter. + * \param[in] currentPartitionIdx The partition Idx of the currently running partition. + * \return TRUE Same counter value. + * FALSE Different counter value. + * \pre This function need to be protected by an exclusive area + * (Crypto_30_LibCv_RandomSourceGenerateCount is accessed). + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_IsRngCalculationValid(uint16 localCount, uint32 currentPartitionIdx); +#endif /* CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON */ + +#if (CRYPTO_30_LIBCV_KEYVALUECHANGEDCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyValueChangedCallout() + **********************************************************************************************************************/ +/*! \brief Call key value changed callout. + * \details - + * \param[in] cryptoKeyId Holds the identifier of the key. + * \pre cryptoKeyId must identify a valid key. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyValueChangedCallout(uint32 cryptoKeyId); +#endif /* CRYPTO_30_LIBCV_KEYVALUECHANGEDCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ +#if (CRYPTO_30_LIBCV_FIPS186 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomFips186Finish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6030, 6050, 6080 3 */ /* MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomFips186Finish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + P2VAR(eslt_WorkSpaceFIPS186, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfFips186(Crypto_30_LibCv_GetFips186IdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SizeOfKeyStorageType fips186KeyIndex; + uint32 fips186KeyLength; + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) randomSeedBuffer = &Crypto_30_LibCv_GetRandomSeedBuffer(Crypto_30_LibCv_GetRandomSeedBufferStartIdxOfObjectInfo(objectId)); + + /* ----- Implementation ------------------------------------------------- */ + /* #50 Initialize workspace header. */ + retValCv = esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_FIPS186, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex; + + /* Get index of keyElement SEED_STATE */ + if (Crypto_30_LibCv_Local_KeyElementSearch(job->cryptoKeyId, CRYPTO_KE_RANDOM_SEED_STATE, &elementIndex) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* #60 Distinguish the different modes for seeding and restoring seed state. */ + /* Check if randomSeed was called on the given key element */ + if (!Crypto_30_LibCv_IsKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALUE_USED_MASK)) + { + /* Get new seed value */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(job->cryptoKeyId, CRYPTO_KE_RANDOM_SEED_STATE, &fips186KeyIndex, &fips186KeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + if (retVal == E_OK) + { + retVal = E_NOT_OK; + /* check if initial seed is required */ + /* #70 Seed if RandomSeed was called on the given key. (first time) */ + if (!Crypto_30_LibCv_Uint8CheckMask(randomSeedBuffer[0], CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_MASK)) + { + retValCv = esl_initFIPS186(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)fips186KeyLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(fips186KeyIndex), + NULL_PTR); + /* mark new seed as initiated */ + Crypto_30_LibCv_Uint8SetMask(randomSeedBuffer[0], CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ + } + else + { + /* #80 Reseed if RandomSeed was called on the given key and restore the old seed state. */ + /* Restore workspace - This is done manually since workspace is not kept forever due to shared memory (union) */ + retValCv = esl_initFIPS186(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)fips186KeyLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(fips186KeyIndex), + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&randomSeedBuffer[1]); + } + /* mark new seed as used */ + Crypto_30_LibCv_SetKeyElementStateByMask(elementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALUE_USED_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL01 */ +# if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + /* Call KeyNvStatus KeyChanged transition since the key element is changed inside esl_initFIPS186 */ + Crypto_30_LibCv_KeyNvStatus_KeyChanged(job->cryptoKeyId, elementIndex); + + if (Crypto_30_LibCv_IsKeyElementPersist(elementIndex) == TRUE) + { + Crypto_30_LibCv_SetProcessJob_Trigger_Write(objectId, TRUE); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } +# endif + } + else + { + retValCv = ESL_ERC_ERROR; + /* keep retVal */ + } + } + else + { + if (Crypto_30_LibCv_Uint8CheckMask(randomSeedBuffer[0], CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_MASK)) + { + /* #85 If the rng is not seeded only restore old seed state. */ + /* Restore workspace - This is done manually since workspace is not kept forever due to shared memory (union) */ + retValCv = esl_initFIPS186(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + (eslt_Length)CRYPTO_30_LIBCV_FIPS_SEED_LENGTH, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&randomSeedBuffer[1], + NULL_PTR); + } + else + { + retValCv = ESL_ERC_ERROR; + retVal = CRYPTO_E_ENTROPY_EXHAUSTION; + } + } + } + else + { + retValCv = ESL_ERC_ERROR; + } + + /* #90 Generate Random Numbers. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + retValCv = esl_getBytesFIPS186(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + + /* #95 Save workspace. */ + /* Save internal state of key random method to continue with the next good value. */ + Crypto_30_LibCv_CopyData(&randomSeedBuffer[1], ((P2VAR(actFIPS186STRUCT, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))workspace->wsFIPS186)->X_KEY, CRYPTO_30_LIBCV_FIPS_SEED_LENGTH); /* PRQA S 3305, 0310, 0315 */ /* MD_CRYPTO_30_LIBCV_3305_CRYPTOLIBRARY_CAST, MD_CRYPTO_30_LIBCV_0310_CRYPTOLIBRARY_CAST, MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_ACT_RANDOM_WORKSPACE_ARRAY_ACCESS */ + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + else if (retVal == CRYPTO_E_KEY_NOT_VALID) + { + retVal = CRYPTO_E_ENTROPY_EXHAUSTION; + } + else + { + /* keep retVal */ + } + + return retVal; +} /* Crypto_30_LibCv_DispatchRandomFips186Finish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed_Fips() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed_Fips( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + /* #5 Deny service for write once keys. */ + if (Crypto_30_LibCv_IsKeyElementWriteOnce(seedStateElementIndex)) + { + retVal = E_NOT_OK; + } + /* #10 Seed key element and update seed state */ + else if (Crypto_30_LibCv_Local_KeyElementSetInternal(cryptoKeyId, seedStateElementIndex, entropyPtr, entropyLength, CRYPTO_30_LIBCV_WA_ALLOWED) == E_OK) /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + { + /* The elementIndex do not need to be checked. The Code is only reachable if the key element is available. (Crypto_30_LibCv_Local_KeyElementSearch) */ + Crypto_30_LibCv_ClearKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_CLEAR_NORMAL_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + *writeBlock = Crypto_30_LibCv_Internal_KeySetValid(cryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + retVal = E_OK; + } + else + { + *writeBlock = FALSE; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_RandomSeed_Fips() */ +#endif /* (CRYPTO_30_LIBCV_FIPS186 == STD_ON) */ + +#if (CRYPTO_30_LIBCV_DRBGAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_AesCtrDrbgReseed() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_AesCtrDrbgReseed( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsDRBG, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + eslt_DRBGMode modeDRBG) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, localRetVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_SizeOfKeyStorageType additionalInputIndex = 0u, seedIndex, reseedCounter; + uint32 reseedCnt, additionalInputLength = 0u; + uint32 seedLength = ESL_CTRDRBG_AES128_SEEDLEN; + uint32 reseedCntLength = CRYPTO_30_LIBCV_RANDOM_RESEED_COUNTER_LEN; + + /* ----- Implementation ------------------------------------------------- */ + + if ((modeDRBG == ESL_DRBGMODE_CTRDRBG_AES256_NODF) || (modeDRBG == ESL_DRBGMODE_CTRDRBG_AES256_DF)) + { + seedLength = ESL_CTRDRBG_AES256_SEEDLEN; + } + + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_RANDOM_SEED_STATE, &seedIndex, &seedLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + { + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER, &reseedCounter, &reseedCntLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + { + /* #1 Reseed: restore seed state */ + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&reseedCnt, Crypto_30_LibCv_GetAddrKeyStorage(reseedCounter)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + retValCv = esl_restoreStateCTRDRBG(wsDRBG, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(seedIndex), + (eslt_Length) seedLength, + (eslt_DRBGReseedCounterType) reseedCnt, + (eslt_Byte) ESL_DRBG_SEED_STATUS_SEEDED, + modeDRBG); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + if (retValCv == ESL_ERC_NO_ERROR) + { + /* #5 check if additional input is available. (optional feature) */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_ADDITIONAL_INPUT, &additionalInputIndex, &additionalInputLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + } + } + + if ((localRetVal == E_OK) && (additionalInputLength > 0u)) + { + /* #10 reseed via esl_seedCTRDRBG */ + retValCv = esl_seedCTRDRBG(wsDRBG, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) entropyPtr, + (eslt_Length) entropyLength, + NULL_PTR, + 0u, + NULL_PTR, + 0u, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(additionalInputIndex), + (eslt_Length) additionalInputLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else if ((localRetVal == CRYPTO_E_KEY_NOT_AVAILABLE) || (localRetVal == E_OK)) + { + retValCv = esl_seedCTRDRBG(wsDRBG, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) entropyPtr, + (eslt_Length) entropyLength, + NULL_PTR, + 0u, + NULL_PTR, + 0u, + NULL_PTR, + 0u); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else + { + /* request failed */ + retValCv = ESL_ERC_ERROR; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_AesCtrDrbgReseed() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_AesCtrDrbgSeedFirst() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_AesCtrDrbgSeedFirst( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsDRBG, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + eslt_DRBGMode modeDRBG) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, localRetVal = E_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_SizeOfKeyStorageType personalizationStrIndex, nonceIndex = 0u; + uint32 personalizationStrLength, nonceLength = 0u; + + /* ----- Implementation ------------------------------------------------- */ + + if ((modeDRBG == ESL_DRBGMODE_CTRDRBG_AES128_DF) || (modeDRBG == ESL_DRBGMODE_CTRDRBG_AES256_DF)) + { + /* #10 Get Nonce */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_NONCE, &nonceIndex, &nonceLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + } + + if (localRetVal == E_OK) + { + /* #15 Get Private String (recommended feature) */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_PERSONALIZATION_STRING, &personalizationStrIndex, &personalizationStrLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if ((localRetVal == E_OK) && (personalizationStrLength > 0u)) + { + /* #20 seed with personal string via esl_seedCTRDRBG */ + retValCv = esl_seedCTRDRBG(wsDRBG, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) entropyPtr, + (eslt_Length)entropyLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(nonceIndex), + (eslt_Length)nonceLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(personalizationStrIndex), + (eslt_Length)personalizationStrLength, + NULL_PTR, + 0u); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else if ((localRetVal == CRYPTO_E_KEY_NOT_AVAILABLE) || (localRetVal == E_OK)) + { + /* #25 Personal string in not available in the key so seed without personal string. */ + retValCv = esl_seedCTRDRBG(wsDRBG, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) entropyPtr, + (eslt_Length) entropyLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(nonceIndex), + (eslt_Length) nonceLength, + NULL_PTR, + 0u, + NULL_PTR, + 0u); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else + { + /* request failed */ + } + + /* #30 set algorithm initiated */ + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_AesCtrDrbgSeedFirst() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_AesCtrDrbgSeed_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_AesCtrDrbgSeed_With_Ws( + uint32 cryptoKeyId, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType reseedCtElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + eslt_DRBGMode modeDRBG, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + eslt_ErrorCode retValCv; + + /* ----- Implementation ------------------------------------------------- */ + /* #1 Initialize workspace header. */ + retValCv = esl_initWorkSpaceHeader(&(wsDRBG->header), ESL_MAXSIZEOF_WS_CTRDRBG, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + retValCv |= esl_initCTRDRBG(wsDRBG, modeDRBG); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* #5 already initiated / Reseeding */ + if (Crypto_30_LibCv_IsKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_MASK)) + { + retVal = Crypto_30_LibCv_AesCtrDrbgReseed(cryptoKeyId, wsDRBG, entropyPtr, entropyLength, modeDRBG); /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS_AND_PTR_AS_PARAMETER */ + } + /* #10 need to be initiated */ + else + { + retVal = Crypto_30_LibCv_AesCtrDrbgSeedFirst(cryptoKeyId, wsDRBG, entropyPtr, entropyLength, modeDRBG); /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS_AND_PTR_AS_PARAMETER */ + } + + if (retVal == E_OK) + { + /* #20 Get current DRBG state and save the seed status */ + retVal = Crypto_30_LibCv_Local_Get_And_Set_NistDrbgAesState( + cryptoKeyId, + seedStateElementIndex, + reseedCtElementIndex, + wsDRBG); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + } + + if ((retValCv != E_OK) || (retVal != E_OK)) + { + retVal = E_NOT_OK; + } + else + { + Crypto_30_LibCv_ClearKeyElementStateByMask(reseedCtElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_INV_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + /* #30 Call the callout if the functionality is enabled and trigger that the key value is changed */ + /* Key validity changed callout is called in Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes_With_Ws */ +# if(CRYPTO_30_LIBCV_KEYVALUECHANGEDCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + Crypto_30_LibCv_KeyValueChangedCallout(cryptoKeyId); +# endif + } + + return retVal; +} /* Crypto_30_LibCv_AesCtrDrbgSeed_With_Ws() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomNistDrbgAesGeneratePrepare() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 9 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomNistDrbgAesGeneratePrepare( + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) ws, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_KeyElementGetType, AUTOMATIC, AUTOMATIC) keyElements, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) seedStateElementIndexPtr, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) seedCounterElementIndexPtr, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) persistPtr, + uint32 seedLength, + eslt_DRBGMode modeDRBG) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + + /* ----- Implementation ------------------------------------------------- */ + + /* # load seed state and reseed counter */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_RANDOM_SEED_STATE, seedLength); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 1u, CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER, CRYPTO_30_LIBCV_RANDOM_RESEED_COUNTER_LEN); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* Get index of keyElement SEED_STATE and CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER */ + (void)Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, CRYPTO_KE_RANDOM_SEED_STATE, seedStateElementIndexPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + (void)Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER, seedCounterElementIndexPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(ws->header), ESL_MAXSIZEOF_WS_CTRDRBG, CRYPTO_30_LIBCV_WATCHDOG_PTR) != ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + retVal = E_NOT_OK; + } + else + { + /* # Initialize CTR DRBG workspace. */ + if (esl_initCTRDRBG(ws, modeDRBG) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + Crypto_30_LibCv_Local_Check_Random_KeyElement_Persist(*seedStateElementIndexPtr, *seedCounterElementIndexPtr, persistPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + } + else + { + retVal = E_NOT_OK; + } + } + } + else if (retVal == CRYPTO_E_KEY_NOT_VALID) + { + retVal = CRYPTO_E_ENTROPY_EXHAUSTION; + } + else + { + /* keep retVal */ + } + + return retVal; +} /* Crypto_30_LibCv_DispatchRandomNistDrbgAesGeneratePrepare() */ + +# if (CRYPTO_30_LIBCV_RANDOM_SOURCE_DRBG_AES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_GetRandomNistDrbgAes() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6010, 6050 5 */ /* MD_MSR_STPTH, MD_MSR_STCAL */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_GetRandomNistDrbgAes( + uint32 partitionIdx, + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) requestBuffer, + uint32 requestLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) persistPtr) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_WorkSpaceCTRDRBG ws; + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex = 0u, seedCounterElementIndex = 0u; + uint32 retry; + uint16 localCount; + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + uint32 reseedCntBuf; + eslt_Byte seedStatus; + eslt_DRBGMode modeDRBG = 0u; + eslt_Length seedLength = 0u; + + /* ----- Implementation ------------------------------------------------- */ + /* # Get Algorithm from the algorithm key element to set the correct DRBG mode */ + if (Crypto_30_LibCv_RandomNistDrbgAes_Set_Mode_And_SeedLength(cryptoKeyId, &modeDRBG, &seedLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* # Prepare DRBG and check key data. */ + retVal = Crypto_30_LibCv_DispatchRandomNistDrbgAesGeneratePrepare(&ws, cryptoKeyId, keyElements, &seedStateElementIndex, &seedCounterElementIndex, persistPtr, (uint32)seedLength, modeDRBG); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + } + + if (retVal == E_OK) + { + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + /* # Calculate random number until calculation is valid or max reties exhausted. */ + for (retry = 0u; retry < CRYPTO_30_LIBCV_DEFAULT_RANDOM_MAX_RETRIES; retry++) + { + /* # Copy counter and RNG paramater to local buffers. */ + localCount = Crypto_30_LibCv_GetRandomSourceGenerateCount(partitionIdx); + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&reseedCntBuf, Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(seedCounterElementIndex)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (Crypto_30_LibCv_IsKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_MASK)) + { + seedStatus = ESL_DRBG_SEED_STATUS_SEEDED; + } + else + { + seedStatus = ESL_DRBG_SEED_STATUS_UNSEEDED; + } + + retValCv = esl_restoreStateCTRDRBG( + (P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) &ws, /* PRQA S 2982 */ /* MD_MSR_RetVal */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(seedStateElementIndex), + seedLength, + reseedCntBuf, + seedStatus, + modeDRBG); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Generate random number DRBG. */ + retValCv = Crypto_30_LibCv_Local_Generate_NistDrbgAes( + cryptoKeyId, + requestBuffer, + requestLength, + &ws); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* # Check if rng counter has changed. */ + if ((Crypto_30_LibCv_IsRngCalculationValid(localCount, partitionIdx)) && (retValCv == ESL_ERC_NO_ERROR)) + { + retVal = Crypto_30_LibCv_Local_Get_And_Set_NistDrbgAesState( + cryptoKeyId, + seedStateElementIndex, + seedCounterElementIndex, + &ws); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + /* break loop */ + break; + } + else + { + retVal = E_NOT_OK; + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + if (retVal != E_OK) + { + /* # clear output buffer if request failed. */ + Crypto_30_LibCv_ClearData(requestBuffer, requestLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + *persistPtr = FALSE; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } + } + + if ((retValCv != ESL_ERC_NO_ERROR) || (retVal != E_OK)) + { + if (retValCv == ESL_ERC_ENTROPY_EXHAUSTION) + { + retVal = CRYPTO_E_ENTROPY_EXHAUSTION; + } + else + { + retVal = E_NOT_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_GetRandomNistDrbgAes() */ +# endif /* (CRYPTO_30_LIBCV_RANDOM_SOURCE_DRBG_AES == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomNistDrbgAesFinishGenerate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ + /* PRQA S 6050 4 */ /* MD_MSR_STCAL */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomNistDrbgAesFinishGenerate( + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2VAR(boolean, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) persistPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex = 0u, seedCounterElementIndex = 0u; + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + eslt_DRBGReseedCounterType reseedCntBuf; + eslt_DRBGMode modeDRBG = 0u; + eslt_Byte seedStatus; + eslt_Length seedLength = 0u; + + if (Crypto_30_LibCv_RandomNistDrbgAes_Set_Mode_And_SeedLength(job->cryptoKeyId, &modeDRBG, &seedLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* #20 Load seed state, seed counter and check key data. */ + retVal = Crypto_30_LibCv_DispatchRandomNistDrbgAesGeneratePrepare(workspace, job->cryptoKeyId, keyElements, &seedStateElementIndex, &seedCounterElementIndex, persistPtr, (uint32)seedLength, modeDRBG); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + } + + if (retVal == E_OK) + { + retVal = E_NOT_OK; + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&reseedCntBuf, Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(seedCounterElementIndex)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (Crypto_30_LibCv_IsKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_MASK)) + { + seedStatus = ESL_DRBG_SEED_STATUS_SEEDED; + } + else + { + seedStatus = ESL_DRBG_SEED_STATUS_UNSEEDED; + } + + /* #30 Set state to current seed state. */ + retValCv = esl_restoreStateCTRDRBG( + workspace, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(seedStateElementIndex), + seedLength, + reseedCntBuf, + seedStatus, + modeDRBG); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* #31 generate random number via esl_getBytesCTRDRBG. */ + retValCv = Crypto_30_LibCv_Local_Generate_NistDrbgAes( + job->cryptoKeyId, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* #32 Set current state. */ + retVal = Crypto_30_LibCv_Local_Get_And_Set_NistDrbgAesState( + job->cryptoKeyId, + seedStateElementIndex, + seedCounterElementIndex, + workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + } + } + + if (retValCv == ESL_ERC_ENTROPY_EXHAUSTION) + { + retVal = CRYPTO_E_ENTROPY_EXHAUSTION; + } + + return retVal; +} /* Crypto_30_LibCv_DispatchRandomNistDrbgAesFinishGenerate() */ +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomNistDrbgAesFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6050 3 */ /* MD_MSR_STCAL */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomNistDrbgAesFinish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + boolean persist = FALSE; + + /* ----- Implementation ------------------------------------------------- */ + /* #10 load workspace */ + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfDRBGAES(Crypto_30_LibCv_GetDRBGAESIdxOfObjectInfo(objectId)); + + retVal = Crypto_30_LibCv_DispatchRandomNistDrbgAesFinishGenerate(workspace, job, &persist); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (retVal != E_OK) + { + /* # clear output buffer if request failed */ + Crypto_30_LibCv_ClearData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + else + { + Crypto_30_LibCv_SetProcessJob_Trigger_Write(objectId, persist); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ +# if(CRYPTO_30_LIBCV_KEYVALUECHANGEDCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + /* Call the callout if the functionality is enabled and trigger that the key value is changed */ + Crypto_30_LibCv_KeyValueChangedCallout(job->cryptoKeyId); +# endif + /* Call the callout if the functionality is enabled and trigger that the key is set to valid */ +# if(CRYPTO_30_LIBCV_KEYVALIDITYSETCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + Crypto_30_LibCv_GetKeyValiditySetCalloutFctNameOfConfigurableCallouts()(job->cryptoKeyId, TRUE); +# endif + } + + return retVal; +} /* Crypto_30_LibCv_DispatchRandomNistDrbgAesFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Generate_NistDrbgAes() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Generate_NistDrbgAes( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) requestBuffer, + uint32 requestLength, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + Std_ReturnType localRetVal; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_LibCv_SizeOfKeyStorageType additionalInputIndex; + uint32 additionalInputLength = 0u; + + /* #10 Load additional input. */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_ADDITIONAL_INPUT, &additionalInputIndex, &additionalInputLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + + /* #20 Generate random number DRBG. */ + if ((localRetVal == E_OK) && (additionalInputLength > 0u)) + { + retValCv = esl_getBytesCTRDRBG( + wsDRBG, + (eslt_Length) requestLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) requestBuffer, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(additionalInputIndex), + (eslt_Length) additionalInputLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else if ((localRetVal == E_OK) || (localRetVal == CRYPTO_E_KEY_NOT_AVAILABLE)) + { + retValCv = esl_getBytesCTRDRBG( + wsDRBG, + (eslt_Length) requestLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) requestBuffer, + NULL_PTR, + 0u); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else + { + retValCv = ESL_ERC_ERROR; + } + + return retValCv; +} /* Crypto_30_LibCv_Local_Generate_NistDrbgAes() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Get_And_Set_NistDrbgAesState() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Get_And_Set_NistDrbgAesState( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType seedCounterElementIndex, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + eslt_ErrorCode retValCv; + eslt_DRBGReseedCounterType reseedCntBuf; + eslt_DRBGSeedStatusType seedStatus; + eslt_DRBGMode modeDRBG; + eslt_Length seedLength = Crypto_30_LibCv_GetKeyElementLength(seedStateElementIndex); + eslt_Length expectedSeedLength = ESL_CTRDRBG_AES128_SEEDLEN; + + if ((wsDRBG->wsDRBG.mode == ESL_DRBGMODE_CTRDRBG_AES256_NODF) || (wsDRBG->wsDRBG.mode == ESL_DRBGMODE_CTRDRBG_AES256_DF)) + { + expectedSeedLength = ESL_CTRDRBG_AES256_SEEDLEN; + } + + /* #10 Get current DRBG state and save the seed state. */ + retValCv = esl_getStateCTRDRBG( + wsDRBG, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(seedStateElementIndex), + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) &seedLength, + (P2VAR(eslt_DRBGReseedCounterType, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) &reseedCntBuf, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) &seedStatus, + (P2VAR(eslt_DRBGMode, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) &modeDRBG); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + retVal = Crypto_30_LibCv_Local_Set_NistDrbgState( + cryptoKeyId, + seedStateElementIndex, + seedCounterElementIndex, + retValCv, + seedLength, + expectedSeedLength, + reseedCntBuf, + seedStatus); + + return retVal; +} /* Crypto_30_LibCv_Local_Get_And_Set_NistDrbgAesState() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock, + eslt_DRBGMode modeDRBG) +{ + /* #10 Initialize workspace */ + eslt_WorkSpaceCTRDRBG wsDRBG; + + /* Call Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes_With_Ws */ + return Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes_With_Ws( /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + cryptoKeyId, + seedStateElementIndex, + entropyPtr, + entropyLength, + writeBlock, + modeDRBG, + &wsDRBG); +} /* Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes_With_Ws( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock, + eslt_DRBGMode modeDRBG, + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyElementsType reseedCtElementIndex; + + /* ----- Implementation ------------------------------------------------- */ + /* #5 Deny service for write once keys. */ + if (Crypto_30_LibCv_Local_Random_Check_For_Write_Once(cryptoKeyId, seedStateElementIndex, &reseedCtElementIndex) != TRUE) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* retVal is already set */ + } + /* #10 seed with new seed value */ + else if (Crypto_30_LibCv_AesCtrDrbgSeed_With_Ws(cryptoKeyId, seedStateElementIndex, reseedCtElementIndex, entropyPtr, entropyLength, modeDRBG, wsDRBG) == E_OK) /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + { + /* The elementIndex do not need to be checked. The Code is only reachable if the key element is available. (Crypto_30_LibCv_Local_KeyElementSearch) */ + Crypto_30_LibCv_ClearKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALUE_USED_INV_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + Crypto_30_LibCv_ClearKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_INV_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + *writeBlock = Crypto_30_LibCv_Internal_KeySetValid(cryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + retVal = E_OK; + } + else + { + *writeBlock = FALSE; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes_With_Ws() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RandomNistDrbgAes_Set_Mode_And_SeedLength() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6080 4 */ /* MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RandomNistDrbgAes_Set_Mode_And_SeedLength( + uint32 cryptoKeyId, + P2VAR(eslt_DRBGMode, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) modeDRBG, + P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) seedLength) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_LibCv_SizeOfKeyElementsType algorithmElementIndex = 0u; + + /* ----- Implementation ------------------------------------------------- */ + + /* #10 Search algorithm index */ + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, CRYPTO_KE_RANDOM_ALGORITHM, &algorithmElementIndex) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* #20 Set correct mode and seed length */ + if (Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(algorithmElementIndex)) == CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES128) + { + *modeDRBG = ESL_DRBGMODE_CTRDRBG_AES128_NODF; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + *seedLength = ESL_CTRDRBG_AES128_SEEDLEN; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + } + else if (Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(algorithmElementIndex)) == CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES128_DF) + { + *modeDRBG = ESL_DRBGMODE_CTRDRBG_AES128_DF; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + *seedLength = ESL_CTRDRBG_AES128_SEEDLEN; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + } + else if (Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(algorithmElementIndex)) == CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES256) + { + *modeDRBG = ESL_DRBGMODE_CTRDRBG_AES256_NODF; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + *seedLength = ESL_CTRDRBG_AES256_SEEDLEN; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + } + else if (Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(algorithmElementIndex)) == CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES256_DF) + { + *modeDRBG = ESL_DRBGMODE_CTRDRBG_AES256_DF; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + *seedLength = ESL_CTRDRBG_AES256_SEEDLEN; /* SBSW_CRYPTO_30_LIBCV_PTR_ACCESS */ + retVal = E_OK; + } + else + { + /* Return value already set */ + } + } + + return retVal; +} /* Crypto_30_LibCv_RandomNistDrbgAes_Set_Mode_And_SeedLength() */ +#endif /* (CRYPTO_30_LIBCV_DRBGAES == STD_ON) */ + +#if (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock) +{ + /* #10 Initialize workspace */ + eslt_WorkSpaceHASHDRBG wsDRBG; + + /* #20 Call Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash_With_Ws */ + return Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash_With_Ws( /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + cryptoKeyId, + seedStateElementIndex, + entropyPtr, + entropyLength, + writeBlock, + &wsDRBG); +} /* Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash_With_Ws( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) writeBlock, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyElementsType reseedCtElementIndex; + + /* ----- Implementation ------------------------------------------------- */ + /* #10 Deny service for write once keys. */ + if (Crypto_30_LibCv_Local_Random_Check_For_Write_Once(cryptoKeyId, seedStateElementIndex, &reseedCtElementIndex) != TRUE) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* retVal is already set */ + } + /* #20 seed with new seed value. */ + else if (Crypto_30_LibCv_HashDrbgSeed_With_Ws(cryptoKeyId, seedStateElementIndex, reseedCtElementIndex, entropyPtr, entropyLength, wsDRBG) == E_OK) /* SBSW_CRYPTO_30_LIBCV_PTR_FORWARDING_WITH_DET_CHECK */ + { + /* The elementIndex do not need to be checked. The Code is only reachable if the key element is available. (Crypto_30_LibCv_Local_KeyElementSearch) */ + Crypto_30_LibCv_ClearKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALUE_USED_INV_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + Crypto_30_LibCv_ClearKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_INV_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ + *writeBlock = Crypto_30_LibCv_Internal_KeySetValid(cryptoKeyId); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + + retVal = E_OK; + } + else + { + *writeBlock = FALSE; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } + + return retVal; +} /* Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash_With_Ws() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_HashDrbgSeed_With_Ws() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_HashDrbgSeed_With_Ws( + uint32 cryptoKeyId, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType reseedCtElementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + eslt_ErrorCode retValCv; + + /* ----- Implementation ------------------------------------------------- */ + /* #1 Initialize workspace header. */ + retValCv = esl_initWorkSpaceHeader(&(wsDRBG->header), ESL_MAXSIZEOF_WS_HASHDRBG, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + retValCv |= esl_initHASHDRBG(wsDRBG, ESL_DRBGMODE_HASHDRBG_SHA512); /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* #5 already initiated / Reseeding */ + if (Crypto_30_LibCv_IsKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_MASK)) + { + retVal = Crypto_30_LibCv_HashDrbgReseed(cryptoKeyId, wsDRBG, entropyPtr, entropyLength); /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS_AND_PTR_AS_PARAMETER */ + } + /* #10 need to be initiated */ + else + { + retVal = Crypto_30_LibCv_HashDrbgSeedFirst(cryptoKeyId, wsDRBG, entropyPtr, entropyLength); /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_STACK_WITH_STACK_BUFFERS_AND_PTR_AS_PARAMETER */ + } + + if (retVal == E_OK) + { + /* #20 Get current DRBG state and save the seed status */ + retVal = Crypto_30_LibCv_Local_Get_And_Set_NistDrbgHashState( + cryptoKeyId, + seedStateElementIndex, + reseedCtElementIndex, + wsDRBG); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + } + + if ((retValCv != E_OK) || (retVal != E_OK)) + { + retVal = E_NOT_OK; + } + else + { + Crypto_30_LibCv_ClearKeyElementStateByMask(reseedCtElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_INV_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_ELEMENT_VIA_KEY */ +# if(CRYPTO_30_LIBCV_KEYVALUECHANGEDCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + /* Call the callout if the functionality is enabled and trigger that the key value is changed */ + /* Key validity changed callout is called in Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash_With_Ws */ + Crypto_30_LibCv_KeyValueChangedCallout(cryptoKeyId); +# endif + } + + return retVal; +} /* Crypto_30_LibCv_HashDrbgSeed_With_Ws() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_HashDrbgSeedFirst() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_HashDrbgSeedFirst( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsDRBG, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, localRetVal; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_SizeOfKeyStorageType personalizationStrIndex, nonceIndex = 0u; + uint32 personalizationStrLength, nonceLength = 0u; + + /* ----- Implementation ------------------------------------------------- */ + + /* #10 Get Nonce index */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_NONCE, &nonceIndex, &nonceLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (localRetVal == E_OK) + { + /* #15 Get Private String (recommended feature) */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_PERSONALIZATION_STRING, &personalizationStrIndex, &personalizationStrLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if ((localRetVal == E_OK) && (personalizationStrLength > 0u)) + { + /* #20 seed with personal string via esl_seedHASHDRBG */ + retValCv = esl_seedHASHDRBG(wsDRBG, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))entropyPtr, + (eslt_Length)entropyLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(nonceIndex), + (eslt_Length)nonceLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(personalizationStrIndex), + (eslt_Length)personalizationStrLength, + NULL_PTR, + 0u); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else if ((localRetVal == CRYPTO_E_KEY_NOT_AVAILABLE) || (localRetVal == E_OK)) + { + /* #25 Personal string in not available in the key so seed without personal string. */ + retValCv = esl_seedHASHDRBG(wsDRBG, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))entropyPtr, + (eslt_Length)entropyLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(nonceIndex), + (eslt_Length)nonceLength, + NULL_PTR, + 0u, + NULL_PTR, + 0u); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else + { + /* request failed */ + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_HashDrbgSeedFirst() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_HashDrbgReseed() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_HashDrbgReseed( + uint32 cryptoKeyId, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsDRBG, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, localRetVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_SizeOfKeyStorageType additionalInputIndex = 0u, seedIndex, reseedCounter; + uint32 seedLength = CRYPTO_30_LIBCV_RANDOM_HASH_INTERNAL_STATE_BUFFER_LEN; + uint32 reseedCntLength = CRYPTO_30_LIBCV_RANDOM_RESEED_COUNTER_LEN; + uint32 reseedCnt, additionalInputLength = 0u; + + /* ----- Implementation ------------------------------------------------- */ + + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_RANDOM_SEED_STATE, &seedIndex, &seedLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + { + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER, &reseedCounter, &reseedCntLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + { + /* #1 Reseed: restore seed state */ + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&reseedCnt, Crypto_30_LibCv_GetAddrKeyStorage(reseedCounter)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + retValCv = esl_restoreStateHASHDRBG(wsDRBG, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(seedIndex), + (eslt_Length)seedLength, + reseedCnt, + (eslt_Byte)ESL_DRBG_SEED_STATUS_SEEDED, + (eslt_DRBGMode)ESL_DRBGMODE_HASHDRBG_SHA512); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + if (retValCv == ESL_ERC_NO_ERROR) + { + /* #5 check if additional input is available. (optional feature) */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_ADDITIONAL_INPUT, &additionalInputIndex, &additionalInputLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + } + } + + if ((localRetVal == E_OK) && (additionalInputLength > 0u)) + { + /* #10 reseed via esl_seedHASHDRBG */ + retValCv = esl_seedHASHDRBG(wsDRBG, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))entropyPtr, + (eslt_Length)entropyLength, + NULL_PTR, + 0u, + NULL_PTR, + 0u, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(additionalInputIndex), + (eslt_Length)additionalInputLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else if ((localRetVal == CRYPTO_E_KEY_NOT_AVAILABLE) || (localRetVal == E_OK)) + { + retValCv = esl_seedHASHDRBG(wsDRBG, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))entropyPtr, + (eslt_Length)entropyLength, + NULL_PTR, + 0u, + NULL_PTR, + 0u, + NULL_PTR, + 0u); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else + { + /* request failed */ + retValCv = ESL_ERC_ERROR; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_HashDrbgReseed() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Get_And_Set_NistDrbgHashState() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Get_And_Set_NistDrbgHashState( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType seedCounterElementIndex, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + eslt_ErrorCode retValCv; + uint32 reseedCntBuf; + eslt_Length seedLength = Crypto_30_LibCv_GetKeyElementLength(seedStateElementIndex); + eslt_DRBGSeedStatusType seedStatus; + eslt_DRBGMode modeDRBG; + + /* #10 Get current DRBG state and save the seed state. */ + retValCv = esl_getStateHASHDRBG(wsDRBG, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(seedStateElementIndex), + &seedLength, + &reseedCntBuf, + &seedStatus, + &modeDRBG); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + retVal = Crypto_30_LibCv_Local_Set_NistDrbgState( + cryptoKeyId, + seedStateElementIndex, + seedCounterElementIndex, + retValCv, + seedLength, + CRYPTO_30_LIBCV_RANDOM_HASH_INTERNAL_STATE_BUFFER_LEN, + reseedCntBuf, + seedStatus); + + return retVal; +} /* Crypto_30_LibCv_Local_Get_And_Set_NistDrbgHashState() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomNistDrbgHashFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6050 3 */ /* MD_MSR_STCAL */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomNistDrbgHashFinish( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, localRetVal; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, seedCounterElementIndex; + uint32 reseedCntBuf; + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + boolean persist = FALSE; + eslt_DRBGSeedStatusType seedStatus; + + /* ----- Implementation ------------------------------------------------- */ + /* #10 load workspace */ + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfDRBGHashSha512(Crypto_30_LibCv_GetDRBGHashSha512IdxOfObjectInfo(objectId)); + + /* #20 Load seed state, seed counter and check key data. */ + localRetVal = Crypto_30_LibCv_DispatchRandomNistDrbgHashGeneratePrepare(workspace, job->cryptoKeyId, keyElements, &seedStateElementIndex, &seedCounterElementIndex, &persist); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (localRetVal == E_OK) + { + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&reseedCntBuf, Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(seedCounterElementIndex)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (Crypto_30_LibCv_IsKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_MASK)) + { + seedStatus = ESL_DRBG_SEED_STATUS_SEEDED; + } + else + { + seedStatus = ESL_DRBG_SEED_STATUS_UNSEEDED; + } + + /* #30 Set state to current seed state. */ + retValCv = esl_restoreStateHASHDRBG(workspace, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(seedStateElementIndex), + (eslt_Length)CRYPTO_30_LIBCV_RANDOM_HASH_INTERNAL_STATE_BUFFER_LEN, + (eslt_DRBGReseedCounterType)reseedCntBuf, + seedStatus, + ESL_DRBGMODE_HASHDRBG_SHA512); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* #31 generate random number via esl_getBytesHASHDRBG. */ + retValCv = Crypto_30_LibCv_Local_Generate_NistDrbgHash( + job->cryptoKeyId, + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, + workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* #32 Set current state. */ + retVal = Crypto_30_LibCv_Local_Get_And_Set_NistDrbgHashState( + job->cryptoKeyId, + seedStateElementIndex, + seedCounterElementIndex, + workspace); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + } + } + else + { + retVal = localRetVal; + } + + if (retValCv == ESL_ERC_ENTROPY_EXHAUSTION) + { + retVal = CRYPTO_E_ENTROPY_EXHAUSTION; + } + + if (retVal != E_OK) + { + /* clear output buffer if request failed */ + Crypto_30_LibCv_ClearData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + else + { + Crypto_30_LibCv_SetProcessJob_Trigger_Write(objectId, persist); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ +# if(CRYPTO_30_LIBCV_KEYVALUECHANGEDCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + /* Call the callout if the functionality is enabled and trigger that the key value is changed */ + Crypto_30_LibCv_KeyValueChangedCallout(job->cryptoKeyId); +# endif + /* Call the callout if the functionality is enabled and trigger that the key is set to valid */ +# if(CRYPTO_30_LIBCV_KEYVALIDITYSETCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + Crypto_30_LibCv_GetKeyValiditySetCalloutFctNameOfConfigurableCallouts()(job->cryptoKeyId, TRUE); +# endif + } + + return retVal; +} /* Crypto_30_LibCv_DispatchRandomNistDrbgHashFinish() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchRandomNistDrbgHashGeneratePrepare() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6060 7 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchRandomNistDrbgHashGeneratePrepare( + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) ws, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_KeyElementGetType, AUTOMATIC, AUTOMATIC) keyElements, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) seedStateElementIndexPtr, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) seedCounterElementIndexPtr, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) persistPtr) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + + /* ----- Implementation ------------------------------------------------- */ + + /* # load seed state and reseed counter */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_RANDOM_SEED_STATE, CRYPTO_30_LIBCV_RANDOM_HASH_INTERNAL_STATE_BUFFER_LEN); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 1u, CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER, CRYPTO_30_LIBCV_RANDOM_RESEED_COUNTER_LEN); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* Get index of keyElement SEED_STATE and CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER */ + (void)Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, CRYPTO_KE_RANDOM_SEED_STATE, seedStateElementIndexPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + (void)Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER, seedCounterElementIndexPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + /* # Initialize workspace header */ + if (esl_initWorkSpaceHeader(&(ws->header), ESL_MAXSIZEOF_WS_HASHDRBG, CRYPTO_30_LIBCV_WATCHDOG_PTR) != ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + retVal = E_NOT_OK; + } + else + { + /* # Initialize workspace */ + if (esl_initHASHDRBG(ws, ESL_DRBGMODE_HASHDRBG_SHA512) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + Crypto_30_LibCv_Local_Check_Random_KeyElement_Persist(*seedStateElementIndexPtr, *seedCounterElementIndexPtr, persistPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + } + else + { + retVal = E_NOT_OK; + } + } + } + else if (retVal == CRYPTO_E_KEY_NOT_VALID) + { + retVal = CRYPTO_E_ENTROPY_EXHAUSTION; + } + else + { + /* keep retVal */ + } + + return retVal; +} /* Crypto_30_LibCv_DispatchRandomNistDrbgHashGeneratePrepare() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Generate_NistDrbgHash() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Generate_NistDrbgHash( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) requestBuffer, + uint32 requestLength, + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) wsDRBG) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + Std_ReturnType localRetVal; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_LibCv_SizeOfKeyStorageType additionalInputIndex; + uint32 additionalInputLength = 0u; + + /* #10 Load additional input. */ + localRetVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndex(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_ADDITIONAL_INPUT, &additionalInputIndex, &additionalInputLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + + /* #20 Generate random number DRBG. */ + if ((localRetVal == E_OK) && (additionalInputLength > 0u)) + { + retValCv = esl_getBytesHASHDRBG(wsDRBG, + (eslt_Length)requestLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))requestBuffer, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(additionalInputIndex), + (eslt_Length)additionalInputLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else if ((localRetVal == E_OK) || (localRetVal == CRYPTO_E_KEY_NOT_AVAILABLE)) + { + retValCv = esl_getBytesHASHDRBG(wsDRBG, + (eslt_Length)requestLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) requestBuffer, + NULL_PTR, + 0u); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + else + { + retValCv = ESL_ERC_ERROR; + } + + return retValCv; +} /* Crypto_30_LibCv_Local_Generate_NistDrbgHash() */ + +# if (CRYPTO_30_LIBCV_RANDOM_SOURCE_DRBG_HASH == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_GetRandomNistDrbgHash() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6010, 6050 5 */ /* MD_MSR_STPTH, MD_MSR_STCAL */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_GetRandomNistDrbgHash( + uint32 partitionIdx, + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) requestBuffer, + uint32 requestLength, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) persistPtr) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + eslt_WorkSpaceHASHDRBG wsDRBG; + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex = 0u, seedCounterElementIndex = 0u; + uint32 retry; + uint16 localCount; + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + uint32 reseedCntBuf; + eslt_DRBGSeedStatusType seedStatus; + + /* ----- Implementation ------------------------------------------------- */ + + /* # Prepare DRBG and check key data. */ + retVal = Crypto_30_LibCv_DispatchRandomNistDrbgHashGeneratePrepare(&wsDRBG, cryptoKeyId, keyElements, &seedStateElementIndex, &seedCounterElementIndex, persistPtr); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + /* # Calculate random number until calculation is valid or max reties exhausted. */ + for (retry = 0u; retry < CRYPTO_30_LIBCV_DEFAULT_RANDOM_MAX_RETRIES; retry++) + { + /* # Copy counter and RNG paramater to local buffers. */ + localCount = Crypto_30_LibCv_GetRandomSourceGenerateCount(partitionIdx); + Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian(&reseedCntBuf, Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(seedCounterElementIndex)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + + if (Crypto_30_LibCv_IsKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_MASK)) + { + seedStatus = ESL_DRBG_SEED_STATUS_SEEDED; + } + else + { + seedStatus = ESL_DRBG_SEED_STATUS_UNSEEDED; + } + + retValCv = esl_restoreStateHASHDRBG( + (P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) &wsDRBG, /* PRQA S 2982 */ /* MD_MSR_RetVal */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(seedStateElementIndex), + (eslt_Length)CRYPTO_30_LIBCV_RANDOM_HASH_INTERNAL_STATE_BUFFER_LEN, + reseedCntBuf, + seedStatus, + ESL_DRBGMODE_HASHDRBG_SHA512); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Generate random number DRBG. */ + retValCv = Crypto_30_LibCv_Local_Generate_NistDrbgHash( + cryptoKeyId, + requestBuffer, + requestLength, + &wsDRBG); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + + SchM_Enter_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + /* # Check if rng counter has changed. */ + if ((Crypto_30_LibCv_IsRngCalculationValid(localCount, partitionIdx)) && (retValCv == ESL_ERC_NO_ERROR)) + { + retVal = Crypto_30_LibCv_Local_Get_And_Set_NistDrbgHashState( + cryptoKeyId, + seedStateElementIndex, + seedCounterElementIndex, + &wsDRBG); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + /* break loop */ + break; + } + else + { + retVal = E_NOT_OK; + } + } + SchM_Exit_Crypto_30_LibCv_CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0(); + + if (retVal != E_OK) + { + /* # clear output buffer if request failed. */ + Crypto_30_LibCv_ClearData(requestBuffer, requestLength); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + *persistPtr = FALSE; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } + } + + if ((retValCv != ESL_ERC_NO_ERROR) || (retVal != E_OK)) + { + if (retValCv == ESL_ERC_ENTROPY_EXHAUSTION) + { + retVal = CRYPTO_E_ENTROPY_EXHAUSTION; + } + else + { + retVal = E_NOT_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_GetRandomNistDrbgHash() */ +# endif /* (CRYPTO_30_LIBCV_RANDOM_SOURCE_DRBG_HASH == STD_ON) */ +#endif /* (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON) */ + +#if((CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON) || (CRYPTO_30_LIBCV_DRBGAES == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Random_Check_For_Write_Once() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Random_Check_For_Write_Once( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) reseedCtElementIndex) +{ + /* ----- Local Variables ------------------------------------------------ */ + boolean retVal = FALSE; + + /* ----- Implementation ------------------------------------------------- */ + + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER, reseedCtElementIndex) != E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* retVal is already set */ + } + /* #10 Deny service for write once keys. */ + else if (Crypto_30_LibCv_IsKeyElementWriteOnce(*reseedCtElementIndex)) + { + retVal = FALSE; + } + else if (Crypto_30_LibCv_IsKeyElementWriteOnce(seedStateElementIndex)) + { + retVal = FALSE; + } + else + { + retVal = TRUE; + } + + return retVal; +} /* Crypto_30_LibCv_Local_Random_Check_For_Write_Once() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Set_NistDrbgState() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6060 9 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Set_NistDrbgState( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType seedCounterElementIndex, + eslt_ErrorCode retValCv, + eslt_Length seedLength, + eslt_Length expectedSeedLength, + uint32 reseedCntBuf, + eslt_DRBGSeedStatusType seedStatus) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + + if ((retValCv == ESL_ERC_NO_ERROR) && (seedLength == expectedSeedLength)) + { + Crypto_30_LibCv_SetKeyElementWrittenLength(seedStateElementIndex, seedLength); + + if (seedStatus == ESL_DRBG_SEED_STATUS_UNSEEDED) + { + Crypto_30_LibCv_ClearKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_INV_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + } + else + { + Crypto_30_LibCv_SetKeyElementStateByMask(seedStateElementIndex, CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_MASK); /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + } + + /* Save reseed counter. */ + Crypto_30_LibCv_Local_Uint32ToUint8ArrayBigEndian(Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(seedCounterElementIndex), reseedCntBuf); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + Crypto_30_LibCv_SetKeyElementWrittenLength(seedCounterElementIndex, CRYPTO_30_LIBCV_RANDOM_RESEED_COUNTER_LEN); + retVal = E_OK; + +# if(CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + /* Call KeyNvStatus KeyChanged transition */ + Crypto_30_LibCv_KeyNvStatus_KeyChanged_Unprotected(cryptoKeyId, seedStateElementIndex); + Crypto_30_LibCv_KeyNvStatus_KeyChanged_Unprotected(cryptoKeyId, seedCounterElementIndex); +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + } + else + { + retVal = E_NOT_OK; + } + + return retVal; +} /* Crypto_30_LibCv_Local_Set_NistDrbgState() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Check_Random_KeyElement_Persist() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Check_Random_KeyElement_Persist( + Crypto_30_LibCv_SizeOfKeyElementsType seedStateElementIndex, + Crypto_30_LibCv_SizeOfKeyElementsType seedCounterElementIndex, + P2VAR(boolean, AUTOMATIC, AUTOMATIC) persistPtr) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Implementation ------------------------------------------------- */ +# if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + if (Crypto_30_LibCv_IsKeyElementPersist(seedStateElementIndex) || Crypto_30_LibCv_IsKeyElementPersist(seedCounterElementIndex)) + { + *persistPtr = TRUE; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } + else +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(seedStateElementIndex); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(seedCounterElementIndex); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + { + *persistPtr = FALSE; /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } +} /* Crypto_30_LibCv_Local_Check_Random_KeyElement_Persist() */ + +#endif /* ((CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON) || (CRYPTO_30_LIBCV_DRBGAES == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_IsRngCalculationValid() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_IsRngCalculationValid(uint16 localCount, uint32 currentPartitionIdx) +{ + /* ----- Local Variables ------------------------------------------------ */ + boolean validCalculation; + + /* ----- Implementation ------------------------------------------------- */ + /* Check if the Rng Counter is the expected value */ + if (localCount == Crypto_30_LibCv_GetRandomSourceGenerateCount(currentPartitionIdx)) + { + validCalculation = TRUE; + Crypto_30_LibCv_SetRandomSourceGenerateCount((Crypto_30_LibCv_RandomSourceGenerateCountType)(localCount + 1u), currentPartitionIdx); /* SBSW_CRYPTO_30_LIBCV_WRITE_PARTITION_DATA */ + } + else + { + validCalculation = FALSE; + } + +# if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS < 2u) + CRYPTO_30_LIBCV_DUMMY_STATEMENT(currentPartitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + + return validCalculation; +} /* Crypto_30_LibCv_IsRngCalculationValid() */ +#endif /* (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYVALUECHANGEDCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyValueChangedCallout() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyValueChangedCallout(uint32 cryptoKeyId) +{ + /* ----- Implementation ------------------------------------------------- */ + /* Call key value changed callout */ + Crypto_30_LibCv_GetKeyValueChangedCalloutFctNameOfConfigurableCallouts()(cryptoKeyId, CRYPTO_KE_RANDOM_SEED_STATE); + Crypto_30_LibCv_GetKeyValueChangedCalloutFctNameOfConfigurableCallouts()(cryptoKeyId, CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER); +} /* Crypto_30_LibCv_KeyValueChangedCallout() */ +#endif /* (CRYPTO_30_LIBCV_KEYVALUECHANGEDCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ +#if (CRYPTO_30_LIBCV_FIPS186 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Fips186() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Fips186( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + /* #5 Distinguish modes. */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + { + retVal = E_OK; + break; + } + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = E_OK; + break; + } + + /* #70 Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_DispatchRandomFips186Finish(objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Fips186() */ +#endif /* (CRYPTO_30_LIBCV_FIPS186 == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYSEEDFIPS186 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySeedFips186() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySeedFips186( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex; + boolean writeBlock = FALSE; + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + if (Crypto_30_LibCv_Local_KeyElementSearch(job->cryptoKeyId, CRYPTO_KE_RANDOM_SEED_STATE, &elementIndex) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* #10 Call Crypto_30_LibCv_Local_RandomSeed_Fips */ + retVal = Crypto_30_LibCv_Local_RandomSeed_Fips(job->cryptoKeyId, elementIndex, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, &writeBlock); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_SetProcessJob_Trigger_Write(objectId, writeBlock); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + else + { + retVal = E_NOT_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeySeedFips186() */ +#endif /* CRYPTO_30_LIBCV_KEYSEEDFIPS186() */ + +#if (CRYPTO_30_LIBCV_DRBGAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_DRBGAES() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_DRBGAES( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + /* #5 Distinguish modes. */ + switch (mode) + { + /* #10 Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = E_OK; + break; + } + /* #15 Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = E_OK; + break; + } + + /* #20 Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_DispatchRandomNistDrbgAesFinish(objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_DRBGAES() */ +#endif /* (CRYPTO_30_LIBCV_DRBGAES == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYSEEDDRBGAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySeedDRBGAES() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySeedDRBGAES( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex; + boolean writeBlock = FALSE; + eslt_DRBGMode modeDRBG = 0u; + eslt_Length seedLength = 0u; + P2VAR(eslt_WorkSpaceCTRDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + workspace = Crypto_30_LibCv_GetWorkspaceOfKeySeedDRBGAES(Crypto_30_LibCv_GetKeySeedDRBGAESIdxOfObjectInfo(objectId)); + + if (Crypto_30_LibCv_Local_KeyElementSearch(job->cryptoKeyId, CRYPTO_KE_RANDOM_SEED_STATE, &elementIndex) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* #10 Set the correct DRBG mode */ + if (Crypto_30_LibCv_RandomNistDrbgAes_Set_Mode_And_SeedLength(job->cryptoKeyId, &modeDRBG, &seedLength) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* #20 Call Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes_With_Ws */ + retVal = Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes_With_Ws(job->cryptoKeyId, elementIndex, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, &writeBlock, modeDRBG, workspace); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + + /* #30 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_SetProcessJob_Trigger_Write(objectId, writeBlock); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + else + { + retVal = E_NOT_OK; + } + } + else + { + retVal = E_NOT_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeySeedDRBGAES() */ +#endif /* CRYPTO_30_LIBCV_KEYSEEDDRBGAES() */ + +#if (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_DRBGHashSha512() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_DRBGHashSha512( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + /* #5 Distinguish modes. */ + switch (mode) + { + /* #10 Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = E_OK; + break; + } + /* #15 Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = E_OK; + break; + } + + /* #20 Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_DispatchRandomNistDrbgHashFinish(objectId, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_DRBGHashSha512() */ +#endif /* (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON) */ + +#if (CRYPTO_30_LIBCV_KEYSEEDDRBGHASHSHA512 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySeedDRBGHashSha512() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySeedDRBGHashSha512( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + P2VAR(eslt_WorkSpaceHASHDRBG, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfKeySeedDRBGHashSha512(Crypto_30_LibCv_GetKeySeedDRBGHashSha512IdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex; + boolean writeBlock = FALSE; + + /* ----- Implementation ------------------------------------------------- */ + if (mode == CRYPTO_OPERATIONMODE_FINISH) + { + if (Crypto_30_LibCv_Local_KeyElementSearch(job->cryptoKeyId, CRYPTO_KE_RANDOM_SEED_STATE, &elementIndex) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + /* #10 Call Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash_With_Ws */ + retVal = Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash_With_Ws(job->cryptoKeyId, elementIndex, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, &writeBlock, workspace); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR_AND_MEMBER_OF_JOB_PTR */ + + /* #20 If key was derived successfully, mark it as valid */ + Crypto_30_LibCv_SetProcessJob_Trigger_Write(objectId, writeBlock); /* SBSW_CRYPTO_30_LIBCV_CSL01_OBJECTID */ + } + else + { + retVal = E_NOT_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_KeySeedDRBGHashSha512() */ +#endif /* Crypto_30_LibCv_KeySeedDRBGHashSha512() */ + +#if ((CRYPTO_30_LIBCV_FIPS186 == STD_ON) || (CRYPTO_30_LIBCV_DRBGAES == STD_ON) || (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* PRQA S 6030, 6050, 6080 4 */ /* MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, algorithmElementIndex; + uint32 seedAlgorithmLength = CRYPTO_30_LIBCV_RANDOM_SEED_SIZEOF_ALGORITHM; + Crypto_30_LibCv_SizeOfKeyStorageType seedAlgorithmStorageIndex; + boolean writeBlock = FALSE; + + /* ----- Implementation ------------------------------------------------- */ + /* #10 Check if the seed state key element is available */ + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, CRYPTO_KE_RANDOM_SEED_STATE, &elementIndex) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + /* #15 Lock write access for the CryptoKey */ + if (Crypto_30_LibCv_Local_KeyWriteLockGet(cryptoKeyId) != E_OK) + { + retVal = CRYPTO_E_BUSY; + } + else +# endif + { + /* #20 Get Algorithm from the algorithm key element */ + if (Crypto_30_LibCv_Local_KeyElementSearch(cryptoKeyId, CRYPTO_KE_RANDOM_ALGORITHM, &algorithmElementIndex) == E_OK) /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + { + if (Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic(algorithmElementIndex, &seedAlgorithmStorageIndex, (P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))&seedAlgorithmLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL, CRYPTO_30_LIBCV_SHE_SERVICE_OTHER) == E_OK) /* SBSW_CRYPTO_30_LIBCV_FORWARDING_STACK_BUFFER */ + { +# if (CRYPTO_30_LIBCV_FIPS186 == STD_ON) + /* #25 handle RNG_FIPS_186_2 */ + if (Crypto_30_LibCv_GetKeyStorage(seedAlgorithmStorageIndex) == CRYPTO_30_LIBCV_RNG_FIPS_186_2_SHA1) + { + retVal = Crypto_30_LibCv_Local_RandomSeed_Fips(cryptoKeyId, elementIndex, entropyPtr, entropyLength, &writeBlock); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + } + else +# endif +# if (CRYPTO_30_LIBCV_DRBGAES == STD_ON) + /* #30 handle NIST 800-90A DRBG CTR AES128 */ + if (Crypto_30_LibCv_GetKeyStorage(seedAlgorithmStorageIndex) == CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES128) + { + retVal = Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes(cryptoKeyId, elementIndex, entropyPtr, entropyLength, &writeBlock, ESL_DRBGMODE_CTRDRBG_AES128_NODF); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + } + else if (Crypto_30_LibCv_GetKeyStorage(seedAlgorithmStorageIndex) == CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES128_DF) + { + retVal = Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes(cryptoKeyId, elementIndex, entropyPtr, entropyLength, &writeBlock, ESL_DRBGMODE_CTRDRBG_AES128_DF); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + } + /* #35 handle NIST 800-90A DRBG CTR AES256 */ + else if (Crypto_30_LibCv_GetKeyStorage(seedAlgorithmStorageIndex) == CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES256) + { + retVal = Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes(cryptoKeyId, elementIndex, entropyPtr, entropyLength, &writeBlock, ESL_DRBGMODE_CTRDRBG_AES256_NODF); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + } + else if (Crypto_30_LibCv_GetKeyStorage(seedAlgorithmStorageIndex) == CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES256_DF) + { + retVal = Crypto_30_LibCv_Local_RandomSeed_NistDrbgAes(cryptoKeyId, elementIndex, entropyPtr, entropyLength, &writeBlock, ESL_DRBGMODE_CTRDRBG_AES256_DF); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + } + else +# endif +# if (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON) + /* #40 handle NIST 800-90A DRBG HASH SHA2-512 */ + if (Crypto_30_LibCv_GetKeyStorage(seedAlgorithmStorageIndex) == CRYPTO_30_LIBCV_RNG_NIST_800_90A_HASH_DRBG_SHA_512) + { + retVal = Crypto_30_LibCv_Local_RandomSeed_NistDrbgHash(cryptoKeyId, elementIndex, entropyPtr, entropyLength, &writeBlock); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_KEYPTR */ + } + else +# endif + { + /* invalid random seed algorithm */ + } + } + } +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) + Crypto_30_LibCv_Local_KeyWriteLockRelease(cryptoKeyId); +# endif +# if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + if (writeBlock) + { + Crypto_30_LibCv_NvBlock_Write_Req(Crypto_30_LibCv_GetNvBlockIdxOfKey(cryptoKeyId)); + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(writeBlock); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + + } + } + return retVal; +} /* Crypto_30_LibCv_Local_RandomSeed() */ +#endif /* ((CRYPTO_30_LIBCV_FIPS186 == STD_ON) || (CRYPTO_30_LIBCV_DRBGAES == STD_ON) || (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) +/********************************************************************************************************************** + * esl_getBytesRNG() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +/* PRQA S 6080 3 */ /* MD_MSR_STMIF */ +FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) esl_getBytesRNG( + const eslt_Length targetLength, + P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) target) +{ + eslt_ErrorCode retVal = ESL_ERC_ERROR; + Std_ReturnType rngResult = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + boolean triggerPersist = FALSE; + uint32 partitionIdx = Crypto_30_LibCv_CurrentPartitionIdx(); + +# if (CRYPTO_30_LIBCV_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + if (partitionIdx < Crypto_30_LibCv_GetSizeOfPartitionIdentifiers()) +# endif + { + uint32 defaultRandomKey = Crypto_30_LibCv_GetDefaultRandomKeyOfPartitionInfo(partitionIdx); +# if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) + if ((Crypto_30_LibCv_IsModulePartitionInitialized(partitionIdx) && Crypto_30_LibCv_IsModuleSharedInitialized()) && (target != NULL_PTR)) +# endif + { +# if(CRYPTO_30_LIBCV_RANDOM_SOURCE_DRBG_AES == STD_ON) +# if(CRYPTO_30_LIBCV_RANDOM_SOURCE_DRBG_HASH == STD_ON) + if(Crypto_30_LibCv_IsAesOfPartitionInfo(partitionIdx)) +# endif + { + /* # Generate Drbg Aes Random Number */ + rngResult = Crypto_30_LibCv_GetRandomNistDrbgAes(partitionIdx, defaultRandomKey, target, targetLength, &triggerPersist); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } +# endif +# if(CRYPTO_30_LIBCV_RANDOM_SOURCE_DRBG_HASH == STD_ON) +# if(CRYPTO_30_LIBCV_RANDOM_SOURCE_DRBG_AES == STD_ON) + if(Crypto_30_LibCv_IsHashOfPartitionInfo(partitionIdx)) +# endif + { + /* # Generate Drbg Hash Random Number */ + rngResult = Crypto_30_LibCv_GetRandomNistDrbgHash(partitionIdx, defaultRandomKey, target, targetLength, &triggerPersist); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + } +# endif + + /* # Persist Key if necessary */ +# if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) + if (triggerPersist) + { + Crypto_30_LibCv_NvBlock_Write_Req(Crypto_30_LibCv_GetNvBlockIdxOfKey(defaultRandomKey)); + } +# endif + } + + if (rngResult == E_OK) + { + retVal = ESL_ERC_NO_ERROR; +# if(CRYPTO_30_LIBCV_KEYVALUECHANGEDCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + /* Call the callout if the functionality is enabled and trigger that the key value is changed */ + Crypto_30_LibCv_KeyValueChangedCallout(defaultRandomKey); +# endif + /* Call the callout if the functionality is enabled and trigger that the key is set to valid */ +# if(CRYPTO_30_LIBCV_KEYVALIDITYSETCALLOUTFCTNAMEOFCONFIGURABLECALLOUTS == STD_ON) + Crypto_30_LibCv_GetKeyValiditySetCalloutFctNameOfConfigurableCallouts()(defaultRandomKey, TRUE); +# endif + } + else if (rngResult == CRYPTO_E_ENTROPY_EXHAUSTION) + { + errorId = CRYPTO_E_RE_ENTROPY_EXHAUSTED; + } + else + { + errorId = CRYPTO_E_RE_GET_BYTES_RNG_ERROR; + } + } +# if (CRYPTO_30_LIBCV_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + else + { + errorId = CRYPTO_E_RE_GET_BYTES_RNG_ERROR; + } +# endif + + /* ----- Development Error Report --------------------------------------- */ +# if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) + /* #90 Report error if applicable */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportRuntimeError((uint16)CRYPTO_30_LIBCV_MODULE_ID, + CRYPTO_30_LIBCV_INSTANCE_ID, + CRYPTO_30_LIBCV_SID_ESL_GETBYTESRNG, + errorId); + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + + return retVal; +} /* esl_getBytesRNG() */ +#endif /* (CRYPTO_30_LIBCV_DEFAULT_RANDOM_SOURCE == STD_ON) */ + +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Random.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_RandomGenerate.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_RandomGenerate.h new file mode 100644 index 0000000..09d3b54 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_RandomGenerate.h @@ -0,0 +1,135 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_RandomGenerate.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for RANDOM Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_RANDOMGENERATE_H) +# define CRYPTO_30_LIBCV_RANDOMGENERATE_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_FIPS186 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Fips186() + *********************************************************************************************************************/ +/*! \brief Dispatches the RandomFips186 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-139102 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Fips186( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_FIPS186 == STD_ON */ + +# if (CRYPTO_30_LIBCV_DRBGAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_DRBGAES() + **********************************************************************************************************************/ +/*! \brief Dispatches the Nist 800-90A DRBG Aes job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-149660 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_DRBGAES( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_DRBGAES == STD_ON */ + +# if (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_DRBGHashSha512() + **********************************************************************************************************************/ +/*! \brief Dispatches the Nist 800-90A DRBG Hash job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-149660 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_DRBGHashSha512( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_RANDOMGENERATE_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_RandomGenerate.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_RandomSeed.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_RandomSeed.h new file mode 100644 index 0000000..68b173a --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_RandomSeed.h @@ -0,0 +1,153 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_RandomSeed.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for Random Seed Services. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#ifndef CRYPTO_30_LIBCV_RANDOMSEED_H +# define CRYPTO_30_LIBCV_RANDOMSEED_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if ((CRYPTO_30_LIBCV_FIPS186 == STD_ON) || (CRYPTO_30_LIBCV_DRBGAES == STD_ON) || (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_RandomSeed() + *********************************************************************************************************************/ +/*! \brief Initialize the seed + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre cryptoKeyId must identify a valid key + * entropyPtr need to be a valid pointer + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_RandomSeed( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) entropyPtr, + uint32 entropyLength); +# endif /* ((CRYPTO_30_LIBCV_FIPS186 == STD_ON) || (CRYPTO_30_LIBCV_DRBGAES == STD_ON) || (CRYPTO_30_LIBCV_DRBGHASHSHA512 == STD_ON)) */ + +# if (CRYPTO_30_LIBCV_KEYSEEDDRBGAES == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySeedDRBGAES() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeySeedDRBGAES job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-149660 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySeedDRBGAES( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* CRYPTO_30_LIBCV_KEYSEEDDRBGAES */ + +# if (CRYPTO_30_LIBCV_KEYSEEDFIPS186 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySeedFips186() + **********************************************************************************************************************/ +/*! \brief Dispatches the KeySeedFips186 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-139102 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySeedFips186( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif/* CRYPTO_30_LIBCV_KEYSEEDFIPS186 */ + +# if (CRYPTO_30_LIBCV_KEYSEEDDRBGHASHSHA512 == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_KeySeedDRBGHashSha512() + *********************************************************************************************************************/ +/*! \brief Dispatches the KeySeedDRBGHashSha512 job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-149660 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_KeySeedDRBGHashSha512( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* Crypto_30_LibCv_KeySeedDRBGHashSha512 */ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_RANDOMSEED_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_RandomSeed.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Services.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Services.h new file mode 100644 index 0000000..c1f6141 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Services.h @@ -0,0 +1,1723 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Services.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Internal header file for service dispatch function prototypes + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_SERVICES_H) +# define CRYPTO_30_LIBCV_SERVICES_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Csm_Types.h" +# include "Crypto_30_LibCv_Cfg.h" + +# include "ESLib_version.h" + +# if !defined (CRYPTO_30_LIBCV_LOCAL) /* COV_CRYPTO_30_LIBCV_LOCAL_DEFINE */ +# define CRYPTO_30_LIBCV_LOCAL static +# endif + +# if !defined (CRYPTO_30_LIBCV_LOCAL_INLINE) /* COV_CRYPTO_30_LIBCV_LOCAL_DEFINE */ +# define CRYPTO_30_LIBCV_LOCAL_INLINE LOCAL_INLINE +# endif + +# if !defined (CRYPTO_30_LIBCV_ALWAYS_LOCAL_INLINE) /* COV_CRYPTO_30_LIBCV_LOCAL_DEFINE */ +# define CRYPTO_30_LIBCV_ALWAYS_LOCAL_INLINE static INLINE /* "static" cannot be removed in this definition */ +# endif + +# if (CRYPTO_30_LIBCV_DEV_ERROR_REPORT == STD_ON) +# include "Det.h" +# endif + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +# if !defined (CRYPTO_30_LIBCV_BYTES_PER_DIGIT) /* COV_CRYPTO_30_LIBCV_BYTES_PER_DIGIT */ +# define CRYPTO_30_LIBCV_BYTES_PER_DIGIT actBN_BYTES_PER_DIGIT +# endif + +/* Masks for KeyElementState */ +# define CRYPTO_30_LIBCV_KEYELEMENTSTATE_CLEAR_NORMAL_MASK CRYPTO_30_LIBCV_KEYELEMENTSTATE_CLEAR_ALL_MASK +# define CRYPTO_30_LIBCV_KEYELEMENTSTATE_CLEAR_ALL_MASK (0x00u) /* clear all flags */ +# define CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_MASK (0x80u) +# define CRYPTO_30_LIBCV_KEYELEMENTSTATE_WRITTEN_ONCE_INV_MASK (0x7Fu) +# define CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_MASK (0x08u) +# define CRYPTO_30_LIBCV_KEYELEMENTSTATE_SEED_INIT_INV_MASK (0xF7u) +# define CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALUE_USED_MASK (0x04u) +# define CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALUE_USED_INV_MASK (0xFBu) +# define CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_MASK (0x01u) +# define CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_INV_MASK (0xFEu) + +/* Mask for KeyElementExtension */ +# define CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_CLEAR_ALL_MASK (0x00u) /* clear all flags */ +# define CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_SHE_KEY_MASK (0x01u) /* she key flags */ +# define CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_SHE_PLAIN_KEY_MASK (0x03u) /* she written plain flags */ +# define CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_SHE_CLEAR_PLAIN_KEY_MASK (0xFDu) /* clear she written plain flags */ + +# if (CRYPTO_30_LIBCV_RSAPKCS1GENERATE == STD_ON) || (CRYPTO_30_LIBCV_RSAPSSGENERATE == STD_ON) +# define CRYPTO_30_LIBCV_RSAGENERATE STD_ON +# else +# define CRYPTO_30_LIBCV_RSAGENERATE STD_OFF +# endif + +# if (CRYPTO_30_LIBCV_RSAPKCS1VERIFY == STD_ON) || (CRYPTO_30_LIBCV_RSAPSSVERIFY == STD_ON) +# define CRYPTO_30_LIBCV_RSAVERIFY STD_ON +# else +# define CRYPTO_30_LIBCV_RSAVERIFY STD_OFF +# endif + +/* General Target Key Element -> always id 1 */ +# define CRYPTO_30_LIBCV_KE_TARGET_KEY (1u) + +/* Size definitions */ +# define CRYPTO_30_LIBCV_CMACAES128_KEY_SIZE ESL_SIZEOF_AES128_KEY +# define CRYPTO_30_LIBCV_CMACAES256_KEY_SIZE ESL_SIZEOF_AES256_KEY +# define CRYPTO_30_LIBCV_CMACAES_MAC_SIZE ESL_SIZEOF_AES128_BLOCK +# define CRYPTO_30_LIBCV_AES_BLOCK_SIZE ESL_SIZEOF_AES128_BLOCK +# define CRYPTO_30_LIBCV_AESCCM_SUM_OF_NONCE_LENGTH_AND_L (15u) + +# define CRYPTO_30_LIBCV_KEY_LOCK_READ_MAX (0xFFu) +# define CRYPTO_30_LIBCV_KEY_LOCK_READ_ONE (3u) +# define CRYPTO_30_LIBCV_KEY_LOCK_FREE (2u) +# define CRYPTO_30_LIBCV_KEY_LOCK_WRITE (1u) + +# define CRYPTO_30_LIBCV_LONG_TERM_WS_LOCK_FREE (CRYPTO_30_LIBCV_MAX_LONGTERMWSLOCK) + +# define CRYPTO_30_LIBCV_SIZEOF_UINT32 (4u) + +# define CRYPTO_30_LIBCV_UINT32_MAX (0xFFFFFFFFuL) +# define CRYPTO_30_LIBCV_UINT24_MAX (0xFFFFFFuL) +# define CRYPTO_30_LIBCV_UINT16_MAX (0xFFFFu) + +/* Length Check */ +# define CRYPTO_30_LIBCV_LENGTH_CHECK_NONE (0u) /* length is not checked */ +# define CRYPTO_30_LIBCV_LENGTH_CHECK_MAX (1u) /* length is smaller / equal to key length */ +# define CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL (2u) /* length is equal to key length */ +# define CRYPTO_30_LIBCV_LENGTH_CHECK_MIN (3u) /* length is bigger / equal to key length */ + +/* SHE key usage types */ +# define CRYPTO_30_LIBCV_SHE_SERVICE_ENCRYPT_DECRYPT (0u) +# define CRYPTO_30_LIBCV_SHE_SERVICE_MAC_GENERATE (1u) +# define CRYPTO_30_LIBCV_SHE_SERVICE_MAC_VERIFY (2u) +# define CRYPTO_30_LIBCV_SHE_SERVICE_KEY_SERVICE (3u) +# define CRYPTO_30_LIBCV_SHE_SERVICE_OTHER (4u) +# define CRYPTO_30_LIBCV_SHE_NUM_SERVICES (4u) + +# define CRYPTO_30_LIBCV_BOOT_PROTECTED (0x01u) +# define CRYPTO_30_LIBCV_DEBUGGER_PROTECTED (0x01u) + +# define CRYPTO_30_LIBCV_SIZEOF_ECC_160_P (20u) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_160_N (21u) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_224_P (28u) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_224_N (28u) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_256_P (32u) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_256_N (32u) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_384_P (48u) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_384_N (48u) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_521_P (66u) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_521_N (66u) + +# define CRYPTO_30_LIBCV_SIZEOF_ECC_160_SIGNATURE (CRYPTO_30_LIBCV_SIZEOF_ECC_160_N) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_224_SIGNATURE (CRYPTO_30_LIBCV_SIZEOF_ECC_224_N) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_256_SIGNATURE (CRYPTO_30_LIBCV_SIZEOF_ECC_256_N) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_384_SIGNATURE (CRYPTO_30_LIBCV_SIZEOF_ECC_384_N) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_521_SIGNATURE (CRYPTO_30_LIBCV_SIZEOF_ECC_521_N) + +# define CRYPTO_30_LIBCV_SIZEOF_ECC_160_KEY_PRIVATE_MIN (CRYPTO_30_LIBCV_SIZEOF_ECC_160_N - 1u) /* Size of private key can have 20 (160 bits) or 21 bytes (161 bit) */ +# define CRYPTO_30_LIBCV_SIZEOF_ECC_160_KEY_PRIVATE (CRYPTO_30_LIBCV_SIZEOF_ECC_160_N) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PRIVATE (CRYPTO_30_LIBCV_SIZEOF_ECC_224_N) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE (CRYPTO_30_LIBCV_SIZEOF_ECC_256_N) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY_PRIVATE (CRYPTO_30_LIBCV_SIZEOF_ECC_384_N) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE (CRYPTO_30_LIBCV_SIZEOF_ECC_521_N) + +# define CRYPTO_30_LIBCV_SIZEOF_ECC_160_KEY_PUBLIC (CRYPTO_30_LIBCV_SIZEOF_ECC_160_P) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PUBLIC (CRYPTO_30_LIBCV_SIZEOF_ECC_224_P) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PUBLIC (CRYPTO_30_LIBCV_SIZEOF_ECC_256_P) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY_PUBLIC (CRYPTO_30_LIBCV_SIZEOF_ECC_384_P) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PUBLIC (CRYPTO_30_LIBCV_SIZEOF_ECC_521_P) + +# define CRYPTO_30_LIBCV_SIZEOF_ECC_160_KEY_PUBLIC_XY (2u * (CRYPTO_30_LIBCV_SIZEOF_ECC_160_P)) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PUBLIC_XY (2u * (CRYPTO_30_LIBCV_SIZEOF_ECC_224_P)) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PUBLIC_XY (2u * (CRYPTO_30_LIBCV_SIZEOF_ECC_256_P)) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY_PUBLIC_XY (2u * (CRYPTO_30_LIBCV_SIZEOF_ECC_384_P)) +# define CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PUBLIC_XY (2u * (CRYPTO_30_LIBCV_SIZEOF_ECC_521_P)) + +# if(CRYPTO_30_LIBCV_ECP521GENERATE == STD_ON) +# define CRYPTO_30_LIBCV_MAX_SIZEOF_SIGNATURE_GENERATE_ECC_KEY (CRYPTO_30_LIBCV_SIZEOF_ECC_521_SIGNATURE) +# elif(CRYPTO_30_LIBCV_ECP384GENERATE == STD_ON) +# define CRYPTO_30_LIBCV_MAX_SIZEOF_SIGNATURE_GENERATE_ECC_KEY (CRYPTO_30_LIBCV_SIZEOF_ECC_384_SIGNATURE) +# else +# if(CRYPTO_30_LIBCV_ECP256GENERATE == STD_ON) +# define CRYPTO_30_LIBCV_MAX_SIZEOF_SIGNATURE_GENERATE_ECC_KEY (CRYPTO_30_LIBCV_SIZEOF_ECC_256_SIGNATURE) +# else +/* The signature contains an R and an S component, the length of the R component is always 160 bits and the length of the S component can be 161 bits, + therefore the maximum size is fixed at 161 bits. */ +# define CRYPTO_30_LIBCV_MAX_SIZEOF_SIGNATURE_GENERATE_ECC_KEY (CRYPTO_30_LIBCV_SIZEOF_ECC_160_SIGNATURE) +# endif +# endif + +/* SM2 length defines */ +# define CRYPTO_30_LIBCV_SM2_SIZEOF_PRIVATE_KEY (32u) +# define CRYPTO_30_LIBCV_SM2_SIZEOF_PUBLIC_KEY (64u) /* Size of the whole public key (X|Y) */ +# define CRYPTO_30_LIBCV_SM2_SIZEOF_PUBLIC_KEY_HALF (CRYPTO_30_LIBCV_SM2_SIZEOF_PUBLIC_KEY / 2u) +# define CRYPTO_30_LIBCV_SM2_SIZEOF_SIGNATURE (64u) /* Size of the whole signature (R|S) */ +# define CRYPTO_30_LIBCV_SM2_SIZEOF_SIGNATURE_HALF (CRYPTO_30_LIBCV_SM2_SIZEOF_SIGNATURE / 2u) +# define CRYPTO_30_LIBCV_SM2_MIN_SIZEOF_ID (1u) /* If an user ID KE is available it must not be empty */ +# define CRYPTO_30_LIBCV_SM2_MAX_SIZEOF_ID (8191u) /* The ID length is given to ESLib as 2byte parameter in bits */ + /* MAX_SIZEOF_ID = 2^16 / 8 - 1 */ + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + +# define Crypto_30_LibCv_NvM_Persist(idx) Crypto_30_LibCv_NvBlock_Write_Req(Crypto_30_LibCv_GetNvBlockIdxOfKey(idx)) + +# define Crypto_30_LibCv_IsLongTermWsLock(id, value) (Crypto_30_LibCv_GetLongTermWsLock((id)) == (value)) + +# define Crypto_30_LibCv_Uint8CheckMask(value, mask) (((value) & (mask)) == (mask)) +# define Crypto_30_LibCv_Uint8SetMask(value, mask) ((value) = (uint8)((value) | (mask))) +# define Crypto_30_LibCv_Uint8ClearMask(value, mask) ((value) = (uint8)((value) & (mask))) + +/* Macros for all elements */ +# define Crypto_30_LibCv_IsKeyElementPartial(Index) (Crypto_30_LibCv_IsPartialOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements((Index)))) +# define Crypto_30_LibCv_IsKeyElementPersist(Index) (Crypto_30_LibCv_IsPersistOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements((Index)))) +# define Crypto_30_LibCv_IsKeyElementWriteOnce(Index) (Crypto_30_LibCv_IsOnceOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements((Index)))) +# define Crypto_30_LibCv_GetKeyElementLength(Index) (Crypto_30_LibCv_GetLengthOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements((Index)))) +# define Crypto_30_LibCv_HasKeyElementInitValue(Index) (Crypto_30_LibCv_IsInitValueUsedOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements((Index)))) +# define Crypto_30_LibCv_GetKeyElementInitValueLength(Index) ((uint16)Crypto_30_LibCv_GetInitValueEndIdxOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements((Index))) - (uint16)Crypto_30_LibCv_GetInitValueStartIdxOfKeyElementInfo(Crypto_30_LibCv_GetKeyElementInfoIdxOfKeyElements(Index))) +# define Crypto_30_LibCv_IsKeyElementValid(Index) ((Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageValidIdxOfKeyElements((Index))) & CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_MASK) == CRYPTO_30_LIBCV_KEYELEMENTSTATE_VALID_MASK) +# define Crypto_30_LibCv_SetKeyElementState(Index, Value) (Crypto_30_LibCv_SetKeyStorage(Crypto_30_LibCv_GetKeyStorageValidIdxOfKeyElements((Index)), (Value))) +# define Crypto_30_LibCv_GetKeyElementState(Index) (Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageValidIdxOfKeyElements((Index)))) +# define Crypto_30_LibCv_ClearKeyElementStateByMask(Index, Mask) (Crypto_30_LibCv_SetKeyElementState((Index), (uint8)(Crypto_30_LibCv_GetKeyElementState((Index)) & (Mask)))) +# define Crypto_30_LibCv_SetKeyElementStateByMask(Index, Mask) (Crypto_30_LibCv_SetKeyElementState((Index), (uint8)(Crypto_30_LibCv_GetKeyElementState((Index)) | (Mask)))) +# define Crypto_30_LibCv_IsKeyElementStateByMask(Index, Mask) ((Crypto_30_LibCv_GetKeyElementState((Index)) & (uint8)(Mask)) == (Mask)) + +# define Crypto_30_LibCv_GetAddrKeyStorageOfKeyElements(Index) (Crypto_30_LibCv_GetAddrKeyStorage(Crypto_30_LibCv_GetKeyStorageStartIdxOfKeyElements(Index))) + +# define Crypto_30_LibCv_SetKeyElementExtension(Index, Value) (Crypto_30_LibCv_SetKeyStorage(Crypto_30_LibCv_GetKeyStorageExtensionIdxOfKeyElements((Index)), (Value))) +# define Crypto_30_LibCv_GetKeyElementExtension(Index) (Crypto_30_LibCv_GetKeyStorage(Crypto_30_LibCv_GetKeyStorageExtensionIdxOfKeyElements((Index)))) +# define Crypto_30_LibCv_ClearKeyElementExtensionByMask(Index, Mask) (Crypto_30_LibCv_SetKeyElementExtension((Index), (uint8)(Crypto_30_LibCv_GetKeyElementExtension((Index)) & (Mask)))) +# define Crypto_30_LibCv_SetKeyElementExtensionByMask(Index, Mask) (Crypto_30_LibCv_SetKeyElementExtension((Index), (uint8)(Crypto_30_LibCv_GetKeyElementExtension((Index)) | (Mask)))) +# define Crypto_30_LibCv_IsKeyElementExtensionByMask(Index, Mask) ((Crypto_30_LibCv_GetKeyElementExtension((Index)) & (uint8)(Mask)) == (Mask)) + +/* SheKeys */ +# define Crypto_30_LibCv_IsSheKey(Index) (Crypto_30_LibCv_IsKeyElementExtensionByMask((Index), CRYPTO_30_LIBCV_KEYELEMENTSEXTENSION_SHE_KEY_MASK)? TRUE : FALSE) + +/* Job mode macro */ +# define Crypto_30_LibCv_IsJobMode(Job, Mask) ((((Job)->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode) & (Mask)) == (Mask)) + +/* EcP Curves */ +# if ((CRYPTO_30_LIBCV_ECP256GENERATE == STD_ON) || (CRYPTO_30_LIBCV_ECP384GENERATE == STD_ON) || (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) || (CRYPTO_30_LIBCV_ECP521GENERATE == STD_ON)) +# define CRYPTO_30_LIBCV_ECPGENERATE STD_ON +# else +# define CRYPTO_30_LIBCV_ECPGENERATE STD_OFF +# endif + +# if ((CRYPTO_30_LIBCV_ECP256VERIFY == STD_ON) || (CRYPTO_30_LIBCV_ECP384VERIFY == STD_ON) || (CRYPTO_30_LIBCV_ECP160VERIFY == STD_ON) || (CRYPTO_30_LIBCV_ECP521VERIFY == STD_ON)) +# define CRYPTO_30_LIBCV_ECPVERIFY STD_ON +# else +# define CRYPTO_30_LIBCV_ECPVERIFY STD_OFF +# endif + +# if ((CRYPTO_30_LIBCV_SIGNATURE_GENERATE_SECFAM_SHA1 == STD_ON)||(CRYPTO_30_LIBCV_SIGNATURE_VERIFY_SECFAM_SHA1 == STD_ON)) +# define CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA1 STD_ON +# else +# define CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA1 STD_OFF +# endif + +# if ((CRYPTO_30_LIBCV_SIGNATURE_GENERATE_SECFAM_SHA2_256 == STD_ON)||(CRYPTO_30_LIBCV_SIGNATURE_VERIFY_SECFAM_SHA2_256 == STD_ON)) +# define CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA2_256 STD_ON +# else +# define CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA2_256 STD_OFF +# endif + +# if ((CRYPTO_30_LIBCV_SIGNATURE_GENERATE_SECFAM_SHA2_384 == STD_ON)||(CRYPTO_30_LIBCV_SIGNATURE_VERIFY_SECFAM_SHA2_384 == STD_ON)) +# define CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA2_384 STD_ON +# else +# define CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA2_384 STD_OFF +# endif + +# if ((CRYPTO_30_LIBCV_SIGNATURE_GENERATE_SECFAM_SHA2_512 == STD_ON)||(CRYPTO_30_LIBCV_SIGNATURE_VERIFY_SECFAM_SHA2_512 == STD_ON)) +# define CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA2_512 STD_ON +# else +# define CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA2_512 STD_OFF +# endif + +# if ((CRYPTO_30_LIBCV_SIGNATURE_GENERATE_SECFAM_SHA1 == STD_ON) || (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_SECFAM_SHA2_256 == STD_ON) || (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_SECFAM_SHA2_384 == STD_ON) || (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_SECFAM_SHA2_512 == STD_ON)) +# define CRYPTO_30_LIBCV_SIGNATURE_GENERATE_PRE_HASH STD_ON +# else +# define CRYPTO_30_LIBCV_SIGNATURE_GENERATE_PRE_HASH STD_OFF +# endif + +# if ((CRYPTO_30_LIBCV_SIGNATURE_VERIFY_SECFAM_SHA1 == STD_ON) || (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_SECFAM_SHA2_256 == STD_ON) || (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_SECFAM_SHA2_384 == STD_ON) || (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_SECFAM_SHA2_512 == STD_ON)) +# define CRYPTO_30_LIBCV_SIGNATURE_VERIFY_PRE_HASH STD_ON +# else +# define CRYPTO_30_LIBCV_SIGNATURE_VERIFY_PRE_HASH STD_OFF +# endif + +# if ((CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA1 == STD_ON) || (CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA2_256 == STD_ON) || (CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA2_384 == STD_ON) || (CRYPTO_30_LIBCV_SIGNATURE_SECFAM_SHA2_512 == STD_ON)) +# define CRYPTO_30_LIBCV_SIGNATURE_PRE_HASH STD_ON +# else +# define CRYPTO_30_LIBCV_SIGNATURE_PRE_HASH STD_OFF +# endif + +# if ((CRYPTO_30_LIBCV_KDF_ALGO_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_ANSIP256R1_ENABLED == STD_ON)\ + || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP256R1_ENABLED == STD_ON)) +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_P256R1_DOMAIN STD_ON +# else +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_P256R1_DOMAIN STD_OFF +# endif + +# if ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP521R1_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P521R1_ENABLED == STD_ON)) +/* max size of ECC key -> corresponding to curve -> p521r1 = 66Byte */ +# define CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE (CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE) + +# elif ((CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM_SECP384R1_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_NIST_SEC_P384R1_ENABLED == STD_ON)) +/* max size of ECC key -> corresponding to curve -> p384r1 = 48Byte */ +# define CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE (CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY_PRIVATE) + +# elif ((CRYPTO_30_LIBCV_KEY_EXCHANGE_P256R1_DOMAIN == STD_ON) || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM_ANSI_NIST_SEC_P256R1_ENABLED == STD_ON)) +/* max size of ECC key -> corresponding to curve -> p256r1 = 32Byte */ +# define CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE (CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE) + +# else +/* max size of ECC key -> corresponding to curve -> p224r1 = 28Byte */ +# define CRYPTO_30_LIBCV_ECC_PRIVATE_KEY_MAXSIZE (CRYPTO_30_LIBCV_SIZEOF_ECC_224_KEY_PRIVATE) +# endif + +/* Mathematic Operation Macros */ +# define Crypto_30_LibCv_Math_Mul2(Value) ((Value) << 1u) +# define Crypto_30_LibCv_Math_Div2(Value) ((Value) >> 1u) +# define Crypto_30_LibCv_Math_IsEven(Value) (((Value) & (1u)) == 0u) +# define Crypto_30_LibCv_Math_CalcMiddle(Value1, Value2) (((Value1) + (Value2)) / (uint8)2u) + +# define Crypto_30_LibCv_Byte2Bit(Byte) ((Byte) << 3u) +# define Crypto_30_LibCv_Bit2Byte(Bit) ((Bit) >> 3u) + +# define Crypto_30_LibCv_IsModulePartitionInitialized(partitionIdx) ((Crypto_30_LibCv_GetPartitionInitialized(partitionIdx) & CRYPTO_30_LIBCV_INITIALIZED) == CRYPTO_30_LIBCV_INITIALIZED) +# define Crypto_30_LibCv_IsModulePartitionNotInitialized(partitionIdx) ((Crypto_30_LibCv_GetPartitionInitialized(partitionIdx) & CRYPTO_30_LIBCV_INITIALIZED) != CRYPTO_30_LIBCV_INITIALIZED) +# define Crypto_30_LibCv_IsModuleSharedInitialized() ((Crypto_30_LibCv_ModuleInitialized & CRYPTO_30_LIBCV_INITIALIZED) == CRYPTO_30_LIBCV_INITIALIZED) +# define Crypto_30_LibCv_IsModuleSharedNotInitialized() ((Crypto_30_LibCv_ModuleInitialized & CRYPTO_30_LIBCV_INITIALIZED) != CRYPTO_30_LIBCV_INITIALIZED) +# define Crypto_30_LibCv_IsModuleBootProtected(value) (((value) & CRYPTO_30_LIBCV_BOOT_PROTECTED) == CRYPTO_30_LIBCV_BOOT_PROTECTED) +# define Crypto_30_LibCv_IsModuleDebuggerProtected(value) (((value) & CRYPTO_30_LIBCV_DEBUGGER_PROTECTED) == CRYPTO_30_LIBCV_DEBUGGER_PROTECTED) + +# define Crypto_30_LibCv_IsUint32Overflow(Value1, Value2) (((Value2) > (uint32)(CRYPTO_30_LIBCV_UINT32_MAX - Value1)) ? TRUE:FALSE ) + +/* Redirection */ +# define CRYPTO_30_LIBCV_NUM_OF_REDIRECTION_KEYS (5u) + +/* Key List */ +/* Keys need to be locked + * + * CryptoKey 1x + * TargetKey 1x + * RandomKey 1x + * RedirectionKeys 5x + */ +# if (CRYPTO_30_LIBCV_REDIRECTION == STD_ON) +/* Relevant Keys: CryptoKey, TargetKey, RandomKey, RedirectionKeys */ +/* Worst case number of Keys: 7x (Job target Key is only relevant if not all redirection keys are used)*/ +# define CRYPTO_30_LIBCV_MAX_NUM_OF_USED_KEYS (CRYPTO_30_LIBCV_NUM_OF_REDIRECTION_KEYS + 2u) +# else +/* Relevant Keys: CryptoKey, TargetKey, RandomKey */ +/* Worst case number of Keys: 3x */ +# define CRYPTO_30_LIBCV_MAX_NUM_OF_USED_KEYS (3u) +# endif + +# define CRYPTO_30_LIBCV_KEY_ACCESS_WRITE (1u) +# define CRYPTO_30_LIBCV_KEY_ACCESS_READ (0u) + +/* Multi Partition */ +# if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS > 1u) +# define Crypto_30_LibCv_CurrentPartitionIdx() Crypto_30_LibCv_GetPartitionIdx() +# define Crypto_30_LibCv_CurrentPartitionIdxViaObject(objectId) Crypto_30_LibCv_GetPartitionIdxOfObjectInfo(objectId) +# else +# define Crypto_30_LibCv_CurrentPartitionIdx() Crypto_30_LibCv_MainPartitionIdx +# define Crypto_30_LibCv_CurrentPartitionIdxViaObject(objectId) Crypto_30_LibCv_MainPartitionIdx +# endif + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +typedef Crypto_30_LibCv_SizeOfKeyStorageType Crypto_30_LibCv_KeyStorageIndexType; + +/* Read multiple key elements type definition */ +typedef struct +{ + uint32 keyElementId; + uint32 keyElementLength; + Crypto_30_LibCv_SizeOfKeyStorageType keyElementIndex; +} Crypto_30_LibCv_KeyElementGetType; + +typedef uint8 Crypto_30_LibCv_KeyElementGetSizeType; + +/* Length Check */ +typedef uint8 Crypto_30_LibCv_LengthCheckType; + +/* Service Check */ +typedef uint8 Crypto_30_LibCv_ServiceType; + +/* Key List */ +typedef struct +{ + uint32 keyId; + uint8 keyAccess; +} Crypto_30_LibCv_KeyLockKeyType; + +typedef struct +{ + Crypto_30_LibCv_KeyLockKeyType keyLockList[CRYPTO_30_LIBCV_MAX_NUM_OF_USED_KEYS]; + uint8 numKeys; +} Crypto_30_LibCv_KeyLockListType; + +# define CRYPTO_30_LIBCV_START_SEC_VAR_ZERO_INIT_8BIT +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_DEV_ERROR_DETECT == STD_ON) +/*! Initialization state of the module */ +extern VAR(uint8, CRYPTO_30_LIBCV_VAR_ZERO_INIT) Crypto_30_LibCv_ModuleInitialized; +# endif + +# define CRYPTO_30_LIBCV_STOP_SEC_VAR_ZERO_INIT_8BIT +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define CRYPTO_30_LIBCV_START_SEC_VAR_NOINIT_8BIT +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +# if (CRYPTO_30_LIBCV_SHE_DEBUG_CMD == STD_ON) +/* It is only allowed to access this data if the SheInfoKey is locked */ +extern VAR(boolean, CRYPTO_30_LIBCV_VAR_NOINIT) Crypto_30_LibCv_She_Debug_Cmd_ChallengeFlag; +# endif +# endif + +# define CRYPTO_30_LIBCV_STOP_SEC_VAR_NOINIT_8BIT +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define CRYPTO_30_LIBCV_START_SEC_VAR_NOINIT_16BIT +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define CRYPTO_30_LIBCV_STOP_SEC_VAR_NOINIT_16BIT +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Init_Key() + *********************************************************************************************************************/ +/*! \brief Initializes the key element. + * \details - + * \param[in] elementIndex Holds the pointer to the found key element index. + * \param[in] initAllBytes Decide if all data bytes shall be init. + * \pre Key is locked for write operations. + * Element index need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Init_Key( + Crypto_30_LibCv_KeyElementsIterType elementIndex, + boolean initAllBytes); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Init_KeySimple() + *********************************************************************************************************************/ +/*! \brief Initializes the key element. + * \details Initialize only written length, extension and status. + * \param[in] elementIndex Holds the pointer to the found key element index. + * \pre Key is locked for write operations. + * Element index need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Init_KeySimple( + Crypto_30_LibCv_KeyElementsIterType elementIndex); + +# if (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Init_KeySheAdditional() + *********************************************************************************************************************/ +/*! \brief Initializes the She key element. + * \details This function initializes additional fields for she keys. + * \param[in] elementIndex Holds the pointer to the found key element index. + * \pre Key is locked for write operations. + * Crypto_30_LibCv_Init_Key need to be called for complete key element initialization. + * Element index need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \note Specification of module initialization + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Init_KeySheAdditional( + Crypto_30_LibCv_KeyElementsIterType elementIndex); +# endif /* (CRYPTO_30_LIBCV_SHEKEYS == STD_ON) */ + +# if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_State_Init() + *********************************************************************************************************************/ +/*! \brief Init Nv State + * \details Init Nv state for the given block. + * \param[in] blockIdx idx of the block. + * \pre blockIdx need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_State_Init( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_MainFunction() + *********************************************************************************************************************/ +/*! \brief Nv main function of the module. + * \details This interface process the provided asynchronous NvBlock request / triggers write block. + * \pre - + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_MainFunction(void); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_ReadFromBlock() + **********************************************************************************************************************/ +/*!\brief Read from Block callback routine. + * \details Block specific callback routine which is called by NvM in order to let the Crypto driver copy data from + * NvM RAM mirror to Crypto RAM block. + * \param[in] blockIdx The internal identifier of the NvM block. + * \param[in] NvMBuffer RAM mirror where Ram block data can be read from. + * \return E_OK Data was copied from buffer. + * \return E_NOT_OK Data was not copied. + * \pre blockIdx need to be valid. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_ReadFromBlock( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2CONST(void, AUTOMATIC, CRYPTO_30_LIBCV_APPL_DATA) NvMBuffer); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_WriteToBlock() + **********************************************************************************************************************/ +/*!\brief Write to Block callback routine. + * \details Block specific callback routine which is called by NvM in order to let the Crypto driver copy data from + * RAM block to NvM RAM mirror. + * \param[in] blockIdx The internal identifier of the NvM block. + * \param[out] NvMBuffer RAM mirror where Ram block data shall be written to. + * \return E_OK Data was copied to buffer. + * \return E_NOT_OK No data was copied. + * \pre blockIdx need to be valid. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_WriteToBlock( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + P2VAR(void, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) NvMBuffer); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_Init() + **********************************************************************************************************************/ +/*!\brief Init Block callback routine. + * \details Block specific callback routine which is called by NvM in order to let the Crypto driver copy default + * data to a RAM block. + * \param[in] blockIdx The internal identifier of the NvM block. + * \return E_OK Data initialized. + * E_NOT_OK Any error occurred. + * \pre blockIdx need to be valid. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_Init( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_Callback() + **********************************************************************************************************************/ +/*!\brief Request finished Block callback routine. + * \details Block specific callback routine which is called by NvM in order to notify the Crypto driver that an + * asynchronous single block request has been finished. + * \param[in] blockIdx The internal identifier of the NvM block. + * \param[in] ServiceId The service identifier of the completed request. + * \param[in] JobResult Result of the single block job. + * \return E_OK Callback function has been processed successfully. + * \return E_NOT_OK Callback function has not been processed successfully. + * \pre blockIdx need to be valid. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_Callback( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx, + uint8 ServiceId, + NvM_RequestResultType JobResult); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_InitKey() + **********************************************************************************************************************/ +/*!\brief InitKey transition of KeyNvStatus. + * \details This transition is called if the module is initialized and sets the given key to state NOT_NV. + * \param[in] cryptoKeyId The identifier of the crypto key being initialized. + * \pre cryptoKeyId needs to be valid. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_InitKey(uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_ReadFromBlock() + **********************************************************************************************************************/ +/*!\brief ReadFromBlock transition of KeyNvStatus. + * \details This transition is called if a NvBlock has been read and sets all persistent keys of this block to + * state NV_SYNC. + * \param[in] blockIdx The internal identifier of the NvM block. + * \pre blockIdx needs to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_ReadFromBlock(Crypto_30_LibCv_SizeOfNvBlockType blockIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_KeyChanged_Unprotected() + **********************************************************************************************************************/ +/*!\brief KeyChanged transition of KeyNvStatus. + * \details If the changed key element is persistent, the key's state is set to KEY_CHANGED. + * This function shall only be called if EXCLUSIVE_AREA_0 has already been entered. + * \param[in] cryptoKeyId The identifier of the crypto key holding the changed key element. + * \param[in] elementIdx The identifier of the changed key element. + * \pre cryptoKeyId and elementIdx need to be valid. + * EXCLUSIVE_AREA_0 has been entered. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_KeyChanged_Unprotected(uint32 cryptoKeyId, Crypto_30_LibCv_SizeOfKeyElementsType elementIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_KeyChanged() + **********************************************************************************************************************/ +/*!\brief KeyChanged transition of KeyNvStatus. + * \details This transition is called if a key element was changed in validity or its data. It enters + * EXCLUSIVE_AREA_0 and calls the actual implementation of the transition. + * \param[in] cryptoKeyId The identifier of the crypto key holding the changed key element. + * \param[in] elementIdx The identifier of the changed key element. + * \pre cryptoKeyId and elementIdx need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_KeyChanged(uint32 cryptoKeyId, Crypto_30_LibCv_SizeOfKeyElementsType elementIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_NvWriteReq() + **********************************************************************************************************************/ +/*!\brief NvWriteReq transition of KeyNvStatus. + * \details This transition is called if a NvBlock was requested to write. All persistent and changed keys of + * this block are set to state NV_WRITE_REQ. + * \param[in] blockIdx The internal identifier of the NvM block. + * \pre blockIdx needs to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_NvWriteReq(Crypto_30_LibCv_SizeOfNvBlockType blockIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_NvCopied() + **********************************************************************************************************************/ +/*!\brief NvCopied transition of KeyNvStatus. + * \details This transition is called if the keys were copied to the NvM buffer. All persistent keys of this block + * which are of state NV_WRITE_REQ, are set to KEY_COPIED. + * \param[in] blockIdx The internal identifier of the NvM block. + * \pre blockIdx needs to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_NvCopied(Crypto_30_LibCv_SizeOfNvBlockType blockIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyNvStatus_NvBlockCallback() + **********************************************************************************************************************/ +/*!\brief NvBlockCallback transition of KeyNvStatus. + * \details This transition is called if the keys were written to the NvM buffer. All persistent keys of this block + * which are of state KEY_COPIED, are set to NV_WRITE_REQ. If the write process was not successful the + * keys are set to WRITE_FAILED. + * \param[in] blockIdx The internal identifier of the NvM block. + * \param[in] jobResult The result of the callback. + * \pre blockIdx and jobResult need to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyNvStatus_NvBlockCallback(Crypto_30_LibCv_SizeOfNvBlockType blockIdx, NvM_RequestResultType jobResult); + +# endif /* (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) */ + +# if (CRYPTO_30_LIBCV_USE_VSTD_LIB == STD_OFF) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_CopyData_Implementation() + *********************************************************************************************************************/ +/*! \brief Copies data from source to destination. + * \details Copies data from source to destination for the given length. Exemplary implementation. + * \param[out] targetData Pointer to buffer where the data shall be copied to + * \param[in] sourceData Pointer to data which shall be copied + * \param[in] dataLength Number of bytes which shall be copied + * \pre Length of the buffer provided by targetDataBuf can hold at least the number of bytes given in dataLength. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_CopyData_Implementation( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) targetData, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) sourceData, + uint32 dataLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_SetData_Implementation() + *********************************************************************************************************************/ +/*! \brief Sets data buffer. + * \details Sets data buffer for the given length with pattern value. Exemplary implementation. + * \param[out] dataBuf Pointer to data which shall be set. + * \param[in] pattern Holds the value which shall be set. + * \param[in] dataLength Number of bytes which shall be set. + * \pre Length of the buffer provided by targetDataBuf can hold at least the number of bytes given in dataLength. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_SetData_Implementation( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataBuf, + uint8 pattern, + uint32 dataLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_ClearData_Implementation() + *********************************************************************************************************************/ +/*! \brief Clears data buffer. + * \details Clears data buffer for the given length (overwrite with 0x00). Exemplary implementation. + * \param[out] dataBuf Pointer to data which shall be cleared + * \param[in] dataLength Number of bytes which shall be cleared + * \pre Length of the buffer provided by targetDataBuf can hold at least the number of bytes given in dataLength + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_ClearData_Implementation( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) dataBuf, + uint32 dataLength); +# endif /* # (CRYPTO_30_LIBCV_USE_VSTD_LIB == STD_OFF) */ + +# if ((CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_CompareData_IsSmaller() + *********************************************************************************************************************/ +/*! \brief Check if the target value is smaller than the reference value + * \details Compare data big-endian bytewise and check if the target value is smaller than the reference value. + * \param[in] targetData target value array in bigEndian format + * \param[in] referenceData reference value array in bigEndian format + * \param[in] dataLength compare length + * \return E_OK Target data is smaller. + * E_NOT_OK Target data is not smaller. + * \pre targetData has to be a valid array with the given dataLength. + * \pre referenceData has to be a valid array with the given dataLength. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_CompareData_IsSmaller( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) targetData, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) referenceData, + uint32 dataLength); +# endif /* ((CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_CERTIFICATE_HANDLING_ENABLED == STD_ON) || (CRYPTO_30_LIBCV_KDF_ALGO_ISO_15118_20_CERTIFICATE_HANDLING_ENABLED == STD_ON)) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Uint32ToUint8ArrayBigEndian() + *********************************************************************************************************************/ +/*! \brief Copies data from source to destination. + * \details Copies data from source to destination from uint32 to uint8 array big endian. + * \param[out] targetData Pointer to buffer where the data shall be copied to + * \param[in] sourceData Data which shall be copied + * \pre All pointers need to be valid. + * targetData need to have at least byte size of unit32. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_ALWAYS_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Uint32ToUint8ArrayBigEndian( + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) targetData, + uint32 sourceData); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian() + *********************************************************************************************************************/ +/*! \brief Copies data from source to destination. + * \details Copies data from source to destination from uint8 array to uint32 big endian. + * \param[out] targetData Pointer to buffer where the data shall be copied to + * \param[in] sourceData Pointer to data which shall be copied + * \pre All pointers need to be valid. + * sourceData need to have at least byte size of unit32. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_ALWAYS_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian( + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) targetData, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) sourceData); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyListAddKey() + **********************************************************************************************************************/ +/*! \brief Add Key to key list. + * \details Add key to keyList if the key is not in keyList. If the Key is in KeyList update keyAccess. + * \param[in,out] keyList Pointer to the keyList. + * \param[in] cryptoKeyId KeyId of the key which shall be add. + * \param[in] keyAccess Key access right of the key which shall be add. + * \pre keyList has to be a valid keyList object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyListAddKey( + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList, + uint32 cryptoKeyId, + uint8 keyAccess); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_GetKeyList() + **********************************************************************************************************************/ +/*! \brief Create list of keys. + * \details A key is only referenced once in the list with the highest access. + * \param[in] job Pointer to the job which shall checked. + * \param[in,out] keyList Pointer to the keyList. + * \pre job has to be a valid job object. + * keyList has to be a valid keyList object with at least 6 elements if redirection is used, otherwise 1. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_GetKeyList( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_GetKeyListAndDet() + **********************************************************************************************************************/ +/*! \brief Create list of keys and check if key exist. + * \details A key is only referenced once in the list with the highest access. + * \param[in] job Pointer to the job which shall checked. + * \param[in,out] keyList Pointer to the keyList. + * \return E_OK Request success. + * E_NOT_OK Request failed, since key id is not valid. + * \pre job has to be a valid job object. + * keyList has to be a valid keyList object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_GetKeyListAndDet( + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyListPreLockKeys() + **********************************************************************************************************************/ +/*! \brief Lock keys in key list. + * \details Lock keys in key list according to their read/write access. + * This access is not protected by a exclusive area. + * \param[in] keyList Pointer to the keyList. + * \return E_OK Request success. + * E_NOT_OK Request failed, since key is already locked. + * \pre keyList has to be a valid keyList object. + * The caller must ensure that this call is protected by a exclusive area. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyListPreLockKeys( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyListPostFreeKeys() + **********************************************************************************************************************/ +/*! \brief Free keys in key list. + * \details Free keys in key list according to their read/write access. + * This access is not protected by a exclusive area. + * \param[in] keyList Pointer to the keyList. + * \pre keyList has to be a valid keyList object. + * The caller must ensure that this call is protected by a exclusive area. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyListPostFreeKeys( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyListPreLockKeysProtected() + **********************************************************************************************************************/ +/*! \brief Lock keys in key list. + * \details Lock keys in key list according to their read/write access. + * \param[in] keyList Pointer to the keyList. + * \return E_OK Request success. + * E_NOT_OK Request failed, since key is already locked. + * \pre keyList has to be a valid keyList object. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyListPreLockKeysProtected( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyListPostFreeKeysProtected() + **********************************************************************************************************************/ +/*! \brief Free keys in key list. + * \details Free keys in key list according to their read/write access. + * \param[in] keyList Pointer to the keyList. + * \pre keyList has to be a valid keyList object. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyListPostFreeKeysProtected( + P2CONST(Crypto_30_LibCv_KeyLockListType, AUTOMATIC, AUTOMATIC) keyList); +# endif /* (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementSearch() + *********************************************************************************************************************/ +/*! \brief Searches the key elementIndex. + * \details Searches the key elementIndex of the given keyElementId in the given cryptoKeyId. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] keyElementId Holds the identifier of the key element which shall be set. + * \param[out] elementIndex Holds the pointer to the found key element index. + * \return E_OK Request successful. + * E_NOT_OK Request failed, key element not found. + * \pre cryptoKeyId has to be a valid identifier to a key in the keyStorage. + * elementIndex has to be a valid element index Ptr. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementSearch( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyElementsType, AUTOMATIC, AUTOMATIC) elementIndex); + +# if ((CRYPTO_30_LIBCV_KEY_DERIVE_ALGORITHM == STD_ON) || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementSet() + *********************************************************************************************************************/ +/*! \brief Sets a key element. This Api is only for internal usage. + * \details Sets the given key element bytes to the key identified by cryptoKeyId. + * If keyLength is zero the old value is deleted. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] keyElementId Holds the identifier of the key element which shall be set. + * \param[in] keyPtr Holds the pointer to the key data which shall be set as key element. + * \param[in] keyLength Contains the length of the key element in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre cryptoKeyId has to be a valid identifier to a key in the keyStorage. + * The crypto key has to be locked for write access. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementSet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength); +# endif /* ((CRYPTO_30_LIBCV_KEY_DERIVE_ALGORITHM == STD_ON) || (CRYPTO_30_LIBCV_KEY_EXCHANGE_ALGORITHM == STD_ON) || (CRYPTO_30_LIBCV_KEY_GENERATE_ALGORITHM == STD_ON)) */ + +# if (CRYPTO_30_LIBCV_NVBLOCK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_NvBlock_Write_Req() + **********************************************************************************************************************/ +/*! \brief Set write request. + * \details Set request wo write block. + * \param[in] blockIdx Holds the identifier of the nv block. + * \pre blockIdx has to be a valid identifier. + * \context TASK + * \reentrant TRUE, for different blocks. + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_NvBlock_Write_Req( + Crypto_30_LibCv_SizeOfNvBlockType blockIdx); +# endif + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetStorageIndex() + *********************************************************************************************************************/ +/*! \brief The key element can be provided for all read access rights values. + * \details This interface shall be used internal to get a key element of the key identified by the cryptoKeyId and store + * the key element in the memory location pointed to by the result pointer. + * \param[in] cryptoKeyId Holds the identifier of the key element storage index. + * \param[in] keyElementId Holds the identifier of the key element which shall be set. + * \param[in,out] resultIndexPtr Holds the pointer to the key data which shall be set as key element. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \param[in] lengthCheck Length check mode. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid identifier to a key in the keyStorage. + * The crypto key has to be locked for read access. + * resultIndexPtr has to be a valid ptr. + * resultLengthPtr has to be a valid ptr. + * \context TASK + * \reentrant TRUE, for different crypto keys. + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetStorageIndex( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_GetElementsIndexJob() + *********************************************************************************************************************/ +/*! \brief Get the key element storage index for all key elements in the list used for Job Processing. + * \details The function will provide the storage index of all required key elements. + * The function return values can be passed to process job. + * If the request fails the function return the first error also if there are several. + * \param[in] cryptoKeyId Holds the identifier of the key element storage index. + * \param[in,out] keyElements Holds the pointer to the key elements structure. + * \param[in] numberOfElements Holds the total number of key elements contained in keyElements. + * \param[in] lengthCheck Length check mode. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid identifier to a key in the keyStorage. + * The crypto key has to be locked for read access. + * keyElements has to be a valid ptr with the number of numberOfElements elements. + * \context TASK + * \reentrant TRUE, for different crypto keys. + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_GetElementsIndexJob( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_KeyElementGetType, AUTOMATIC, AUTOMATIC) keyElements, + Crypto_30_LibCv_KeyElementGetSizeType numberOfElements, + Crypto_30_LibCv_LengthCheckType lengthCheck); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_ElementGetterSetId() + **********************************************************************************************************************/ +/*! \brief Set key element id in keyElements structure. + * \details - + * \param[in,out] keyElements Holds the pointer to the key elements structure. + * \param[in] elementNumber Holds the total number of the key element which shall be accessed. + * \param[in] keyElementId Holds the key element id which shall be set. + * \pre keyElements has to be a valid ptr with at least the length of elementNumber elements. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_ElementGetterSetId( + P2VAR(Crypto_30_LibCv_KeyElementGetType, AUTOMATIC, AUTOMATIC) keyElements, + Crypto_30_LibCv_KeyElementGetSizeType elementNumber, + uint32 keyElementId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_ElementGetterSetIdAndLength() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +/*! \brief Set key element id and expected length in keyElements structure. + * \details - + * \param[in,out] keyElements Holds the pointer to the key elements structure. + * \param[in] elementNumber Holds the total number of the key element which shall be accessed. + * \param[in] keyElementId Holds the key element id which shall be set. + * \param[in] keyLength Holds the key element expected length which shall be set. + * \pre keyElements has to be a valid ptr with at least the length of elementNumber elements. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_ElementGetterSetIdAndLength( + P2VAR(Crypto_30_LibCv_KeyElementGetType, AUTOMATIC, AUTOMATIC) keyElements, + Crypto_30_LibCv_KeyElementGetSizeType elementNumber, + uint32 keyElementId, + uint32 keyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional() + *********************************************************************************************************************/ +/*! \brief Get the key element storage index for an optional key element used for Job Processing. + * \details The function will provide the storage index of the required key element. + * The function return values can be passed to process job expect CRYPTO_E_KEY_NOT_AVAILABLE. + * \param[in] cryptoKeyId Holds the identifier of the key element storage index. + * \param[in] keyElementId Holds the identifier of the key element which shall be set. + * \param[in,out] resultIndexPtr Holds the pointer to the key data which shall be set as key element. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \param[in] lengthCheck Length check mode. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid identifier to a key in the keyStorage. + * The crypto key has to be locked for read access. + * resultIndexPtr has to be a valid ptr. + * resultLengthPtr has to be a valid ptr. + * \context TASK + * \reentrant TRUE, for different crypto keys. + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob() + *********************************************************************************************************************/ +/*! \brief Get the key element storage index for a key element used for Job Processing. + * \details The function will provide the storage index of the required key element. + * The function return values can be passed to process job. + * \param[in] cryptoKeyId Holds the identifier of the key element storage index. + * \param[in] keyElementId Holds the identifier of the key element which shall be set. + * \param[in,out] resultIndexPtr Holds the pointer to the key data which shall be set as key element. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \param[in] lengthCheck Length check mode. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid identifier to a key in the keyStorage. + * The crypto key has to be locked for read access. + * resultIndexPtr has to be a valid ptr. + * resultLengthPtr has to be a valid ptr. + * \context TASK + * \reentrant TRUE, for different crypto keys. + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended() + *********************************************************************************************************************/ +/*! \brief The key element storage index can be provided for all read access rights values. + * \details This interface shall be used internal to get a key element of the key identified by the + * cryptoKeyId and store the key element in the memory location pointed to by the result pointer. + * The key element will be searched and checked vor validity. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be provided. + * \param[in] keyElementId Holds the Id of the key element which shall be provided. + * \param[in,out] resultIndexPtr Holds the pointer to the storage index which shall be provided. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \param[in] lengthCheck Length check mode. + * \param[in] serviceType SHE service Type. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre cryptoKeyId has to be a valid identifier to a key in the keyStorage. + * The crypto key has to be locked for read access. + * resultIndexPtr has to be a valid ptr. + * resultLengthPtr has to be a valid ptr. + * \context TASK + * \reentrant TRUE, for different crypto keys. + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetStorageIndexExtended( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck, + Crypto_30_LibCv_ServiceType serviceType); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic() + *********************************************************************************************************************/ +/*! \brief The key element storage index can be provided for all read access rights values. + * \details This interface shall be used internal to get a key element of the key identified by the + * cryptoKeyId and store the key element in the memory location pointed to by the result pointer. + * The key element will not be checked for validity. + * \param[in] elementIndex Holds the index of the key element which shall be provided. + * \param[in,out] resultIndexPtr Holds the pointer to the storage index which shall be provided. + * \param[in,out] resultLengthPtr Contains the length of the key element in bytes. + * \param[in] lengthCheck Length check mode. + * \param[in] serviceType SHE service Type. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre elementIndex has to be a valid identifier to a key in the keyStorage. + * The crypto key has to be locked for read access. + * resultIndexPtr has to be a valid ptr. + * resultLengthPtr has to be a valid ptr. + * \context TASK + * \reentrant TRUE, for different crypto keys. + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementGetStorageIndexBasic( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) resultIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) resultLengthPtr, + Crypto_30_LibCv_LengthCheckType lengthCheck, + Crypto_30_LibCv_ServiceType serviceType); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyElementSetInternal() + *********************************************************************************************************************/ +/*! \brief Sets a key element. This Api is only for internal usage. + * \details Sets the given key element bytes to the key identified by cryptoKeyId. + * If keyLength is zero the old value is deleted. + * \param[in] cryptoKeyId Holds the identifier of the key storage index. + * \param[in] elementIndex Holds the index of the key element which shall be set. + * \param[in] keyPtr Holds the pointer to the key data which shall be set as key element. + * \param[in] keyLength Contains the length of the key element in bytes. + * \param[in] writeAccess Hold the max write access right which could be accessed. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre cryptoKeyId has to be a valid identifier to a key in the keyStorage. + * elementIndex has to be a valid identifier to a keyElement in the keyStorage. + * The crypto key has to be locked for write access. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyElementSetInternal( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength, + Crypto_30_LibCv_WriteOfKeyElementInfoType writeAccess); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementSetInternalStandard() + *********************************************************************************************************************/ +/*! \brief Copies data to key storage. + * \details Copies data of the keyPtr to the internal key storage identified by the elementIndex. + * If keyLength is zero the old value is deleted. + * \param[in] elementIndex Holds the identifier of the keyElement in the keyStorage. + * \param[in] keyPtr Holds the data which shall be copied to the key storage + * \param[in] keyLength Specifies the number of bytes which shall be copied. + * \return E_OK Request successful. + * E_NOT_OK Request failed, keyElement was written, but connected key not found. + * \pre elementIndex has to be a valid identifier to a keyElement in the keyStorage. + * keyLength has to be smaller or equal in length to available key storage space. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementSetInternalStandard( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_KeyElementSetInternalStandardWithCryptoKeyId() + *********************************************************************************************************************/ +/*! \brief Copies data to key storage. + * \details Copies data of the keyPtr to the internal key storage identified by the elementIndex. + * If keyLength is zero the old value is deleted. + * \param[in] cryptoKeyId Holds the identifier of the key storage index. + * \param[in] elementIndex Holds the identifier of the keyElement in the keyStorage. + * \param[in] keyPtr Holds the data which shall be copied to the key storage + * \param[in] keyLength Specifies the number of bytes which shall be copied. + * \pre cryptoKeyId has to be a valid identifier to a key in the keyStorage. + * elementIndex has to be a valid identifier to a keyElement in the keyStorage. + * keyPtr has to be a valid ptr. + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_KeyElementSetInternalStandardWithCryptoKeyId( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) keyPtr, + uint32 keyLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SetKeyElementWrittenLength() + *********************************************************************************************************************/ +/*! \brief Sets the key element written length. + * \details Sets the written length of a key element in the key storage. + * Note: This function does not track the key change regarding KeyNvStatus and the key changed callout. Use + * Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId instead or call the + * KeyChanged transition of the CryptoKey and the callout manually. + * \param[in] keyElementIndex Holds the index of the key element whose written length shall be set. + * \param[in] keyElementLength Written length of the key element + * \pre keyElementId has to hold a valid identifier of the key element + * \note This function does not call the callout for the key value changed + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SetKeyElementWrittenLength( + Crypto_30_LibCv_SizeOfKeyElementsType keyElementIndex, + uint32 keyElementLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyIdSearch() + *********************************************************************************************************************/ +/*! \brief Sets the key element written length. + * \details Sets the written length of a key element in the keystore and searches the crypto key ID + * to call the callout to change the key value. + * \param[in] keyElementIndex Holds the index of the key element whose written length shall be set. + * \param[in] keyElementLength Written length of the key element + * \return E_OK Request successful. + * E_NOT_OK Request failed, key not found. + * \pre keyElementId has to hold a valid identifier of the key element + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyIdSearch( + Crypto_30_LibCv_SizeOfKeyElementsType keyElementIndex, + uint32 keyElementLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId() + *********************************************************************************************************************/ +/*! \brief Sets the key element written length. + * \details Sets the written length of a key element in the key storage. + * \param[in] cryptoKeyId Holds the id of the key. + * \param[in] keyElementIndex Holds the index of the key element whose written length shall be set. + * \param[in] keyElementLength Written length of the key element + * \pre cryptoKeyId has to be a valid identifier to a key in the keyStorage. + * keyElementId has to hold a valid identifier of the key element + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SetKeyElementWrittenLengthWithCryptoKeyId( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfKeyElementsType keyElementIndex, + uint32 keyElementLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_SetKeyElementStateWritten() + **********************************************************************************************************************/ +/*! \brief Sets the key element state for a written key element. + * \details Sets the state to invalid and write once if required. + * \param[in] elementIndex Holds the index of the key element whose written length shall be set. + * \pre keyElementId has to hold a valid identifier of the key element + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_SetKeyElementStateWritten( + Crypto_30_LibCv_SizeOfKeyElementsType elementIndex); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Internal_KeySetValid() + *********************************************************************************************************************/ +/*! \brief Sets the state of a key. + * \details The function the key states of all associated key elements of the given key to valid. + * \param[in] cryptoKeyId Holds the identifier of the key. + * \return TRUE Request NvM Write. + * FALSE No writing necessary. + * \pre cryptoKeyId has to hold a valid identifier of a key + * \context TASK + * \reentrant TRUE, for different cryptoKeyIds + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Internal_KeySetValid( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Internal_KeySetInvalid() + *********************************************************************************************************************/ +/*! \brief Sets the given key invalid. + * \details The function the key states of all associated key elements of the given key to invalid. + * \param[in] cryptoKeyId Holds the identifier of the key. + * \return TRUE Request NvM Write. + * FALSE No writing necessary. + * \pre cryptoKeyId has to hold a valid identifier of a key + * \context TASK + * \reentrant TRUE, for different cryptoKeyIds + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Internal_KeySetInvalid( + uint32 cryptoKeyId); + +# if (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyReadLockGet() + *********************************************************************************************************************/ +/*! + * \brief Try to get key read lock. + * \details Try to get a key read lock. Increment the key read lock, if there is no write lock. + * \param[in] cryptoKeyId Id of the crypto key. + * \return E_OK Lock key read access success. + * E_NOT_OK Lock key read access failed. + * \pre cryptoKeyId Has to hold a valid identifier of a key. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyReadLockGet( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyReadLockRelease() + *********************************************************************************************************************/ +/*! + * \brief Release key read lock. + * \details Release key read lock. Decrement the key read lock. + * \param[in] cryptoKeyId Id of the crypto key. + * \pre cryptoKeyId Has to hold a valid identifier of a key. + * The caller has to ensure that the key is locked for read access. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyReadLockRelease( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyReadLockGetNotProtected() + *********************************************************************************************************************/ +/*! + * \brief Try to get key read lock. + * \details This access is not protected by a exclusive area. + * \param[in] cryptoKeyId Id of the crypto key. + * \return E_OK Lock key read access success. + * E_NOT_OK Lock key read access failed. + * \pre cryptoKeyId Has to hold a valid identifier of a key. + * The caller has to ensure that this call is protected by a exclusive area. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyReadLockGetNotProtected( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected() + *********************************************************************************************************************/ +/*! + * \brief Release key read lock. + * \details This access is not protected by a exclusive area. + * \param[in] cryptoKeyId Id of the crypto key. + * \pre cryptoKeyId Has to hold a valid identifier of a key. + * The caller has to ensure that this call is protected by a exclusive area. + * The caller has to ensure that the key is locked for read access. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyReadLockReleaseNotProtected( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyWriteLockGet() + *********************************************************************************************************************/ +/*! + * \brief Try to get key write lock. + * \details Try to get key write lock. Only one write lock can be allocated, if there is no read lock. + * \param[in] cryptoKeyId Id of the crypto key. + * \return E_OK Lock key write access success. + * E_NOT_OK Lock key write access failed. + * \pre cryptoKeyId Has to hold a valid identifier of a key. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyWriteLockGet( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyWriteLockRelease() + *********************************************************************************************************************/ +/*! + * \brief Release key write lock. + * \details Release key write lock. Only one write lock can be allocated. + * \param[in] cryptoKeyId Id of the crypto key. + * \pre cryptoKeyId Has to hold a valid identifier of a key. + * The caller has to ensure that the key is locked for write access. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyWriteLockRelease( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected() + *********************************************************************************************************************/ +/*! + * \brief Try to get key write lock. + * \details Try to get key write lock. Only one write lock can be allocated, if there is no read lock. + * \param[in] cryptoKeyId Id of the crypto key. + * \return E_OK Lock key write access success. + * E_NOT_OK Lock key write access failed. + * The caller has to ensure that this call is protected by a exclusive area. + * \pre cryptoKeyId Has to hold a valid identifier of a key. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyWriteLockGetNotProtected( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected() + *********************************************************************************************************************/ +/*! + * \brief Release key write lock. + * \details Release key write lock. Only one write lock can be allocated. + * \param[in] cryptoKeyId Id of the crypto key. + * \pre cryptoKeyId Has to hold a valid identifier of a key. + * The caller has to ensure that this call is protected by a exclusive area. + * The caller has to ensure that the key is locked for write access. + * \context TASK + * \reentrant TRUE, for different keys + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_KeyWriteLockReleaseNotProtected( + uint32 cryptoKeyId); +# endif /* (CRYPTO_30_LIBCV_ENABLE_KEY_LOCKING == STD_ON) */ + +# if (CRYPTO_30_LIBCV_LONGTERMWS == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_LongWsLockGet() + **********************************************************************************************************************/ +/*! \brief Try to obtain long term workspace lock. + * \details This function tries to lock the long term workspace and determines the workspace idx. + * \param[in] cryptoKeyId Holds the key id which will lock the workspace + * \param[out] longWsIdxPtr Provided long term workspace idx. + * \return E_OK Lock is obtained or was already obtained. + * E_NOT_OK Request Failed + * \pre longWsIdxPtr has to be a valid pointer. + * \note Is a lock is already occupied for the key id the service will return this Idx. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_LongWsLockGet( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_SizeOfLongTermWsLockType, AUTOMATIC, AUTOMATIC) longWsIdxPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_LongWsIsLock() + **********************************************************************************************************************/ +/*! \brief Check if long term workspace is locked. + * \details This function checks if the long term workspace is locked and provides the workspace idx. + * \param[in] cryptoKeyId Holds the key id which will lock the workspace + * \param[out] longWsIdxPtr Provided long term workspace idx. + * \return E_OK Lock is obtained or was already obtained. + * E_NOT_OK Request Failed + * \pre longWsIdxPtr has to be a valid pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_LongWsIsLock( + uint32 cryptoKeyId, + P2VAR(Crypto_30_LibCv_SizeOfLongTermWsLockType, AUTOMATIC, AUTOMATIC) longWsIdxPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_LongWsLockRelease() + **********************************************************************************************************************/ +/*! \brief Release long term workspace lock. + * \details - + * \param[in] cryptoKeyId Holds the key id which will lock the workspace + * \param[in] longWsIdx Holds the long term workspace idx. + * \pre longWsIdx has to be a valid index. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_LongWsLockRelease( + uint32 cryptoKeyId, + Crypto_30_LibCv_SizeOfLongTermWsLockType longWsIdx); +# endif /* (CRYPTO_30_LIBCV_LONGTERMWS == STD_ON) */ + +# if (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_ObjectWorkspaceHasChanged() + *********************************************************************************************************************/ +/*! \brief Check if the driver object workspace type has changed. + * \details - + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in] job Pointer to the job which shall be dispatched. + * \return TRUE The object workspace has changed. + * FALSE The object workspace is the same as in the last job. + * \pre objectId has to be a valid driver object handle. + * job has to be a valid job object handle. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(boolean, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_ObjectWorkspaceHasChanged( + uint32 objectId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_ClearObjectWorkspaceForChangedKey() + *********************************************************************************************************************/ +/*! \brief Clear the last driver object workspace type for all driver objects which the given key was used. + * \details - + * \param[in] cryptoKeyId Id of the crypto key. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre cryptoKeyId Has to hold a valid identifier of a key. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_ClearObjectWorkspaceForChangedKey( + uint32 cryptoKeyId); +# endif /* (CRYPTO_30_LIBCV_CMAC_AES_ROUNDKEY_REUSE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_NUMBER_OF_PARTITIONS > 1u) +/********************************************************************************************************************** + * Crypto_30_LibCv_GetPartitionIdx() + *********************************************************************************************************************/ +/*! \brief Returns the current active partition idx. + * \details - + * \return Current partition idx if called by configured application, + * Size of known partitions if called by unknown application + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(uint32, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_GetPartitionIdx(void); +# endif + +/********************************************************************************************************************** + * Crypto_30_LibCv_MainFunctionHandler() + *********************************************************************************************************************/ +/*! + * \brief Handles the MainFunctions for the different partitions. + * \details Is called cyclically and handles asynchronous jobs from the queue. + * \param[in] partitionIdx Valid partitionIdx + * \pre - + * \context TASK + * \reentrant TRUE for different partitionIdx + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_MainFunctionHandler(uint32 partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_InitMemoryHandler() + *********************************************************************************************************************/ +/*! \brief The function initializes variables, which cannot be initialized with the startup code. + * \details Initialize component variables at power up. + * It should be called once from each partition where the module is used. + * \param[in] partitionIdx Valid partitionIdx + * \pre Module is uninitialized. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_InitMemoryHandler(uint32 partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Uint32ToUint8ArrayBigEndian() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_ALWAYS_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Uint32ToUint8ArrayBigEndian( /* PRQA S 3219 */ /* MD_CRYPTO_30_LIBCV_3219 */ + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) targetData, + uint32 sourceData) +{ + targetData[0] = (uint8)(((sourceData)& 0xff000000u) >> 24); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + targetData[1] = (uint8)(((sourceData)& 0x00ff0000u) >> 16); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + targetData[2] = (uint8)(((sourceData)& 0x0000ff00u) >> 8); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ + targetData[3] = (uint8)(((sourceData)& 0x000000ffu)); /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ +} + +/********************************************************************************************************************** + * Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_ALWAYS_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Local_Uint8ArrayToUint32BigEndian( /* PRQA S 3219 */ /* MD_CRYPTO_30_LIBCV_3219 */ + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) targetData, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) sourceData) +{ + *targetData = ((((uint32)sourceData[0]) & 0x000000FFu) << 24) | ((((uint32)sourceData[1]) & 0x000000FFu) << 16) | ((((uint32)sourceData[2]) & 0x000000FFu) << 8) | (((uint32)sourceData[3]) & 0x000000FFu); /* PRQA S 2985 */ /* MD_CRYPTO_30_LIBCV_2985 */ /* SBSW_CRYPTO_30_LIBCV_API_CHECKED_SIZE_ACCESS */ +} + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* CRYPTO_30_LIBCV_SERVICES_H */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Services.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Signature.c b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Signature.c new file mode 100644 index 0000000..57ad5ae --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_Signature.c @@ -0,0 +1,6445 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_Signature.c + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Implementation for SIGNATURE Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_SIGNATURE_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Crypto_30_LibCv.h" +#include "Crypto_30_LibCv_Services.h" +#include "Crypto_30_LibCv_Curve.h" +#include "Crypto_30_LibCv_SignatureGenerate.h" +#include "Crypto_30_LibCv_SignatureVerify.h" +#include "Crypto_30_LibCv_Hash.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/* RSA */ +#define CRYPTO_30_LIBCV_RSA_SALT_LENGTH_SIZE (2u) +#define CRYPTO_30_LIBCV_SIGNATURE_RSA_PSS_SALT_SIZE_AUTO_CALC (-1) + +/* Pre-Hash */ +#define CRYPTO_30_LIBCV_PREHASH_DIGEST_MAXSIZE ESL_SIZEOF_SHA512_DIGEST +#define CRYPTO_30_LIBCV_VSECPRIM_HASH_ALGO_INVALID (0xFFu) + +#define CRYPTO_E_PARAM_HANDLE_CUSTOM (0x0Fu) + +#define Crypto_30_LibCv_GetUint16(hiByte, loByte) ((uint16)((((uint16)(hiByte)) << 8) | ((uint16)(loByte)))) + +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_LIBCV_START_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if ((CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) +# if (CRYPTO_30_LIBCV_SIGNATURE_PRE_HASH == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_PreHashStart() + *********************************************************************************************************************/ +/*! + * \brief pre-hashing start mode. + * \details This function dispatches and executes the pre-hashing for the required job. + * \param[in,out] wsHash Pointer to the vSecPrim hash workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre job has to be a pointer to a valid job object. + * wsHash has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_PreHashStart( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsHash, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_PreHashUpdate() + *********************************************************************************************************************/ +/*! + * \brief pre-hashing update mode. + * \details This function dispatches and executes the pre-hashing for the required job. + * \param[in,out] wsHash Pointer to the vSecPrim hash workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre job has to be a pointer to a valid job object. + * wsHash has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_PreHashUpdate( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsHash, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_PreHashFinish() + *********************************************************************************************************************/ +/*! + * \brief pre-hashing finish mode. + * \details This function dispatches and executes the pre-hashing for the required job. If no pre-hashing + * is required the input data is copied to the hashPtr. + * \param[in,out] wsHash Pointer to the vSecPrim hash workspace. + * \param[out] hashPtr Pointer to the hash. + * \param[in,out] hashLengthPtr Pointer to the hash length. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre job has to be a pointer to a valid job object. + * wsHash has to be valid. + * hashPtr has to be valid pointer with the length of the hashLengthPtr value. + * hashLengthPtr has to be valid pointer. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_PreHashFinish( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsHash, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) hashPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) hashLengthPtr); +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_PRE_HASH == STD_ON) */ +#endif /* ((CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateStart() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime generate job in start mode to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workSpace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateStart( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateUpdate() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime generate job in update mode to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workSpace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre job has to be a job object handle. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateUpdate( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_EccPrimeGenerateSignature_SignData() + *********************************************************************************************************************/ +/*! + * \brief Calls the lower layer to compute the signature based on the provided domain parameters. + * \details This function retrieves the private key and passes the domain parameters, the key + * and the message to the crypto library to compute the ECDSA signature. + * \param[in,out] job Pointer to the job which is dispatched. + * \param[in,out] workSpace Pointer to the esl workspace. + * \param[in] EcDomainPtr Pointer to the curve domain parameters + * \param[in] EcDomainExtPtr Pointer to the curve domain extension parameters + * \param[in] EcSpeedUpExtPtr Pointer to the curve speed up extension parameters + * \param[in] expectedKeyLength Expected length of the private key for signature generation + * \param[in] messagePtr Pointer to the plain message. + * \param[in] messageLength Length of the plain message. + * \return E_OK Signature computation was successful. + * E_NOT_OK Signature computation failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre job has to be a pointer to a valid job object. + * workSpace has to be valid. + * messagePtr has to be valid ptr with the length messageLength. + * All other provided pointers have to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_EccPrimeGenerateSignature_SignData( + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcSpeedUpExtPtr, + uint32 expectedKeyLength, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) messagePtr, + uint32 messageLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_EccPrimeGenerateSignature_ConvertSignatureForOutputBuffer() + *********************************************************************************************************************/ +/*! + * \brief Processes the signature output of the lower layer. + * \details This function processes the signature output of the crypto library and writes the signature parts + * to the job's output parameter. + * \param[in,out] job Pointer to the job which is dispatched. + * \param[in] sigLength Maximum length of one signature component. + * \param[in] doubleSigLength Twice the maximum length of one signature component. + * \param[in] sigLengthR Length of signature component r. + * \param[in] sigLengthS Length of signature component s. + * \param[in] expectedKeyLength Expected length of the private key for signature generation + * \param[in] signatureR Pointer to the buffer storing the r component of the signature. + * \param[in] signatureS Pointer to the buffer storing the s component of the signature. + * \return E_OK Signature post-processing was successful. + * E_NOT_OK Signature post-processing failed. + * \pre job has to be a pointer to a valid job object. + * workSpace has to be valid. + * messagePtr has to be valid ptr with the length messageLength. + * All other provided pointers have to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_EccPrimeGenerateSignature_ConvertSignatureForOutputBuffer( + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + eslt_Length sigLength, + eslt_Length doubleSigLength, + eslt_Length sigLengthR, + eslt_Length sigLengthS, + uint32 expectedKeyLength, + P2CONST(eslt_Byte, AUTOMATIC, AUTOMATIC) signatureR, + P2CONST(eslt_Byte, AUTOMATIC, AUTOMATIC) signatureS); + +/********************************************************************************************************************** + * Crypto_30_LibCv_EccPrimeGenerateSignature() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime generate job in finish mode to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] messagePtr Pointer to the plain message. + * \param[in] messageLength Length of the plain message. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre job has to be a pointer to a valid job object. + * workSpace has to be valid. + * messagePtr has to be valid ptr with the length messageLength. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_EccPrimeGenerateSignature( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) messagePtr, + uint32 messageLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateFinish() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime generate job in finish mode to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre job has to be a pointer to a valid job object. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateFinish( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyStart() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime verify job in start mode to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workSpace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workSpace has to be valid. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyStart( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyUpdate() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime verify job in update mode to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workSpace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre job has to be a pointer to a valid job object. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyUpdate( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish_CvOperation() + *********************************************************************************************************************/ +/*! + * \brief Calls the lower layer to verify the signature based on the provided domain parameters. + * \details This function retrieves the public key for signature verification and passes the + * domain parameters and the message to the crypto library to verify the ECDSA signature. + * \param[in,out] job Pointer to the job which is dispatched. + * \param[in,out] workSpace Pointer to the esl workspace. + * \param[in] EcDomainPtr Pointer to the curve domain parameters + * \param[in] EcDomainExtPtr Pointer to the curve domain extension parameters + * \param[in] messagePtr Pointer to the plain message. + * \param[in] messageLength Length of the plain message. + * \return E_OK Signature verification was successful. + * E_NOT_OK Signature verification failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre job has to be a pointer to a valid job object. + * workSpace has to be valid. + * messagePtr has to be valid ptr with the length messageLength. + * All other provided pointers have to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish_CvOperation( + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) messagePtr, + uint32 messageLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime verify job in finish mode to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workSpace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre job has to be a pointer to a valid job object. + * workSpace has to be valid. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_RSAVERIFY == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureVerifyResult() + *********************************************************************************************************************/ +/*! + * \brief Dispatch the return value of the verification function. + * \details This functions handles the return value of the verification function and set the result to the corresponding result ptr. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] retValCv Return value of the verification function. + * \param[in] signatureInvalidValue Expected value for a invalid signature. + * \return ESL_ERC_ERROR Dispatching was successful and verification failed. + * ESL_ERC_NO_ERROR Dispatching was successful and verification successful. + * \pre job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureVerifyResult( + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + eslt_ErrorCode retValCv, + eslt_ErrorCode signatureInvalidValue); +#endif /* ((CRYPTO_30_LIBCV_RSAVERIFY == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1GenerateStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for RSA PKCS1 signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre workspace has to be a valid eslt_WorkSpaceRSAsig handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1GenerateStart( + P2VAR(eslt_WorkSpaceRSAsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1GenerateUpdate() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode update for RSA PKCS1 signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceRSAsig handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1GenerateUpdate( + P2VAR(eslt_WorkSpaceRSAsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1GenerateFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode finish for RSA PKCS1 signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceRSAsig handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1GenerateFinish( + P2VAR(eslt_WorkSpaceRSAsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1VerifyStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for RSA PKCS1 signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre workspace has to be a valid eslt_WorkSpaceRSAver handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1VerifyStart( + P2VAR(eslt_WorkSpaceRSAver, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1VerifyUpdate() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode update for RSA PKCS1 signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceRSAver handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1VerifyUpdate( + P2VAR(eslt_WorkSpaceRSAver, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1VerifyFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode finish for RSA PKCS1 signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceRSAver handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1VerifyFinish( + P2VAR(eslt_WorkSpaceRSAver, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPSSGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssGenerateStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for RSA PSS signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre workspace has to be a valid eslt_WorkSpaceRSAPSSsig handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssGenerateStart( + P2VAR(eslt_WorkSpaceRSAPSSsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssGenerateUpdate() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode update for RSA PSS signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre workspace has to be a valid eslt_WorkSpaceRSAPSSsig handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssGenerateUpdate( + P2VAR(eslt_WorkSpaceRSAPSSsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssGenerateFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode finish for RSA PSS signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre workspace has to be a valid eslt_WorkSpaceRSAPSSsig handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssGenerateFinish( + P2VAR(eslt_WorkSpaceRSAPSSsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_RSAPSSGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPSSVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SignatureRsaPssVerifyGetKeyElements() + *********************************************************************************************************************/ +/*! + * \brief Load all required key elements and handle return values for RSA Pss verify. + * \details This function load the required key elements and handles the return values. + * \param[in] cryptoKeyId Id of the crypto key. + * \param[out] saltLengthPtr Pointer to where the salt length should be stored. + * \param[out] SigExponentIndexPtr Holds the index to the key data which shall be set as key element. + * \param[in,out] SigExponentLength Contains the length of the key element in bytes. + * \param[out] SigModulusIndexPtr Holds the index to the key data which shall be set as key element. + * \param[in,out] SigModulusLength Contains the length of the key element in bytes. + * \return E_OK Read key elements success. + * E_NOT_OK Read key elements failed. + * \pre objectId has to be a valid driver object handle. + * SigExponentIndexPtr has to be a valid ptr. + * sigExponentLength has to be a valid ptr. + * SigModulusIndexPtr has to be a valid ptr. + * sigModulusLength has to be a valid ptr. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SignatureRsaPssVerifyGetKeyElements( + uint32 cryptoKeyId, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) saltLengthPtr, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) SigExponentIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) SigExponentLength, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) SigModulusIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) SigModulusLength); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssVerifyStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for RSA PSS signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid Crypto_30_LibCv_WorkSpaceRsaPssVer handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssVerifyStart( + P2VAR(Crypto_30_LibCv_WorkSpaceRsaPssVer, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssVerifyUpdate() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode update for RSA PSS signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid Crypto_30_LibCv_WorkSpaceRsaPssVer handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssVerifyUpdate( + P2VAR(Crypto_30_LibCv_WorkSpaceRsaPssVer, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssVerifyFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode finish for RSA PSS signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid Crypto_30_LibCv_WorkSpaceRsaPssVer handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssVerifyFinish( + P2VAR(Crypto_30_LibCv_WorkSpaceRsaPssVer, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_RSAPSSVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1CRTGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1CrtGenerateStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for RSA CRT PKCS1 signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceRSACRTsig handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1CrtGenerateStart( + P2VAR(eslt_WorkSpaceRSACRTsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1CrtGenerateUpdate() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for RSA CRT PKCS1 signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceRSACRTsig handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1CrtGenerateUpdate( + P2VAR(eslt_WorkSpaceRSACRTsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1CrtGenerateFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for RSA CRT PKCS1 signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceRSACRTsig handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1CrtGenerateFinish( + P2VAR(eslt_WorkSpaceRSACRTsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1CRTGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519GenerateStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for Ed25519 signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEd25519 handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519GenerateStart( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519GenerateFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode finish for Ed25519 signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEd25519 handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519GenerateFinish( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519VerifyStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for Ed25519 signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEd25519 handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519VerifyStart( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519VerifyFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode finish for Ed25519 signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEd25519 handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519VerifyFinish( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON || CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Ed25519_getEslInstanceofDeprecatedAlgoMode() + *********************************************************************************************************************/ +/*! \brief Handle the deprecated version of ED25519 in START operation mode. + * \details This function sets the ESL_INSTANCE identifier based on the secondary algorithm family. + * \param[in] secAlgoFam Secondary algorithm family identifier. + * \param[out] eslInstancePtr Pointer to where the eslInstance should be stored. + * \pre Secondary algorithm family has to be CRYPTO_ALGOFAM_NOT_SET or CRYPTO_ALGOFAM_SHA2_512. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Ed25519_getEslInstanceofDeprecatedAlgoMode( + Crypto_AlgorithmSecondaryFamilyType secAlgoFam, + P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) eslInstancePtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Ed25519_Update_deprecatedAlgoMode() + *********************************************************************************************************************/ +/*! \brief Handle the deprecated version of ED25519 in UPDATE operation mode. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEd25519 handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Ed25519_Update_deprecatedAlgoMode( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Ed25519_getFinishInputLengthOfDeprecatedAlgoMode() + *********************************************************************************************************************/ +/*! \brief Handle the deprecated version of ED25519 in FINISH operation mode. + * \details This function sets the inputLength based on the secondary algorithm family. + * \param[in] jobInputLength Input Length of used job. + * \param[in] secAlgoFam Secondary algorithm family identifier. + * \param[out] inputLengthPtr Pointer to where the inputLength should be stored + * \pre Secondary algorithm family has to be CRYPTO_ALGOFAM_NOT_SET or CRYPTO_ALGOFAM_SHA2_512. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Ed25519_getFinishInputLengthOfDeprecatedAlgoMode( + uint32 jobInputLength, + Crypto_AlgorithmSecondaryFamilyType secAlgoFam, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) inputLengthPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519Update() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode update for Ed25519 signature generate and verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEd25519 handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519Update( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON || CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448GenerateStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for Ed448 signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEdDSA handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448GenerateStart( + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448GenerateFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode finish for Ed448 signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEdDSA handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448GenerateFinish( + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448VerifyStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for Ed448 signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEdDSA handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448VerifyStart( + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448VerifyFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode finish for Ed448 signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEdDSA handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448VerifyFinish( + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON || CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448Update() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode update for Ed448 signature generate and verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEdDSA handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448Update( + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON || CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON || CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2_CalcUserInfo() + *********************************************************************************************************************/ +/*! \brief Calculate SM2 user info. + * \details This function reads the public key and the optional user id and provides them to the lower layer + * crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \param[in] publicKeyElementId Key element ID of public key. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre workspace has to be a valid eslt_WorkSpaceSM2 handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2_CalcUserInfo( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint32 publicKeyElementId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2Update() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode update for SM2 signature generate and verify. + * \details This function provides the message data to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceSM2 handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2Update( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON || CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2GenerateStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for SM2 signature generate. + * \details This function initializes the SM2 algorithm of lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre workspace has to be a valid eslt_WorkSpaceSM2 handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2GenerateStart( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2GenerateFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode finish for SM2 signature generate. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre workspace has to be a valid eslt_WorkSpaceSM2 handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2GenerateFinish( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2VerifyStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for SM2 signature verify. + * \details This function initializes the SM2 algorithm of lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre workspace has to be a valid eslt_WorkSpaceSM2 handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2VerifyStart( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2VerifyFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode finish for SM2 signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceSM2 handle. + * job has to be a pointer to a valid job object. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2VerifyFinish( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); +#endif /* (CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SLHDSAVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SlhDsaVerifyStart() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode start for SLH-DSA signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the vSecPrim workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] version Version of the algorithm. + * \param[in] hashId ID of the hash function used by the algorithm. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid vSecPrimType_WorkSpaceVerifySLHDSA handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SlhDsaVerifyStart( + P2VAR(vSecPrimType_WorkSpaceVerifySLHDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + vSecPrim_SLHDSA_Version version, vSecPrim_SLHDSA_HashAlgorithm hashId); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SlhDsaVerifyUpdate() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode update for SLH-DSA signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the vSecPrim workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid vSecPrimType_WorkSpaceVerifySLHDSA handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SlhDsaVerifyUpdate( + P2VAR(vSecPrimType_WorkSpaceVerifySLHDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SlhDsaVerifyFinish() + *********************************************************************************************************************/ +/*! \brief Handle Operation mode finish for SLH-DSA signature verify. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the vSecPrim workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] publicKeyLength Length of the byte-array publicKey. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre workspace has to be a valid vSecPrimType_WorkSpaceVerifySLHDSA handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SlhDsaVerifyFinish( + P2VAR(vSecPrimType_WorkSpaceVerifySLHDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint32 publicKeyLength); +#endif /* (CRYPTO_30_LIBCV_SLHDSAVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECPKEYCHECK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_IsPublicKeyOnCurveEcc() + *********************************************************************************************************************/ +/*! \brief Check if a public key is on elliptic curve and write result into the job's resultPtr. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] EcDomainPtr Pointer to domain parameter structure. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEcPKeyCheck handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-CRYPTO-ISPUBLICKEYONCURVE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_IsPublicKeyOnCurveEcc( + P2CONST(eslt_WorkSpaceEcPKeyCheck, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_IsPrivateKeyOnCurveEcc() + *********************************************************************************************************************/ +/*! \brief Check if a private key is on elliptic curve and write result into the job's resultPtr. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] EcDomainPtr Pointer to domain parameter structure. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEcPKeyCheck handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-CRYPTO-ISPRIVATEKEYONCURVE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_IsPrivateKeyOnCurveEcc( + P2CONST(eslt_WorkSpaceEcPKeyCheck, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr); + +/********************************************************************************************************************** + * Crypto_30_LibCv_EcPKeyCheck_DispatchByKeyType() + *********************************************************************************************************************/ +/*! \brief Distinguish between checking a private or a public key based on secondary algorithm family. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] EcDomainPtr Pointer to domain parameter structure. + * \param[in] EcDomainExtPtr Pointer to domain parameter extension structure. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEcPKeyCheck handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_EcPKeyCheck_DispatchByKeyType( + P2VAR(eslt_WorkSpaceEcPKeyCheck, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr); +#endif /* (CRYPTO_30_LIBCV_ECPKEYCHECK == STD_ON) */ + +#if (CRYPTO_30_LIBCV_EDKEYCHECK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_EdKeyCheck_DispatchByKeyType() + *********************************************************************************************************************/ +/*! \brief Distinguish between checking a private or a public key based on secondary algorithm family. + * \details This function dispatches the provided job to the lower layer crypto library. + * \param[in,out] workspace Pointer to the esl workspace. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] curve Curve to be used (ESL_CURVE25519 or ESL_CURVE448). + * \param[in] expectedKeyLength Used to check the key element length. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre workspace has to be a valid eslt_WorkSpaceEdKeyCheck handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_EdKeyCheck_DispatchByKeyType( + P2VAR(eslt_WorkSpaceEdKeyCheck, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + const eslt_Size16 curve, + const uint32 expectedKeyLength); +#endif /* (CRYPTO_30_LIBCV_EDKEYCHECK == STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ +#if ((CRYPTO_30_LIBCV_RSAVERIFY == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureVerifyResult() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureVerifyResult( + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ + eslt_ErrorCode retValCv, + eslt_ErrorCode signatureInvalidValue) +{ + eslt_ErrorCode retVal = ESL_ERC_ERROR; + /* # Handle Signature Verify Return Value. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Verification Passed */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = ESL_ERC_NO_ERROR; + } + else + { + /* # Verification Failed */ + if ((retValCv == signatureInvalidValue) || (retValCv == ESL_ERC_SIGNATURE_INVALID) +# if CRYPTO_30_LIBCV_RSAVERIFY + /* Special cases for RSA Verify */ + || (retValCv == ESL_ERC_RSA_SIGNATURE_OUT_OF_RANGE) || (retValCv == ESL_ERC_RSA_ENCODING_INVALID) || (retValCv == ESL_ERC_RSA_MODULE_OUT_OF_RANGE) +# endif + ) + { + retVal = ESL_ERC_NO_ERROR; + } + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + return retVal; +} /* Crypto_30_LibCv_DispatchSignatureVerifyResult() */ +#endif /* ((CRYPTO_30_LIBCV_RSAVERIFY == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1GenerateStart() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1GenerateStart( + P2VAR(eslt_WorkSpaceRSAsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_RSA_SIG, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CUSTOM_RSA_PRIVATE_EXPONENT); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CUSTOM_RSA_MODULUS); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + retVal = E_NOT_OK; + /* # Initialize algorithm based on secondary algorithm family. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_initSignRSASHA1_V15(workspace, + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex), + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_initSignRSASHA256_V15(workspace, + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex), + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retValCv remains on ESL_ERC_ERROR and retVal on E_NOT_OK */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_RsaPkcs1GenerateStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1GenerateUpdate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1GenerateUpdate( + P2VAR(eslt_WorkSpaceRSAsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Update algorithm based on secondary algorithm family. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_updateSignRSASHA1_V15(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_updateSignRSASHA256_V15(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retValCv remains on ESL_ERC_ERROR and retVal on E_NOT_OK */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_RsaPkcs1GenerateUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1GenerateFinish() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1GenerateFinish( + P2VAR(eslt_WorkSpaceRSAsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + eslt_Length outputLength = (eslt_Length)(*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + /* # Generate Signature based on secondary algorithm family. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_finalizeSignRSASHA1_V15(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + &outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_finalizeSignRSASHA256_V15(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + &outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retValCv remains on ESL_ERC_ERROR and retVal on E_NOT_OK */ + break; + } + } + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = (uint32)outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_RsaPkcs1GenerateFinish() */ +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1VerifyStart() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1VerifyStart( + P2VAR(eslt_WorkSpaceRSAver, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_RSA_VER, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CUSTOM_RSA_MODULUS); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CUSTOM_RSA_PUBLIC_EXPONENT); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + retVal = E_NOT_OK; + /* # Initialize algorithm based on secondary algorithm family. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_initVerifyRSASHA1_V15(workspace, + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_initVerifyRSASHA256_V15(workspace, + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retValCv remains on ESL_ERC_ERROR and retVal on E_NOT_OK */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + } + return retVal; +} /* Crypto_30_LibCv_RsaPkcs1VerifyStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1VerifyUpdate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1VerifyUpdate( + P2VAR(eslt_WorkSpaceRSAver, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Update algorithm based on secondary algorithm family. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_updateVerifyRSASHA1_V15(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_updateVerifyRSASHA256_V15(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retValCv remains on ESL_ERC_ERROR and retVal on E_NOT_OK */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_RsaPkcs1VerifyUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1VerifyFinish() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1VerifyFinish( + P2VAR(eslt_WorkSpaceRSAver, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Init verifyPtr to CRYPTO_E_VER_NOT_OK */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Verify Signature based on secondary algorithm family. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_finalizeVerifyRSASHA1_V15(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr); + + retValCv = Crypto_30_LibCv_DispatchSignatureVerifyResult(job, retValCv, ESL_ERC_RSA_SIGNATURE_INVALID); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_finalizeVerifyRSASHA256_V15(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr); + + retValCv = Crypto_30_LibCv_DispatchSignatureVerifyResult(job, retValCv, ESL_ERC_RSA_SIGNATURE_INVALID); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PKCS1_v1_5_SHA2_256 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retValCv remains on ESL_ERC_ERROR and retVal on E_NOT_OK */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_RsaPkcs1VerifyFinish() */ +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPSSGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssGenerateStart() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssGenerateStart( + P2VAR(eslt_WorkSpaceRSAPSSsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_RSA_PSS_SIG, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CUSTOM_RSA_MODULUS); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CUSTOM_RSA_PRIVATE_EXPONENT); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + retVal = E_NOT_OK; + /* # Initialize algorithm based on secondary algorithm family. */ + + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_initSignRSASHA1_PSS(workspace, + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_initSignRSASHA256_PSS(workspace, + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_256 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_384 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_384: + { + retValCv = esl_initSignRSASHA384_PSS(workspace, + (eslt_Length)keyElements[0].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), + (eslt_Length)keyElements[1].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_384 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retValCv remains on ESL_ERC_ERROR and retVal on E_NOT_OK */ + break; + } + } + + } + } + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_RsaPssGenerateStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssGenerateUpdate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssGenerateUpdate( + P2VAR(eslt_WorkSpaceRSAPSSsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Update algorithm based on secondary algorithm family. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_updateSignRSASHA1_PSS(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_updateSignRSASHA256_PSS(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_256 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_384 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_384: + { + retValCv = esl_updateSignRSASHA384_PSS(workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_384 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retValCv remains on ESL_ERC_ERROR and retVal on E_NOT_OK */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_RsaPssGenerateUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssGenerateFinish() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssGenerateFinish( + P2VAR(eslt_WorkSpaceRSAPSSsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + /* # Load salt key element. */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CUSTOM_RSA_SALT); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + eslt_Length outputLength = (eslt_Length)(*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_NOT_OK; + + /* # Generate Signature based on secondary algorithm family. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_finalizeSignRSASHA1_PSS(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_finalizeSignRSASHA256_PSS(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_256 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_384 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_384: + { + retValCv = esl_finalizeSignRSASHA384_PSS(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_RSASSA_PSS_SHA2_384 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retValCv remains on ESL_ERC_ERROR and retVal on E_NOT_OK */ + break; + } + } + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_RsaPssGenerateFinish() */ +#endif /* (CRYPTO_30_LIBCV_RSAPSSGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPSSVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_SignatureRsaPssVerifyGetKeyElements() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6060 8 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_SignatureRsaPssVerifyGetKeyElements( + uint32 cryptoKeyId, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) saltLengthPtr, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) SigExponentIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) SigExponentLength, + P2VAR(Crypto_30_LibCv_SizeOfKeyStorageType, AUTOMATIC, AUTOMATIC) SigModulusIndexPtr, + P2VAR(uint32, AUTOMATIC, AUTOMATIC) SigModulusLength) +{ + Std_ReturnType retVal; + Std_ReturnType retValRequired, retValOptional; + + Crypto_30_LibCv_KeyElementGetType keyElements[2]; + + Crypto_30_LibCv_SizeOfKeyStorageType SignatureSaltLengthIndex; + uint32 SignatureSaltLengthSize = CRYPTO_30_LIBCV_RSA_SALT_LENGTH_SIZE; + + /* Check if key element is accessible */ + /* # Read required key elements */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CUSTOM_RSA_PUBLIC_EXPONENT); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CUSTOM_RSA_MODULUS); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + retValRequired = Crypto_30_LibCv_Local_GetElementsIndexJob(cryptoKeyId, keyElements, 2u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + retValOptional = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(cryptoKeyId, CRYPTO_KE_CUSTOM_RSA_SALT_LENGTH, &SignatureSaltLengthIndex, &SignatureSaltLengthSize, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # check results */ + if (retValRequired == E_OK) + { + *SigExponentIndexPtr = keyElements[0u].keyElementIndex; /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + *SigExponentLength = keyElements[0u].keyElementLength; /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + *SigModulusIndexPtr = keyElements[1u].keyElementIndex; /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + *SigModulusLength = keyElements[1u].keyElementLength; /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + /* # check if the salt length key element is available. */ + if (retValOptional == E_OK) + { + *saltLengthPtr = (uint32)Crypto_30_LibCv_GetUint16(Crypto_30_LibCv_GetKeyStorage(SignatureSaltLengthIndex), Crypto_30_LibCv_GetKeyStorage(SignatureSaltLengthIndex + 1u)); /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + retVal = E_OK; + } + else if (retValOptional == CRYPTO_E_KEY_NOT_AVAILABLE) + { + /* # if the salt length key element is not available use specific value to auto calculate salt length. */ + *saltLengthPtr = (uint32)(eslt_Length)CRYPTO_30_LIBCV_SIGNATURE_RSA_PSS_SALT_SIZE_AUTO_CALC; /* PRQA S 2890, 2895 */ /* MD_CRYPTO_30_LIBCV_3.1, MD_CRYPTO_30_LIBCV_3.1 */ /* SBSW_CRYPTO_30_LIBCV_WORKSPACE_MEMBER_ACCESS */ + retVal = E_OK; + } + else + { + /* invalid salt length */ + retVal = retValOptional; + } + } + else + { + retVal = retValRequired; + } + return retVal; +} /* Crypto_30_LibCv_SignatureRsaPssVerifyGetKeyElements() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssVerifyStart() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssVerifyStart( + P2VAR(Crypto_30_LibCv_WorkSpaceRsaPssVer, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_AlgorithmSecondaryFamilyType secAlgoFam = job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily; + + Crypto_30_LibCv_SizeOfKeyStorageType SigExponentIndex; + uint32 SigExponentLength; + Crypto_30_LibCv_SizeOfKeyStorageType SigModulusIndex; + uint32 SigModulusLength; + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->wsRsa.header), ESL_MAXSIZEOF_WS_RSA_PSS_VER, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_SignatureRsaPssVerifyGetKeyElements(job->cryptoKeyId, &workspace->saltLength, &SigExponentIndex, &SigExponentLength, &SigModulusIndex, &SigModulusLength); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + retVal = E_NOT_OK; + + /* # Initialize algorithm based on secondary algorithm family. */ + switch (secAlgoFam) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_initVerifyRSASHA1_PSS(&(workspace->wsRsa), + (eslt_Length)SigModulusLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(SigModulusIndex), + (eslt_Length)SigExponentLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(SigExponentIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_initVerifyRSASHA256_PSS(&(workspace->wsRsa), + (eslt_Length)SigModulusLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(SigModulusIndex), + (eslt_Length)SigExponentLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(SigExponentIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_256 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_384 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_384: + { + retValCv = esl_initVerifyRSASHA384_PSS(&(workspace->wsRsa), + (eslt_Length)SigModulusLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(SigModulusIndex), + (eslt_Length)SigExponentLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR)) Crypto_30_LibCv_GetAddrKeyStorage(SigExponentIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_384 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retValCv remains on ESL_ERC_ERROR and retVal on E_NOT_OK */ + break; + } + } + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + } + return retVal; +} /* Crypto_30_LibCv_RsaPssVerifyStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssVerifyUpdate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssVerifyUpdate( + P2VAR(Crypto_30_LibCv_WorkSpaceRsaPssVer, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_AlgorithmSecondaryFamilyType secAlgoFam = job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily; + + /* # Update algorithm based on secondary algorithm family. */ + switch (secAlgoFam) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_updateVerifyRSASHA1_PSS(&(workspace->wsRsa), + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_updateVerifyRSASHA256_PSS(&(workspace->wsRsa), + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_256 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_384 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_384: + { + retValCv = esl_updateVerifyRSASHA384_PSS(&(workspace->wsRsa), + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_384 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retValCv remains on ESL_ERC_ERROR and retVal on E_NOT_OK */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_RsaPssVerifyUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPssVerifyFinish() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPssVerifyFinish( + P2VAR(Crypto_30_LibCv_WorkSpaceRsaPssVer, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + Crypto_AlgorithmSecondaryFamilyType secAlgoFam = job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily; + + /* # Init verifyPtr to CRYPTO_E_VER_NOT_OK */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Verify Signature based on secondary algorithm family. */ + switch (secAlgoFam) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA1 == STD_ON) + case CRYPTO_ALGOFAM_SHA1: + { + retValCv = esl_finalizeVerifyRSASHA1_PSS(&(workspace->wsRsa), /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (eslt_Length)workspace->saltLength, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr); + + retValCv = Crypto_30_LibCv_DispatchSignatureVerifyResult(job, retValCv, ESL_ERC_RSA_SIGNATURE_INVALID); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_256 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_256: + { + retValCv = esl_finalizeVerifyRSASHA256_PSS(&(workspace->wsRsa), /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (eslt_Length)workspace->saltLength, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr); + + retValCv = Crypto_30_LibCv_DispatchSignatureVerifyResult(job, retValCv, ESL_ERC_RSA_SIGNATURE_INVALID); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_256 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_384 == STD_ON) + case CRYPTO_ALGOFAM_SHA2_384: + { + retValCv = esl_finalizeVerifyRSASHA384_PSS(&(workspace->wsRsa), /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (eslt_Length)workspace->saltLength, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr); + + retValCv = Crypto_30_LibCv_DispatchSignatureVerifyResult(job, retValCv, ESL_ERC_RSA_SIGNATURE_INVALID); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + break; + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_RSA_RSASSA_PSS_SHA2_384 == STD_ON) */ + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* unsupported mode - retVal has already been set to E_NOT_OK */ + break; + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_RsaPssVerifyFinish() */ + +#endif /* (CRYPTO_30_LIBCV_RSAPSSVERIFY == STD_ON) */ + +#if ((CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) +# if (CRYPTO_30_LIBCV_SIGNATURE_PRE_HASH == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_PreHashStart() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_PreHashStart( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsHash, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_2 */ + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + /* Dispatch secondary algorithm for pre-hashing. */ + if(job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_NOT_SET) + { + /* Without pre-hashing */ + retVal = E_OK; + } + else + { + /* With pre-hashing */ + retVal = Crypto_30_LibCv_Dispatch_Hash_ModeStart(wsHash, job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily); /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_WORKSPACE */ + } + + return retVal; +} /* Crypto_30_LibCv_PreHashStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_PreHashUpdate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_PreHashUpdate( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsHash, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_2 */ + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + /* Dispatch secondary algorithm for pre-hashing. */ + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_NOT_SET) + { + /* without pre hashing */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength != 0u) && (!Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_FINISH))) + { + retVal = E_NOT_OK; + } + else + { + retVal = E_OK; + } + } + else + { + /* With pre hashing */ + retVal = Crypto_30_LibCv_Dispatch_Hash_ModeUpdate(wsHash, job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); + } + + return retVal; +} /* Crypto_30_LibCv_PreHashUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_PreHashFinish() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_PreHashFinish( + P2VAR(vSecPrimType_WorkSpaceHash, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) wsHash, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) hashPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) hashLengthPtr) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + /* Dispatch secondary algorithm for pre-hashing. */ + retVal = Crypto_30_LibCv_Dispatch_Hash_ModeFinish(wsHash, hashLengthPtr, hashPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_OF_WORKSPACE */ + + return retVal; +} /* Crypto_30_LibCv_PreHashFinish() */ +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_PRE_HASH == STD_ON) */ +#endif /* ((CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) || (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON)) */ + +#if (CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateStart() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateStart( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_2 */ + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ + +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_PRE_HASH == STD_ON) + /* # Handle pre-hashing start. */ + retVal = Crypto_30_LibCv_PreHashStart(&(workSpace->wsPreHash), job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(workSpace); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(job); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + + return retVal; +} /* Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateUpdate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateUpdate( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_2 */ + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_PRE_HASH == STD_ON) + /* # Handle pre-hashing update. */ + retVal = Crypto_30_LibCv_PreHashUpdate(&(workSpace->wsPreHash), job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(workSpace); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(job); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + + return retVal; +} /* Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_EccPrimeGenerateSignature_SignData() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +/* PRQA S 6050, 6060, 6080 10 */ /* MD_MSR_STCAL, MD_CRYPTO_30_LIBCV_STPAR, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_EccPrimeGenerateSignature_SignData( + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcSpeedUpExtPtr, + uint32 expectedKeyLength, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) messagePtr, + uint32 messageLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + eslt_Length sigLength = 0u, doubleSigLength = 0u, sigLengthR = 0u, sigLengthS = 0u; + uint32 sigKeyLength = 0u; + + eslt_Byte signatureR[CRYPTO_30_LIBCV_MAX_SIZEOF_SIGNATURE_GENERATE_ECC_KEY] = {0u}; + eslt_Byte signatureS[CRYPTO_30_LIBCV_MAX_SIZEOF_SIGNATURE_GENERATE_ECC_KEY] = {0u}; + + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) privateKeyElementPtr; +# if (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) + eslt_Byte privateKeyElementBuffer[CRYPTO_30_LIBCV_MAX_SIZEOF_SIGNATURE_GENERATE_ECC_KEY] = { 0u }; +# endif + + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + /* ----- Implementation ------------------------------------------------- */ + /* # Get private key for signature generation. */ + sigKeyLength = (uint32)(esl_getLengthOfEcPprivateKey(EcDomainPtr)); /* SBSW_CRYPTO_30_LIBCV_ESL_CONST_WORKSPACE */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_SIGNATURE_KEY, sigKeyLength); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Initialize ECC workspace header. */ + if (esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(workSpace->wsEcP.header), ESL_MAXSIZEOF_WS_ECP, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* # Check if key element for private key is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (keyElements[0].keyElementLength < expectedKeyLength) + { + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + + if (retVal == E_OK) + { + retVal = E_NOT_OK; + if (esl_initSignDSAEcP_prim((P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(workSpace->wsEcP), EcDomainPtr, EcDomainExtPtr, EcSpeedUpExtPtr) == ESL_ERC_NO_ERROR) /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + { +# if (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) + if (sigKeyLength == (keyElements[0].keyElementLength + 1u)) + { + privateKeyElementBuffer[0] = 0u; /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_ACCESS_WITH_SIZE */ + Crypto_30_LibCv_CopyData(&privateKeyElementBuffer[1u], Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), (keyElements[0].keyElementLength)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + privateKeyElementPtr = privateKeyElementBuffer; + } + else +# endif /* (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) */ + { + privateKeyElementPtr = Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex); + } + + /* # Calculate signature. */ + /* # get esl size of signature length for r and s (signature = [signature_r|signature_s]) */ + sigLength = esl_getLengthOfEcPsignature_comp(EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CONST_WORKSPACE */ + doubleSigLength = (eslt_Length)Crypto_30_LibCv_Math_Mul2(sigLength); + if (*(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) >= doubleSigLength) + { + sigLengthS = sigLength; + sigLengthR = sigLength; + + /* # Finalize and store output. */ + retValCv = esl_signDSAEcP_prim(&(workSpace->wsEcP), /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (eslt_Length)messageLength, (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))messagePtr, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))privateKeyElementPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&sigLengthR, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))signatureR, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&sigLengthS, (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))signatureS); + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = Crypto_30_LibCv_EccPrimeGenerateSignature_ConvertSignatureForOutputBuffer(job, sigLength, doubleSigLength, sigLengthR, sigLengthS, expectedKeyLength, signatureR, signatureS); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR_AND_MEMBER_OF_JOB_PTR */ + } + } + } + } + } + + return retVal; +} /* Crypto_30_LibCv_EccPrimeGenerateSignature_SignData() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_EccPrimeGenerateSignature_ConvertSignatureForOutputBuffer() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6060 10 */ /* MD_CRYPTO_30_LIBCV_STPAR */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_EccPrimeGenerateSignature_ConvertSignatureForOutputBuffer( + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ + eslt_Length sigLength, + eslt_Length doubleSigLength, + eslt_Length sigLengthR, + eslt_Length sigLengthS, + uint32 expectedKeyLength, + P2CONST(eslt_Byte, AUTOMATIC, AUTOMATIC) signatureR, + P2CONST(eslt_Byte, AUTOMATIC, AUTOMATIC) signatureS) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; +# if (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) + boolean outputIsSet = FALSE; /* PRQA S 2981 */ /* MD_MSR_RetVal */ +# endif + + /* ----- Implementation ------------------------------------------------- */ + if ((sigLengthR == sigLength) && (sigLengthS == sigLength)) + { +# if (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) + /* # Check if the return length is one greater than expected, the SECp160r1 can return 161 bits. */ + if (sigLength == (expectedKeyLength + 1u)) + { + /* # Check the first bytes and delete the zero padding. */ + if ((signatureR[0] == 0u) && (signatureS[0] == 0u)) + { + Crypto_30_LibCv_CopyData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, &signatureR[1u], (eslt_Length)(sigLengthR - 1u)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + Crypto_30_LibCv_CopyData(&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[sigLengthR - 1u], &signatureS[1u], (eslt_Length)(sigLengthS - 1u)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = (eslt_Length)(doubleSigLength - 2u); /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + outputIsSet = TRUE; + } + else + { + outputIsSet = FALSE; + } + } + else + { + outputIsSet = FALSE; + } + + /* # If the first bytes are not equal zero, copy the signature to the output ptr. */ + if (outputIsSet == FALSE) +# else /* !(CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(expectedKeyLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +# endif + { + Crypto_30_LibCv_CopyData(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, signatureR, (sigLengthR)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + Crypto_30_LibCv_CopyData(&job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr[sigLengthR], signatureS, (sigLengthS)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = doubleSigLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_EccPrimeGenerateSignature_ConvertSignatureForOutputBuffer() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_EccPrimeGenerateSignature() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_EccPrimeGenerateSignature( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) messagePtr, + uint32 messageLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, retValDispatching = E_NOT_OK; + uint32 expectedKeyLength = 0u; + uint32 messageLengthCut = 0u; + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr = Crypto_30_LibCv_EccCurveEmptyDomain; + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr = Crypto_30_LibCv_EccCurveEmptyDomain; + P2CONST(eslt_EccSpeedUpExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcSpeedUpExtPtr = Crypto_30_LibCv_EccCurveEmptyDomain; + + /* ----- Implementation ------------------------------------------------- */ + /* # Choose domain parameters according to configured primitive. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { +# if (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P160R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveSecP160R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveSecP160R1DomainExt; + EcSpeedUpExtPtr = Crypto_30_LibCv_EccCurveSecP160R1SpeedUpExt; + expectedKeyLength = CRYPTO_30_LIBCV_SIZEOF_ECC_160_KEY_PRIVATE - 1u; + retValDispatching = E_OK; + break; +# endif /* (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECP256GENERATE == STD_ON) + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P256R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt; + EcSpeedUpExtPtr = Crypto_30_LibCv_EccCurveNistAnsiSecP256R1SpeedUpExt; + expectedKeyLength = CRYPTO_30_LIBCV_SIZEOF_ECC_256_KEY_PRIVATE; + retValDispatching = E_OK; + break; +# endif /* (CRYPTO_30_LIBCV_ECP256GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECP384GENERATE == STD_ON) + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P384R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveNistSecP384R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt; + EcSpeedUpExtPtr = Crypto_30_LibCv_EccCurveNistSecP384R1SpeedUpExt; + expectedKeyLength = CRYPTO_30_LIBCV_SIZEOF_ECC_384_KEY_PRIVATE; + retValDispatching = E_OK; + break; +# endif /* (CRYPTO_30_LIBCV_ECP384GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECP521GENERATE == STD_ON) + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P521R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveNistSecP521R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt; + EcSpeedUpExtPtr = Crypto_30_LibCv_EccCurveNistSecP521R1SpeedUpExt; + expectedKeyLength = CRYPTO_30_LIBCV_SIZEOF_ECC_521_KEY_PRIVATE; + retValDispatching = E_OK; + break; +# endif /* (CRYPTO_30_LIBCV_ECP521GENERATE == STD_ON) */ + + default: + /* not reachable, misra only. */ + break; + } + + if (retValDispatching == E_OK) + { + /* # Adapt message length according to maximum length. */ + messageLengthCut = messageLength; +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_PRE_HASH == STD_ON) + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily != CRYPTO_ALGOFAM_NOT_SET) /* COV_CRYPTO_30_LIBCV_ECDSA_PREHASHING_ENABLED */ + { + if (messageLength > esl_getMaxLengthOfEcPmessage(EcDomainPtr)) /* COV_CRYPTO_30_LIBCV_ECDSA_CONFIGURATION */ /* SBSW_CRYPTO_30_LIBCV_ESL_CONST_WORKSPACE */ + { + messageLengthCut = esl_getMaxLengthOfEcPmessage(EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CONST_WORKSPACE */ + } + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_PRE_HASH == STD_ON) */ + + /* # # Call ECC algorithm. */ + retVal = Crypto_30_LibCv_EccPrimeGenerateSignature_SignData(job, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + workSpace, + EcDomainPtr, + EcDomainExtPtr, + EcSpeedUpExtPtr, + expectedKeyLength, + messagePtr, + messageLengthCut); + } + + return retVal; +} /* Crypto_30_LibCv_EccPrimeGenerateSignature() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateFinish() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateFinish( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal; + uint32 messageLength; + const uint8 *messagePtr; + +# if ((CRYPTO_30_LIBCV_SIGNATURE_GENERATE_PRE_HASH == STD_ON)) + uint8 messageBuf[CRYPTO_30_LIBCV_PREHASH_DIGEST_MAXSIZE]; + Std_ReturnType localRetVal; +# endif + + /* ----- Implementation ------------------------------------------------- */ + /* # Handle pre-hashing finish. */ +# if ((CRYPTO_30_LIBCV_SIGNATURE_GENERATE_PRE_HASH == STD_ON)) + retVal = E_NOT_OK; + messageLength = CRYPTO_30_LIBCV_PREHASH_DIGEST_MAXSIZE; + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_NOT_SET) /* COV_CRYPTO_30_LIBCV_ECDSA_PREHASHING_ENABLED */ + { +# endif + /* without pre hashing */ + messagePtr = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr; + messageLength = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength; +# if ((CRYPTO_30_LIBCV_SIGNATURE_GENERATE_PRE_HASH == STD_ON)) + localRetVal = E_OK; + } + else + { + localRetVal = Crypto_30_LibCv_PreHashFinish(&(workSpace->wsPreHash), messageBuf, &messageLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + messagePtr = messageBuf; + } + + if (localRetVal == E_OK) +# endif /* ((CRYPTO_30_LIBCV_SIGNATURE_GENERATE_PRE_HASH == STD_ON)) */ + { + /* # Pass on potentially pre-hashed message for signature computation. */ + retVal = Crypto_30_LibCv_EccPrimeGenerateSignature(workSpace, job, messagePtr, messageLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } + + return retVal; +} /* Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateFinish() */ +#endif /* (CRYPTO_30_LIBCV_ECPGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyStart() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyStart( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_2 */ + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_PRE_HASH == STD_ON) + /* # Handle pre-hashing start. */ + retVal = Crypto_30_LibCv_PreHashStart(&(workSpace->wsPreHash), job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(workSpace); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(job); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + + return retVal; +} /* Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyUpdate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyUpdate( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_2 */ + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ------------------------------------------------- */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_PRE_HASH == STD_ON) + /* # Handle pre-hashing update. */ + retVal = Crypto_30_LibCv_PreHashUpdate(&(workSpace->wsPreHash), job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(workSpace); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(job); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + + return retVal; +} /* Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish_CvOperation() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6060, 6080 8 */ /* MD_CRYPTO_30_LIBCV_STPAR, MD_MSR_STMIF */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish_CvOperation( + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) messagePtr, + uint32 messageLength) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + uint32 sigKeyLength = 0u; + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + /* ----- Implementation ------------------------------------------------- */ + /* # Retrieve the public key. */ + /* get esl size of key length for x and y component of the public key (key = [key_x|key_y]) */ + sigKeyLength = (uint32)(Crypto_30_LibCv_Math_Mul2((uint32)esl_getLengthOfEcPpublicKey_comp(EcDomainPtr))); /* SBSW_CRYPTO_30_LIBCV_ESL_CONST_WORKSPACE */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_SIGNATURE_KEY, sigKeyLength); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Initialize ECC workspace header. */ + if (esl_initWorkSpaceHeader((P2VAR(eslt_WorkSpaceHeader, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(workSpace->wsEcP.header), ESL_MAXSIZEOF_WS_ECP, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* # Initialize ECC algorithm. */ + retVal = E_NOT_OK; + retValCv = esl_initVerifyDSAEcP_prim((P2VAR(eslt_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(workSpace->wsEcP), EcDomainPtr, EcDomainExtPtr); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Check if value is even */ + if (Crypto_30_LibCv_Math_IsEven(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength)) + { + /* # Calculate and verify signature. */ + retValCv = esl_verifyDSAEcP_prim(&(workSpace->wsEcP), (eslt_Length)messageLength, (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))messagePtr, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex + Crypto_30_LibCv_Math_Div2(sigKeyLength)), + (eslt_Length)Crypto_30_LibCv_Math_Div2(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength), (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + (eslt_Length)Crypto_30_LibCv_Math_Div2(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength), (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr[(eslt_Length)Crypto_30_LibCv_Math_Div2(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength)])); + + retValCv = Crypto_30_LibCv_DispatchSignatureVerifyResult(job, retValCv, ESL_ERC_ECC_SIGNATURE_INVALID); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_JOB_PTR */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + } + } + } + + return retVal; +} /* Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish_CvOperation() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish( + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workSpace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK, retValDispatching = E_NOT_OK; + uint32 messageLength; + const uint8* messagePtr; + +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_PRE_HASH == STD_ON) + Std_ReturnType localRetVal; +# endif + + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr = Crypto_30_LibCv_EccCurveEmptyDomain; + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr = Crypto_30_LibCv_EccCurveEmptyDomain; + +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_PRE_HASH == STD_ON) + uint8 messageBuf[CRYPTO_30_LIBCV_PREHASH_DIGEST_MAXSIZE]; +# endif + + /* ----- Implementation ------------------------------------------------- */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + +# if (CRYPTO_30_LIBCV_ECP160VERIFY == STD_ON) + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P160R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveSecP160R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveSecP160R1DomainExt; + retValDispatching = E_OK; + break; +# endif + +# if (CRYPTO_30_LIBCV_ECP256VERIFY == STD_ON) + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P256R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt; + retValDispatching = E_OK; + break; +# endif + +# if (CRYPTO_30_LIBCV_ECP384VERIFY == STD_ON) + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P384R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveNistSecP384R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt; + retValDispatching = E_OK; + break; +# endif + +# if (CRYPTO_30_LIBCV_ECP521VERIFY == STD_ON) + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P521R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveNistSecP521R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt; + retValDispatching = E_OK; + break; +# endif + + default: + /* not reachable, misra only. */ + break; + } + + if (retValDispatching == E_OK) + { + /* # Handle pre-hashing finish. */ +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_PRE_HASH == STD_ON) + messageLength = CRYPTO_30_LIBCV_PREHASH_DIGEST_MAXSIZE; + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_NOT_SET) /* COV_CRYPTO_30_LIBCV_ECDSA_PREHASHING_ENABLED */ +# endif + { + /* without pre hashing */ + messagePtr = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr; + messageLength = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength; +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_PRE_HASH == STD_ON) + localRetVal = E_OK; +# endif + } +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_PRE_HASH == STD_ON) + else + { + localRetVal = Crypto_30_LibCv_PreHashFinish(&(workSpace->wsPreHash), messageBuf, &messageLength); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + messagePtr = messageBuf; + } + /* # Adapt message length according to maximum length. */ + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily != CRYPTO_ALGOFAM_NOT_SET) /* COV_CRYPTO_30_LIBCV_ECDSA_PREHASHING_ENABLED */ + { + if (messageLength > esl_getMaxLengthOfEcPmessage(EcDomainPtr)) /* COV_CRYPTO_30_LIBCV_ECDSA_CONFIGURATION */ /* SBSW_CRYPTO_30_LIBCV_ESL_CONST_WORKSPACE */ + { + messageLength = esl_getMaxLengthOfEcPmessage(EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CONST_WORKSPACE */ + } + } + + if (localRetVal == E_OK) +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_PRE_HASH == STD_ON) */ + { + /* # Call ECC algorithm. */ + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish_CvOperation(job, workSpace, /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + EcDomainPtr, EcDomainExtPtr, + messagePtr, messageLength); + } + } + + return retVal; +} /* Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish() */ +#endif /* (CRYPTO_30_LIBCV_ECPVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1CRTGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1CrtGenerateStart() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1CrtGenerateStart( + P2VAR(eslt_WorkSpaceRSACRTsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + Crypto_30_LibCv_KeyElementGetType keyElements[5]; + + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 0u, CRYPTO_KE_CUSTOM_RSA_PRIME_P); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 1u, CRYPTO_KE_CUSTOM_RSA_PRIME_Q); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 2u, CRYPTO_KE_CUSTOM_RSA_EXPONENT_DP); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 3u, CRYPTO_KE_CUSTOM_RSA_EXPONENT_DQ); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetId(keyElements, 4u, CRYPTO_KE_CUSTOM_RSA_INVERSE_QI); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), ESL_MAXSIZEOF_WS_RSA_CRT_SIG, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* Check if key element is accessible */ + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 5u, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + retVal = E_NOT_OK; + /* # Initialize algorithm based on secondary algorithm family. */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA1 == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA2_256 == STD_ON) + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_SHA1) +# endif + { + retValCv = esl_initSignRSACRTSHA1_V15( + workspace, + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (eslt_Length)keyElements[1u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1u].keyElementIndex), + (eslt_Length)keyElements[2u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[2u].keyElementIndex), + (eslt_Length)keyElements[3u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[3u].keyElementIndex), + (eslt_Length)keyElements[4u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[4u].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA2_256 == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA1 == STD_ON) + else +# endif + { + retValCv = esl_initSignRSACRTSHA256_V15( + workspace, + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (eslt_Length)keyElements[1u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[1u].keyElementIndex), + (eslt_Length)keyElements[2u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[2u].keyElementIndex), + (eslt_Length)keyElements[3u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[3u].keyElementIndex), + (eslt_Length)keyElements[4u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[4u].keyElementIndex)); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA2_256 == STD_ON) */ + } + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_RsaPkcs1CrtGenerateStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1CrtGenerateUpdate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1CrtGenerateUpdate( + P2VAR(eslt_WorkSpaceRSACRTsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + + /* # Update algorithm based on secondary algorithm family. */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA1 == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA2_256 == STD_ON) + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_SHA1) +# endif + { + retValCv = esl_updateSignRSACRTSHA1_V15( + workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA2_256 == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA1 == STD_ON) + else +# endif + { + retValCv = esl_updateSignRSACRTSHA256_V15( + workspace, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA2_256 == STD_ON) */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + + return retVal; +} /* Crypto_30_LibCv_RsaPkcs1CrtGenerateUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_RsaPkcs1CrtGenerateFinish() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_RsaPkcs1CrtGenerateFinish( + P2VAR(eslt_WorkSpaceRSACRTsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv; + + eslt_Length outputLength; + outputLength = (eslt_Length)(*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* # Generate Signature based on secondary algorithm family. */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA1 == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA2_256 == STD_ON) + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_SHA1) +# endif + { + retValCv = esl_finalizeSignRSACRTSHA1_V15( + workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA1 == STD_ON) */ +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA2_256 == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA1 == STD_ON) + else +# endif + { + retValCv = esl_finalizeSignRSACRTSHA256_V15( + workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFER_AND_STACK_BUFFER */ + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr); + } +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_GENERATE_RSA_CUSTOM_RSASSA_PKCS1_v1_5_CRT_SHA2_256 == STD_ON) */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + return retVal; +} /* Crypto_30_LibCv_RsaPkcs1CrtGenerateFinish() */ +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1CRTGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519GenerateStart() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519GenerateStart( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Initialize workspace header. */ + retValCv = esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_Ed25519, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) contextPtr = NULL_PTR; + Crypto_30_LibCv_SizeOfKeyStorageType contextIndex = 0u; + uint32 contextLength = 0u; + + /* # Read key element to get context. */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(job->cryptoKeyId, CRYPTO_KE_CUSTOM_EDDSA_CONTEXT, &contextIndex, &contextLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + contextPtr = Crypto_30_LibCv_GetAddrKeyStorage(contextIndex); + } + else if (retVal == CRYPTO_E_KEY_NOT_AVAILABLE) + { + /* Key has no context key element. */ + /* ContextPtr remains NULL_PTR and length remains zero. */ + retVal = E_OK; + } + else + { + /* retVal remains. */ + } + + if (retVal == E_OK) + { + eslt_Byte eslInstance = 0xFFu; /* Init as invalid value. */ + + /* # Determine eslInstance based on algorithm mode. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_NOT_SET: + /* # If AlgoMode is not set use deprecated Ed25519 function. */ + Crypto_30_LibCv_Ed25519_getEslInstanceofDeprecatedAlgoMode( /* PRQA S 0310 */ /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR)) &eslInstance); + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_PURE: + eslInstance = ESL_INSTANCE_Ed25519; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_CTX: + eslInstance = ESL_INSTANCE_Ed25519CTX; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_PH: + eslInstance = ESL_INSTANCE_Ed25519PH; + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Unsupported mode */ + } + + /* # Init EdDSA algorithm with determined eslInstance. */ + retValCv = esl_initSignEdDSA(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + ESL_CURVE25519, + eslInstance, + contextPtr, + (eslt_Length)contextLength); + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed25519GenerateStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519GenerateFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519GenerateFinish( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_SIGNATURE_KEY, ESL_SIZEOF_Ed25519_SECRET_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Check if key element is accessible. */ + /* # Read key element to get secret key. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + uint32 inputLength = 0u; + /* Get outputLength in local variable to omit type mismatches */ + eslt_Length outputLength = (eslt_Length)*(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* # Determine inputLength based on algorithm mode. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_NOT_SET: + /* # If AlgoMode is not set use deprecated Ed25519 function. */ + Crypto_30_LibCv_Ed25519_getFinishInputLengthOfDeprecatedAlgoMode( /* PRQA S 0310 */ /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily, + (P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))&inputLength); + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_PURE: + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_CTX: + inputLength = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_PH: + /* inputLength remains 0. */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Unsupported mode */ + } + + /* # Generate signature with determined inputLength. */ + retValCv = esl_signEdDSA(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))NULL_PTR, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength); + + if (retValCv == ESL_ERC_NO_ERROR) + { + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) = outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed25519GenerateFinish() */ +#endif /* (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519VerifyStart() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519VerifyStart( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Initialize workspace header. */ + retValCv = esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_Ed25519, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) contextPtr = NULL_PTR; + Crypto_30_LibCv_SizeOfKeyStorageType contextIndex = 0u; + uint32 contextLength = 0u; + + /* # Read key element to get context. */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(job->cryptoKeyId, CRYPTO_KE_CUSTOM_EDDSA_CONTEXT, &contextIndex, &contextLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + contextPtr = Crypto_30_LibCv_GetAddrKeyStorage(contextIndex); + } + else if (retVal == CRYPTO_E_KEY_NOT_AVAILABLE) + { + /* Key has no context key element. */ + /* ContextPtr remains NULL_PTR and length remains zero. */ + retVal = E_OK; + } + else + { + /* retVal remains. */ + } + + if (retVal == E_OK) + { + eslt_Byte eslInstance = 0xFFu; /* Init as invalid value. */ + + /* # Determine eslInstance based on algorithm mode. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_NOT_SET: + /* # If AlgoMode is not set use deprecated Ed25519 function. */ + Crypto_30_LibCv_Ed25519_getEslInstanceofDeprecatedAlgoMode( /* PRQA S 0310 */ /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))&eslInstance); + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_PURE: + eslInstance = ESL_INSTANCE_Ed25519; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_CTX: + eslInstance = ESL_INSTANCE_Ed25519CTX; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_PH: + eslInstance = ESL_INSTANCE_Ed25519PH; + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Unsupported mode */ + } + + /* # Init EdDSA algorithm with determined eslInstance. */ + retValCv = esl_initVerifyEdDSA(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + ESL_CURVE25519, + eslInstance, + contextPtr, + (eslt_Length)contextLength); + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed25519VerifyStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519VerifyFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519VerifyFinish( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + /* # Init verifyPtr to CRYPTO_E_VER_NOT_OK */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* Check if key element is accessible. */ + /* # Read key elements to get public key. */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_SIGNATURE_KEY, ESL_SIZEOF_Ed25519_PUBLIC_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + uint32 inputLength = 0u; + + /* # Determine inputLength based on algorithm mode. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_NOT_SET: + /* # If AlgoMode is not set use deprecated Ed25519 function. */ + Crypto_30_LibCv_Ed25519_getFinishInputLengthOfDeprecatedAlgoMode( /* PRQA S 0310 */ /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength), + job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily, + (P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR))&inputLength); + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_PURE: + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_CTX: + inputLength = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_PH: + /* inputLength remains 0 */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Unsupported mode */ + } + + /* # Verify signature with determined inputLength. */ + retValCv = esl_verifyEdDSA(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); + + /* # Write result in verification pointer. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + else + { + if (retValCv == ESL_ERC_SIGNATURE_INVALID) + { + retValCv = ESL_ERC_NO_ERROR; + } + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed25519VerifyFinish() */ +#endif /* (CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON || CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Ed25519_getEslInstanceofDeprecatedAlgoMode() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Ed25519_getEslInstanceofDeprecatedAlgoMode( + Crypto_AlgorithmSecondaryFamilyType secAlgoFam, + P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) eslInstancePtr) +{ + if (secAlgoFam == CRYPTO_ALGOFAM_SHA2_512) + { + /* # If secondary algorithm family is set, use Ed25519ph as eslInstance. */ + *eslInstancePtr = ESL_INSTANCE_Ed25519ph; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + } + else /* CRYPTO_ALGOFAM_NOT_SET */ + { + /* # Else set eslInstance to Ed25519 */ + *eslInstancePtr = ESL_INSTANCE_Ed25519; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + } +} /* Crypto_30_LibCv_Ed25519_getEslInstanceofDeprecatedAlgoMode() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Ed25519_Update_deprecatedAlgoMode() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(eslt_ErrorCode, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Ed25519_Update_deprecatedAlgoMode( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Calculate Prehash if necessary based on secondary algorithm family. */ + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_SHA2_512) + { + /* Calculate Prehash. */ + retValCv = esl_updateEdDSA(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength); + } + else + { + /* No input data in update is allowed because it can't be processed. */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength == 0u) || (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_FINISH))) + { + /* Nothing to do if no prehashing is used. */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + retValCv = ESL_ERC_ERROR; + } + } + return retValCv; +} /* Crypto_30_LibCv_Ed25519_Update_deprecatedAlgoMode() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Ed25519_getFinishInputLengthOfDeprecatedAlgoMode() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(void, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Ed25519_getFinishInputLengthOfDeprecatedAlgoMode( + uint32 jobInputLength, + Crypto_AlgorithmSecondaryFamilyType secAlgoFam, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) inputLengthPtr) +{ + if (secAlgoFam == CRYPTO_ALGOFAM_SHA2_512) + { + /* # If secondary algorithm family is set, use inputLength 0 because the input has been preHashed. */ + *inputLengthPtr = 0u; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + } + else /* CRYPTO_ALGOFAM_NOT_SET */ + { + /* # Else use the job's inputLength. */ + *inputLengthPtr = jobInputLength; /* SBSW_CRYPTO_30_LIBCV_VARIABLE_ACCESS_PTR_FROM_STACK */ + } +} /* Crypto_30_LibCv_Ed25519_getFinishInputLengthOfDeprecatedAlgoMode() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519Update() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519Update( + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Distinguish mode based on algorithm mode. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_NOT_SET: + /* # If AlgoMode is not set use deprecated Ed25519 function. */ + retValCv = Crypto_30_LibCv_Ed25519_Update_deprecatedAlgoMode(workspace, job); /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_PURE: + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_CTX: + /* If pure or context mode is set, no input data in update is allowed because it can't be processed. */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength == 0u) || (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_FINISH))) + { + /* Nothing to do if no prehashing is used. */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + retValCv = ESL_ERC_ERROR; + } + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED25519_PH: + /* # Process prehashing if necessary. */ + retValCv = esl_updateEdDSA(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Unsupported mode */ + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed25519Update() */ +#endif /* (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON || CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448GenerateStart() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448GenerateStart( + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Initialize workspace header. */ + retValCv = esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_EDDSA, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) contextPtr = NULL_PTR; + uint32 contextLength = 0u; + Crypto_30_LibCv_SizeOfKeyStorageType contextIndex = 0u; + + /* # Read key element to get context. */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(job->cryptoKeyId, CRYPTO_KE_CUSTOM_EDDSA_CONTEXT, &contextIndex, &contextLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + contextPtr = Crypto_30_LibCv_GetAddrKeyStorage(contextIndex); + } + else if (retVal == CRYPTO_E_KEY_NOT_AVAILABLE) + { + /* Key has no context key element. */ + /* ContextPtr remains NULL_PTR and length remains zero. */ + retVal = E_OK; + } + else + { + /* retVal remains. */ + } + + if (retVal == E_OK) + { + eslt_Byte eslInstance = 0xFFu; /* Init as invalid value. */ + + /* # Determine eslInstance based on algorithm mode. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED448_PURE: + eslInstance = ESL_INSTANCE_Ed448; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED448_PH: + eslInstance = ESL_INSTANCE_Ed448PH; + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Unsupported mode */ + } + + /* # Init EdwardsDsa algorithm with determined eslInstance. */ + retValCv = esl_initSignEdwardsDSA(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + ESL_CURVE448, + eslInstance, + contextPtr, + (eslt_Length)contextLength); + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed448GenerateStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448GenerateFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448GenerateFinish( + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_SIGNATURE_KEY, ESL_SIZEOF_Ed448_SECRET_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* Check if key element is accessible. */ + /* # Read key elements to get secret key. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + uint32 inputLength = 0u; + /* Get outputLength in local variable to omit type mismatches */ + eslt_Length outputLength = (eslt_Length)*(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr); + + /* # Determine inputLength based on algorithm mode. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED448_PURE: + /* Use the job's inputLength. */ + inputLength = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED448_PH: + /* inputLength remains 0. */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Unsupported mode */ + } + + /* # Generate signature with determined inputLength. */ + retValCv = esl_signEdwardsDSA(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))NULL_PTR, + (eslt_Length)0u, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&outputLength); + + if (retValCv == ESL_ERC_NO_ERROR) + { + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) = outputLength; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed448GenerateFinish() */ +#endif /* (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448VerifyStart() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448VerifyStart( + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Initialize workspace header. */ + retValCv = esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_EDDSA, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) contextPtr = NULL_PTR; + uint32 contextLength = 0u; + Crypto_30_LibCv_SizeOfKeyStorageType contextIndex = 0u; + + /* # Read key element to get context. */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(job->cryptoKeyId, CRYPTO_KE_CUSTOM_EDDSA_CONTEXT, &contextIndex, &contextLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + contextPtr = Crypto_30_LibCv_GetAddrKeyStorage(contextIndex); + } + else if (retVal == CRYPTO_E_KEY_NOT_AVAILABLE) + { + /* Key has no context key element. */ + /* ContextPtr remains NULL_PTR and length remains zero. */ + retVal = E_OK; + } + else + { + /* retVal remains. */ + } + + if (retVal == E_OK) + { + eslt_Byte eslInstance = 0xFFu; /* Init as invalid value. */ + + /* # Determine eslInstance based on algorithm mode. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED448_PURE: + eslInstance = ESL_INSTANCE_Ed448; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED448_PH: + eslInstance = ESL_INSTANCE_Ed448PH; + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Unsupported mode */ + } + + /* # Init EdwardsDSA algorithm with determined eslInstance. */ + retValCv = esl_initVerifyEdwardsDSA(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + ESL_CURVE448, + eslInstance, + contextPtr, + (eslt_Length)contextLength); + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed448VerifyStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448VerifyFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448VerifyFinish( + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + /* # Init verifyPtr to CRYPTO_E_VER_NOT_OK */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* Check if key element is accessible. */ + /* # Read key elements to get public key. */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_SIGNATURE_KEY, ESL_SIZEOF_Ed448_PUBLIC_KEY); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + uint32 inputLength = 0u; + + /* # Determine inputLength based on algorithm mode. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED448_PURE: + /* Use the job's inputLength. */ + inputLength = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED448_PH: + /* inputLength remains 0. */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Unsupported mode */ + } + + /* # Verify signature with determined inputLength. */ + retValCv = esl_verifyEdwardsDSA(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (eslt_Length)keyElements[0u].keyElementLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); + + /* # Write result in verification pointer. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + else + { + if (retValCv == ESL_ERC_SIGNATURE_INVALID) + { + retValCv = ESL_ERC_NO_ERROR; + } + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed448VerifyFinish() */ +#endif /* (CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON || CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448Update() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448Update( + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED448_PURE: + /* # If pure mode is set, no input data in update is allowed because it can't be processed. */ + if ((job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength == 0u) || (Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_FINISH))) + { + /* Nothing to do if no prehashing is used. */ + retValCv = ESL_ERC_NO_ERROR; + } + else + { + retValCv = ESL_ERC_ERROR; + } + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_ED448_PH: + /* Process prehashing if necessary. */ + retValCv = esl_updateEdwardsDSA(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + break; /* Unsupported mode */ + } + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed448Update() */ +#endif /* (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON || CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON || CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2_CalcUserInfo() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2_CalcUserInfo( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint32 publicKeyElementId) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) publicKeyPtr = NULL_PTR; + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) userIdPtr = NULL_PTR; + + uint32 publicKeyLengthHalf = 0u; + uint32 publicKeyLength = CRYPTO_30_LIBCV_SM2_SIZEOF_PUBLIC_KEY; + uint32 userIdLength = CRYPTO_30_LIBCV_SM2_MAX_SIZEOF_ID; + + Crypto_30_LibCv_SizeOfKeyStorageType publicKeyIndex = 0u; + Crypto_30_LibCv_SizeOfKeyStorageType userIdIndex = 0u; + + /* # Get public key (X|Y). */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(job->cryptoKeyId, publicKeyElementId, &publicKeyIndex, &publicKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + publicKeyPtr = Crypto_30_LibCv_GetAddrKeyStorage(publicKeyIndex); + publicKeyLengthHalf = Crypto_30_LibCv_Math_Div2(publicKeyLength); + + /* # Try to get user ID. */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(job->cryptoKeyId, CRYPTO_KE_CUSTOM_SM2_ID, &userIdIndex, &userIdLength, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == CRYPTO_E_KEY_NOT_AVAILABLE) + { + /* # If KE is not available use NULL_PTR for user ID with length 0 since it's optional. */ + userIdPtr = NULL_PTR; + userIdLength = 0; + retVal = E_OK; + } + else if ((retVal == E_OK) && (userIdLength < CRYPTO_30_LIBCV_SM2_MIN_SIZEOF_ID)) + { + /* # If KE is empty return CRYPTO_E_KEY_SIZE_MISMATCH */ + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + else if (retVal == E_OK) + { + /* # If KE is available (and not empty), get its pointer from index. */ + userIdPtr = Crypto_30_LibCv_GetAddrKeyStorage(userIdIndex); + } + else + { + /* # Else retVal remains on error code from KeyElementGetStorageIndexJobOptional. */ + } + + if (retVal == E_OK) + { + /* # Calculate User Info (ESLib expects user ID length in bits). */ + retValCv = esl_addUserInfoSM2_ECP(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_NULL_PTR */ /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_KEYPTR_AND_LENGTH */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))NULL_PTR, + (eslt_Length)0u, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))userIdPtr, + (eslt_Length)Crypto_30_LibCv_Byte2Bit(userIdLength), + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))publicKeyPtr, + (eslt_Length)publicKeyLengthHalf, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&publicKeyPtr[publicKeyLengthHalf], + (eslt_Length)publicKeyLengthHalf); + + if (retValCv != ESL_ERC_NO_ERROR) + { + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Sm2_CalcUserInfo() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2Update() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2Update( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Add message data to SM2 signature algorithm */ + retValCv = esl_updateMessageSM2_ECP(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength); + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_Sm2Update() */ +#endif /* (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON || CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2GenerateStart() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2GenerateStart( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Init workspace header. */ + if ((esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_SM2, CRYPTO_30_LIBCV_WATCHDOG_PTR)) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* # Init SM2 algorithm with SM2P256V1 curve. */ + retValCv = esl_initSignSM2_ECP(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR */ + Crypto_30_LibCv_EccCurveSm2P256v1Domain, + Crypto_30_LibCv_EccCurveSm2P256v1DomainExt, + Crypto_30_LibCv_EccCurveSm2P256v1SpeedUpExt); + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Calculate User Info. */ + retVal = Crypto_30_LibCv_Dispatch_Sm2_CalcUserInfo(workspace, job, CRYPTO_KE_CUSTOM_SM2_GENERATE_PUBLIC_KEY); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Sm2GenerateStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2GenerateFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2GenerateFinish( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + uint32 privateKeyLength = CRYPTO_30_LIBCV_SM2_SIZEOF_PRIVATE_KEY; + Crypto_30_LibCv_SizeOfKeyStorageType privateKeyIndex = 0u; + + /* # Get private key. */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(job->cryptoKeyId, CRYPTO_KE_SIGNATURE_KEY, &privateKeyIndex, &privateKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* # Check if output buffer is large enough to write the signature (R|S) into it. */ + if (*job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr < CRYPTO_30_LIBCV_SM2_SIZEOF_SIGNATURE) + { + retVal = CRYPTO_E_SMALL_BUFFER; + } + else + { + /* # Get outputLengths in local variables to omit type mismatches. */ + eslt_Length signatureLengthR = CRYPTO_30_LIBCV_SM2_SIZEOF_SIGNATURE_HALF; + eslt_Length signatureLengthS = CRYPTO_30_LIBCV_SM2_SIZEOF_SIGNATURE_HALF; + + P2VAR(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) signaturePtr = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr; + + /* # Generate signature (R|S) with SM2 algorithm. */ + retValCv = esl_signSM2_ECP(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_KEYPTR_AND_LENGTH */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(privateKeyIndex), + (eslt_Length)privateKeyLength, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))signaturePtr, + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&signatureLengthR, + (P2VAR(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&signaturePtr[signatureLengthR], + (P2VAR(eslt_Length, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&signatureLengthS); + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Summarize output lengths of concatenated signature (R|S). */ + *(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) = (uint32)signatureLengthR + (uint32)signatureLengthS; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Sm2GenerateFinish() */ +#endif /* (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2VerifyStart() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2VerifyStart( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Init workspace header. */ + if ((esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_SM2, CRYPTO_30_LIBCV_WATCHDOG_PTR)) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { + /* # Init SM2 algorithm with SM2P256V1 curve. */ + retValCv = esl_initVerifySM2_ECP(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ + Crypto_30_LibCv_EccCurveSm2P256v1Domain, /* SBSW_CRYPTO_30_LIBCV_DOMAIN_PTR */ + Crypto_30_LibCv_EccCurveSm2P256v1DomainExt); + + if (retValCv == ESL_ERC_NO_ERROR) + { + /* # Calculate User Info. */ + retVal = Crypto_30_LibCv_Dispatch_Sm2_CalcUserInfo(workspace, job, CRYPTO_KE_SIGNATURE_KEY); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Sm2VerifyStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2VerifyFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2VerifyFinish( + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + uint32 publicKeyLength = CRYPTO_30_LIBCV_SM2_SIZEOF_PUBLIC_KEY; + Crypto_30_LibCv_SizeOfKeyStorageType publicKeyIndex = 0u; + + /* Init verifyPtr to CRYPTO_E_VER_NOT_OK. */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* Get public key (X|Y). */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(job->cryptoKeyId, CRYPTO_KE_SIGNATURE_KEY, &publicKeyIndex, &publicKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + retVal = E_NOT_OK; + /* Check signature for correct size before dividing by two */ + if (job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength == CRYPTO_30_LIBCV_SM2_SIZEOF_SIGNATURE) + { + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) publicKeyPtr = Crypto_30_LibCv_GetAddrKeyStorage(publicKeyIndex); + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) signaturePtr = job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr; + uint32 publicKeyLengthHalf = Crypto_30_LibCv_Math_Div2(publicKeyLength); + uint32 signatureLengthHalf = Crypto_30_LibCv_Math_Div2(job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); + + /* Verify signature with SM2 algorithm. */ + retValCv = esl_verifySM2_ECP(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ /* SBSW_CRYPTO_30_LIBCV_CALL_WITH_KEYPTR_AND_LENGTH */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))publicKeyPtr, + (eslt_Length)publicKeyLengthHalf, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&publicKeyPtr[publicKeyLengthHalf], + (eslt_Length)publicKeyLengthHalf, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))signaturePtr, + (eslt_Length)signatureLengthHalf, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))&signaturePtr[signatureLengthHalf], + (eslt_Length)signatureLengthHalf); + + /* Write result in verification pointer. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else if (retValCv == ESL_ERC_ECC_SIGNATURE_INVALID) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Sm2VerifyFinish() */ +#endif /* (CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SLHDSAVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SlhDsaVerifyStart() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SlhDsaVerifyStart( + P2VAR(vSecPrimType_WorkSpaceVerifySLHDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + vSecPrim_SLHDSA_Version version, vSecPrim_SLHDSA_HashAlgorithm hashId) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Initialize workspace header. */ + if (esl_initWorkSpaceHeader(&(workspace->header), VSECPRIM_SIZEOF_WS_SLHDSA, CRYPTO_30_LIBCV_WATCHDOG_PTR) == ESL_ERC_NO_ERROR) /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + { +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PURE == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PREHASH == STD_ON) + /* differentiate between pure and pre-hash mode - when mode is pre-hash, a hash function is set as a secondary family */ + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_NOT_SET) +# endif + { + retValCv = vSecPrim_initVerifySLHDSA_pure(workspace, /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + (vSecPrim_SLHDSA_Version)version, + (vSecPrim_SLHDSA_HashAlgorithm)hashId); + } +# endif +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PREHASH == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PURE == STD_ON) + /* differentiate between pure and pre-hash mode*/ + else +# endif + { + Crypto_AlgorithmFamilyType hashAlgoFam = job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily; + + if (hashAlgoFam < Crypto_30_LibCv_GetSizeOfFamilyToHashMapping()) + { + retValCv = vSecPrim_initVerifySLHDSA_preHash(workspace, /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + (vSecPrim_SLHDSA_Version)version, + (vSecPrim_SLHDSA_PreHashAlgorithm)Crypto_30_LibCv_GetFamilyToHashMapping(hashAlgoFam), + (vSecPrim_SLHDSA_HashAlgorithm)hashId); + } + else + { + /* hashAlgoFam not valid */ + /* retValCv = ESL_ERC_ERROR has already been set */ + } + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(job); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_SlhDsaVerifyStart() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SlhDsaVerifyUpdate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SlhDsaVerifyUpdate( + P2VAR(vSecPrimType_WorkSpaceVerifySLHDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job) +{ + Std_ReturnType retVal = E_NOT_OK; + +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PURE == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PREHASH == STD_ON) + /* differentiate between pure and pre-hash mode - when mode is pre-hash, a hash function is set as a secondary family */ + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_NOT_SET) +# endif + { + /* Nothing to do in pure update step */ + retVal = E_OK; + } +# endif +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PREHASH == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PURE == STD_ON) + /* differentiate between pure and pre-hash mode */ + else +# endif + { + eslt_ErrorCode retValCv = vSecPrim_updateVerifySLHDSA_preHash(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength); + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = E_OK; + } + } +# else + CRYPTO_30_LIBCV_DUMMY_STATEMENT(workspace); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CRYPTO_30_LIBCV_DUMMY_STATEMENT(job); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + + return retVal; +} /* Crypto_30_LibCv_Dispatch_SlhDsaVerifyUpdate() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SlhDsaVerifyFinish() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SlhDsaVerifyFinish( + P2VAR(vSecPrimType_WorkSpaceVerifySLHDSA, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + uint32 publicKeyLength) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + P2CONST(uint8, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) publicKey = NULL_PTR; + P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) contextPtr = NULL_PTR; + Crypto_30_LibCv_SizeOfKeyStorageType publicKeyIndex = 0u; + Crypto_30_LibCv_SizeOfKeyStorageType contextIndex = 0u; + uint32 contextLength = 0u; + + /* Init verifyPtr to CRYPTO_E_VER_NOT_OK */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJob(job->cryptoKeyId, CRYPTO_KE_SIGNATURE_KEY, &publicKeyIndex, &publicKeyLength, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* Get publicKey pointer from key element index. */ + publicKey = Crypto_30_LibCv_GetAddrKeyStorage(publicKeyIndex); + + /* context size is checked by vSecPrim */ + retVal = Crypto_30_LibCv_Local_KeyElementGetStorageIndexJobOptional(job->cryptoKeyId, CRYPTO_KE_CUSTOM_SLHDSA_CONTEXT, &contextIndex, &contextLength, CRYPTO_30_LIBCV_LENGTH_CHECK_NONE); /* SBSW_CRYPTO_30_LIBCV_STACK_VARIABLE_AS_PTR */ + + /* check if context is available */ + switch (retVal) + { + case E_OK: + { + contextPtr = Crypto_30_LibCv_GetAddrKeyStorage(contextIndex); + break; + } + case CRYPTO_E_KEY_NOT_AVAILABLE: + { + /* Key has no context key element. */ + /* ContextPtr remains NULL_PTR and length remains zero. */ + retVal = E_OK; + break; + } + default: + { + /* retVal remains */ + break; + } + } + } + + if (retVal == E_OK) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PURE == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PREHASH == STD_ON) + /* differentiate between pure and pre-hash mode - when mode is pre-hash, a hash function is set as a secondary family */ + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_NOT_SET) +# endif + { + /* pure mode */ + retValCv = vSecPrim_finalizeVerifySLHDSA_pure(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + contextPtr, (eslt_Length)contextLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))publicKey, + (eslt_Length)publicKeyLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); + } +# endif +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PREHASH == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PURE == STD_ON) + /* differentiate between pure and pre-hash mode */ + else +# endif + { + /* pre-hash mode */ + retValCv = vSecPrim_finalizeVerifySLHDSA_preHash(workspace, /* PRQA S 0310 */ /* MD_CRYPTO_30_LIBCV_0310 */ /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_CONST_BUFFER */ + contextPtr, (eslt_Length)contextLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))publicKey, + (eslt_Length)publicKeyLength, + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + (eslt_Length)job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength); + } +# endif + + /* # Write result into verification pointer. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else if (retValCv == ESL_ERC_SIGNATURE_INVALID) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_SlhDsaVerifyFinish() */ +#endif /* (CRYPTO_30_LIBCV_SLHDSAVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECPKEYCHECK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_IsPublicKeyOnCurveEcc() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_IsPublicKeyOnCurveEcc( + P2CONST(eslt_WorkSpaceEcPKeyCheck, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + uint32 keyLength = 0u; + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + /* # Retrieve the public key. */ + /* Get esl size of key length for x and y component of the public key (key = [key_x|key_y]). */ + keyLength = (uint32)(Crypto_30_LibCv_Math_Mul2((uint32)esl_getLengthOfEcPpublicKey_comp(EcDomainPtr))); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_SIGNATURE_KEY, keyLength); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* # Check key on curve. */ + retValCv = esl_publicKeyCheckEcP_prim(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_KEY_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (eslt_Length)Crypto_30_LibCv_Math_Div2(keyLength), + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex + Crypto_30_LibCv_Math_Div2(keyLength)), + (eslt_Length)Crypto_30_LibCv_Math_Div2(keyLength)); + + /* # Write result in verification pointer */ + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else if (retValCv == ESL_ERC_KEY_INVALID) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_IsPublicKeyOnCurveEcc() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_IsPrivateKeyOnCurveEcc() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_IsPrivateKeyOnCurveEcc( + P2CONST(eslt_WorkSpaceEcPKeyCheck, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_3 */ + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr) +{ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + uint32 keyLength = 0u; + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + /* # Retrieve the private key. */ + keyLength = (uint32)esl_getLengthOfEcPprivateKey(EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_PTR */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_SIGNATURE_KEY, keyLength); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Handle the specials case that the private key of P160R1 can have a length of 20 or 21 Bytes. */ + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode == CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P160R1) + { + uint32 minKeyLength = CRYPTO_30_LIBCV_SIZEOF_ECC_160_KEY_PRIVATE_MIN; + + /* Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_MAX); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + if (retVal == E_OK) + { + /* Check if key is long enough. */ + if (keyElements[0].keyElementLength < minKeyLength) + { + retVal = CRYPTO_E_KEY_SIZE_MISMATCH; + } + else if (keyElements[0].keyElementLength == minKeyLength) + { + /* Enlarge private key to get required size (21 Bytes): key = [0x00 | privateKey] */ + eslt_Byte privateKeyElementBuffer[CRYPTO_30_LIBCV_SIZEOF_ECC_160_KEY_PRIVATE] = { 0u }; + Crypto_30_LibCv_CopyData(&privateKeyElementBuffer[1u], Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), (keyElements[0].keyElementLength)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_LIBCV_CSL02_KEY_STORAGE_VIA_KEY_ELEMENT */ + /* Check key on curve. */ + retValCv = esl_privateKeyCheckEcP_prim(workspace, privateKeyElementBuffer, (eslt_Length)sizeof(privateKeyElementBuffer)); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + } + else + { + /* Check key on curve. */ + retValCv = esl_privateKeyCheckEcP_prim(workspace, Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), (eslt_Length)(keyElements[0].keyElementLength)); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_STACK_BUFFER */ + } + } + } + else + { + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* # Check key on curve. */ + retValCv = esl_privateKeyCheckEcP_prim(workspace, Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0].keyElementIndex), (eslt_Length)(keyElements[0].keyElementLength)); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_KEY_PTR */ + } + } + + if (retVal == E_OK) + { + /* # Write result in verification pointer. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + else if (retValCv == ESL_ERC_KEY_INVALID) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + } + else + { + retVal = E_NOT_OK; + } + } + return retVal; +} /* Crypto_30_LibCv_IsPrivateKeyOnCurveEcc() */ + +/********************************************************************************************************************** + * Crypto_30_LibCv_EcPKeyCheck_DispatchByKeyType() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_EcPKeyCheck_DispatchByKeyType( + P2VAR(eslt_WorkSpaceEcPKeyCheck, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr, + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr) +{ + Std_ReturnType retVal = E_NOT_OK; + + /* # Init verifyPtr to CRYPTO_E_VER_NOT_OK */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Init keyCheck algorithm. */ + if (esl_initKeyCheckEcP_prim(workspace, EcDomainPtr, EcDomainExtPtr) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ + { + /* # Distinguish between checking a private or a public key based on secondary algorithm family.*/ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily) + { + case CRYPTO_ALGOFAM_CUSTOM_CRYPTO_30_LIBCV_ISPUBLICKEYONCURVE: + retVal = Crypto_30_LibCv_IsPublicKeyOnCurveEcc(workspace, job, EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + + case CRYPTO_ALGOFAM_CUSTOM_CRYPTO_30_LIBCV_ISPRIVATEKEYONCURVE: + retVal = Crypto_30_LibCv_IsPrivateKeyOnCurveEcc(workspace, job, EcDomainPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported mode */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_EcPKeyCheck_DispatchByKeyType() */ +#endif /* (CRYPTO_30_LIBCV_ECPKEYCHECK == STD_ON) */ + +#if (CRYPTO_30_LIBCV_EDKEYCHECK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_EdKeyCheck_DispatchByKeyType() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_LIBCV_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_EdKeyCheck_DispatchByKeyType( + P2VAR(eslt_WorkSpaceEdKeyCheck, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) workspace, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + const eslt_Size16 curve, + const uint32 expectedKeyLength) + { + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + + /* # Init verifyPtr to CRYPTO_E_VER_NOT_OK */ + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + + /* # Init keyCheck algorithm. */ + if (esl_initKeyCheckEdwards(workspace, curve) == ESL_ERC_NO_ERROR) /* SBSW_CRYPTO_30_LIBCV_ESL_PARAMETER_WORKSPACE */ + { + Crypto_30_LibCv_KeyElementGetType keyElements[1]; + + /* # Retrieve the public or private key. */ + Crypto_30_LibCv_Local_ElementGetterSetIdAndLength(keyElements, 0u, CRYPTO_KE_SIGNATURE_KEY, expectedKeyLength); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + + /* # Read key elements. */ + retVal = Crypto_30_LibCv_Local_GetElementsIndexJob(job->cryptoKeyId, keyElements, 1u, CRYPTO_30_LIBCV_LENGTH_CHECK_EQUAL); /* SBSW_CRYPTO_30_LIBCV_STACK_ARRAY_VARIABLE_AS_PTR */ + if (retVal == E_OK) + { + /* # Distinguish between checking a private or a public key based on secondary algorithm family.*/ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily) + { + case CRYPTO_ALGOFAM_CUSTOM_CRYPTO_30_LIBCV_ISPUBLICKEYONCURVE: + /* # Check public key on curve. */ + retValCv = esl_publicKeyCheckEdwards(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_KEY_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (eslt_Length)keyElements[0u].keyElementLength); + break; + + case CRYPTO_ALGOFAM_CUSTOM_CRYPTO_30_LIBCV_ISPRIVATEKEYONCURVE: + /* # Check private key on curve. */ + retValCv = esl_privateKeyCheckEdwards(workspace, /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_KEY_PTR */ + (P2CONST(eslt_Byte, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR))Crypto_30_LibCv_GetAddrKeyStorage(keyElements[0u].keyElementIndex), + (eslt_Length)keyElements[0u].keyElementLength); + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported mode */ + break; + } + + /* # Write result in verification pointer. */ + if (retValCv == ESL_ERC_NO_ERROR) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else if (retValCv == ESL_ERC_KEY_INVALID) + { + *job->CRYPTO_30_LIBCV_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = CRYPTO_E_VER_NOT_OK; /* SBSW_CRYPTO_30_LIBCV_WRITE_ACCESS_TO_JOBPRIMITIVE_INPUTOUTPUT_PTR */ + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + } + } + + return retVal; +} /* Crypto_30_LibCv_EdKeyCheck_DispatchByKeyType() */ +#endif /* (CRYPTO_30_LIBCV_EDKEYCHECK == STD_ON) */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ +#if (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519Generate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfEd25519Generate(Crypto_30_LibCv_GetEd25519GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceEd25519)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_Ed25519GenerateStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_Ed25519Update(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_Ed25519GenerateFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed25519Generate() */ + +#endif /* (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519Verify() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceEd25519, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfEd25519Verify(Crypto_30_LibCv_GetEd25519VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceEd25519)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_Ed25519VerifyStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_Ed25519Update(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_Ed25519VerifyFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + retVal = E_NOT_OK; /* Unsupported State */ + break; + } + } + + return retVal; + +} /* Crypto_30_LibCv_Dispatch_Ed25519Verify() */ +#endif /* (CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448Generate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfEd448Generate(Crypto_30_LibCv_GetEd448GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceEdDSA)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_Ed448GenerateStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_Ed448Update(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_Ed448GenerateFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Ed448Generate() */ + +#endif /* (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448Verify() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceEdDSA, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfEd448Verify(Crypto_30_LibCv_GetEd448VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceEdDSA)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_Ed448VerifyStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_Ed448Update(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_Ed448VerifyFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + retVal = E_NOT_OK; /* Unsupported State */ + break; + } + } + + return retVal; + +} /* Crypto_30_LibCv_Dispatch_Ed448Verify() */ +#endif /* (CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2Generate() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfSm2Generate(Crypto_30_LibCv_GetSm2GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceSM2)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_Sm2GenerateStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_Sm2Update(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_Sm2GenerateFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_Sm2Generate() */ + +#endif /* (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2Verify() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceSM2, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfSm2Verify(Crypto_30_LibCv_GetSm2VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceSM2)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_Sm2VerifyStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_Sm2Update(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_Sm2VerifyFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + retVal = E_NOT_OK; /* Unsupported State */ + break; + } + } + + return retVal; + +} /* Crypto_30_LibCv_Dispatch_Sm2Verify() */ +#endif /* (CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_SLHDSAVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SlhDsaVerify() + **********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SlhDsaVerify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + uint32 publicKeyLength = 0u; + vSecPrim_SLHDSA_Version version = 0xFFu; /* Init an invalid value. */ + vSecPrim_SLHDSA_HashAlgorithm hashId = 0xFFu; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(vSecPrimType_WorkSpaceVerifySLHDSA, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfSlhDsaVerify(Crypto_30_LibCv_GetSlhDsaVerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(vSecPrimType_WorkSpaceVerifySLHDSA)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* Determine SLH-DSA version and hash ID based on job algorithm mode. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_SHA2_128S: + { + publicKeyLength = VSECPRIM_SLHDSA_PK_LENGTH_128S; + version = VSECPRIM_SLHDSA_VERSION_128S; + hashId = VSECPRIM_SLHDSA_HASH_ID_SHA2_256; + retVal = E_OK; + break; + } + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + retVal = E_NOT_OK; /* retVal has been set before, set it here anyways */ + break; /* Unsupported mode */ + } + } + + if (retVal == E_OK) + { +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PURE == STD_ON) +# if (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PREHASH == STD_ON) + /* Determine if SLHDSA should be executed in pure mode */ + if (job->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily == CRYPTO_ALGOFAM_NOT_SET) +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PREHASH == STD_ON) */ + { + /* no secondary algorithm family is given, therefore the algorithm shall be executed in pure mode + * this is only applicable if the job mode is single call */ + if (!Crypto_30_LibCv_IsJobMode(job, CRYPTO_OPERATIONMODE_SINGLECALL)) + { + retVal = E_NOT_OK; + } + } + + if (retVal == E_OK) +# endif /* (CRYPTO_30_LIBCV_SIGNATURE_VERIFY_CUSTOM_SLH_DSA_PURE == STD_ON) */ + { + /* Distinguish operation modes. */ + switch (mode) + { + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_Dispatch_SlhDsaVerifyStart(workspace, job, version, hashId); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_Dispatch_SlhDsaVerifyUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_Dispatch_SlhDsaVerifyFinish(workspace, job, publicKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_SlhDsaVerify() */ +#endif /* (CRYPTO_30_LIBCV_SLHDSAVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Generate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6030, 6050, 6080 4 */ /* MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceRSAsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfRsaPkcs1Generate(Crypto_30_LibCv_GetRsaPkcs1GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceRSAsig)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_RsaPkcs1GenerateStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_RsaPkcs1GenerateUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_RsaPkcs1GenerateFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaPkcs1Generate() */ +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Verify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6030, 6050, 6080 4 */ /* MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceRSAver, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfRsaPkcs1Verify(Crypto_30_LibCv_GetRsaPkcs1VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceRSAver)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_RsaPkcs1VerifyStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_RsaPkcs1VerifyUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_RsaPkcs1VerifyFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaPkcs1Verify() */ +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPSSGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPssGenerate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6030, 6050, 6080 4 */ /* MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPssGenerate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + + P2VAR(eslt_WorkSpaceRSAPSSsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfRsaPssGenerate(Crypto_30_LibCv_GetRsaPssGenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceRSAPSSsig)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_RsaPssGenerateStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_RsaPssGenerateUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_RsaPssGenerateFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaPssGenerate() */ +#endif /* (CRYPTO_30_LIBCV_RSAPSSGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPSSVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPssVerify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6030, 6050, 6080 4 */ /* MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPssVerify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(Crypto_30_LibCv_WorkSpaceRsaPssVer, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfRsaPssVerify(Crypto_30_LibCv_GetRsaPssVerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(Crypto_30_LibCv_WorkSpaceRsaPssVer)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_RsaPssVerifyStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_RsaPssVerifyUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_RsaPssVerifyFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaPssVerify() */ +#endif /* (CRYPTO_30_LIBCV_RSAPSSVERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_RSAPKCS1CRTGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1CrtGenerate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1CrtGenerate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + + /* ----- Implementation ------------------------------------------------- */ + P2VAR(eslt_WorkSpaceRSACRTsig, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace = Crypto_30_LibCv_GetWorkspaceOfRsaPkcs1CrtGenerate(Crypto_30_LibCv_GetRsaPkcs1CrtGenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceRSACRTsig)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + retVal = Crypto_30_LibCv_RsaPkcs1CrtGenerateStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + retVal = Crypto_30_LibCv_RsaPkcs1CrtGenerateUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + retVal = Crypto_30_LibCv_RsaPkcs1CrtGenerateFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported State */ + break; + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_RsaPkcs1CrtGenerate() */ +#endif /* (CRYPTO_30_LIBCV_RSAPKCS1CRTGENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP160Generate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP160Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + /* ----- Implementation ------------------------------------------------- */ + workspace = Crypto_30_LibCv_GetWorkspaceOfEcP160Generate(Crypto_30_LibCv_GetEcP160GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(vSecPrimType_WorkSpaceHash)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_EcP160Generate() */ +#endif /* (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECP160VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP160Verify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP160Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + /* ----- Implementation ------------------------------------------------- */ + workspace = Crypto_30_LibCv_GetWorkspaceOfEcP160Verify(Crypto_30_LibCv_GetEcP160VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(vSecPrimType_WorkSpaceHash)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_EcP160Verify() */ +#endif /* (CRYPTO_30_LIBCV_ECP160VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECP256GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP256Generate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP256Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + /* ----- Implementation ------------------------------------------------- */ + /* NISTp256r1 = ANSIp256r1 = SECp256r1 */ + workspace = Crypto_30_LibCv_GetWorkspaceOfEcP256Generate(Crypto_30_LibCv_GetEcP256GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(vSecPrimType_WorkSpaceHash)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_EcP256Generate() */ +#endif /* (CRYPTO_30_LIBCV_ECP256GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECP256VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP256Verify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP256Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + /* ----- Implementation ------------------------------------------------- */ + /* NISTp256r1 = ANSIp256r1 = SECp256r1 */ + workspace = Crypto_30_LibCv_GetWorkspaceOfEcP256Verify(Crypto_30_LibCv_GetEcP256VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(vSecPrimType_WorkSpaceHash)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_EcP256Verify() */ +#endif /* (CRYPTO_30_LIBCV_ECP256VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECP384GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP384Generate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP384Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + /* ----- Implementation ------------------------------------------------- */ + /* NISTp384r1 = SECp384r1 */ + workspace = Crypto_30_LibCv_GetWorkspaceOfEcP384Generate(Crypto_30_LibCv_GetEcP384GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(vSecPrimType_WorkSpaceHash)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_EcP384Generate() */ +#endif /* (CRYPTO_30_LIBCV_ECP384GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECP384VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP384Verify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP384Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + /* ----- Implementation ------------------------------------------------- */ + /* NISTp384r1 = SECp384r1 */ + workspace = Crypto_30_LibCv_GetWorkspaceOfEcP384Verify(Crypto_30_LibCv_GetEcP384VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(vSecPrimType_WorkSpaceHash)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_EcP384Verify() */ +#endif /* (CRYPTO_30_LIBCV_ECP384VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECP521GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP521Generate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP521Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + /* ----- Implementation ------------------------------------------------- */ + workspace = Crypto_30_LibCv_GetWorkspaceOfEcP521Generate(Crypto_30_LibCv_GetEcP521GenerateIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(vSecPrimType_WorkSpaceHash)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeGenerateFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_EcP521Generate() */ +#endif /* (CRYPTO_30_LIBCV_ECP521GENERATE == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECP521VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP521Verify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP521Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + P2VAR(Crypto_30_LibCv_WorkSpaceEcP, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + + /* ----- Implementation ------------------------------------------------- */ + workspace = Crypto_30_LibCv_GetWorkspaceOfEcP521Verify(Crypto_30_LibCv_GetEcP521VerifyIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(vSecPrimType_WorkSpaceHash)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operationmode START. */ + case CRYPTO_OPERATIONMODE_START: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyStart(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + /* # Handle operationmode UPDATE. */ + case CRYPTO_OPERATIONMODE_UPDATE: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyUpdate(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + retVal = Crypto_30_LibCv_DispatchSignatureEccPrimeVerifyFinish(workspace, job); /* SBSW_CRYPTO_30_LIBCV_ESL_CALL_WITH_WORKSPACE_AND_BUFFERS */ + break; + } + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + { + /* Not supported State */ + break; + } + } + + return retVal; +} /* Crypto_30_LibCv_Dispatch_EcP521Verify() */ +#endif /* (CRYPTO_30_LIBCV_ECP521VERIFY == STD_ON) */ + +#if (CRYPTO_30_LIBCV_ECPKEYCHECK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcPKeyCheck() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcPKeyCheck( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + P2VAR(eslt_WorkSpaceEcPKeyCheck, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + P2CONST(eslt_EccDomain, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainPtr = Crypto_30_LibCv_EccCurveEmptyDomain; + P2CONST(eslt_EccDomainExt, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) EcDomainExtPtr = Crypto_30_LibCv_EccCurveEmptyDomain; + + /* ----- Implementation ------------------------------------------------- */ + workspace = Crypto_30_LibCv_GetWorkspaceOfEcPKeyCheck(Crypto_30_LibCv_GetEcPKeyCheckIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceEcPKeyCheck)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operation mode START and UPDATE. */ + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + { + /* Nothing to do. */ + retVal = E_OK; + break; + } + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + /* # Determine curve domain based on algorithm mode. */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.mode) + { + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P160R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveSecP160R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveSecP160R1DomainExt; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P256R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveNistAnsiSecP256R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistAnsiSecP256R1DomainExt; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P384R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveNistSecP384R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistSecP384R1DomainExt; + break; + + case CRYPTO_ALGOMODE_CUSTOM_CRYPTO_30_LIBCV_P521R1: + EcDomainPtr = Crypto_30_LibCv_EccCurveNistSecP521R1Domain; + EcDomainExtPtr = Crypto_30_LibCv_EccCurveNistSecP521R1DomainExt; + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported mode */ + break; + } + + /* # Initialize workspace header. */ + retValCv = esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_ECP_KEY_CHECK, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = Crypto_30_LibCv_EcPKeyCheck_DispatchByKeyType(workspace, job, EcDomainPtr, EcDomainExtPtr); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + } + break; + } + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported mode */ + break; + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_EcPKeyCheck() */ +#endif /* (CRYPTO_30_LIBCV_ECPKEYCHECK == STD_ON) */ + +#if (CRYPTO_30_LIBCV_EDKEYCHECK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EdKeyCheck() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EdKeyCheck( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, /* PRQA S 3673 */ /* MD_CRYPTO_30_LIBCV_3673_1 */ + Crypto_OperationModeType mode) +{ + /* ----- Local Variables ------------------------------------------------ */ + Std_ReturnType retVal = E_NOT_OK; + eslt_ErrorCode retValCv = ESL_ERC_ERROR; + P2VAR(eslt_WorkSpaceEdKeyCheck, AUTOMATIC, CRYPTO_30_LIBCV_CRYPTOCV_APPL_VAR) workspace; + eslt_Size16 curve = 0u; + uint32 expectedKeyLength = 0u; + + /* ----- Implementation ------------------------------------------------- */ + workspace = Crypto_30_LibCv_GetWorkspaceOfEdKeyCheck(Crypto_30_LibCv_GetEdKeyCheckIdxOfObjectInfo(objectId)); + Crypto_30_LibCv_SetLengthOfSaveAndRestoreWorkspace(objectId, sizeof(eslt_WorkSpaceEdKeyCheck)); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_SIZEOFWORKSPACELENGTH */ + + /* # Distinguish modes. */ + switch (mode) + { + /* # Handle operation mode START and UPDATE. */ + case CRYPTO_OPERATIONMODE_START: + case CRYPTO_OPERATIONMODE_UPDATE: + { + /* Nothing to do. */ + retVal = E_OK; + break; + } + /* # Handle operationmode FINISH. */ + case CRYPTO_OPERATIONMODE_FINISH: + { + /* # Determine curve based on algorithm family */ + switch (job->jobPrimitiveInfo->primitiveInfo->algorithm.family) + { + case CRYPTO_ALGOFAM_ED25519: + curve = ESL_CURVE25519; + expectedKeyLength = ESL_SIZEOF_Ed25519_KEY; /* Same size for private and public key */ + break; + + case CRYPTO_ALGOFAM_CUSTOM_CRYPTO_30_LIBCV_ED448: + curve = ESL_CURVE448; + expectedKeyLength = ESL_SIZEOF_Ed448_KEY; /* Same size for private and public key */ + break; + + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported mode */ + break; + } + + /* # Initialize workspace header. */ + retValCv = esl_initWorkSpaceHeader(&(workspace->header), ESL_SIZEOF_WS_EDKEYCHECK, CRYPTO_30_LIBCV_WATCHDOG_PTR); /* PRQA S 3395 */ /* MD_CRYPTO_30_LIBCV_3395 */ /* SBSW_CRYPTO_30_LIBCV_INIT_ESL_WORKSPACE */ + + if (retValCv == ESL_ERC_NO_ERROR) + { + retVal = Crypto_30_LibCv_EdKeyCheck_DispatchByKeyType(workspace, job, curve, expectedKeyLength); /* SBSW_CRYPTO_30_LIBCV_FORWARDING_OF_WORKSPACE_AND_JOB_PTR */ + } + break; + } + default: /* COV_CRYPTO_30_LIBCV_MISRA_ADDITIONAL_STATEMENT */ + /* Not supported mode */ + break; + } + return retVal; +} /* Crypto_30_LibCv_Dispatch_EdKeyCheck() */ +#endif /* (CRYPTO_30_LIBCV_EDKEYCHECK == STD_ON) */ + +#define CRYPTO_30_LIBCV_STOP_SEC_CODE +#include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_Signature.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_SignatureGenerate.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_SignatureGenerate.h new file mode 100644 index 0000000..879f8ce --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_SignatureGenerate.h @@ -0,0 +1,334 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_SignatureGenerate.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for SIGNATURE Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_SIGNATUREGENERATE_H) +# define CRYPTO_30_LIBCV_SIGNATUREGENERATE_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519Generate() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature Ed25519 generate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-137758 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ED25519GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448Generate() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature Ed448 generate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-Ed448Generate + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ED448GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2Generate() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature Sm2 generate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-Sm2Generate + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_SM2GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAPKCS1GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Generate() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature RSA PKCS1 generate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-137967 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAPKCS1GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAPSSGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPssGenerate() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature RSA PSS generate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-137761 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPssGenerate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAPSSGENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAPKCS1CRTGENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1CrtGenerate() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature RSA CRT PKCS1 generate job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-149659 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1CrtGenerate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAPKCS1CRTGENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP160Generate() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime generate job based on curve SECP160 to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-244684 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP160Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ECP160GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECP256GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP256Generate() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime generate job based on curve SECP256 to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-139645, CREQ-141041, CREQ-141043 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP256Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ECP256GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECP384GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP384Generate() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime generate job based on curve SECP384 to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-158943, CREQ-158945 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP384Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ECP384GENERATE == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECP521GENERATE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP521Generate() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime generate job based on curve SECP521 to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-313250, CREQ-322902 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP521Generate( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ECP521GENERATE == STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CRYPTO_30_LIBCV_SIGNATUREGENERATE_H) */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_SignatureGenerate.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_SignatureVerify.h b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_SignatureVerify.h new file mode 100644 index 0000000..96b46b1 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Implementation/Crypto_30_LibCv_SignatureVerify.h @@ -0,0 +1,389 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_LibCv_SignatureVerify.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Dispatcher for SIGNATURE Services + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_LIBCV_SIGNATUREVERIFY_H) +# define CRYPTO_30_LIBCV_SIGNATUREVERIFY_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_LibCv_Cfg.h" + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_START_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed25519Verify() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature Ed25519 verify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-137762 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed25519Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ED25519VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Ed448Verify() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature Ed448 verify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-Ed448Verify + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Ed448Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ED448VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_Sm2Verify() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature SM2 verify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-Sm2Verify + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_Sm2Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_SM2VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_SLHDSAVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_SlhDsaVerify() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature SLH-DSA verify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-SlhDsaVerify + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_SlhDsaVerify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_SLHDSAVERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAPKCS1VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPkcs1Verify() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature RSA PKCS1 verify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-137763 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPkcs1Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAPKCS1VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_RSAPSSVERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_RsaPssVerify() + *********************************************************************************************************************/ +/*! \brief Dispatches the signature RSA PSS verify job to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-137966 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_RsaPssVerify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_RSAPSSVERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECP160VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP160Verify() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime verify job based on curve SECP160 to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-244685 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP160Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ECP160VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECP256VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP256Verify() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime verify job based on curve SECP256 to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-139644, CREQ-141042, CREQ-141044 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP256Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ECP256VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECP384VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP384Verify() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime verify job based on curve SECP384 to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-158944 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP384Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ECP384VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECP521VERIFY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcP521Verify() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the signature Ecc prime verify job based on curve SECP521 to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-313251, CREQ-322901 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcP521Verify( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif /* (CRYPTO_30_LIBCV_ECP521VERIFY == STD_ON) */ + +# if (CRYPTO_30_LIBCV_ECPKEYCHECK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EcPKeyCheck() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the IsKeyOnCurve job based on EC curves to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-CRYPTO-ISPUBLICKEYONCURVE, CREQ-CRYPTO-ISPRIVATEKEYONCURVE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EcPKeyCheck( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif + +# if (CRYPTO_30_LIBCV_EDKEYCHECK == STD_ON) +/********************************************************************************************************************** + * Crypto_30_LibCv_Dispatch_EdKeyCheck() + *********************************************************************************************************************/ +/*! + * \brief Dispatches the IsKeyOnCurve job based on Ed curves to the lower layer. + * \details This function dispatches the provided job to the lower layer crypto library. Based on the jobs + * operation mode, it triggers different stages of the service. + * \param[in] objectId Holds the identifier of the Crypto Driver Object. + * \param[in,out] job Pointer to the job which shall be dispatched. + * \param[in] mode Operation mode in which the job currently is. + * \return E_OK Dispatching was successful. + * E_NOT_OK Dispatching failed. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre objectId has to be a valid driver object handle. + * job has to be a pointer to a valid job object. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-CRYPTO-ISPUBLICKEYONCURVE, CREQ-CRYPTO-ISPRIVATEKEYONCURVE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_LIBCV_CODE) Crypto_30_LibCv_Dispatch_EdKeyCheck( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_LIBCV_APPL_VAR) job, + Crypto_OperationModeType mode); +# endif + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +# define CRYPTO_30_LIBCV_STOP_SEC_CODE +# include "Crypto_30_LibCv_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CRYPTO_30_LIBCV_SIGNATUREVERIFY_H) */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_LibCv_SignatureVerify.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_cfg.mak b/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_cfg.mak new file mode 100644 index 0000000..24baadf --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_cfg.mak @@ -0,0 +1,81 @@ +############################################################################### +# File Name : Crypto_30_LibCv_cfg.mak +# Description: Configuration makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Crypto_30_LibCv_rules.mak file. +############################################################################### + +############################################################## +# CAN_CONFIG_PATH: (not used for Vector) +# The Variable CAN_CONFIG_PATH is optional. It allows the +# configuration of the directory, where you can also find the +# generated source files. Generally they should be in the +# directory $(PROJECT_ROOT)\source\networks. +# But if the application should run on several hardware +# targets, then different CAN configurations of different +# directories will be necessary. Therefor the variable +# CAN_CONFIG_PATH should be used. +# +# For example: +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\st10 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# + +#_CONFIG_PATH = + + +############################################################## +# CAN_DRIVER_MODE: (not used for Vector) +# This Variable contains the name of the can driver module. At +# the moment the Standard Software Core Supports the two driver +# can_drv.c (single CAN) and can_drvm.c (multi CAN). Other +# values are not allowed. +# +# For example: +# CAN_DRIVER_MODE = singlechannel/multichannel +# + +#_DRIVER_MODE = singlechannel + + +############################################################### +# REQUIRED +# +# No Other resources are required to write a Configuration +# Makefile. +# +############################################################### + + +############################################################### +# PROVIDE +# +# A Configuration Makefile does not provide resources for other +# basic software bundles or the base_make package +# +############################################################### + + +############################################################### +# REGISTRY +# +# Like the Provide-Section this block is empty. +# +############################################################### + + +############################################################### +# SPECIFIC +# +# All variables in the _cfg makefile are "Specific" variables, +# because they should only be used in the *_check.mak, +# *_defs.mak and *_rules.mak Makefiles of the same basic +# software bundle. +############################################################### diff --git a/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_check.mak b/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_check.mak new file mode 100644 index 0000000..b162b41 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_check.mak @@ -0,0 +1,79 @@ +############################################################################### +# File Name : Crypto_30_LibCv_check.mak +# Description: Configuration check makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Crypto_30_LibCv_rules.mak file. +############################################################################### + +############################################################### +# REGISTRY +# + +#e.g.: PREPARE_CONFIGURATION_INTERFACE += CAN_MODULES +PREPARE_CONFIGURATION_INTERFACE += + +CHECK_VARS_WHICH_ARE_REQUIRED += + +CHECK_VARS_WHICH_ARE_OPTIONAL += + +CHECK_VARS_WHICH_ARE_OBSOLETE += + +CHECK_VARS_WITH_ONE_CC_FILE += +CHECK_VARS_WITH_MORE_CC_FILES += + +CHECK_VARS_WITH_ONE_CPP_FILE += +CHECK_VARS_WITH_MORE_CPP_FILES += + +CHECK_VARS_WITH_ONE_ASM_FILE += +CHECK_VARS_WITH_MORE_ASM_FILES += + +CHECK_VARS_WITH_ONE_LIB_FILE += +CHECK_VARS_WITH_MORE_LIB_FILES += + +CHECK_VARS_WITH_ONE_OBJ_FILE += +CHECK_VARS_WITH_MORE_OBJ_FILES += + +#e.g: CHECK_VARS_WITH_ONE_DIRECTORY += $(DIRECTORIES_TO_CREATE) +# $(DIRECTORIES_TO_CREATE) = C:\demo\drv (this var is defined in _rules.mak) +CHECK_VARS_WITH_ONE_DIRECTORY += +CHECK_VARS_WITH_MORE_DIRECTORIES += + +CHECK_VARS_WITH_ONE_FILE += +CHECK_VARS_WITH_MORE_FILES += + +CHECK_VARS_WITH_MAX_LENGTH_ONE += + +############################################################### +# SPECIFIC +# +#ifneq ($(CAN_DRIVER_MODE),singlechannel) +#ifneq ($(CAN_DRIVER_MODE),multichannel) +#$(error The value of the variable CAN_DRIVER_MODE is not valid. \ +# Please use singlechannel or multichannel) +#endif +#endif + + +############################################################### +# REQUIRED +# +# No other resources are required for a Configuration Check +# Makefile +# +############################################################### + + +############################################################### +# PROVIDE +# +# A configuration Makefile does not provide resources for other +# basic software bundles or the base-make package. +# +############################################################### + diff --git a/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_defs.mak b/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_defs.mak new file mode 100644 index 0000000..13a5621 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_defs.mak @@ -0,0 +1,81 @@ +############################################################################### +# File Name : Crypto_30_LibCv_defs.mak +# Description: Public makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Crypto_30_LibCv_rules.mak file. +############################################################################### + +############################################################### +# INTERNAL REQUIRED CONFIGURATION (in can_cfg.mak) +# +# CAN_MODULES (required) (not necessary for Vector) +# CAN_DRIVER_MODE (required) (not necessary for Vector) +# CAN_PROJECT_PATH (optional) +# CAN_BUILD_LIBRARY (required) + + +############################################################### +# REQUIRED (defined in base_make) +# +# PROJECT_ROOT +# SSC_ROOT +############################################################### + + +############################################################### +# SPECIFIC +# Specific variables which were defined here are only for local use in this Makefile +# if for example additional includes are necessary, these vars can be defined and used in the REGISTRY-Part. +# e.g.: $(CAN_CORE_PATH) = $(SSC_ROOT)\Can could be used for CPP_INCLUDE_PATH += $(CAN_CORE_PATH)\CPP_FILES\... +CRYPTO_30_LIBCV_CORE_PATH = +# e.g.: CAN_OUTPUT_PATH = $(GENDATA_DIR) +CRYPTO_30_LIBCV_OUTPUT_PATH = $(GENDATA_DIR) + +#CAN_TOOL_PATH = $(PROJECT_ROOT)\core\com\can\gentool + +# it is also possible to generate own configurations with some checks like the following example +# ifneq ( $(CAN_CONFIG_PATH),) +# CAN_PROJECT_PATH = $(CAN_CONFIG_PATH) +# else +# CAN_PROJECT_PATH = $(PROJECT_ROOT)\source\network\can +# endif + + +############################################################### +# REGISTRY +# +# $(SSC_PLUGINS) is a list of the components. Here can is added (not necessary for Vector, whole component-list also exists in Global.makefile.target.make...) +# e.g.: SSC_PLUGINS += can +SSC_PLUGINS += +#e.g.: can_DEPENDENT_PLUGINS = +CRYPTO_30_LIBCV_DEPENDENT_PLUGINS = + +#----------------------------------------------------------------------------------------- +# MakeSupport usually includes all header-files which were in the same +# directory as the source-files automatically, but to ensure that the +# Asr-Makefiles will also work with other Basic-Make-Packages, +# it is necessary to define all include directories for this Module +# e.g.: CC_INCLUDE_PATH += $(CAN_CORE_PATH) +#------------------------------------------------------------------------------------------ +CC_INCLUDE_PATH += Crypto_30_LibCv$(BSW_SRC_DIR) +CPP_INCLUDE_PATH += +ASM_INCLUDE_PATH += + +#PREPROCESSOR_DEFINES+= drivermode + +#drivermode_KEY = CAN_MODE +#drivermode_VALUE = $(CAN_DRIVER_MODE) + + +############################################################### +# PROVIDE +# +# A Public Makefile does not provide resources for other basic +# software bundles or the base_make package. +############################################################### diff --git a/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_rules.mak b/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_rules.mak new file mode 100644 index 0000000..01cdb17 --- /dev/null +++ b/Source/bsw/Crypto_30_LibCv/Make/Crypto_30_LibCv_rules.mak @@ -0,0 +1,105 @@ +############################################################################### +# File Name : Crypto_30_LibCv_rules.mak +# Description: Rules makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Version Date Author Description +#------------------------------------------------------------------------------ +# 1.00.00 2016-11-24 vismss Creation for ASR 4.3 +# 1.01.00 2019-02-06 vircbl Added support of component-based SIP structure +# 1.02.00 2020-02-07 vistof Add Crypto_30_LibCv_KeyDerive.c and Crypto_30_LibCv_KeyEchange.c +# 1.03.00 2020-04-27 visenc Add Crypto_30_LibCv_KeyGenerate.c +# 13.01.00 2023-06-29 viskju Add Crypto_30_LibCv_Curve.c +# main-1 2024-03-25 coechsler Change history is maintained in the global +# ChangeHistory.txt file starting with this release. +#------------------------------------------------------------------------------ +# TemplateVersion = 1.03 +############################################################################### + + +############################################################### +# REGISTRY +# + +#e.g.: LIBRARIES_TO_BUILD += $(LIB_OUPUT_PATH)\vendorx_canlib1.$(LIB_FILE_SUFFIX) +LIBRARIES_TO_BUILD += Crypto_30_LibCv +Crypto_30_LibCv_FILES = Crypto_30_LibCv$(BSW_SRC_DIR)\Crypto_30_LibCv*.c + +# e.g.: CC_FILES_TO_BUILD += drv\can_drv.c +CC_FILES_TO_BUILD += Crypto_30_LibCv$(BSW_SRC_DIR)\Crypto_30_LibCv*.c +CPP_FILES_TO_BUILD += +ASM_FILES_TO_BUILD += + +#LIBRARIES_LINK_ONLY += (not yet supported) +#OBJECTS_LINK_ONLY += (not yet supported) + +#------------------------------------------------------------------------------------------------- +#only define new dirs, OBJ, LIB, LOG were created automaticly +#------------------------------------------------------------------------------------------------- +DIRECTORIES_TO_CREATE += + +#DEPEND_GCC_OPTS += (not yet supported) + +# e.g.: GENERATED_SOURCE_FILES += $(GENDATA_DIR)\drv_par.c +GENERATED_SOURCE_FILES += $(GENDATA_DIR)\Crypto_30_LibCv_Cfg.c + +#e.g.: COMMON_SOURCE_FILES += $(GENDATA_DIR)\v_par.c +COMMON_SOURCE_FILES += + +#------------------------------------------------------------------------------------------------- +# .dep & .lnk & .bin and..... +# all in err\ & obj\ & lst\ & lib\ & log\ will be deleted by clean-rule automaticly +# so in this clean-rule it is only necessary to define additional files which +# were not delete automaticly. +# e.g.: $()\can_test.c +#------------------------------------------------------------------------------------------------- +MAKE_CLEAN_RULES += +#MAKE_GENERATE_RULES += +#MAKE_COMPILER_RULES += +#MAKE_DEBUG_RULES += +#MAKE_CONFIG_RULES += +#MAKE_ADD_RULES += + + +############################################################### +# REQUIRED (defined in BaseMake (global.Makefile.target.make...)) +# +# SSC_ROOT (required) +# PROJECT_ROOT (required) +# +# LIB_OUTPUT_PATH (optional) +# OBJ_OUTPUT_PATH (optional) +# +# OBJ_FILE_SUFFIX +# LIB_FILE_SUFFIX +# +############################################################### + + +############################################################### +# PROVIDE this Section can be used to define own additional rules +# +# In vendorx_can_cfg.mak: +# Please configure the project file: +#CAN_CONFIG_FILE = $(PROJECT_ROOT)\source\network\can\my_can_config.cfg + +#In vendorx_can_config : +#generate_can_config: + #$(SSC_ROOT)\core\com\can\tools\canconfiggen.exe -o $(CAN_CONFIG_FILE) + + +############################################################### +# SPECIFIC +# +# There are no rules defined for the Specific part of the +# Rules-Makefile. Each author is free to create temporary +# variables or to use other resources of GNU-MAKE +# +############################################################### + + diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm.c b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm.c new file mode 100644 index 0000000..e399cb2 --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm.c @@ -0,0 +1,1806 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_vHsm.c + * \brief MICROSAR vHsm Crypto Driver (Crypto) + * + * \details Core of the Vector Hardware Security Module Firmware driver. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + * + * FILE VERSION + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the VERSION CHECK below. + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Crypto_30_vHsm.h" +#include "Crypto_30_vHsm_Ipc.h" +#include "Crypto_30_vHsm_Jobs.h" +#include "Crypto_30_vHsm_Private.h" +#include "SchM_Crypto_30_vHsm.h" +#include "vstdlib.h" +#include "CryIf_Cbk.h" + +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) +# include "Det.h" +#endif + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ + + /* Check the version of CRYPTO header file */ +#if ( (CRYPTO_30_VHSM_MAJOR_VERSION != (4u)) \ + || (CRYPTO_30_VHSM_MINOR_VERSION != (1u)) \ + || (CRYPTO_30_VHSM_PATCH_VERSION != (2u)) ) +# error "Vendor specific version numbers of Crypto_30_vHsm.c and Crypto_30_vHsm.h are inconsistent" +#endif + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION MACROS + *********************************************************************************************************************/ +#if !defined (CRYPTO_30_VHSM_LOCAL) /* COV_CRYPTO_30_VHSM_LOCAL_DEFINE */ +# define CRYPTO_30_VHSM_LOCAL static +#endif + +#if !defined (CRYPTO_30_VHSM_LOCAL_INLINE) /* COV_CRYPTO_30_VHSM_LOCAL_DEFINE */ +# define CRYPTO_30_VHSM_LOCAL_INLINE LOCAL_INLINE +#endif + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_START_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_IsCryptoJobAccepted() + *********************************************************************************************************************/ +/*! + * + * \brief Check if the job can be accepted + * \details When a job is not finished, only the same jobId will be forwarded. All other jobs will be blocked. + * \param[in] jobRequestId Valid driver object ID which shall be checked + * \param[in] jobId JobId which shall be checked for acceptance + * \param[in] ignoreRequestLock Determines if the lock on the jobRequest should be ignored. + * Lock can only be ignored if driver object lock is set accordingly. + * \return E_OK if the job is accepted, otherwise E_NOT_OK + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_IsCryptoJobAccepted( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + uint32 jobId, + boolean ignoreRequestLock); + +/********************************************************************************************************************** + * Crypto_30_vHsm_FinalizeSyncCryptoJob() + *********************************************************************************************************************/ + /*! + * + * \brief Finalize a synchronous crypto job. + * \details Frees the locks if suitable. + * \param[in] jobRequestId Valid jobRequestId of the job to be concluded + * \param[in] job Valid pointer to the job structure + * \param[in] cancel Indicates if this was a cancel request + * \return Return of the job + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_FinalizeSyncCryptoJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) job, + boolean cancel); + +/********************************************************************************************************************** + * Crypto_30_vHsm_ProcessCryptoJob() + *********************************************************************************************************************/ +/*! + * + * \brief Process a crypto job + * \details Putting the job request into the IPC and send the request to the vHsm + * \param[in] jobRequestId Valid jobRequestId which shall be used to process the job + * \param[in] job Valid pointer to the job structure + * \param[in] cancel Indicates if this is a cancel request + * \param[in] ignoreRequestLock Determines if the lock on the jobRequest should be ignored. + * Lock can only be ignored if driver object lock is set accordingly. + * \return Return of the job + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE or FALSE depending on the job + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ProcessCryptoJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) job, + boolean cancel, + boolean ignoreRequestLock); + +/********************************************************************************************************************** + * Crypto_30_vHsm_TransmitRequest() + *********************************************************************************************************************/ +/*! + * + * \brief Use the Ipc to transmit a job request + * \details - + * \param[in] jobRequestId Valid Id of the job request + * \param[out] channel Valid pointer to the memory location which will contain the channel + * \return Return of the job request + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_TransmitRequest( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2VAR(Crypto_30_vHsm_ChannelIdType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) channel); + +#define CRYPTO_30_VHSM_STOP_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define CRYPTO_30_VHSM_START_SEC_RAMCODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_WaitForSynchJobResponse() + *********************************************************************************************************************/ +/*! \brief Waits for a synchronous job response. + * \details - + * \param[in] jobRequestId Valid Id of the job request (in range of Crypto_30_vHsm_GetSizeOfJobRequest()) + * \param[in] partitionIdx Valid identifier of the partition. + * \param[in] rxChannelId Rx channel to poll. + * \pre jobRequestId < Crypto_30_vHsm_GetSizeOfJobRequest() + * \context TASK + * \reentrant FALSE + * \synchronous TRUE Sync + * \trace CREQ-Crypto-WaitLoopCallout, CREQ-Crypto-AsyncCallout + *********************************************************************************************************************/ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_WaitForSynchJobResponse( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx, + Crypto_30_vHsm_ChannelIdType rxChannelId); + +#define CRYPTO_30_VHSM_STOP_SEC_RAMCODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ +#define CRYPTO_30_VHSM_START_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_IsCryptoJobAccepted() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_IsCryptoJobAccepted( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + uint32 jobId, + boolean ignoreRequestLock) /* PRQA S 3673 */ /* MD_CRYPTO_30_VHSM_3673_API_SPECIFIC */ +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + + uint32 acceptedCryptoJobId; + + /* ----- Implementation ----------------------------------------------- */ + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_0(); + + acceptedCryptoJobId = Crypto_30_vHsm_GetDriverObjectLock(jobRequestId); + + /* #10 Check if the driver object accepts all jobs */ + if (acceptedCryptoJobId == CRYPTO_30_VHSM_ACCEPT_ANY_JOBID) + { + /* #11 Check if the jobRequestId is free */ + if (Crypto_30_vHsm_IsLockOfJobRequest(jobRequestId) == FALSE) /* currently needed as driver object is released before this lock */ + { + /* #12 Lock the jobRequestId */ + Crypto_30_vHsm_SetDriverObjectLock(jobRequestId, jobId); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + /* #13 Prevent the access of the driver object from other other jobs */ + Crypto_30_vHsm_SetLockOfJobRequest(jobRequestId, TRUE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + retVal = E_OK; + } + } + /* #20 Check if the given JobId can be accepted for this driver object */ + else if (acceptedCryptoJobId == jobId) + { +#if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) + if (ignoreRequestLock == TRUE) + { + /* #21 If the job request lock should be ignored, accept the crypto job */ + retVal = E_OK; + } + else +#endif /* (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) */ + /* Driver object is already acquired by this job - Check if there is an former update pending or if we can start with this one */ + /* #22 Otherwise check if the jobRequestId is free */ + if (Crypto_30_vHsm_IsLockOfJobRequest(jobRequestId) == FALSE) + { + /* #23 Lock the jobRequestId */ + Crypto_30_vHsm_SetLockOfJobRequest(jobRequestId, TRUE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + retVal = E_OK; + } + else + { + /* Do nothing. retVal already set. */ + } + } + else + { + /* driver object is is use - retval already set */ + } + + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_0(); + +#if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_OFF) + CRYPTO_30_VHSM_DUMMY_STATEMENT(ignoreRequestLock); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_IsCryptoJobAccepted() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_FinalizeSyncCryptoJob() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_FinalizeSyncCryptoJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) job, + boolean cancel) +{ + Std_ReturnType retVal; + + /* #10 Obtain state and return value of synchronous crypto job. */ + job->CRYPTO_30_VHSM_JOB_STATE_MEMBER = Crypto_30_vHsm_GetJobStateOfJobRequest(jobRequestId); /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + retVal = (Std_ReturnType)Crypto_30_vHsm_GetResultOfJobRequest(jobRequestId); + +#if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) + /* #11 Only free locks if job was not timeouted */ + if (Crypto_30_vHsm_GetStateOfJobRequest(jobRequestId) != CRYPTO_30_VHSM_JOBREQUEST_STATE_TIMEOUT) +#endif + { + /* #20 Free the job request lock */ + Crypto_30_vHsm_SetLockOfJobRequest(jobRequestId, FALSE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + /* #21 Check if the mode was finish or error or cancel */ + if ((retVal != E_OK) + || ((job->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode & CRYPTO_OPERATIONMODE_FINISH) == CRYPTO_OPERATIONMODE_FINISH) + || cancel) + { + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_2(); + /* #30 Remove the lock from the driver object to accept new jobs */ + Crypto_30_vHsm_SetDriverObjectLock(jobRequestId, CRYPTO_30_VHSM_ACCEPT_ANY_JOBID); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_2(); + } + } + + return retVal; +} /* Crypto_30_vHsm_ProcessCryptoJob() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ProcessCryptoJob() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ProcessCryptoJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) job, + boolean cancel, + boolean ignoreRequestLock) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check if the request is accepted by the crypto driver object and can be allocated inside the IPC */ + if (Crypto_30_vHsm_IsCryptoJobAccepted(jobRequestId, job->jobInfo->jobId, ignoreRequestLock) == E_OK) /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + { +#if (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION == STD_ON) + /* #20 Set the parameters of the job request */ + if( (job->jobPrimitiveInfo->primitiveInfo->service) == CRYPTO_MACVERIFY) + { + Crypto_30_vHsm_SetKindOfJobRequest(jobRequestId, CRYPTO_30_VHSM_CRYPTO_MACVER_JOBKIND); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + else if ((job->jobPrimitiveInfo->primitiveInfo->service) == CRYPTO_MACGENERATE) + { + Crypto_30_vHsm_SetKindOfJobRequest(jobRequestId, CRYPTO_30_VHSM_CRYPTO_MACGEN_JOBKIND); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + else +#endif /* (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION == STD_ON) */ +#if (CRYPTO_30_VHSM_KEY_DERIVE_JOB_SUPPORT == STD_ON) + if ((job->jobPrimitiveInfo->primitiveInfo->service) == CRYPTO_KEYDERIVE) + { + Crypto_30_vHsm_SetKindOfJobRequest(jobRequestId, CRYPTO_30_VHSM_KEYMANAGEMENT_KEYDERIVEJOB_JOBKIND); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + else +#endif + { + Crypto_30_vHsm_SetKindOfJobRequest(jobRequestId, CRYPTO_30_VHSM_CRYPTO_JOBKIND); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + + Crypto_30_vHsm_SetCryptoJobOfJobRequest(jobRequestId, job); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetCancelOfJobRequest(jobRequestId, cancel); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_SetContextClassOfJobRequest(jobRequestId, CRYPTO_30_VHSM_CALLOUT_CRYPTOJOB); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetContextIdOfJobRequest(jobRequestId, Crypto_30_vHsm_GetCryptoJobOfJobRequest(jobRequestId)->jobInfo->jobId); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#endif + + if (cancel == TRUE) + { +#if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) + if (Crypto_30_vHsm_GetTimeoutRecoveryStateOfJobRequest(jobRequestId) == CRYPTO_30_VHSM_TIMEOUT_RECOVERY_PENDING) + { + /* If the original job was timeouted, we try to asynchronously cancel the job. */ + Crypto_30_vHsm_SetProcessingTypeOfJobRequest(jobRequestId, CRYPTO_PROCESSING_ASYNC); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + else +#endif /* (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) */ + { + Crypto_30_vHsm_SetProcessingTypeOfJobRequest(jobRequestId, CRYPTO_PROCESSING_SYNC); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + } + else + { + Crypto_30_vHsm_SetProcessingTypeOfJobRequest(jobRequestId, job->jobPrimitiveInfo->processingType); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + + /* 21 Save job state and set it to processing */ + Crypto_30_vHsm_SetJobStateOfJobRequest(jobRequestId, job->CRYPTO_30_VHSM_JOB_STATE_MEMBER); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + job->CRYPTO_30_VHSM_JOB_STATE_MEMBER = CRYPTO_JOBSTATE_PROGRESSING; /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + + /* #30 Process crypto job request. */ + retVal = Crypto_30_vHsm_ProcessJobRequest(jobRequestId, Crypto_30_vHsm_GetCurrentPartitionIdxOfObjectInfo(jobRequestId)); + + /* #40 Check if the job request has been correctly issued */ + if (retVal == E_OK) + { + /* #50 If the job is synchronous: */ + if (Crypto_30_vHsm_GetProcessingTypeOfJobRequest(jobRequestId) == CRYPTO_PROCESSING_SYNC) + { + /* #51 Finalize synchronous job */ + retVal = Crypto_30_vHsm_FinalizeSyncCryptoJob(jobRequestId, job, cancel); /* SBSW_CRYPTO_30_VHSM_PROCESS_CRYPTO_JOB */ + } + /* #60 ELSE: If the job is asynchronous return E_OK */ + } + /* #70 If job could not be issued correctly: */ + else + { + /* #71 Restore job state and free the job request lock */ + job->CRYPTO_30_VHSM_JOB_STATE_MEMBER = Crypto_30_vHsm_GetJobStateOfJobRequest(jobRequestId); /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + Crypto_30_vHsm_SetLockOfJobRequest(jobRequestId, FALSE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_2(); + /* #72 Remove the lock from the driver object to accept new jobs */ + Crypto_30_vHsm_SetDriverObjectLock(jobRequestId, CRYPTO_30_VHSM_ACCEPT_ANY_JOBID); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_2(); + } + } + else + { + /* #80 If the job request could not be allocated because the IPC was full return BUSY */ + retVal = CRYPTO_E_BUSY; + } + + return retVal; +} /* Crypto_30_vHsm_ProcessCryptoJob() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_TransmitRequest() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_TransmitRequest( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2VAR(Crypto_30_vHsm_ChannelIdType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) channel) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + Crypto_30_vHsm_ChannelIdType txChannelIdTmp; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdxOfObjectInfo(jobRequestId); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Get the TxChannel */ + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_0(); + for (txChannelIdTmp = 0u; txChannelIdTmp < Crypto_30_vHsm_GetSizeOfChannelState(partitionIdx); txChannelIdTmp++) + { + if (Crypto_30_vHsm_GetChannelState(txChannelIdTmp, partitionIdx) == CRYPTO_30_VHSM_IPC_CHANNELSTATE_FREE) + { + *channel = txChannelIdTmp; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_STACK */ + Crypto_30_vHsm_SetChannelState(txChannelIdTmp, (Crypto_30_vHsm_ChannelStateType)(Crypto_30_vHsm_GetProcessingTypeOfJobRequest(jobRequestId) + 1u), partitionIdx); /* SBSW_CRYPTO_30_VHSM_CSL01_CHANNELSTATE */ + break; + } + } + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_0(); + + if (txChannelIdTmp >= Crypto_30_vHsm_GetSizeOfChannelState(partitionIdx)) + { + retVal = CRYPTO_E_BUSY; + } + else + { + /* #30 Transmit the job request */ + retVal = Crypto_30_vHsm_Ipc_TransmitRequest(*channel, jobRequestId); + } + +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_TransmitRequest() */ + +#define CRYPTO_30_VHSM_STOP_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define CRYPTO_30_VHSM_START_SEC_RAMCODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/********************************************************************************************************************** + * Crypto_30_vHsm_WaitForSynchJobResponse() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_WaitForSynchJobResponse( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx, + Crypto_30_vHsm_ChannelIdType rxChannelId) +{ +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_Start_Callout( /* PRQA S 0404 */ /* MD_CRYPTO_30_VHSM_0404_VOLATILE_READ */ + CRYPTO_30_VHSM_CALLOUT_JOBREQUEST, + Crypto_30_vHsm_GetHsmObjIdOfObjectInfo(jobRequestId), + Crypto_30_vHsm_GetContextClassOfJobRequest(jobRequestId), + Crypto_30_vHsm_GetContextIdOfJobRequest(jobRequestId)); +#endif + /* #10 Wait until job response is available */ + /* The Flag will be set in the interrupt triggered by the vHsm */ + while (Crypto_30_vHsm_GetStateOfJobRequest(jobRequestId) == CRYPTO_30_VHSM_JOBREQUEST_STATE_PROCESSING) /* FETA_CRYPTO_30_VHSM_WAIT_FOR_HSM_WITH_CALLOUT */ + { + /* #20 Process the job response available in the IPC if interrupt mode is disabled */ + Crypto_30_vHsm_Ipc_ReceiveResponse(partitionIdx, rxChannelId); + +#if (CRYPTO_30_VHSM_WAIT_LOOP_CALLOUT_ENABLED == STD_ON) + Crypto_30_vHsm_GetWaitLoopCallout()(); +#endif +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_Loop_Callout( /* PRQA S 0404 */ /* MD_CRYPTO_30_VHSM_0404_VOLATILE_READ */ + CRYPTO_30_VHSM_CALLOUT_JOBREQUEST, + Crypto_30_vHsm_GetHsmObjIdOfObjectInfo(jobRequestId), + Crypto_30_vHsm_GetContextClassOfJobRequest(jobRequestId), + Crypto_30_vHsm_GetContextIdOfJobRequest(jobRequestId)); +#endif + } + +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_End_Callout( /* PRQA S 0404 */ /* MD_CRYPTO_30_VHSM_0404_VOLATILE_READ */ + CRYPTO_30_VHSM_CALLOUT_JOBREQUEST, + Crypto_30_vHsm_GetHsmObjIdOfObjectInfo(jobRequestId), + Crypto_30_vHsm_GetContextClassOfJobRequest(jobRequestId), + Crypto_30_vHsm_GetContextIdOfJobRequest(jobRequestId)); +#endif + +#if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) + if (Crypto_30_vHsm_GetStateOfJobRequest(jobRequestId) == CRYPTO_30_VHSM_JOBREQUEST_STATE_TIMEOUT) + { + /* Save the used channelId of the job request to be able to check for a response */ + Crypto_30_vHsm_SetChannelOfJobRequest(jobRequestId, rxChannelId); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + else +#endif /* (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) */ + { + Crypto_30_vHsm_SetStateOfJobRequest(jobRequestId, CRYPTO_30_VHSM_JOBREQUEST_STATE_IDLE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + + /* #21 Check if a Det error has been reported */ + Crypto_30_vHsm_Ipc_HandleDet(partitionIdx); /* PRQA S 2987 */ /* MD_CRYPTO_30_VHSM_2987_HANDLEDET */ +} /* Crypto_30_vHsm_WaitForSynchJobResponse() */ + +#define CRYPTO_30_VHSM_STOP_SEC_RAMCODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ +#define CRYPTO_30_VHSM_START_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_Init() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Init(void) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Crypto_30_vHsm_ChannelStateIterType txChannel; + Crypto_30_vHsm_ObjectInfoIterType objectInfo; + + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Check initialization state of the component for the partition */ + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) == (uint8)CRYPTO_30_VHSM_INITIALIZED) + { + errorId = CRYPTO_E_INIT_FAILED; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #20 Initialize the IPC */ +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES > 1u) + Crypto_30_vHsm_Ipc_MemoryPtrOfPartition[partitionIdx] = &Crypto_30_vHsm_GetIpcMemoryPtr(partitionIdx)[0U]; /* SBSW_CRYPTO_30_VHSM_IPC_MEMORY_PTR_ARRAY */ +#else + Crypto_30_vHsm_Ipc_MemoryPtrOfPartition[partitionIdx] = &Crypto_30_vHsm_Ipc_Memory[0U]; /* SBSW_CRYPTO_30_VHSM_IPC_MEMORY_PTR_ARRAY */ +#endif + +#if (CRYPTO_30_VHSM_IPC_INITIALIZATION == STD_ON) + /* Check if Ipc has already been initialized before */ +# if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES > 1u) + if ((*(volatile uint32*)CRYPTO_30_VHSM_HOST2_HSM_ADDRESS & ((uint32)1u << (uint32)Crypto_30_vHsm_GetIpcInstanceId(partitionIdx))) != ((uint32)1u << (uint32)Crypto_30_vHsm_GetIpcInstanceId(partitionIdx))) /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ +# else + if (Crypto_30_vHsm_IsIpcNotInitialized()) /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ +# endif + { + /* Initialize IPC */ + VStdLib_MemClr(Crypto_30_vHsm_Ipc_MemoryPtrOfPartition[partitionIdx], (uint32)CRYPTO_30_VHSM_IPC_MEMORY_SIZE); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_VHSM_INIT_IPC_MEMORY */ + } +#endif /* (CRYPTO_30_VHSM_IPC_INITIALIZATION == STD_ON) */ + + for (txChannel = 0u; txChannel < Crypto_30_vHsm_GetSizeOfChannelState(partitionIdx); txChannel++) + { + Crypto_30_vHsm_SetChannelState(txChannel, CRYPTO_30_VHSM_IPC_CHANNELSTATE_FREE, partitionIdx); /* SBSW_CRYPTO_30_VHSM_CSL01_CHANNELSTATE */ + } + +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_Ipc_DriverProtocolVersion(partitionIdx) = CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION; /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ +#endif + + /* #30 Reset job request states */ + for (objectInfo = 0u; objectInfo < Crypto_30_vHsm_GetSizeOfObjectInfo(); objectInfo++) + { +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES > 1u) + /* Initialize only the objects mapped to the current partition */ + if (Crypto_30_vHsm_GetPartitionIdxOfObjectInfo(objectInfo) == partitionIdx) +#endif + { + Crypto_30_vHsm_SetDriverObjectLock(objectInfo, CRYPTO_30_VHSM_ACCEPT_ANY_JOBID); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetLockOfJobRequest(objectInfo, FALSE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetStateOfJobRequest(objectInfo, CRYPTO_30_VHSM_JOBREQUEST_STATE_IDLE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetCounterOfJobRequest(objectInfo, 0u); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + +#if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) + Crypto_30_vHsm_SetTimeoutRecoveryStateOfJobRequest(objectInfo, CRYPTO_30_VHSM_TIMEOUT_RECOVERY_IDLE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#endif + } + } + +#if (CRYPTO_30_VHSM_IPC_INITIALIZATION == STD_ON) + /* Indicate that IPC has been initialized. HSM will now be able to use the IPC. */ + Crypto_30_vHsm_IndicateInitializedIpcOfPartition(partitionIdx); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ /* SBSW_CRYPTO_30_VHSM_REGISTER_ACCESS */ + + Crypto_30_vHsm_TriggerInterruptOfPartition(partitionIdx); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_TRIGGER_INTERRUPT */ +#endif + + /* #40 Set module state to initialized for the partition */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + Crypto_30_vHsm_SetPartitionInitialized(CRYPTO_30_VHSM_INITIALIZED, partitionIdx); /* SBSW_CRYPTO_30_VHSM_WRITE_PARTITION_DATA */ +#endif + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + /* #100 Call Det if error occurred */ + (void)Det_ReportError(CRYPTO_30_VHSM_MODULE_ID, CRYPTO_30_VHSM_INSTANCE_ID, CRYPTO_30_VHSM_SID_INIT, errorId); + } +#else + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ +} /* Crypto_30_vHsm_Init() */ + +#if (CRYPTO_30_VHSM_VERSION_INFO_API == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_GetVersionInfo() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_GetVersionInfo( + P2VAR(Std_VersionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) versioninfo +) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Check if provided pointer is valid */ + if (versioninfo == NULL_PTR) + { + /* [SWS_Crypto_00042] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else +# endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #20 Copy the version info to the provided buffer */ + versioninfo->vendorID = (uint16)CRYPTO_30_VHSM_VENDOR_ID; /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + versioninfo->moduleID = (uint8)CRYPTO_30_VHSM_MODULE_ID; /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + versioninfo->sw_major_version = (uint8)CRYPTO_30_VHSM_MAJOR_VERSION; /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + versioninfo->sw_minor_version = (uint8)CRYPTO_30_VHSM_MINOR_VERSION; /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + versioninfo->sw_patch_version = (uint8)CRYPTO_30_VHSM_PATCH_VERSION; /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + /* #30 Call Det if pointer was invalid */ + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + (uint8)CRYPTO_30_VHSM_SID_GET_VERSION_INFO, + errorId); + } +# else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} /* Crypto_30_vHsm_GetVersionInfo() */ +#endif /* (CRYPTO_30_VHSM_VERSION_INFO_API == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ProcessJob() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ProcessJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) job) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + /* #9 Check plausibility of input parameters */ + /* [SWS_Crypto_00058] Check if driver object is valid */ + if (objectId >= Crypto_30_vHsm_GetSizeOfObjMap()) + { + errorId = CRYPTO_E_PARAM_HANDLE; + } + /* [SWS_Crypto_00059] Check if job is a null pointer */ + else if ( job == NULL_PTR ) + { + errorId = CRYPTO_E_PARAM_POINTER; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #10 Get internal handle */ + if (Crypto_30_vHsm_IsObjectInfoUsedOfObjMap(objectId) == FALSE) /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + { + /* [SWS_Crypto_00058] Check if object id is out of range */ + errorId = CRYPTO_E_PARAM_HANDLE; + } +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + /* #11 Check initialization state of the component */ + else if(Crypto_30_vHsm_GetPartitionInitialized(Crypto_30_vHsm_GetCurrentPartitionIdxOfObjectInfo(Crypto_30_vHsm_GetObjectInfoIdxOfObjMap(objectId))) == (uint8)CRYPTO_30_VHSM_UNINIT) + { + /* [SWS_Crypto_00057] Check initialization state of the component */ + errorId = CRYPTO_E_UNINIT; + } +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + else + { + errorId = CRYPTO_E_NO_ERROR; + + /* #12 Process the job */ + retVal = Crypto_30_vHsm_ProcessCryptoJob(Crypto_30_vHsm_GetObjectInfoIdxOfObjMap(objectId), job, FALSE, FALSE); /* SBSW_CRYPTO_30_VHSM_PROCESS_CRYPTO_JOB */ + } + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + /* #100 Call Det if error occurred */ + (void)Det_ReportError(CRYPTO_30_VHSM_MODULE_ID, CRYPTO_30_VHSM_INSTANCE_ID, CRYPTO_30_VHSM_SID_PROCESS_JOB, errorId); + } +#else + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +} /* Crypto_30_vHsm_ProcessJob() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_CancelJob() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ + /* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_CancelJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) job) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + uint8 errorId; + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + /* #9 Check plausibility of input parameters */ + /* [SWS_Crypto_00124] Check if driver object is valid */ + if (objectId >= Crypto_30_vHsm_GetSizeOfObjMap()) + { + errorId = CRYPTO_E_PARAM_HANDLE; + } + /* [SWS_Crypto_00125] Check if job is a null pointer */ + else if (job == NULL_PTR) + { + errorId = CRYPTO_E_PARAM_POINTER; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + + /* #10 Get internal handle */ + if (Crypto_30_vHsm_IsObjectInfoUsedOfObjMap(objectId) == FALSE) /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + { + /* [SWS_Crypto_00124] Check if object id is out of range */ + errorId = CRYPTO_E_PARAM_HANDLE; + } +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + /* #11 Check if module is initialized */ + /* [SWS_Crypto_00057] Check initialization state of the component */ + else if (Crypto_30_vHsm_GetPartitionInitialized(Crypto_30_vHsm_GetCurrentPartitionIdxOfObjectInfo(Crypto_30_vHsm_GetObjectInfoIdxOfObjMap(objectId))) == (uint8)CRYPTO_30_VHSM_UNINIT) + { + errorId = CRYPTO_E_UNINIT; + } +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + else + { + errorId = CRYPTO_E_NO_ERROR; + + /* #12 Process the job */ + retVal = Crypto_30_vHsm_ProcessCryptoJob(Crypto_30_vHsm_GetObjectInfoIdxOfObjMap(objectId), job, TRUE, FALSE); /* SBSW_CRYPTO_30_VHSM_PROCESS_CRYPTO_JOB */ + + if ( (retVal == E_OK) + && (job->jobPrimitiveInfo->processingType == CRYPTO_PROCESSING_ASYNC)) + { + CryIf_CallbackNotification(job, CRYPTO_E_JOB_CANCELED); /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + } + } + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + /* #100 Call Det if error occurred */ + (void)Det_ReportError(CRYPTO_30_VHSM_MODULE_ID, CRYPTO_30_VHSM_INSTANCE_ID, CRYPTO_30_VHSM_SID_CANCEL_JOB, errorId); + } +#else + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint !e438 */ +#endif /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + + if (retVal != E_OK) + { + retVal = E_NOT_OK; + } + + return retVal; +} /* Crypto_30_vHsm_CancelJob() */ + +#if (CRYPTO_30_VHSM_NUMBER_OF_PARTITIONS > 1u) +/********************************************************************************************************************** + * Crypto_30_vHsm_GetPartitionIdx() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Crypto_30_vHsm_PartitionIdentifiersIterType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_GetPartitionIdx(void) +{ + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = 0u; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdentifierIdx = 0u; + ApplicationType applicationId = GetApplicationID(); + + for (partitionIdentifierIdx = 0u; partitionIdentifierIdx < Crypto_30_vHsm_GetSizeOfPartitionIdentifiers(); partitionIdentifierIdx++) + { + if (applicationId == Crypto_30_vHsm_GetPartitionSNVOfPartitionIdentifiers(partitionIdentifierIdx)) + { + partitionIdx = Crypto_30_vHsm_GetPCPartitionConfigIdxOfPartitionIdentifiers(partitionIdentifierIdx); + break; + } + } + return partitionIdx; +} /* Crypto_30_vHsm_GetPartitionIdx() */ +#endif /* (CRYPTO_30_VHSM_NUMBER_OF_PARTITIONS > 1u) */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_TriggerInterruptOfPartition() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_TriggerInterruptOfPartition(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ +#if (CRYPTO_30_VHSM_FLAG_SETTING_CHECK_NEEDED == STD_ON) + /* #10 Check if the interrupt triggering for the partition is enabled */ + if (Crypto_30_vHsm_GetFlagSetting(partitionIdx) == 1u) +#endif + { +#if (CRYPTO_30_VHSM_INTERRUPT_SETTING_AVAILABLE ==STD_ON) +# if (CRYPTO_30_VHSM_IS_VTT == STD_OFF) /* COV_CRYPTO_30_VHSM_VTT */ + /* #20 Check how the interrupt shall be triggered for RealTarget */ + switch (Crypto_30_vHsm_GetFlagSetHandling(partitionIdx)) + { +# if (CRYPTO_30_VHSM_INTERRUPT_SET_INCLUSIVE_OR_ASSIGNMENT_AVAILABLE == STD_ON) + case CRYPTO_30_VHSM_SET_INCLUSIVE_OR_ASSIGNMENT: + (*(volatile uint32*)((uint32)Crypto_30_vHsm_GetFlagSetAddress(partitionIdx))) |= Crypto_30_vHsm_GetFlagSetMask(partitionIdx); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ /* SBSW_CRYPTO_30_VHSM_REGISTER_ACCESS */ + break; +# endif +# if (CRYPTO_30_VHSM_INTERRUPT_SET_CALLOUT_AVAILABLE == STD_ON) + case CRYPTO_30_VHSM_SET_CALLOUT: + Crypto_30_vHsm_RequestInterruptSet_Callout(Crypto_30_vHsm_GetFlagSetAddress(partitionIdx), Crypto_30_vHsm_GetFlagSetMask(partitionIdx)); /* SBSW_CRYPTO_30_VHSM_HANDLE_INTERRUPT */ + break; +# endif +# if (CRYPTO_30_VHSM_INTERRUPT_SET_ONLY_ASSIGNMENT_AVAILABLE == STD_ON) + case CRYPTO_30_VHSM_SET_ONLY_ASSIGNMENT: + (*(volatile uint32*)((uint32)Crypto_30_vHsm_GetFlagSetAddress(partitionIdx))) = Crypto_30_vHsm_GetFlagSetMask(partitionIdx); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ /* SBSW_CRYPTO_30_VHSM_REGISTER_ACCESS */ + break; +# endif + default: /* COV_CRYPTO_30_VHSM_MISRA_ADDITIONAL_STATEMENT */ /* PRQA S 2016 */ /* MD_MSR_EmptyClause */ + break; + } +# else /* !(CRYPTO_30_VHSM_IS_VTT == STD_OFF) */ + /* #30 Call the helper function for VTT */ + Ht2Hsmf(); +# endif +#endif /* (CRYPTO_30_VHSM_INTERRUPT_SETTING_AVAILABLE ==STD_ON) */ + } + + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +} /* Crypto_30_vHsm_TriggerInterruptOfPartition() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ClearInterruptOfPartition() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ClearInterruptOfPartition(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ +#if (CRYPTO_30_VHSM_FLAG_CLEARING_CHECK_NEEDED == STD_ON) + /* #10 Check if the interrupt clearing for the partition is enabled */ + if (Crypto_30_vHsm_GetFlagClearing(partitionIdx) == 1u) /*lint !e506 */ +#endif + { +#if (CRYPTO_30_VHSM_INTERRUPT_CLEARING_AVAILABLE ==STD_ON) +# if (CRYPTO_30_VHSM_IS_VTT == STD_OFF) /* COV_CRYPTO_30_VHSM_VTT */ + /* #20 Check how the interrupt shall be cleared */ + switch (Crypto_30_vHsm_GetFlagClearHandling(partitionIdx)) + { +# if (CRYPTO_30_VHSM_INTERRUPT_CLEAR_INCLUSIVE_AND_NOT_ASSIGNMENT_AVAILABLE == STD_ON) + case CRYPTO_30_VHSM_CLEAR_INCLUSIVE_AND_NOT_ASSIGNMENT: + (*(volatile uint32*)((uint32)Crypto_30_vHsm_GetFlagClearAddress(partitionIdx))) &= ~((uint32)Crypto_30_vHsm_GetFlagClearMask(partitionIdx)); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ /* SBSW_CRYPTO_30_VHSM_REGISTER_ACCESS */ + break; +# endif +# if (CRYPTO_30_VHSM_INTERRUPT_CLEAR_INCLUSIVE_OR_ASSIGNMENT_AVAILABLE == STD_ON) + case CRYPTO_30_VHSM_CLEAR_INCLUSIVE_OR_ASSIGNMENT: + (*(volatile uint32*)((uint32)Crypto_30_vHsm_GetFlagClearAddress(partitionIdx))) |= Crypto_30_vHsm_GetFlagClearMask(partitionIdx); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ /* SBSW_CRYPTO_30_VHSM_REGISTER_ACCESS */ + break; +# endif +# if (CRYPTO_30_VHSM_INTERRUPT_CLEAR_CALLOUT_AVAILABLE == STD_ON) + case CRYPTO_30_VHSM_CLEAR_CALLOUT: + Crypto_30_vHsm_ResponseInterruptClear_Callout(Crypto_30_vHsm_GetFlagClearAddress(partitionIdx), Crypto_30_vHsm_GetFlagClearMask(partitionIdx), Crypto_30_vHsm_GetFlagClearValue(partitionIdx)); /* SBSW_CRYPTO_30_VHSM_HANDLE_INTERRUPT */ + break; +# endif +# if (CRYPTO_30_VHSM_INTERRUPT_CLEAR_ONLY_READ_AVAILABLE == STD_ON) + case CRYPTO_30_VHSM_CLEAR_ONLY_READ: + { + volatile uint32 dummy = (*(volatile uint32*)(uint32)Crypto_30_vHsm_GetFlagClearAddress(partitionIdx)); /* PRQA S 3205, 0303 */ /* MD_CRYPTO_30_VHSM_3205_DUMMY_READ */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(dummy); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + } + break; +# endif /* (CRYPTO_30_VHSM_INTERRUPT_CLEAR_ONLY_READ_AVAILABLE == STD_ON) */ + default: /* COV_CRYPTO_30_VHSM_MISRA_ADDITIONAL_STATEMENT */ /* PRQA S 2016 */ /* MD_MSR_EmptyClause */ + break; + } +# endif /* (CRYPTO_30_VHSM_IS_VTT == STD_OFF) */ +#endif /* (CRYPTO_30_VHSM_INTERRUPT_CLEARING_AVAILABLE ==STD_ON) */ + } + + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +} /* Crypto_30_vHsm_ClearInterruptOfPartition() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_IndicateInitializedIpcOfPartition() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_IndicateInitializedIpcOfPartition(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES>1) + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_4(); + *(volatile uint32*)CRYPTO_30_VHSM_HOST2_HSM_ADDRESS |= (uint32)((uint32)1u << (uint32)Crypto_30_vHsm_GetIpcInstanceId(partitionIdx)); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ /* SBSW_CRYPTO_30_VHSM_REGISTER_ACCESS */ + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_4(); +#else + Crypto_30_vHsm_IndicateInitializedIpc(); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ /* SBSW_CRYPTO_30_VHSM_REGISTER_ACCESS */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES>1) */ +} /* Crypto_30_vHsm_IndicateInitializedIpcOfPartition() */ + +#if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_PerformTimeout() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_PerformTimeout(uint32 objectId) +{ + Std_ReturnType retVal = E_NOT_OK; + if (objectId >= Crypto_30_vHsm_GetSizeOfObjMap()) + { + retVal = E_NOT_OK; + } + else if (Crypto_30_vHsm_IsObjectInfoUsedOfObjMap(objectId) == FALSE) + { + retVal = E_NOT_OK; + } + else + { + Crypto_30_vHsm_JobRequestIterType jobRequestId = Crypto_30_vHsm_GetObjectInfoIdxOfObjMap(objectId); + + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_0(); + if(Crypto_30_vHsm_GetStateOfJobRequest(jobRequestId) == CRYPTO_30_VHSM_JOBREQUEST_STATE_PROCESSING) + { + Crypto_30_vHsm_SetStateOfJobRequest(jobRequestId, CRYPTO_30_VHSM_JOBREQUEST_STATE_TIMEOUT); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetResultOfJobRequest(jobRequestId, E_NOT_OK); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + retVal = E_OK; + } + else + { + retVal = E_NOT_OK; + } + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_0(); + } + + return retVal; +} + +/********************************************************************************************************************** + * Crypto_30_vHsm_HandleTimeout() + *********************************************************************************************************************/ + /*! + * Internal comment removed. + * + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_HandleTimeout(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ + Crypto_30_vHsm_JobRequestIterType jobRequestId; + + /* ----- Implementation ----------------------------------------------- */ + /* Iterate over all job request slots */ + for (jobRequestId = 0u; jobRequestId < Crypto_30_vHsm_GetSizeOfJobRequest(); jobRequestId++) + { +# if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES > 1u) + /* Check if the jobRequestId mapped to the current partition */ + if (Crypto_30_vHsm_GetPartitionIdxOfObjectInfo(jobRequestId) == partitionIdx) +# endif + { + if (Crypto_30_vHsm_GetStateOfJobRequest(jobRequestId) == CRYPTO_30_VHSM_JOBREQUEST_STATE_TIMEOUT) + { + Crypto_30_vHsm_Ipc_ReceiveResponse(partitionIdx, (Crypto_30_vHsm_ChannelIdType)Crypto_30_vHsm_GetChannelOfJobRequest(jobRequestId)); + } + + if (Crypto_30_vHsm_GetTimeoutRecoveryStateOfJobRequest(jobRequestId) == CRYPTO_30_VHSM_TIMEOUT_RECOVERY_PENDING) + { + /* Queue asynchronous cancel job */ + if (Crypto_30_vHsm_ProcessCryptoJob(jobRequestId, Crypto_30_vHsm_GetCryptoJobOfJobRequest(jobRequestId), TRUE, TRUE) == E_OK) /* SBSW_CRYPTO_30_VHSM_PROCESS_CRYPTO_JOB */ + { + Crypto_30_vHsm_SetTimeoutRecoveryStateOfJobRequest(jobRequestId, CRYPTO_30_VHSM_TIMEOUT_RECOVERY_TRIGGERED); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + } + } + } +} + +/********************************************************************************************************************** + * Crypto_30_vHsm_RecoverFromTimeout() + *********************************************************************************************************************/ + /*! + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_RecoverFromTimeout( + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx, + Crypto_30_vHsm_JobRequestIterType jobRequestId, + uint32 writeIdx, +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + uint32 jobResponseData, +# endif + Crypto_30_vHsm_JobResponseBufferPtrType jobResponseBuffer) +{ + /* Deserialize job state */ +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_GetJobStateOfJobRequest(jobRequestId) = (Crypto_JobStateType)Crypto_30_vHsm_Deserialize_Uint32(&jobResponseBuffer[4]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR_WITH_BUFFER */ +# else + Crypto_30_vHsm_SetJobStateOfJobRequest(jobRequestId, (uint8)(jobResponseData >> CRYPTO_30_VHSM_JOBRESPONSE_STATE_BITPOSITION)); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + CRYPTO_30_VHSM_DUMMY_STATEMENT_CONST(jobResponseBuffer); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + + /* Remove the old response from the IPC */ + Crypto_30_vHsm_Ipc_GetRxChannelReadIdx(partitionIdx, Crypto_30_vHsm_GetChannelOfJobRequest(jobRequestId)) = writeIdx; /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ + + /* Indicate that the channel can now be used by other jobs */ + Crypto_30_vHsm_SetChannelState(Crypto_30_vHsm_GetChannelOfJobRequest(jobRequestId), CRYPTO_30_VHSM_IPC_CHANNELSTATE_FREE, partitionIdx); /* SBSW_CRYPTO_30_VHSM_CSL01_CHANNELSTATE */ + + Crypto_30_vHsm_JobKindType jobResponseKind = Crypto_30_vHsm_GetKindOfJobRequest(jobRequestId); + + /* Check if the job is still active in Hsm */ + if ((jobResponseKind != CRYPTO_30_VHSM_KEYMANAGEMENT_JOBKIND) + && (jobResponseKind != CRYPTO_30_VHSM_KEYMANAGEMENT_COPY_PARTIAL_JOBKIND) + && (Crypto_30_vHsm_GetJobStateOfJobRequest(jobRequestId) != CRYPTO_JOBSTATE_IDLE)) /* PRQA S 3415 */ /* MD_CRYPTO_30_VHSM_3415_LOGICAL_OPERATOR */ + { + /* Hsm is not yet finished with the job -> needs cancellation. */ + Crypto_30_vHsm_SetTimeoutRecoveryStateOfJobRequest(jobRequestId, CRYPTO_30_VHSM_TIMEOUT_RECOVERY_PENDING); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + else + { + /* Hsm is finished with the job -> job request can be freed. */ + /* State processing of job request is done and result is ignored */ + Crypto_30_vHsm_SetStateOfJobRequest(jobRequestId, CRYPTO_30_VHSM_JOBREQUEST_STATE_IDLE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + /* job request can be used by other jobs */ + Crypto_30_vHsm_SetLockOfJobRequest(jobRequestId, FALSE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_2(); + /* any job can use the driver object again */ + Crypto_30_vHsm_SetDriverObjectLock(jobRequestId, CRYPTO_30_VHSM_ACCEPT_ANY_JOBID); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_2(); + + /* Call timeout recovered callout */ + Crypto_30_vHsm_TimeoutRecovered_Callout(Crypto_30_vHsm_GetHsmObjIdOfObjectInfo(jobRequestId)); + } + +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif +} +#endif /* (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) */ + +#define CRYPTO_30_VHSM_STOP_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define CRYPTO_30_VHSM_START_SEC_RAMCODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ProcessJobRequest() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ProcessJobRequest( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + Crypto_30_vHsm_ChannelIdType channel = Crypto_30_vHsm_GetIpcChannelsOfvHsm(partitionIdx); + + /* ----- Implementation ----------------------------------------------- */ +#if (CRYPTO_30_VHSM_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + /* Check if the driver object is used by the correct partition */ + if (Crypto_30_vHsm_GetApplicationIdOfObjectInfo(jobRequestId) != GetApplicationID()) + { +# if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + (void)Det_ReportError(CRYPTO_30_VHSM_MODULE_ID, CRYPTO_30_VHSM_INSTANCE_ID, CRYPTO_30_VHSM_SID_PROCESS_JOB_REQUEST, CRYPTO_E_PARAM_HANDLE); +# endif + retVal = E_NOT_OK; + } + else +#endif /* (CRYPTO_30_VHSM_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) */ + if (Crypto_30_vHsm_Ipc_IsRamExec(partitionIdx) == TRUE) /* PRQA S 0310, 3305, 4340 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ + { + retVal = CRYPTO_E_BUSY; + } + else + { + /* #10 Set the state of the request to processing */ + Crypto_30_vHsm_SetStateOfJobRequest(jobRequestId, CRYPTO_30_VHSM_JOBREQUEST_STATE_PROCESSING); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + /* #20 Transmit the job request to the IPC */ + retVal = Crypto_30_vHsm_TransmitRequest(jobRequestId, &channel); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + + /* #21 Check if the job request was transmitted correctly */ + if (retVal == E_OK) + { +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + /* #22 If it is an asynchronous job, call the timeout detect start callout */ + if (Crypto_30_vHsm_GetProcessingTypeOfJobRequest(jobRequestId) == CRYPTO_PROCESSING_ASYNC) + { + Crypto_30_vHsm_TimeoutDetect_Start_Callout( /* PRQA S 0404 */ /* MD_CRYPTO_30_VHSM_0404_VOLATILE_READ */ + CRYPTO_30_VHSM_CALLOUT_ASYNC, + Crypto_30_vHsm_GetHsmObjIdOfObjectInfo(jobRequestId), + Crypto_30_vHsm_GetContextClassOfJobRequest(jobRequestId), + Crypto_30_vHsm_GetContextIdOfJobRequest(jobRequestId)); + } +#endif /* (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) */ + + /* #23 Mark transmitted job as ready so that vHSM can start execution */ + /* Note: This will make the new job request immediately visible from vHsm. */ + Crypto_30_vHsm_Ipc_GetTxChannelWriteIdx(partitionIdx, channel) += 1u; /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ + + Crypto_30_vHsm_TriggerInterruptOfPartition(partitionIdx); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_TRIGGER_INTERRUPT */ /*lint !e522 */ + + /* #30 Check if it is a synchronous job */ + if (Crypto_30_vHsm_GetProcessingTypeOfJobRequest(jobRequestId) == CRYPTO_PROCESSING_SYNC) + { + /* #31 Wait for job response */ + Crypto_30_vHsm_WaitForSynchJobResponse(jobRequestId, partitionIdx, channel); + } + } + else + { + /* #40 Clear state if job could not be transmitted */ + if (channel < Crypto_30_vHsm_GetSizeOfChannelState(partitionIdx)) + { + Crypto_30_vHsm_SetChannelState(channel, CRYPTO_30_VHSM_IPC_CHANNELSTATE_FREE, partitionIdx); /* SBSW_CRYPTO_30_VHSM_CSL01_CHANNELSTATE */ + } + Crypto_30_vHsm_SetStateOfJobRequest(jobRequestId, CRYPTO_30_VHSM_JOBREQUEST_STATE_IDLE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + } + + return retVal; +} /* Crypto_30_vHsm_ProcessJobRequest() */ + +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) +/********************************************************************************************************************** + * Crypto_30_vHsm_WaitForHsmRam() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_WaitForHsmRam(void) +{ + /* #10 Call partition handler function with default partition */ + Crypto_30_vHsm_Ipc_WaitForHsmRamForPartition(Crypto_30_vHsm_GetCurrentPartitionIdx()); +} /* Crypto_30_vHsm_WaitForHsmRam() */ + +#else /* !(CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) */ +/********************************************************************************************************************** + * Crypto_30_vHsm_WaitForHsmRamForApplication() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_WaitForHsmRamForApplication(ApplicationType applicationId) +{ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdentifierIdx = 0u; + + for (partitionIdentifierIdx = 0u; partitionIdentifierIdx < Crypto_30_vHsm_GetSizeOfPartitionIdentifiers(); partitionIdentifierIdx++) + { + if (applicationId == Crypto_30_vHsm_GetPartitionSNVOfPartitionIdentifiers(partitionIdentifierIdx)) + { + /* #10 Call partition handler function with partition of the passed application if a matching one is found */ + Crypto_30_vHsm_Ipc_WaitForHsmRamForPartition(Crypto_30_vHsm_GetPCPartitionConfigIdxOfPartitionIdentifiers(partitionIdentifierIdx)); + retVal = E_OK; + break; + } + } + return retVal; +} /* Crypto_30_vHsm_WaitForHsmRamForApplication() */ + +#endif /* !(CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) */ + +#define CRYPTO_30_VHSM_STOP_SEC_RAMCODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Module specific MISRA deviations + *********************************************************************************************************************/ +/* Module specific MISRA deviations: + +MD_CRYPTO_30_VHSM_0306_CHECK_MEMORY_LAYOUT: +Reason: Cast needed to evaluate if the pointer address is located in a specific memory region. +Risk: Size of pointer type is hardware specific - not compatible between platforms. Invalid memory access. +Prevention: vHsm for specific hardware(32 - Bit platforms) (pointer size type can not differ). Valid memory access ensured by code review and test + +MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO: +Reason: Cast needed in order to have a platform independent IPC on shared memory for different architectures +Risk: Writing or reading of invalid memory +Prevention: Covered by code review and tests. + +MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO: +Reason: Cast needed in order to have a platform independent IPC on shared memory. Ptr needs to be transferred by their address. +Risk: Size of pointer type is hardware specific - not compatible between platforms. Invalid memory access. +Prevention: vHsm for specific hardware(32 - Bit platforms) (pointer size type can not differ). Valid memory access ensured by code review and test + +MD_CRYPTO_30_VHSM_0310_KEYELEMENT_CONTENT: +Reason: The content of a key element which is an uint8 array has to be copied to e.g. a uint32 value. +Risk: Wrong interpretation of the data. +Prevention: Covered by code review and tests on hardware. + +MD_CRYPTO_30_VHSM_IPC_MACRO +Reason: Cast needed in order to have a platform independent IPC on shared memory for different architectures +Risk: Writing or reading of invalid memory +Prevention: Covered by code review and tests. + +MD_CRYPTO_30_VHSM_3453_IPC_MACRO +Reason: Macro used because macros are faster than functions and IPC is performance critical +Risk: Macros don't evaluate types. Can cause invalid memory access +Prevention: Covered by code review and tests. + +MD_CRYPTO_30_VHSM_3673_API_SPECIFIC +Reason: Parameter cannot be set to const since it is passed as var parameter to lower layer library. +Risk: - +Prevention: - + +MD_CRYPTO_30_VHSM_2822_DEREFERENCING_NULLPTR +Reason: Parameter my be NULL_PTR which will then be dereferenced. +Risk: Undefined or unspecified behaviour +Prevention: On hardware platforms, NULL_PTR may be a valid address. Covered by code review and tests. + +MD_CRYPTO_30_VHSM_2987_HANDLEDET +Reason: Function is detected without side effects even if it clears a variable in the IPC +Risk: - +Prevention: - + +MD_CRYPTO_30_VHSM_UNUSED_PARAMETER +Reason: The API is designed to be the same for multiple sub components. Some implementations don't use a parameter. +Risk: Unused parameter may be less efficient +Prevention: Code review, tests + +MD_CRYPTO_30_VHSM_REGISTER_ACCESS +Reason: Register access +Risk: Access to invalid memory +Prevention: The user has to make sure that only the correct register address is configured to access the hardware register. The register is hardware dependant. + +MD_CRYPTO_30_VHSM_TRIGGER_INTERRUPT +Reason: Register access +Risk: Access to invalid memory +Prevention: The user has to make sure that only the correct register address is configured to trigger the interrupt. The register is hardware dependant. + +MD_CRYPTO_30_VHSM_2985_REDUNDANT_OP_WHEN_NO_REDIRECTION +Reason: This operation is redundant. The value of the result is always that of the left-hand operand when redirection is disabled +Risk: Not needed operation +Prevention: Code review, tests + +MD_CRYPTO_30_VHSM_3679_JOB_POINTER_AS_VAR +Reason: The object referenced by the pointer is not modified through it, so the object could be declared with type 'objectType const*'. However the referenced data inside the struct is modified, therefore P2VAR. +Risk: - +Prevention: Code review, tests + +MD_CRYPTO_30_VHSM_0404_VOLATILE_READ +Reason: Volatile reads could have side-effects. More than 1 volatile read is done at a sequence point, so the order of the read cannot be guaranteed. +Risk: None, as no registers with side-effects are read. +Prevention: Covered by code review. + +MD_CRYPTO_30_VHSM_3415_LOGICAL_OPERATOR +Reason: Volatile reads could have side-effects. The right side of the logical operator may not get evaluated and therefore doesn't produce the side-effect. +Risk: None, as no registers with side-effects are read or access is enclosed via exclusive areas +Prevention: Covered by code review. + +MD_CRYPTO_30_VHSM_3205_DUMMY_READ +Reason: Read to a dummy variable needs to be performed to clear interrupts. The read value will not be used. +Risk: None, as reading the register to clear interrupt flags is required by the hardware. +Prevention: Covered by code review. + +MD_CRYPTO_30_VHSM_3206_SINGLE_PARTITION_IPC_ACCESS +Reason: A parameter for the partition is passed and is not used when only a single partition is configured. The parameter will be replaced via a macro by the constant 0u due to performance reasons. +Risk: None, as variable is not read in a specific configuration +Prevention: Covered by code review. + + */ + +/* +\CM CM_CRYPTO_30_VHSM_IPC_SERIALIZE The total size of the serialized data per job is fixed. Before serialization, a runtime check is performed if the section in the ipc is big enough to hold the serialized job. + */ + +/* SBSW_JUSTIFICATION_BEGIN + +\ID SBSW_CRYPTO_30_VHSM_FORWARDING_PTR +\DESCRIPTION The caller forwards as parameter one or more pointer. +\COUNTERMEASURE \N The pointer is forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR +\DESCRIPTION A variable located on the stack is given as parameter pointer to a function. +\COUNTERMEASURE \N The pointer is forwarded and assumed to be valid. + +\ID SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR_WITH_BUFFER +\DESCRIPTION A variable located on the stack is given as parameter pointer to a function. Also a pointer to a buffer is passed which is used to read a value from the IPC. +\COUNTERMEASURE \N The pointer is forwarded and assumed to be valid. The buffer always points to the valid IPC memory area which is always available. + +\ID SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC +\DESCRIPTION A variable located in the ipc memory is written. +\COUNTERMEASURE \N The memory area in the IPC is assumed to be valid. The offset is static and depending on the IPC protocol version + +\ID SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 +\DESCRIPTION A variable is serialized to the IPC. An offset is used to determine the destination in the IPC memory +\COUNTERMEASURE \R [CM_CRYPTO_30_VHSM_IPC_SERIALIZE] + +\ID SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR +\DESCRIPTION A pointer is serialized to the IPC. An offset is used to determine the destination in the IPC memory +\COUNTERMEASURE \R [CM_CRYPTO_30_VHSM_IPC_SERIALIZE] + +\ID SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO +\DESCRIPTION Access of ObjectInfo + DriverObjectLock, + OutputLengthPtrDataBuffer + SecondaryOutputLengthPtrDataBuffer + VerifyPtrDataBuffer + LockOfJobRequest, StateOfJobRequest, ProcessingTypeOfJobRequest, KindOfJobRequest, CryptoJobOfJobRequest, + KeyMJobOfJobRequest, ResultOfJobRequest, CancelOfJobRequest, JobStateOfJobRequest, OutputOffsetOfJobRequest, + SecondaryOutputOffsetOfJobRequest, UsedBufferOfJobRequest, TrimmedOutputBufferOfJobRequest, ObjectIdOfJobRequest, + ContextClassOfJobRequest, ContextIdOfJobRequest + with same index using ComStackLib +\COUNTERMEASURE \N Qualified use-case CSL02 of ComStackLib. + +\ID SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO_JOB_PTR +\DESCRIPTION Access of CryptoJobOfJobRequest (via indirection over ObjectInfo) using ComStackLib. +\COUNTERMEASURE \N Qualified use-case CSL02 of ComStackLib. Additionally the pointers inside the job are assumed to be valid. The caller of Crypto_30_vHsm_CancelJob or Crypto_30_vHsm_ProcessJob must ensure the validity of the pointers inside the job structure. + +\ID SBSW_CRYPTO_30_VHSM_CSL01_CHANNELSTATE +\DESCRIPTION Access of ChannelState using ComStackLib. The GetSizeOf-check is performed in Crypto_30_vHsm_TransmitRequest(). +\COUNTERMEASURE \N Qualified use-case CSL01 of ComStackLib. + +\ID SBSW_CRYPTO_30_VHSM_PROCESS_CRYPTO_JOB +\DESCRIPTION The function passes a pointer referencing a job. The passed pointer has been checked before for validity. + Access to JobRequest via indirection over ObjMap. ObjectId has been checked for validity beforehand. +\COUNTERMEASURE \N Pointer to job and objectId is checked for validity before usage + and Qualified use-case CSL03 of ComStackLib for JobRequestId. + +\ID SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK +\DESCRIPTION Write access to a pointer. +\COUNTERMEASURE \R The pointer is checked for validity before. + +\ID SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_STACK +\DESCRIPTION The value of a pointer to a variable located on the stack is written. +\COUNTERMEASURE \N The function call is synchronous and there is no array access. + +\ID SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL +\DESCRIPTION The value of a pointer to a global variable of the CSL is written. +\COUNTERMEASURE \N The function call is synchronous and there is no array access. + +\ID SBSW_CRYPTO_30_VHSM_FORWARDING_STACK_VARIABLE_PTR +\DESCRIPTION The function is called with pointers pointing to stack variables. +\COUNTERMEASURE \N The pointer is forwarded and assumed to be valid + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SendRequestToIpc +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to Crypto_30_vHsm_SendRequestToIpc. + The function is specified to only write a maximum of CRYPTO_30_VHSM_IPC_TX_CHANNEL_MEMORY_SIZE bytes to the pointer which is the size of the allocated array in the IPC. +\COUNTERMEASURE \N The function call is synchronous and the function only serializes a known maximum number of bytes (CRYPTO_30_VHSM_IPC_TX_CHANNEL_MEMORY_SIZE), + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_CryptoJob_Inputs +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to a Crypto_30_vHsm_SerializeRequest_CryptoJob_Inputs. + The function is specified to only write a maximum of 24 bytes to the pointer which is smaller than the size of the allocated array in the IPC. +\COUNTERMEASURE \N The function call is synchronous and the function only serializes a known maximum number of bytes (24), + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_CryptoJob_Outputs +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to a Crypto_30_vHsm_SerializeRequest_CryptoJob_Outputs. + The function is specified to only write a maximum of 16 bytes to the pointer which is smaller than the size of the allocated array in the IPC. +\COUNTERMEASURE \N The function call is synchronous and the function only serializes a known maximum number of bytes (16), + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_CryptoJob +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to a Crypto_30_vHsm_SerializeRequest_CryptoJob. + The function is specified to only write a maximum of 80 bytes to the pointer which is smaller than the size of the allocated array in the IPC minus the already written header data. +\COUNTERMEASURE \N The function call is synchronous and the function only serializes a known maximum number of bytes (80), + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_KeyMJob +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to a Crypto_30_vHsm_SerializeRequest_KeyMJob. + The function is specified to only write a maximum of 36 bytes to the pointer which is smaller than the size of the allocated array in the IPC minus the already written header data. +\COUNTERMEASURE \N The function call is synchronous and the function only serializes a known maximum number of bytes (36), + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_KeyMJob_CopyPartial +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to a Crypto_30_vHsm_SerializeRequest_KeyMJob_CopyPartial. + The function is specified to only write a maximum of 32 bytes to the pointer which is smaller than the size of the allocated array in the IPC minus the already written header data. +\COUNTERMEASURE \N The function call is synchronous and the function only serializes a known maximum number of bytes (32), + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_KeyMJob_KeyDerive +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to a Crypto_30_vHsm_SerializeRequest_KeyMJob_KeyDerive. + The function is specified to only write a maximum of 36 bytes to the pointer which is smaller than the size of the allocated array in the IPC minus the already written header data. +\COUNTERMEASURE \N The function call is synchronous and the function only serializes a known maximum number of bytes (36), + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_CryptoJob_MacGen +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to a Crypto_30_vHsm_SerializeRequest_CryptoJob_MacGen. + The function is specified to only write a maximum of 44 bytes to the pointer which is smaller than the size of the allocated array in the IPC minus the already written header data. +\COUNTERMEASURE \N The function call is synchronous and the function only serializes a known maximum number of bytes (44), + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_CryptoJob_MacVer +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to a Crypto_30_vHsm_SerializeRequest_CryptoJob_MacVer. + The function is specified to only write a maximum of 48 bytes to the pointer which is smaller than the size of the allocated array in the IPC minus the already written header data. +\COUNTERMEASURE \N The function call is synchronous and the function only serializes a known maximum number of bytes (48), + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_ReceiveResponse_KeyMJob +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to a Crypto_30_vHsm_ReceiveResponse_KeyMJob. + The function is specified to only read a maximum of CRYPTO_30_VHSM_KEYM_JOBRESULTTYPE_DESERIALIZED_BUF_SIZE bytes from the pointer which is in the range of the buffer allocated in the IPC minus the already processed header data. +\COUNTERMEASURE \N The function call is synchronous and the function only deserializes a known maximum number of bytes (CRYPTO_30_VHSM_KEYM_JOBRESULTTYPE_DESERIALIZED_BUF_SIZE), + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_ReceiveResponse_CryptoJob +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to a Crypto_30_vHsm_ReceiveResponse_CryptoJob. + The function is specified to only read a maximum of CRYPTO_30_VHSM_CRYPTO_JOBRESULTTYPE_DESERIALIZED_BUF_SIZE bytes from the pointer which is in the range of the buffer allocated in the IPC minus the already processed header data. +\COUNTERMEASURE \N The function call is synchronous and the function only deserializes a known maximum number of bytes (CRYPTO_30_VHSM_CRYPTO_JOBRESULTTYPE_DESERIALIZED_BUF_SIZE), + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_RecoverFromTimeout +\DESCRIPTION A pointer to an array located in the global ipc memory is given as parameter to a Crypto_30_vHsm_RecoverFromTimeout. + The function is specified to only read the JobState from the pointer which is in the range of the buffer allocated in the IPC minus the already processed header data. +\COUNTERMEASURE \N The function call is synchronous and the function only accesses a known offset, + therefore the array in the IPC is valid for the function call. + +\ID SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_REDIRECTION_WITH_GLOBAL_BUFFERS +\DESCRIPTION The function is called with pointers to the global buffer and parameters containing the key and element id. +\COUNTERMEASURE \N The pointer to the global buffer is assumed to be valid. + +\ID SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_PTR_WITH_GLOBAL_BUFFERS +\DESCRIPTION The function is called with pointers to the global buffer and the original ptr which shall be serialized. +\COUNTERMEASURE \N The pointer to the global buffer is assumed to be valid. + +\ID SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE +\DESCRIPTION The function is called with a pointer to a job which has been checked, the pointer to the memory area in the IPC where the job shall be serialized and a pointer to a local variable on the stack (offset). +\COUNTERMEASURE \N The pointer to the job has been checked in Crypto_30_vHsm_ProcessJob or Crypto_30_vHsm_CancelJob or is a local variable on the stack in a synchronous call in case of a KeyM job. The buffer has a static size in the IPC memory and is always available and the offset is a local variable on the stack. + +\ID SBSW_CRYPTO_30_VHSM_MEMORY_VALID_CHECK +\DESCRIPTION The caller forwards as parameter one pointers. The data can be NULL_PTR. +\COUNTERMEASURE \N The pointer is forwarded and is allowed to be NULL_PTR. Depending on the length, the function will return an error. + +\ID SBSW_CRYPTO_30_VHSM_COPY_TO_DESTINATION_FROM_GLOBAL_BUFFER +\DESCRIPTION The original pointers in the job are used as destination for the data in the global buffer which is always available because the caller always passes a valid job. +\COUNTERMEASURE \N The pointers in the job are assumed to be valid. The pointer to the global buffer is assumed to be valid or have a size of 0. The destination pointer and length have been checked against NULL_PTR. + The length is checked, that it is not bigger than the original provided buffer. + The vHsm Firmware can therefore not trigger any memory corruption via the driver when providing a bigger output buffer size than the size of the buffer in the job pointer. + +\ID SBSW_CRYPTO_30_VHSM_COPY_TO_GLOBAL_BUFFER_FROM_SOURCE +\DESCRIPTION The original pointers in the job are used as source for the data in the global buffer which is always available because the caller always passes a valid job. +\COUNTERMEASURE \N The pointers in the job are assumed to be valid. The pointer to the global buffer is assumed to be valid or have a size of 0. The source pointer has been checked against NULL_PTR. + The length is checked, that it is not bigger than the original provided buffer. + +\ID SBSW_CRYPTO_30_VHSM_REGISTER_ACCESS +\DESCRIPTION An address is accessed as uint32 to access a hardware register +\COUNTERMEASURE \S The address, mask and value is configured by the user and is platform dependant. The user must make sure to only provide a valid address. [SMI-427853] + +\ID SBSW_CRYPTO_30_VHSM_HANDLE_INTERRUPT +\DESCRIPTION An address is accessed as uint32 to trigger the interrupt or clear the interrupt flag +\COUNTERMEASURE \S The address, mask and value is configured by the user and is platform dependant. The user must make sure to only provide a valid address. [SMI-427853] + +\ID SBSW_CRYPTO_30_VHSM_INIT_IPC_MEMORY +\DESCRIPTION The function is called with the ipc memory which is always available and a known size. +\COUNTERMEASURE \N The array is always available and the size is known. + +\ID SBSW_CRYPTO_30_VHSM_IPC_MEMORY_PTR_ARRAY +\DESCRIPTION The array is accessed with an always valid partition index. + The array is not generated via CSL via partition indirection because of performance reasons during access of the IPC in the multi partition use-case. +\COUNTERMEASURE \N The partition index is either 0 or a valid one is returned from Crypto_30_vHsm_GetCurrentPartitionIdx() which searches via CSL for a matching one. + Validations are in place that there will always be a match. + +\ID SBSW_CRYPTO_30_VHSM_WRITE_PARTITION_DATA +\DESCRIPTION Write of Partition specific data using ComStackLib. +\COUNTERMEASURE \N The index for the Partition specific data is either fixed (for single partition usecase) or provided by searching the current application id + in the PartitionIdentifiers and using its corresponding partitionIdx or passed as parameter (Qualified use-case CSL05 of ComStackLib). + Therefore it is guaranteed to be in the acceptable range. + +SBSW_JUSTIFICATION_END */ + +/* COV_JUSTIFICATION_BEGIN + + \ID COV_CRYPTO_30_VHSM_LOCAL_DEFINE + \ACCEPT TX + \ACCEPT XF + \REASON CRYPTO_30_VHSM_LOCAL is always defined externally. + + \ID COV_CRYPTO_30_VHSM_CSM_DEFINES + \ACCEPT XF + \ACCEPT TX + \REASON This defines could be defined in other crypto drivers as well. In order to increase flexibility, defines are defined in crypto driver if not provided yet. + + \ID COV_CRYPTO_30_VHSM_MISRA_ADDITIONAL_STATEMENT + \ACCEPT X + \REASON This else/default statements are required by misra but cannot be reached in code. The statement is captured by upper Api. + + \ID COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS + \ACCEPT TX + \REASON The Crypto needs custom key elements, which could be defined in other modules as well. + + \ID COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENT_VALUE + \ACCEPT TX + \REASON The Crypto needs custom key elements, which could be defined in other modules as well. + + \ID COV_CRYPTO_30_VHSM_KEY_ELEMENTS_RIGHTS + \ACCEPT TX + \REASON The Crypto provides key elements rights which can be defined in upper layer. + + \ID COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM + \ACCEPT TX + \REASON The Crypto needs custom algorithm and algorithm mode defines, which could be defined in other modules as well. + + \ID COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM + \ACCEPT TX + \REASON The Crypto needs custom key algorithm, which could be defined in other modules as well. + + \ID COV_CRYPTO_30_VHSM_CUSTOM_KDF + \ACCEPT TX + \REASON The Crypto needs custom key algorithm, which could be defined in other modules as well. + + \ID COV_CRYPTO_30_VHSM_DOUBLE_CHECK + \ACCEPT TX + \REASON To avoid unnecessary entering of exclusive areas, rare occurring events are checked twice: Outside of an exclusive area before entering it + and again inside the area to make sure that it is not already handled meanwhile. + + \ID COV_CRYPTO_30_VHSM_COMMENT + \ACCEPT TX + \ACCEPT XF + \REASON - + + \ID COV_CRYPTO_30_VHSM_DATABUFFER + \ACCEPT TX + \REASON A Configuration without a configured data buffer for inputPtr, secondaryInputPtr or outputPtr is not really usable. + + \ID COV_CRYPTO_30_VHSM_IPC_BUFFER_SIZE_CHECK + \REASON The buffer size is defined in a lookup table and can not be altered from outside. Due to defensive coding the check is done nevertheless. + + \ID COV_CRYPTO_30_VHSM_ROBUST_POINTER_CHECK + \ACCEPT TF tf tx + \ACCEPT XF xf xx + \REASON There are more checks for the pointers as needed to improve the robustness on different platforms. + + \ID COV_CRYPTO_30_VHSM_MEMMAP_EXAMPLE + \ACCEPT TX xf tx tx tx + \ACCEPT TX xf tx + \ACCEPT TX + \REASON Examples for different compilers are given in the MemMap file. Project is only compiled with one compiler in all configs. + + \ID COV_CRYPTO_30_VHSM_ASR_COMPATIBILITY + \ACCEPT XF + \ACCEPT TX + \REASON The Crypto_JobType differs between the different ASR version to support ASR 4.3.0 the defines ca be overwritten. Standard is ASR 4.3.1. + + \ID COV_CRYPTO_30_VHSM_VTT + \ACCEPT TX + \REASON The feature is only active for VTT and not supported in SafeBSW. As the VTT product is always not SafeBsw, + there is no extra MSSV Plugin enforcing that the feature is not active. + + \ID COV_CRYPTO_30_VHSM_READWRITE_AVAILABLE + \ACCEPT XF + \REASON COV_MSR_UNSUPPORTED + + \ID COV_CRYPTO_30_VHSM_NOBUFFERING_ENABLED + \ACCEPT XF + \REASON COV_MSR_UNSUPPORTED + +COV_JUSTIFICATION_END */ + +/* FETA_JUSTIFICATION_BEGIN + + \ID FETA_CRYPTO_30_VHSM_WAIT_FOR_HSM_WITH_CALLOUT + \DESCRIPTION The loop waits for an action done by the HSM core. This action could possibly never occur. + \COUNTERMEASURE \N The loop can be terminated by using a callout which has to be implemented by the user. + + \ID FETA_CRYPTO_30_VHSM_MONOTONIC_LOOP_UP_WITH_UNCHANGED_BOUNDS_STATIC_GENDATA + \DESCRIPTION Loop bounds are determined by static GenData which is accessed via ComStackLib. + \COUNTERMEASURE \N The here applied loop uses variables as lower and upper bound which are set via a ComStackLib macro + and remain unchanged during loop execution. The lower bound variable is guaranteed to be less + than or equal to the upper bound variable. The loop's type of the counter variable is appropriate + for the loop's type of lower and upper bound determining variables as it is an iteration type suitable for the + used CSL indirection. The counter variable is increased once within each single loop iteration (strictly monotonically increasing) + until it reaches a value that makes the loop stop without any occurrences of overflows. This + is done by a comparison used as loop termination condition that considers the amount of the + increment that is applied within each single loop. + + FETA_JUSTIFICATION_END */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_vHsm.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm.h b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm.h new file mode 100644 index 0000000..589b60d --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm.h @@ -0,0 +1,628 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_vHsm.h + * \brief MICROSAR vHsm Crypto Driver (Crypto) + * + * \details Core of the Vector Hardware Security Module Firmware driver. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2017-06-23 vistof - Initial creation for ASR 4.3 + * vismsl Concept Work + * 01.01.00 2018-01-09 vistof STORYC-4214 Feature Completion: + * Fixed handling code flash write access. + * Added Det forwarding from vHsm + * Added support for key element deletion + * Removed not needed DET checks for cryptoKeyId + * Fixed serialization of secondaryInputLength during MacVerify + * Fixed Addresses of memory sections to support more derivatives. + * Added support for cancel + * Added Address of global structure is now configurable + * Added asynchronous job processing + * Fixed global RAM buffer handling. Each object has now its own buffer. + * Added option to use vHsm without interrupts + * visfpt Added padding modes (PKCS7, None, Zero) for hardware AES. + * vismsl Rework of Ipc + * 01.02.00 2018-05-04 visfpt STORYC-5257 Release of Component + * vistof ESCAN00099366 Fixed: Missing compiler abstractions + * 01.03.00 2018-06-20 visjhi STORYC-5741 Added Hardware independent memory area configuration + * 02.00.00 2018-08-21 vistof STORYC-6297 Requests will immediately return CRYPTO_E_BUSY when vHsm Firmware is in RAM loop. + * STORYC-6296 Added check if provided output buffer is too big to be buffered to the shared RAM. + * STORYC-6295 Ensure alignment of driver object buffers + * STORYC-6294 Add callout during waiting loops + * ESCAN00100450 Blocking of driver object for other jobs when job is canceled. + * 2018-09-13 visrpp STORYC-6521 MISRA-C:2012 Compliance + * ESCAN00100842 Fixed: Possibility of an endless loop in polling mode + * 02.01.00 2018-12-19 vistof STORYC-7341 Support fast MAC Verify/Generate processing + * STORYC-7143 Support redirection of input/output buffers from/to key elements + * STORYC-7339 Support partial key element copy + * ESCAN00101843 Compiler option -Ospeed does not work in interrupt mode because + * Crypto_30_vHsm_JobRequest is not volatile + * 02.01.01 2019-05-09 visjhi STORYC-8370 Remove VTT switches + * ESCAN00103101 MacVerify: NULL_PTR as verifyPtr not accepted in START/UPDATE mode (streaming) + * 02.02.00 2019-08-06 vistof ESCAN00103942 Fixed: Det error CRYPTO_E_PARAM_POINTER during Fast MAC Generation + * HSM-432 Added DET when configured global ram buffer is too small + * HSM-432 Rework buffer handling + * 02.02.01 2020-01-28 vistof ESCAN00105494 Compiler error: unresolved external symbol Det_ReportError + * when DEV_ERROR_REPORT and DEV_ERROR_DETECT have different values + * 02.03.00 2020-01-30 vistof HSM-629 Trigger Host to HSM ISR + * HSM-619 Asynchronous Key Handling + * HSM-160 Make DET errors from vHsm distinguishable from application core DET errors + * HSM-699 Initialize IPC and inform vHsm + * 02.03.01 2020-07-14 vistof ESCAN00106838 Execution of a job switches from E_OK to continuously returning E_NOT_OK + * ESCAN00106857 Async jobs may return wrong values in polling mode + * 02.04.00 2020-08-07 vistof HSM-984 Harmonize Crypto_JobType according to different ASR version + * 02.05.00 2020-10-02 vistof HSM-1193 Allow parallel Key Management operations + * HSM-1190 Improve Exclusive area design + * HSM-1225 Discard job inputs/outputs which are not relevant for the service + * 02.05.01 2020-10-27 vistof ESCAN00107729 Compiler error: CRYPTO_KEYSETVALID not defined + * when Csm according to ASR 4.3 instead of ASR 4.4 is used + * ESCAN00107730 Undefined behaviour when calling key management APIs + * 02.06.00 2021-01-05 vistof HSM-1296 Support NoBuffering driver objects + * ESCAN00108351 Use interrupts only for async jobs + * 03.00.00 2021-01-25 vistof ESCAN00108526 Race condition in IPC processing leads to undefined behaviour + * ESCAN00108682 Cancel for async jobs is processed async and retVal of Callback is E_OK instead of CRYPTO_E_CANCELED + * HSM-1324 Add support for IPCv3, Remove support for IPCv1 + * HSM-943 Improve IPCv3 via shifts + * HSM-1318 Improve IPCv3 via exchanging pointers with values + * visrpp HSM-270 Custom Modes according ASR 20-11 + * 03.00.01 2021-03-15 vistof ESCAN00108847 Buffer inside GlobalRamBuffer is not allocated correctly during runtime + * HSM-1608 Remove not needed global variables + * 03.01.00 2021-07-26 visebj HSM-1595 Introduce access to HSM2HOST and HOST2HSM registers via KeyElement APIs + * HSM-1785 Support save/restore context + * HSM-1833 Indicate initialized IPC via interrupt + * 03.02.00 2022-07-07 vistof HSM-2091 Usage of _MemMap.h + * ESCAN00112312 Driver object is still locked after vHsm has returned an error during processing of a crypto job + * 03.03.00 2022-10-24 vistof HSM-3092 Support for special Interrupt handling + * 03.04.00 2023-02-13 viskju HSM-3377 FETA analysis, Rework loop callout + * 04.00.00 2023-04-14 vistof HSM-3734 Support Multi Partition Use-Case + * ESCAN00114445 Save/Restore Context only works for services which have both input and output pointers + * ESCAN00114875 Fix Compiler warning: Not initialized variable is mapped to ZERO_INIT section + * 04.00.01 2023-06-06 vistof ESCAN00114796 Compiler warning: unreferenced formal parameter 'partitionIdx' + * ESCAN00114814 IpcInstance has wrong mapping to partitions + * ESCAN00114934 Runtime exception for Vtt Use-Case during triggering and clearing an interrupt + * HSM-4392 Rework InitMemory for Multicore + * 04.01.00 2024-07-01 viskju HSM-3833 Create API which can be called as a reaction to timeouts + * ESCAN00117786 Fix that IPC channel stays locked after error is detected + * HSM-5340 Support KeySetInvalid and KeyGetStatus + * 04.01.01 2024-08-22 viskju ESCAN00118087 Fix Validation error for primitive service CRYPTO_KEYSETINVALID + * 04.01.02 2025-02-13 vistof ESCAN00118425 Wrong response handling during Key Derive Job + * viskju ESCAN00118923 TimeoutDetect callouts for asynchronous jobs can occur in wrong order + * ESCAN00119461 Unexpected overwriting of data in outputPtr or secondaryOutputPtr using SaveContext or RestoreContext functionality + * ESCAN00119487 Unexpected overwriting of data in outputPtr or secondaryOutputPtr using CancelJob functionality + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_VHSM_H) +# define CRYPTO_30_VHSM_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_vHsm_Types.h" +# include "Crypto_30_vHsm_Cfg.h" +# include "Crypto_30_vHsm_KeyManagement.h" +# include "Crypto_30_vHsm_Custom.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* Vendor and module identification */ +# define CRYPTO_30_VHSM_VENDOR_ID (30u) +# define CRYPTO_30_VHSM_MODULE_ID (114u) +# define CRYPTO_30_VHSM_INSTANCE_ID (0u) + +/* AUTOSAR Software specification version information */ +# define CRYPTO_30_VHSM_AR_RELEASE_MAJOR_VERSION (0x04u) +# define CRYPTO_30_VHSM_AR_RELEASE_MINOR_VERSION (0x03u) +# define CRYPTO_30_VHSM_AR_RELEASE_REVISION_VERSION (0x01u) + +/* ----- Component version information (decimal version of ALM implementation package) ----- */ +# define CRYPTO_30_VHSM_MAJOR_VERSION (4u) +# define CRYPTO_30_VHSM_MINOR_VERSION (1u) +# define CRYPTO_30_VHSM_PATCH_VERSION (2u) + +/* ----- API service IDs ----- */ +# define CRYPTO_30_VHSM_SID_INIT (0x00u) /*!< Service ID: Crypto_30_vHsm_Init() */ +# define CRYPTO_30_VHSM_SID_GET_VERSION_INFO (0x01u) /*!< Service ID: Crypto_30_vHsm_GetVersionInfo() */ +# define CRYPTO_30_VHSM_SID_PROCESS_JOB (0x03u) /*!< Service ID: Crypto_30_vHsm_ProcessJob() */ +# define CRYPTO_30_VHSM_SID_KEY_ELEMENT_SET (0x04u) /*!< Service ID: Crypto_30_vHsm_KeyElementSet() */ +# define CRYPTO_30_VHSM_SID_KEY_VALID_SET (0x05u) /*!< Service ID: Crypto_30_vHsm_KeyValidSet() */ +# define CRYPTO_30_VHSM_SID_KEY_ELEMENT_GET (0x06u) /*!< Service ID: Crypto_30_vHsm_KeyElementGet() */ +# define CRYPTO_30_VHSM_SID_KEY_GENERATE (0x07u) /*!< Service ID: Crypto_30_vHsm_KeyGenerate() */ +# define CRYPTO_30_VHSM_SID_KEY_DERIVE (0x08u) /*!< Service ID: Crypto_30_vHsm_KeyDerive() */ +# define CRYPTO_30_VHSM_SID_KEY_EXCHANGE_CALC_PUB_VAL (0x09u) /*!< Service ID: Crypto_30_vHsm_KeyExchangeCalcPubVal() */ +# define CRYPTO_30_VHSM_SID_KEY_EXCHANGE_CALC_SECRET (0x0Au) /*!< Service ID: Crypto_30_vHsm_KeyExchangeCalcSecret() */ +# define CRYPTO_30_VHSM_SID_CERTIFICATE_PARSE (0x0Bu) /*!< Service ID: Crypto_30_vHsm_CertificateParse() */ +# define CRYPTO_30_VHSM_SID_MAIN_FUNCTION (0x0Cu) /*!< Service ID: Crypto_30_vHsm_MainFunction() */ +# define CRYPTO_30_VHSM_SID_RANDOM_SEED (0x0Du) /*!< Service ID: Crypto_30_vHsm_RandomSeed() */ +# define CRYPTO_30_VHSM_SID_CANCEL_JOB (0x0Eu) /*!< Service ID: Crypto_30_vHsm_CancelJob() */ +# define CRYPTO_30_VHSM_SID_KEY_ELEMENT_COPY (0x0Fu) /*!< Service ID: Crypto_30_vHsm_KeyElementCopy() */ +# define CRYPTO_30_VHSM_SID_KEY_COPY (0x10u) /*!< Service ID: Crypto_30_vHsm_KeyCopy() */ +# define CRYPTO_30_VHSM_SID_KEY_ELEMENT_IDS_GET (0x11u) /*!< Service ID: Crypto_30_vHsm_KeyElementIdsGet() */ +# define CRYPTO_30_VHSM_SID_CERTIFICATE_VERIFY (0x12u) /*!< Service ID: Crypto_30_vHsm_CertificateVerify() */ +# define CRYPTO_30_VHSM_SID_KEY_ELEMENT_COPY_PARTIAL (0x13u) /*!< Service ID: Crypto_30_vHsm_KeyElementCopyPartial() */ +# define CRYPTO_30_VHSM_SID_KEY_SET_INVALID (0x14u) /*!< Service ID: Crypto_30_vHsm_KeySetInvalid() */ +# define CRYPTO_30_VHSM_SID_KEY_GET_STATUS (0x15u) /*!< Service ID: Crypto_30_vHsm_KeyGetStatus() */ +# define CRYPTO_30_VHSM_SID_COPYJOBREQUESTTXDATA (0x20u) /*!< Service ID: Crypto_30_vHsm_CopyJobRequestTxData() */ +# define CRYPTO_30_VHSM_SID_COPYJOBRESPONSERXDATA (0x21u) /*!< Service ID: Crypto_30_vHsm_GetResponseFromIpc() */ +# define CRYPTO_30_VHSM_SID_PROCESS_JOB_REQUEST (0x22u) /*!< Service ID: Crypto_30_vHsm_ProcessJobRequest() */ + +/* ----- Module States ----- */ +/* State: Module is uninitialized */ +# define CRYPTO_30_VHSM_UNINIT (0x00u) +/* State: Module is initialized */ +# define CRYPTO_30_VHSM_INITIALIZED (0x01u) + +/* Development Error Types [SWS_Crypto_00040] */ +# if !defined (CRYPTO_E_NO_ERROR) /* COV_CRYPTO_30_VHSM_CSM_DEFINES */ +# define CRYPTO_E_NO_ERROR (255u) +# endif +# if !defined (CRYPTO_E_UNINIT) /* COV_CRYPTO_30_VHSM_CSM_DEFINES */ +# define CRYPTO_E_UNINIT (0u) +# endif +# if !defined (CRYPTO_E_INIT_FAILED) /* COV_CRYPTO_30_VHSM_CSM_DEFINES */ +# define CRYPTO_E_INIT_FAILED (1u) +# endif +# if !defined (CRYPTO_E_PARAM_POINTER) /* COV_CRYPTO_30_VHSM_CSM_DEFINES */ +# define CRYPTO_E_PARAM_POINTER (2u) +# endif +# if !defined (CRYPTO_E_PARAM_HANDLE) /* COV_CRYPTO_30_VHSM_CSM_DEFINES */ +# define CRYPTO_E_PARAM_HANDLE (4u) +# endif +# if !defined (CRYPTO_E_PARAM_VALUE) /* COV_CRYPTO_30_VHSM_CSM_DEFINES */ +# define CRYPTO_E_PARAM_VALUE (5u) +# endif +# if !defined (CRYPTO_E_GLOBAL_BUFFER_TOO_SMALL) /* COV_CRYPTO_30_VHSM_CSM_DEFINES */ +# define CRYPTO_E_GLOBAL_BUFFER_TOO_SMALL (100u) +# endif + +# define CRYPTO_30_VHSM_JOBREQUEST_STATE_IDLE (0x00u) +# define CRYPTO_30_VHSM_JOBREQUEST_STATE_PROCESSING (0x01u) +# define CRYPTO_30_VHSM_JOBREQUEST_STATE_RESULT_AVAILABLE (0x02u) +# define CRYPTO_30_VHSM_JOBREQUEST_STATE_TIMEOUT (0x03u) + +# define CRYPTO_30_VHSM_HSM2HOST_ACTIVE (0u) +# define CRYPTO_30_VHSM_HSM2HOST_READY (1u) +# define CRYPTO_30_VHSM_HSM2HOST_UPDATERRUNNING (15u) + +/* Macros for Job access */ +# if !defined (CRYPTO_30_VHSM_JOB_STATE_MEMBER) /* COV_CRYPTO_30_VHSM_ASR_COMPATIBILITY */ +# define CRYPTO_30_VHSM_JOB_STATE_MEMBER jobState +# endif + +# if !defined (CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER) /* COV_CRYPTO_30_VHSM_ASR_COMPATIBILITY */ +# define CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER jobPrimitiveInputOutput +# endif + +/* Multi Partition */ +# if (CRYPTO_30_VHSM_NUMBER_OF_PARTITIONS > 1u) +# define Crypto_30_vHsm_GetCurrentPartitionIdx() Crypto_30_vHsm_GetPartitionIdx() +# define Crypto_30_vHsm_GetCurrentPartitionIdxOfObjectInfo(objectId) Crypto_30_vHsm_GetPartitionIdxOfObjectInfo(objectId) +# else +# define Crypto_30_vHsm_GetCurrentPartitionIdx() 0u +# define Crypto_30_vHsm_GetCurrentPartitionIdxOfObjectInfo(objectId) 0u +# endif + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_VHSM_START_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_Init() + *********************************************************************************************************************/ +/*! \brief Initializes the Crypto Driver + * \details This function initializes the module Crypto_30_vHsm. It initializes all variables and sets the + * module state to initialized. + * \pre Interrupts are disabled. + * Module is uninitialized. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + * \note Specification of module initialization + * \trace CREQ-131331 + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Init(void); + +# if (CRYPTO_30_VHSM_VERSION_INFO_API == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_GetVersionInfo() + *********************************************************************************************************************/ +/*! \brief Returns the version information + * \details Function returns version information, vendor ID and AUTOSAR module ID of the component. + * \param[out] versioninfo Valid pointer to where to store the version information. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \config CRYPTO_30_VHSM_VERSION_INFO_API == STD_ON + * \trace CREQ-131329 + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_GetVersionInfo( + P2VAR(Std_VersionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) versioninfo); +# endif /* (CRYPTO_30_VHSM_VERSION_INFO_API == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ProcessJob() + *********************************************************************************************************************/ +/*! \brief Processes the received job + * \details Performs the crypto primitive, that is configured in the job parameter. + * \param[in] objectId Valid Id of the Crypto Driver Object. + * \param[in,out] job Valid pointer to the configuration of the job. Contains structures with job and + * primitive relevant information but also pointer to result buffers. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_NOT_VALID Request failed, the key is not valid. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, a key element has the wrong size. + * CRYPTO_E_QUEUE_FULL Request failed, the queue is full. + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, the entropy is exhausted + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * CRYPTO_E_COUNTER_OVERFLOW The counter is overflowed. + * CRYPTO_E_JOB_CANCELED The service request failed because the synchronous Job has been canceled. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE|FALSE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ProcessJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) job); + +/********************************************************************************************************************** + * Crypto_30_vHsm_CancelJob() + *********************************************************************************************************************/ +/*! \brief Cancels the received job + * \details This interface removes the provided job from the queue and cancels the processing of the job if possible. + * \param[in] objectId Valid identifier of the Crypto Driver Object. + * \param[in,out] job Valid pointer to the configuration of the job. Contains structures with user and + * primitive relevant information. + * \return E_OK Request successful, job has been removed. + * E_NOT_OK Request failed, job could not be removed. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_CancelJob( + uint32 objectId, + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) job); + +# if (CRYPTO_30_VHSM_NUMBER_OF_PARTITIONS > 1u) +/********************************************************************************************************************** + * Crypto_30_vHsm_GetPartitionIdx() + *********************************************************************************************************************/ +/*! \brief Returns the current active partition idx. + * \details - + * \return Current partition idx + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Crypto_30_vHsm_PartitionIdentifiersIterType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_GetPartitionIdx(void); +# endif /* (CRYPTO_30_VHSM_NUMBER_OF_PARTITIONS > 1u) */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_TriggerInterruptOfPartition() + *********************************************************************************************************************/ +/*! \brief Trigger an interrupt to the HSM + * \details - + * \param[in] partitionIdx Valid identifier of the partition. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_TriggerInterruptOfPartition(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_vHsm_ClearInterruptOfPartition() + *********************************************************************************************************************/ +/*! \brief Clear the response interrupt flag + * \details - + * \param[in] partitionIdx Valid identifier of the partition. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ClearInterruptOfPartition(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_vHsm_IndicateInitializedIpcOfPartition() + *********************************************************************************************************************/ +/*! \brief Indicate that the IPC has been initialized to the HSM + * \details For multi partition use-case, a spinlock is needed to synchronize the access to the HOST2HSM register when IPC initialization shall be done by the driver. + * \param[in] partitionIdx Valid identifier of the partition. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_IndicateInitializedIpcOfPartition(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +# if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_PerformTimeout() + *********************************************************************************************************************/ + /*! + * \brief Performs a timeout on the stuck driver object and stops the active waiting for an answer of the Hsm. + * \details Can be called from the timeout detect callout when a timeout is detected. + * \param[in] objectId The driver object which is stuck and should be timeouted. + * \return E_OK Timeout successfully set. + * E_NOT_OK Timeout failed. + * \pre Only to be called by Crypto_30_vHsm_TimeoutDetect_Loop_Callout(). + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_PerformTimeout(uint32 objectId); +# endif /* (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) */ + +# define CRYPTO_30_VHSM_STOP_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define CRYPTO_30_VHSM_START_SEC_RAMCODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ProcessJobRequest() + *********************************************************************************************************************/ +/*! \brief Process the job request + * \details - + * \param[in] jobRequestId Valid Id of the job request (in range of Crypto_30_vHsm_GetSizeOfJobRequest()) + * \param[in] partitionIdx Valid identifier of the partition. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre jobRequestId < Crypto_30_vHsm_GetSizeOfJobRequest() + * \context TASK + * \reentrant FALSE + * \synchronous TRUE|FALSE Sync or Async, depends on the job configuration + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ProcessJobRequest( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +# if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) +/********************************************************************************************************************** + * Crypto_30_vHsm_WaitForHsmRam() + *********************************************************************************************************************/ +/*! + * \brief Waits in the RAM for the vHsm Ready flag. + * \details This is only needed because the vHsm has no control over the application core startup when a debugger is attached. + * When a debugger is attached, all cores will startup immediately. + * \pre - + * \context * + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-WaitLoopCallout + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_WaitForHsmRam(void); +# else /* !(CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) */ +/********************************************************************************************************************** + * Crypto_30_vHsm_WaitForHsmRamForApplication() + *********************************************************************************************************************/ +/*! + * \brief Waits in the RAM for the vHsm Ready flag. + * \details This is only needed because the vHsm has no control over the application core startup when a debugger is attached. + * When a debugger is attached, all cores will startup immediately. + * \param[in] applicationId Valid ApplicationId + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * \pre - + * \context * + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-WaitLoopCallout + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_WaitForHsmRamForApplication(ApplicationType applicationId); +# endif /* !(CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) */ + +# define CRYPTO_30_VHSM_STOP_SEC_RAMCODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define CRYPTO_30_VHSM_START_SEC_APPL_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_19.1 */ + +# if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_TimeoutDetect_Start_Callout() + *********************************************************************************************************************/ +/*! \brief Notification just before waiting for a response from the vHsm Firmware. + * \details Implementation has to be done in the application. + * \param[in] calloutId Identifies the loop. + * \param[in] objectId Id of the Crypto Driver Object of the current context. This is only relevant if calloutId is + * CRYPTO_30_VHSM_CALLOUT_JOBREQUEST or CRYPTO_30_VHSM_CALLOUT_ASYNC. + * \param[in] contextClass Type of the current context. Only relevant if calloutId is CRYPTO_30_VHSM_CALLOUT_JOBREQUEST + * or CRYPTO_30_VHSM_CALLOUT_ASYNC. + * \param[in] contextId If contextClass is CRYPTO_30_VHSM_CALLOUT_CRYPTOJOB, this parameter is the crypto job id, + * if contextClass is CRYPTO_30_VHSM_CALLOUT_KEYMJOB, this parameter is the key id. + * Only relevant if calloutId is CRYPTO_30_VHSM_CALLOUT_JOBREQUEST. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_APPL_CODE) Crypto_30_vHsm_TimeoutDetect_Start_Callout(Crypto_30_vHsm_CalloutIdType calloutId, + uint32 objectId, Crypto_30_vHsm_CalloutContextClassType contextClass, uint32 contextId); + +/********************************************************************************************************************** + * Crypto_30_vHsm_TimeoutDetect_Loop_Callout() + *********************************************************************************************************************/ +/*! \brief Notification about ongoing waiting for a response from the vHsm Firmware. + * \details Implementation has to be done in the application. + * \param[in] calloutId Identifies the loop. + * \param[in] objectId Id of the Crypto Driver Object of the current context. This is only relevant if calloutId is + * CRYPTO_30_VHSM_CALLOUT_JOBREQUEST or CRYPTO_30_VHSM_CALLOUT_ASYNC. + * \param[in] contextClass Type of the current context. Only relevant if calloutId is CRYPTO_30_VHSM_CALLOUT_JOBREQUEST + * or CRYPTO_30_VHSM_CALLOUT_ASYNC. + * \param[in] contextId If contextClass is CRYPTO_30_VHSM_CALLOUT_CRYPTOJOB, this parameter is the crypto job id, + * if contextClass is CRYPTO_30_VHSM_CALLOUT_KEYMJOB, this parameter is the key id. + * Only relevant if calloutId is CRYPTO_30_VHSM_CALLOUT_JOBREQUEST. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_APPL_CODE) Crypto_30_vHsm_TimeoutDetect_Loop_Callout(Crypto_30_vHsm_CalloutIdType calloutId, + uint32 objectId, Crypto_30_vHsm_CalloutContextClassType contextClass, uint32 contextId); + +/********************************************************************************************************************** + * Crypto_30_vHsm_TimeoutDetect_End_Callout() + *********************************************************************************************************************/ +/*! \brief Notification just after waiting for a response from the vHsm Firmware. + * \details Implementation has to be done in the application. + * \param[in] calloutId Identifies the loop. + * \param[in] objectId Id of the Crypto Driver Object of the current context. This is only relevant if calloutId is + * CRYPTO_30_VHSM_CALLOUT_JOBREQUEST or CRYPTO_30_VHSM_CALLOUT_ASYNC. + * \param[in] contextClass Type of the current context. Only relevant if calloutId is CRYPTO_30_VHSM_CALLOUT_JOBREQUEST + * or CRYPTO_30_VHSM_CALLOUT_ASYNC. + * \param[in] contextId If contextClass is CRYPTO_30_VHSM_CALLOUT_CRYPTOJOB, this parameter is the crypto job id, + * if contextClass is CRYPTO_30_VHSM_CALLOUT_KEYMJOB, this parameter is the key id. + * Only relevant if calloutId is CRYPTO_30_VHSM_CALLOUT_JOBREQUEST. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_APPL_CODE) Crypto_30_vHsm_TimeoutDetect_End_Callout(Crypto_30_vHsm_CalloutIdType calloutId, + uint32 objectId, Crypto_30_vHsm_CalloutContextClassType contextClass, uint32 contextId); +# endif /* (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) */ + +# if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_TimeoutRecovered_Callout() + *********************************************************************************************************************/ + /*! \brief Notification about a recovered driver object after a timeout was detected. + * \details Implementation has to be done in the application. + * \param[in] objectId Id of the recovered Crypto Driver Object of the current context. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_APPL_CODE) Crypto_30_vHsm_TimeoutRecovered_Callout(uint32 objectId); +# endif /* (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) */ + +# if (CRYPTO_30_VHSM_INTERRUPT_SET_CALLOUT_AVAILABLE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_RequestInterruptSet_Callout() + *********************************************************************************************************************/ +/*! \brief Function which is called to set the request interrupt flag. + * \details Usually the driver provides the capability to handle setting the interrupt flag by itself. However new + * platforms or use-cases may require more specific handling which can be implemented in this callout. + * \param[in] address Address configured in the Cfg5 for the response interrupt clearing + * \param[in] mask Mask configured in the Cfg5 for the response interrupt clearing + * \param[in] value Value configured in the Cfg5 for the response interrupt clearing + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_APPL_CODE) Crypto_30_vHsm_RequestInterruptSet_Callout(uint32 address, uint32 mask); +# endif /* (CRYPTO_30_VHSM_INTERRUPT_SET_CALLOUT_AVAILABLE == STD_ON) */ + +# if (CRYPTO_30_VHSM_INTERRUPT_CLEAR_CALLOUT_AVAILABLE == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_ResponseInterruptClear_Callout() + *********************************************************************************************************************/ +/*! \brief Function which is called to clear the response interrupt flag. + * \details Usually the driver provides the capability to handle clearing the interrupt flag by itself. However new + * platforms or use-cases may require more specific handling which can be implemented in this callout. + * \param[in] address Address configured in the Cfg5 for the response interrupt clearing + * \param[in] mask Mask configured in the Cfg5 for the response interrupt clearing + * \param[in] value Value configured in the Cfg5 for the response interrupt clearing + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_APPL_CODE) Crypto_30_vHsm_ResponseInterruptClear_Callout(uint32 address, uint32 mask, uint32 value); +# endif /* (CRYPTO_30_VHSM_INTERRUPT_CLEAR_CALLOUT_AVAILABLE == STD_ON) */ + +# define CRYPTO_30_VHSM_STOP_SEC_APPL_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_19.1 */ + +#endif /* !defined (CRYPTO_30_VHSM_H) */ + +/*! + * \exclusivearea CRYPTO_30_VHSM_EXCLUSIVE_AREA_0 + * Protects global data from inconsistencies + * \protects Crypto_30_vHsm_JobRequestMap, Crypto_30_vHsm_DriverObjectList, Crypto_30_vHsm_JobRequestList + * \usedin Crypto_30_vHsm_ProcessJob, Crypto_30_vHsm_CancelJob, Crypto_30_vHsm_CertificateParse, + * Crypto_30_vHsm_CertificateVerify, Crypto_30_vHsm_KeyCopy, Crypto_30_vHsm_KeyDerive, Crypto_30_vHsm_KeyElementCopy, + * Crypto_30_vHsm_KeyElementGet, Crypto_30_vHsm_KeyElementIdsGet, Crypto_30_vHsm_KeyElementSet, + * Crypto_30_vHsm_KeyExchangeCalcPubVal, Crypto_30_vHsm_KeyExchangeCalcSecret, Crypto_30_vHsm_KeyGenerate, + * Crypto_30_vHsm_KeyValidSet Crypto_30_vHsm_RandomSeed + * \exclude All functions provided by Crypto. + * \length SHORT The access to the protected variables is kept short + * \endexclusivearea + */ + +/*! + * \exclusivearea CRYPTO_30_VHSM_EXCLUSIVE_AREA_1 + * Protects that a forwarded DET from the vHsm to be processed only once. (Flag is located in the IPC memory) + * \protects The IPC memory referenced by Crypto_30_vHsm_Ipc_MemoryPtr + * \usedin Crypto_30_vHsm_ProcessJobRequest, Crypto_30_vHsm_MainFunction + * \exclude Crypto_30_vhsm_GetVersionInfo + * \length SHORT The access to the protected variables is kept short + * \endexclusivearea + */ + +/*! + * \exclusivearea CRYPTO_30_VHSM_EXCLUSIVE_AREA_2 + * Protects workspace locking resources when it can not be ensured that uint32 write access is atomic. + * If atomic uint32 write access can be guaranteed, this critical section can be empty. + * \protects Crypto_30_vHsm_DriverObjectLock + * \usedin Crypto_30_vHsm_ProcessCryptoJob + * \exclude All functions provided by Crypto. + * \length SHORT The access to the protected variables is kept short and is only a uint32 write operation. + * \endexclusivearea + */ + +/*! + * \exclusivearea CRYPTO_30_VHSM_EXCLUSIVE_AREA_3 + * Protects workspace locking resources when it can not be ensured that uint32 write access is atomic. + * If atomic uint32 write access can be guaranteed, this critical section can be empty. + * If interrupt mode of driver is used and ISRs can't be interrupted by the same interrupt, this critical section does not need to be protected. + * \protects Crypto_30_vHsm_DriverObjectLock + * \usedin Crypto_30_vHsm_Ipc_ProcessCallbacks + * \exclude All functions provided by Crypto. + * \length SHORT The access to the protected variables is kept short and is only a uint32 write operation. + * \endexclusivearea + */ + +/*! + * \exclusivearea CRYPTO_30_VHSM_EXCLUSIVE_AREA_4 + * Protects HOST2HSM register if multiple partitions are configured because multiple cores need to write to the register. + * This needs to be a spinlock for multi core configurations + * \protects HOST2HSM register + * \usedin Crypto_30_vHsm_IndicateInitializedIpcOfPartition + * \exclude All functions provided by Crypto. + * \length SHORT The access to the protected variables is kept short and is only a uint32 write operation. + * \endexclusivearea + */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_vHsm.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Custom.h b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Custom.h new file mode 100644 index 0000000..c89c9d2 --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Custom.h @@ -0,0 +1,425 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_vHsm_Custom.h + * \brief MICROSAR Crypto Driver (Crypto) + * + * \details Internal header file for custom algorithms + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_VHSM_CUSTOM_H) +# define CRYPTO_30_VHSM_CUSTOM_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +# include "Crypto_30_vHsm_Custom_Generated.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* ----- Additional Key Element defines ---------------------------------------------- */ + +/* AES MAC */ +# if !defined (CRYPTO_KE_CUSTOM_MAC_AES_ROUNDKEY) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_MAC_AES_ROUNDKEY (129u) +# endif + +/* Key Derive */ +# if !defined (CRYPTO_KE_CUSTOM_KEYDERIVATION_LABEL) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_KEYDERIVATION_LABEL (130u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_KEYDERIVATION_ADDITIONAL_INFO (131u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_ADDITIONAL_INFO) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_ADDITIONAL_INFO (131u) +# endif + +/* RSA */ +# if !defined (CRYPTO_KE_CUSTOM_RSA_MODULUS) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_MODULUS (160u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_RSA_PUBLIC_EXPONENT) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_PUBLIC_EXPONENT (161u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_RSA_PRIVATE_EXPONENT) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_PRIVATE_EXPONENT (162u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_RSA_SALT) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_SALT (163u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_RSA_SALT_LENGTH) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_SALT_LENGTH (164u) +# endif + +/* TLS */ +# if !defined (CRYPTO_KE_CUSTOM_TLS_CLIENT_HELLO_RANDOM) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_TLS_CLIENT_HELLO_RANDOM (3000u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_TLS_SERVER_HELLO_RANDOM) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_TLS_SERVER_HELLO_RANDOM (3001u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_TLS_HMAC_KEY_SIZE) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_TLS_HMAC_KEY_SIZE (3002u) +# endif + +/* Key Exchange */ +# if !defined (CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_KEYEXCHANGE_PARTNER_PUB_KEY (3003u) +# endif + +/* Smart Charge Communication */ +# if !defined (CRYPTO_KE_CUSTOM_SCC_CONTRACT_PUBLIC_KEY) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SCC_CONTRACT_PUBLIC_KEY (3013u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_SCC_IV_AND_ENCRYPTED_PRIVATE_KEY) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SCC_IV_AND_ENCRYPTED_PRIVATE_KEY (3014u) +# endif + +/* Random Number Generation */ +# if !defined (CRYPTO_KE_CUSTOM_RANDOM_PERSONALIZATION_STRING) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RANDOM_PERSONALIZATION_STRING (3015u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_RANDOM_ADDITIONAL_INPUT) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RANDOM_ADDITIONAL_INPUT (3016u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_RANDOM_NONCE) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RANDOM_NONCE (3017u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RANDOM_RESEED_COUNTER (3018u) +# endif + +/* SHE Key Update */ +# if !defined (CRYPTO_KE_CUSTOM_SHE_COUNTER) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SHE_COUNTER (3019u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_SHE_UID) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SHE_UID (3021u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_SHE_BOOT_PROTECTION) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SHE_BOOT_PROTECTION (3056u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_SHE_DEBUGGER_PROTECTION) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SHE_DEBUGGER_PROTECTION (3057u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_SHE_DEBUG_CMD) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_SHE_DEBUG_CMD (3059u) +# endif + +/* RSA CRT */ +# if !defined (CRYPTO_KE_CUSTOM_RSA_PRIME_P) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_PRIME_P (3051u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_RSA_PRIME_Q) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_PRIME_Q (3052u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_RSA_EXPONENT_DP) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_EXPONENT_DP (3053u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_RSA_EXPONENT_DQ) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_EXPONENT_DQ (3054u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_RSA_INVERSE_QI) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_RSA_INVERSE_QI (3055u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_LABEL) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_LABEL (3058u) +# endif + +/* Spake2+ */ +# if !defined (CRYPTO_KE_CUSTOM_W0) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_W0 (3084u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_W1) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_W1 (3085u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_L) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_L (3086u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_VERIFICATION) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VERIFICATION (3087u) +# endif + +# if !defined (CRYPTO_KE_CUSTOM_VERIFICATION_RESULT) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VERIFICATION_RESULT (3088u) +# endif + +/* ----- Custom Algorithm Mode Defines ---------------------------------------------- */ +/* ECC curve p256r1 */ +# if !defined (CRYPTO_ALGOMODE_CUSTOM_P256R1) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_P256R1 (128u) +# endif + +/* RSA CRT */ +# if !defined (CRYPTO_ALGOMODE_CUSTOM_RSASSA_PKCS1_v1_5_CRT) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_RSASSA_PKCS1_v1_5_CRT (129u) +# endif + +# if !defined (CRYPTO_ALGOMODE_CUSTOM_RSAES_OAEP_CRT) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_RSAES_OAEP_CRT (132u) +# endif + +/* Use Derivation function e.g. for NIST DRBG AES128 */ +# if !defined (CRYPTO_ALGOMODE_CUSTOM_USE_DF) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_USE_DF (130u) +# endif + +/* ECC curve p384r1 */ +# if !defined (CRYPTO_ALGOMODE_CUSTOM_P384R1) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOMODE_CUSTOM_P384R1 (131u) +# endif + +/* ----- Custom Algorithm Family Defines ---------------------------------------------- */ +/* Ecc-ANSI conform */ +# if !defined (CRYPTO_ALGOFAM_CUSTOM_ECCANSI) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_ECCANSI (129u) +# endif +/* Ecc-SEC conform */ +# if !defined (CRYPTO_ALGOFAM_CUSTOM_ECCSEC) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_ECCSEC (130u) +# endif +/* NIST 800-90A DRBG conform */ +# if !defined (CRYPTO_ALGOFAM_CUSTOM_DRBG) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_DRBG (131u) +# endif +/* FIPS 186.2 conform */ +# if !defined (CRYPTO_ALGOFAM_CUSTOM_FIPS186) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_FIPS186 (132u) +# endif +/* Padding PKCS7 */ +# if !defined (CRYPTO_ALGOFAM_CUSTOM_PADDING_PKCS7) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_PADDING_PKCS7 (133u) +# endif + +/* ----- Custom Key Exchange Algorithm Defines ---------------------------------------------- */ +/* Exchange algorithm x25519 */ +# if !defined (CRYPTO_30_LIBCV_KEY_EXCHANGE_X25519) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_X25519 (0u) +# endif +/* Exchange algorithm ANSI p256r1 */ +# if !defined (CRYPTO_30_LIBCV_KEY_EXCHANGE_ANSIP256R1) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_ANSIP256R1 (1u) +# endif + +/* Exchange algorithm SEC p256r1 */ +# if !defined (CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP256R1) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP256R1 (2u) +# endif +/* Exchange algorithm SEC p384r1 */ +# if !defined (CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP384R1) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KEY_EXCHANGE_SECP384R1 (4u) +# endif + +/* ----- Custom Key Derivation Algorithm Defines ---------------------------------------------- */ +/* KDF_NIST_800-108 'KDF in Counter Mode' with SHA-256 as PRF */ +# if !defined (CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_SYM_NIST_800_108_CNT_MODE_SHA256 (1u) +# endif + +/* NIST.FIPS.186-4 'Key Pair Generation Using Extra Random Bits' with 'KDF in Counter Mode' as RBG */ +# if !defined (CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_ASYM_NIST_FIPS_186_4_ERB (2u) +# endif + +/* NIST.SP.800-56A Single-Step KDF with Option 1: H(x) = hash(x) */ +# if !defined (CRYPTO_30_LIBCV_KDF_ALGO_KDF_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_NIST_800_56_A_ONE_PASS_C1E1S_SINGLE_STEP_KDF_SHA256 (3u) +# endif + +/* ISO 15118 install and update certificate. */ +# if !defined (CRYPTO_30_LIBCV_KDF_ALGO_KDF_ISO_15118_CERTIFICATE_HANDLING) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_ISO_15118_CERTIFICATE_HANDLING (4u) +# endif + +/* KDF X9.63 SHA 1 */ +# if !defined (CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA1) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA1 (5u) +# endif + +/* KDF X9.63 SHA 256 */ +# if !defined (CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA256) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA256 (6u) +# endif + +/* KDF X9.63 SHA 512 */ +# if !defined (CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA512) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_KDF_ALGO_KDF_X963_SHA512 (7u) +# endif + +/* ----- Custom Random Seed Algorithm Defines ---------------------------------------------- */ +/* Random Seed according to FIPS 186-2 SHA1 */ +# if !defined (CRYPTO_30_LIBCV_RNG_FIPS_186_2_SHA1) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_RNG_FIPS_186_2_SHA1 (0u) +# endif +/* Random Seed according to NIST 800-90A CTR_DRBG with AES-128 */ +# if !defined (CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES128) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ALGORITHM */ +# define CRYPTO_30_LIBCV_RNG_NIST_800_90A_CTR_DRBG_AES128 (1u) +# endif + +# if !defined (CRYPTO_ALGOFAM_CUSTOM_SECURE_BOOT) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_SECURE_BOOT (160u) /* This define is deprecated */ +# endif +# if !defined (CRYPTO_ALGOFAM_CUSTOM_VHSM_SECURE_BOOT) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_VHSM_SECURE_BOOT (160u) +# endif +# if !defined (CRYPTO_ALGOFAM_CUSTOM_SOFTWARE_DOWNLOAD) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_SOFTWARE_DOWNLOAD (161u) /* This define is deprecated */ +# endif +# if !defined (CRYPTO_ALGOFAM_CUSTOM_VHSM_SOFTWARE_DOWNLOAD) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_VHSM_SOFTWARE_DOWNLOAD (161u) +# endif +# if !defined (CRYPTO_ALGOFAM_CUSTOM_VHSM_FIRMWARE_UPDATE) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_VHSM_FIRMWARE_UPDATE (163u) +# endif +# if !defined (CRYPTO_ALGOFAM_CUSTOM_VHSM_BOOT_UPDATE) /* COV_CRYPTO_30_VHSM_CUSTOM_ALGORITHM */ +# define CRYPTO_ALGOFAM_CUSTOM_VHSM_BOOT_UPDATE (164u) +# endif + +/* vHsm Core */ +# if !defined (CRYPTO_KE_CUSTOM_VHSM_VERSION) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_VERSION (3020u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_UID) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_UID (3021u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_PERFORM_PERSISTING) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_PERFORM_PERSISTING (3022u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_ERRORLOG) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_ERRORLOG (3023u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_SLOT_ADDRESS) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_SLOT_ADDRESS (3024u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_SLOT_SIZE) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_SLOT_SIZE (3025u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_SLOT_CMAC) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_SLOT_CMAC (3026u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_SLOT_SANCTION) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_SLOT_SANCTION (3027u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_END) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_END (3028u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_RESULT) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_RESULT (3037u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_FIRMWARE_UPDATE_START_UPDATER) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_FIRMWARE_UPDATE_START_UPDATER (3038u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_PERFORM_REPERSISTING) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_PERFORM_REPERSISTING (3036u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_SLOT_KEY) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_SECURE_BOOT_SLOT_KEY (1u) +# endif + +/* vHsm Custom */ +# if !defined (CRYPTO_KE_CUSTOM_VHSM_BUNDLING_REQ) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_BUNDLING_REQ (3029u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_BUNDLING_RESP) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_BUNDLING_RESP (3030u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_BUNDLING_COUNTER) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_BUNDLING_COUNTER (3031u) +# endif + +/* vHsm Hal */ +# if !defined (CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION (3032u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_RESET_VECTORS) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_RESET_VECTORS (3033u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_OPTION_BYTES) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_OPTION_BYTES (3034u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_UPGP) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_UPGP (3035u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_STATUS_HSM2HOST) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_STATUS_HSM2HOST (3090u) +# endif +# if !defined (CRYPTO_KE_CUSTOM_VHSM_STATUS_HOST2HSM) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENTS */ +# define CRYPTO_KE_CUSTOM_VHSM_STATUS_HOST2HSM (3091u) +# endif + +# if !defined (CRYPTO_30_VHSM_DATAFLASH_START) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENT_VALUE */ +# define CRYPTO_30_VHSM_DATAFLASH_START (0u) +# endif +# if !defined (CRYPTO_30_VHSM_DATAFLASH_STOP) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENT_VALUE */ +# define CRYPTO_30_VHSM_DATAFLASH_STOP (1u) +# endif +# if !defined (CRYPTO_30_VHSM_CODEFLASH_START) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENT_VALUE */ +# define CRYPTO_30_VHSM_CODEFLASH_START (2u) +# endif +# if !defined (CRYPTO_30_VHSM_CODEFLASH_STOP) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENT_VALUE */ +# define CRYPTO_30_VHSM_CODEFLASH_STOP (3u) +# endif + +# if !defined (CRYPTO_30_VHSM_SANCTION_NONE) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENT_VALUE */ +# define CRYPTO_30_VHSM_SANCTION_NONE (0u) +# endif +# if !defined (CRYPTO_30_VHSM_SANCTION_RESET) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENT_VALUE */ +# define CRYPTO_30_VHSM_SANCTION_RESET (1u) +# endif +# if !defined (CRYPTO_30_VHSM_SANCTION_CUSTOM) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENT_VALUE */ +# define CRYPTO_30_VHSM_SANCTION_CUSTOM (2u) +# endif +# if !defined (CRYPTO_30_VHSM_SANCTION_HALT) /* COV_CRYPTO_30_VHSM_CUSTOM_KEY_ELEMENT_VALUE */ +# define CRYPTO_30_VHSM_SANCTION_HALT (3u) +# endif + +#endif /* !defined (CRYPTO_30_VHSM_CUSTOM_H) */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_vHsm_Custom.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc.c b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc.c new file mode 100644 index 0000000..6bb66ea --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc.c @@ -0,0 +1,989 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file Crypto_30_vHsm_Ipc.c + * \brief MICROSAR vHsm Crypto Driver (Crypto) + * + * \details Inter-processor communication between Host and Vector Hardware Security Module Firmware. + * + *********************************************************************************************************************/ + + /********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_IPC_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Crypto_30_vHsm.h" +#include "Crypto_30_vHsm_Ipc.h" +#include "Crypto_30_vHsm_Jobs.h" +#include "Crypto_30_vHsm_Private.h" +#include "CryIf_Cbk.h" +#include "SchM_Crypto_30_vHsm.h" +#include "vstdlib.h" + +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) +# include "Det.h" +#endif + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION MACROS + *********************************************************************************************************************/ +#if !defined (CRYPTO_30_VHSM_LOCAL) /* COV_CRYPTO_30_VHSM_LOCAL_DEFINE */ +# define CRYPTO_30_VHSM_LOCAL static +#endif + +#if !defined (CRYPTO_30_VHSM_LOCAL_INLINE) /* COV_CRYPTO_30_VHSM_LOCAL_DEFINE */ +# define CRYPTO_30_VHSM_LOCAL_INLINE LOCAL_INLINE +#endif + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_START_SEC_VAR_NOINIT_32BIT +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*! Pointer to the IPC memory */ +P2VAR(uint32, CRYPTO_30_VHSM_VAR_NOINIT, CRYPTO_30_VHSM_VAR_NOINIT) Crypto_30_vHsm_Ipc_MemoryPtrOfPartition[CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES]; + +#define CRYPTO_30_VHSM_STOP_SEC_VAR_NOINIT_32BIT +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ +#define CRYPTO_30_VHSM_START_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SendRequestToIpc() + *********************************************************************************************************************/ +/*! + * \brief Serialize the jobrequest + * \details - + * \param[in] jobRequestId Valid Id of the jobrequest + * \param[in] jobRequestBuffer Valid buffer pointer where the job shall be serialized. + * Must at least be of size CRYPTO_30_VHSM_IPC_TX_CHANNEL_MEMORY_SIZE. + * \return TRUE if the job request was correctly serialized, otherwise E_NOT_OK + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SendRequestToIpc( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + Crypto_30_vHsm_JobRequestBufferPtrType jobRequestBuffer); + +/********************************************************************************************************************** + * Crypto_30_vHsm_GetResponseFromIpc() + *********************************************************************************************************************/ +/*! + * \brief Deserialize the job response + * \details - + * \param[in] partitionIdx Valid partition index + * \param[in] rxChannelId Valid Channel where the response is allocated + * \param[in] writeIdx WriteIdx of the channel which will be used to acknowledge the response in the IPC. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_GetResponseFromIpc( + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx, + Crypto_30_vHsm_ChannelIdType rxChannelId, + uint32 writeIdx); + +#define CRYPTO_30_VHSM_STOP_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ +#define CRYPTO_30_VHSM_START_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SendRequestToIpc() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SendRequestToIpc( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + Crypto_30_vHsm_JobRequestBufferPtrType jobRequestBuffer) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_vHsm_JobKindType jobRequestKind; +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + Crypto_JobRedirectionInfoType Crypto_JobRedirectionInfoDummy; + P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) Crypto_JobRedirectionInfoPtr; + boolean isCryptoJob = FALSE; +#endif + uint32 jobInformation; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Get the kind of the job request */ + jobRequestKind = Crypto_30_vHsm_GetKindOfJobRequest(jobRequestId); + + if ((jobRequestKind == CRYPTO_30_VHSM_CRYPTO_JOBKIND) +#if (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION == STD_ON) + || (jobRequestKind == CRYPTO_30_VHSM_CRYPTO_MACGEN_JOBKIND) + || (jobRequestKind == CRYPTO_30_VHSM_CRYPTO_MACVER_JOBKIND) +#endif + ) + { +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + isCryptoJob = TRUE; +#endif + } + /* #21 Add job request header. */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + Crypto_30_vHsm_SetCounterOfJobRequest(jobRequestId, (Crypto_30_vHsm_CounterOfJobRequestType)(Crypto_30_vHsm_GetCounterOfJobRequest(jobRequestId) + 1u)); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + /* still some free flags... redirection flags are only 5 bit currently */ + jobInformation = (((uint32)(Crypto_30_vHsm_GetCounterOfJobRequest(jobRequestId)) << CRYPTO_30_VHSM_JOBREQUEST_COUNTER_BITPOSITION) + | ((uint32)(Crypto_30_vHsm_GetHsmObjIdOfObjectInfo(jobRequestId)) << CRYPTO_30_VHSM_JOBREQUEST_OBJECTID_BITPOSITION) + | jobRequestId); +#else + jobInformation = ((((uint32)(Crypto_30_vHsm_GetHsmObjIdOfObjectInfo(jobRequestId)) << CRYPTO_30_VHSM_JOBREQUEST_OBJECTID_BITPOSITION)) | jobRequestId); +#endif /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) */ +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + if ((isCryptoJob == TRUE) + && (Crypto_30_vHsm_GetCryptoJobOfJobRequest(jobRequestId)->jobRedirectionInfoRef != NULL_PTR)) /* PRQA S 3415 */ /* MD_CRYPTO_30_VHSM_3415_LOGICAL_OPERATOR */ + { + jobInformation |= (((uint32)Crypto_30_vHsm_GetCryptoJobOfJobRequest(jobRequestId)->jobRedirectionInfoRef->redirectionConfig) << CRYPTO_30_VHSM_JOBREQUEST_REDIRECTION_BITPOSITION); + Crypto_JobRedirectionInfoPtr = Crypto_30_vHsm_GetCryptoJobOfJobRequest(jobRequestId)->jobRedirectionInfoRef; + } + else + { + Crypto_JobRedirectionInfoDummy.redirectionConfig = 0u; + Crypto_JobRedirectionInfoPtr = &Crypto_JobRedirectionInfoDummy; + } +#endif /* (CRYPTO_30_VHSM_REDIRECTION == STD_ON) */ + +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + /* Buffer size */ + Crypto_30_vHsm_Serialize_Uint32(CRYPTO_30_VHSM_IPC_TX_CHANNEL_ENTRY_MEMORY_SIZE, jobRequestBuffer); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + /* Header */ + Crypto_30_vHsm_Serialize_Uint32(jobInformation, &jobRequestBuffer[4]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(jobRequestKind, &jobRequestBuffer[8]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32((uint32)Crypto_30_vHsm_IsCancelOfJobRequest(jobRequestId), &jobRequestBuffer[12]); /* PRQA S 0310, 3305, 4304 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ +#else /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) */ + /* Header */ + Crypto_30_vHsm_Serialize_Uint32(jobInformation, &jobRequestBuffer[0]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(jobRequestKind, &jobRequestBuffer[4]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ +#endif + + /* Set init values inside jobRequest */ + Crypto_30_vHsm_SetUsedBufferOfJobRequest(jobRequestId, 0u); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + Crypto_30_vHsm_SetTrimmedOutputBufferOfJobRequest(jobRequestId, FALSE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#endif + + /* #22 Call job request transmission function. */ + switch (jobRequestKind) + { +#if (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION == STD_ON) + case CRYPTO_30_VHSM_CRYPTO_MACVER_JOBKIND: + retVal = Crypto_30_vHsm_SerializeRequest_CryptoJob_MacVer( /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_CryptoJob_MacVer */ + jobRequestId, + Crypto_30_vHsm_GetCryptoJobOfJobRequest(jobRequestId), + &jobRequestBuffer[16] +# if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , Crypto_JobRedirectionInfoPtr +# endif + ); + break; + case CRYPTO_30_VHSM_CRYPTO_MACGEN_JOBKIND: + retVal = Crypto_30_vHsm_SerializeRequest_CryptoJob_MacGen( /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_CryptoJob_MacGen */ + jobRequestId, + Crypto_30_vHsm_GetCryptoJobOfJobRequest(jobRequestId), + &jobRequestBuffer[16] +# if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , Crypto_JobRedirectionInfoPtr +# endif + ); + break; +#endif /* (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION == STD_ON) */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) +# if (CRYPTO_30_VHSM_KEY_DERIVE_JOB_SUPPORT == STD_ON) + case CRYPTO_30_VHSM_KEYMANAGEMENT_KEYDERIVEJOB_JOBKIND: +# endif +#endif + case CRYPTO_30_VHSM_CRYPTO_JOBKIND: + retVal = Crypto_30_vHsm_SerializeRequest_CryptoJob( /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_CryptoJob */ + jobRequestId, + Crypto_30_vHsm_GetCryptoJobOfJobRequest(jobRequestId), +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + &jobRequestBuffer[8] +#else + &jobRequestBuffer[16] +#endif +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , Crypto_JobRedirectionInfoPtr +#endif + ); + break; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + case CRYPTO_30_VHSM_KEYMANAGEMENT_COPY_PARTIAL_JOBKIND: +#endif + case CRYPTO_30_VHSM_KEYMANAGEMENT_JOBKIND: + retVal = Crypto_30_vHsm_SerializeRequest_KeyMJob( /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_KeyMJob */ + jobRequestId, + Crypto_30_vHsm_GetKeyMJobOfJobRequest(jobRequestId), +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + &jobRequestBuffer[8] +#else + &jobRequestBuffer[16] +#endif + ); + break; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + case CRYPTO_30_VHSM_KEYMANAGEMENT_COPY_PARTIAL_JOBKIND: + retVal = Crypto_30_vHsm_SerializeRequest_KeyMJob_CopyPartial( /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_KeyMJob_CopyPartial */ + jobRequestId, + Crypto_30_vHsm_GetKeyMJobOfJobRequest(jobRequestId), + &jobRequestBuffer[16]); + break; +# if (CRYPTO_30_VHSM_KEY_DERIVE_JOB_SUPPORT == STD_ON) + case CRYPTO_30_VHSM_KEYMANAGEMENT_KEYDERIVEJOB_JOBKIND: + retVal = Crypto_30_vHsm_SerializeRequest_CryptoJob_KeyDerive( /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_KeyMJob_KeyDerive */ + jobRequestId, + Crypto_30_vHsm_GetCryptoJobOfJobRequest(jobRequestId), + &jobRequestBuffer[16]); + break; +# endif /* (CRYPTO_30_VHSM_KEY_DERIVE_JOB_SUPPORT == STD_ON) */ +#endif /* (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) */ + default: /* COV_CRYPTO_30_VHSM_MISRA_ADDITIONAL_STATEMENT */ /* PRQA S 2016 */ /* MD_MSR_EmptyClause */ + break; + } + + return retVal; +} /* Crypto_30_vHsm_SendRequestToIpc() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_GetResponseFromIpc() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + */ + /* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_GetResponseFromIpc( + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx, + Crypto_30_vHsm_ChannelIdType rxChannelId, + uint32 writeIdx) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_PARAM_VALUE; + + Crypto_30_vHsm_JobRequestIterType jobRequestId; + uint32 jobResponseData; + Crypto_30_vHsm_JobKindType jobResponseKind; + Crypto_30_vHsm_JobResponseBufferPtrType jobResponseBuffer = (Crypto_30_vHsm_JobResponseBufferPtrType)Crypto_30_vHsm_Ipc_GetRxChannelBuffer(partitionIdx, rxChannelId); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ + + /* #20 Parse and remove job response header. */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + jobResponseData = Crypto_30_vHsm_Deserialize_Uint32(&jobResponseBuffer[4]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR_WITH_BUFFER */ + jobResponseKind = (Crypto_30_vHsm_JobKindType)Crypto_30_vHsm_Deserialize_Uint32(&jobResponseBuffer[8]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR_WITH_BUFFER */ +#else + jobResponseData = Crypto_30_vHsm_Deserialize_Uint32(&jobResponseBuffer[0]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR_WITH_BUFFER */ +#endif + jobRequestId = jobResponseData & CRYPTO_30_VHSM_JOBRESPONSE_ID_MASK; + + /* #30 Check if jobRequestKind is valid. */ + if ((jobRequestId >= Crypto_30_vHsm_GetSizeOfJobRequest())) + { + /* Remove the invalid response from the IPC */ + Crypto_30_vHsm_Ipc_GetRxChannelReadIdx(partitionIdx, rxChannelId) = writeIdx; /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ + } +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES > 1u) + /* Check if the received job belongs to the correct partition */ + else if (partitionIdx != Crypto_30_vHsm_GetCurrentPartitionIdxOfObjectInfo(jobRequestId)) + { + /* Remove the invalid response from the IPC */ + Crypto_30_vHsm_Ipc_GetRxChannelReadIdx(partitionIdx, rxChannelId) = writeIdx; /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ + } +#endif /* (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES > 1u) */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + /* Check if this is the response we expect */ + else if (((Crypto_30_vHsm_CounterOfJobRequestType)((jobResponseData & CRYPTO_30_VHSM_JOBRESPONSE_COUNTER_MASK) >> CRYPTO_30_VHSM_JOBRESPONSE_COUNTER_BITPOSITION) != Crypto_30_vHsm_GetCounterOfJobRequest(jobRequestId))) + { + /* Remove the invalid response from the IPC */ + Crypto_30_vHsm_Ipc_GetRxChannelReadIdx(partitionIdx, rxChannelId) = writeIdx; /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ + } +#else /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) */ + /* Check if the jobRequestKind inside the request is the same as in the jobRequestList */ + else if (Crypto_30_vHsm_GetKindOfJobRequest(jobRequestId) != jobResponseKind) + { + Crypto_30_vHsm_Ipc_GetRxChannelReadIdx(partitionIdx, rxChannelId) = writeIdx; /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ + } +#endif + /* check if jobrequest still waits for an answer */ + else if (Crypto_30_vHsm_GetStateOfJobRequest(jobRequestId) != CRYPTO_30_VHSM_JOBREQUEST_STATE_PROCESSING) + { +#if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) + if (Crypto_30_vHsm_GetStateOfJobRequest(jobRequestId) == CRYPTO_30_VHSM_JOBREQUEST_STATE_TIMEOUT) + { + Crypto_30_vHsm_RecoverFromTimeout(partitionIdx, jobRequestId, writeIdx, /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_RecoverFromTimeout */ +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + jobResponseData, + &jobResponseBuffer[4]); +# else + &jobResponseBuffer[12]); +# endif + errorId = CRYPTO_E_NO_ERROR; + } + else +#endif /* (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) */ + { + /* Remove the invalid response from the IPC */ + Crypto_30_vHsm_Ipc_GetRxChannelReadIdx(partitionIdx, rxChannelId) = writeIdx; /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ + } + } + else + { + jobResponseKind = Crypto_30_vHsm_GetKindOfJobRequest(jobRequestId); + /* #50 Call job response receive function for processing. */ + if ((jobResponseKind == CRYPTO_30_VHSM_KEYMANAGEMENT_JOBKIND) + || (jobResponseKind == CRYPTO_30_VHSM_KEYMANAGEMENT_COPY_PARTIAL_JOBKIND)) + { + Crypto_30_vHsm_ReceiveResponse_KeyMJob( /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_ReceiveResponse_KeyMJob */ + jobRequestId, +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + jobResponseData, + &jobResponseBuffer[4]); +#else + &jobResponseBuffer[12]); +#endif + } + else + { + Crypto_30_vHsm_ReceiveResponse_CryptoJob( /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_ReceiveResponse_CryptoJob */ + jobRequestId, +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + jobResponseData, + &jobResponseBuffer[4]); +#else + &jobResponseBuffer[12]); +#endif + } + + /* #61 Commit the reception of the job response to the IPC */ + Crypto_30_vHsm_Ipc_GetRxChannelReadIdx(partitionIdx, rxChannelId) = writeIdx; /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ + + /* #62 Indicate that the channel can now be used by other jobs */ + Crypto_30_vHsm_SetChannelState(rxChannelId, CRYPTO_30_VHSM_IPC_CHANNELSTATE_FREE, partitionIdx); /* SBSW_CRYPTO_30_VHSM_CSL01_CHANNELSTATE */ + + /* #63 State processing of job request is done and job results are available. */ + Crypto_30_vHsm_SetStateOfJobRequest(jobRequestId, CRYPTO_30_VHSM_JOBREQUEST_STATE_RESULT_AVAILABLE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + errorId = CRYPTO_E_NO_ERROR; +#endif + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + /* #100 Call Det if error occurred */ + (void)Det_ReportError(CRYPTO_30_VHSM_MODULE_ID, CRYPTO_30_VHSM_INSTANCE_ID, CRYPTO_30_VHSM_SID_COPYJOBRESPONSERXDATA, errorId); + } +#else + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + +} /* Crypto_30_vHsm_GetResponseFromIpc() */ + +#define CRYPTO_30_VHSM_STOP_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ +#define CRYPTO_30_VHSM_START_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_TransmitRequest() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_TransmitRequest( + Crypto_30_vHsm_ChannelIdType txChannelId, + Crypto_30_vHsm_JobRequestIterType jobRequestId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + uint8 errorId = CRYPTO_30_VHSM_IPC_E_NO_ERROR; + uint32 readIdx; + uint32 writeIdx; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdxOfObjectInfo(jobRequestId); + + /* Use local copy of read index to prevent concurrency issues. */ + readIdx = Crypto_30_vHsm_Ipc_GetTxChannelReadIdx(partitionIdx, txChannelId); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ + writeIdx = Crypto_30_vHsm_Ipc_GetTxChannelWriteIdx(partitionIdx, txChannelId); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ + + /* ----- Implementation ----------------------------------------------- */ + + /* #10 Return BUSY when channel is full. */ + if ((writeIdx - readIdx) > 0u) + { + /* Error: Tx Channel is full. */ + retVal = CRYPTO_E_BUSY; +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + /* Error: Cannot allocate enough space for job request in Tx channel. */ + errorId = CRYPTO_30_VHSM_IPC_E_CANNOT_ALLOCATE_JOBREQUEST_BUFFER; +#endif + } + else /* (writeIdx - readIdx) < CRYPTO_30_VHSM_IPC_CHANNEL_SIZE */ + { + /* #30 Copy job request data from driver into Tx channel for transmission to vHsm. */ + retVal = Crypto_30_vHsm_SendRequestToIpc(jobRequestId, (Crypto_30_vHsm_JobRequestBufferPtrType)Crypto_30_vHsm_Ipc_GetTxChannelBuffer(partitionIdx, txChannelId)); /* PRQA S 0310 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SendRequestToIpc */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (E_OK != retVal) + { + /* Error: Copying job request data for transmission failed. */ + errorId = CRYPTO_30_VHSM_IPC_E_CANNOT_COPY_JOBREQUEST_DATA; + } +#endif + } + + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_30_VHSM_IPC_E_NO_ERROR) + { + /* #100 Report Det if error occurred */ + (void)Det_ReportError(CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, CRYPTO_30_VHSM_IPC_SID_TRANSMITJOBREQUEST, errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_Ipc_TransmitRequest() */ + +#define CRYPTO_30_VHSM_STOP_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define CRYPTO_30_VHSM_START_SEC_RAMCODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_ReceiveResponse() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_ReceiveResponse( + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx, + Crypto_30_vHsm_ChannelIdType rxChannelId) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32 readIdx; + uint32 writeIdx; + + /* ----- Implementation ----------------------------------------------- */ + readIdx = Crypto_30_vHsm_Ipc_GetRxChannelReadIdx(partitionIdx, rxChannelId); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ + /* Use local copy of write index to prevent concurrency issues. */ + writeIdx = Crypto_30_vHsm_Ipc_GetRxChannelWriteIdx(partitionIdx, rxChannelId); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ + + /* #10 Receive job responses from Rx channel if present. */ + if (readIdx != writeIdx) + { + /* #40 Copy job response data to driver for processing. */ + /* When a job response was invalid it is marked as read and will be discared! */ + Crypto_30_vHsm_GetResponseFromIpc(partitionIdx, rxChannelId, writeIdx); + } +} /* Crypto_30_vHsm_Ipc_ReceiveResponse() */ + +#define CRYPTO_30_VHSM_STOP_SEC_RAMCODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define CRYPTO_30_VHSM_START_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_GetDet() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_GetDet( + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx, + P2VAR(uint16, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) moduleId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) instanceId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) apiId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) errorId) +{ + /* ----- Local Variables ---------------------------------------------- */ + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Get the values of the Det stored inside the Ipc */ + /* PRQA S 0310, 3305 4 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ + *moduleId = Crypto_30_vHsm_Ipc_GetDetModuleId(partitionIdx); /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_STACK */ + *instanceId = Crypto_30_vHsm_Ipc_GetDetInstanceId(partitionIdx); /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_STACK */ + *apiId = Crypto_30_vHsm_Ipc_GetDetApiId(partitionIdx); /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_STACK */ + *errorId = Crypto_30_vHsm_Ipc_GetDetErrorId(partitionIdx); /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_STACK */ + +# if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + +} /* Crypto_30_vHsm_Ipc_GetDet() */ +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + +/********************************************************************************************************************* + * Crypto_30_vHsm_Ipc_ProcessChannels() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_ProcessChannels(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ + /* ----- Implementation ----------------------------------------------- */ + Crypto_30_vHsm_ChannelStateIterType rxChannel; + + /* #10 Process the job response available in the IPC */ + for (rxChannel = 0u; rxChannel < Crypto_30_vHsm_GetSizeOfChannelState(partitionIdx); rxChannel ++) + { + if (Crypto_30_vHsm_GetChannelState(rxChannel, partitionIdx) == CRYPTO_30_VHSM_IPC_CHANNELSTATE_ASYNC) + { + Crypto_30_vHsm_Ipc_ReceiveResponse(partitionIdx, (Crypto_30_vHsm_ChannelIdType)rxChannel); + } + } +} /* Crypto_30_vHsm_Ipc_ProcessChannels() */ + +/********************************************************************************************************************* + * Crypto_30_vHsm_Ipc_ProcessCallbacks() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + /* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_ProcessCallbacks(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ + /* ----- Local Variables ---------------------------------------------- */ + Crypto_30_vHsm_JobRequestIterType jobRequestId; + Std_ReturnType jobRetVal; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Iterate over job request slots */ + for (jobRequestId = 0u; jobRequestId < Crypto_30_vHsm_GetSizeOfJobRequest(); jobRequestId++) + { +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES > 1u) + /* #11 Check if the jobRequestId mapped to the current partition */ + if (Crypto_30_vHsm_GetPartitionIdxOfObjectInfo(jobRequestId) == partitionIdx) +#endif + { + /* #21 Check if the job is an async job */ + if (Crypto_30_vHsm_GetProcessingTypeOfJobRequest(jobRequestId) == CRYPTO_PROCESSING_ASYNC) + { + /* #22 Check if the job request lock is still set */ + if (Crypto_30_vHsm_IsLockOfJobRequest(jobRequestId)) + { + /* #23 Check if the job request is finished */ + if (Crypto_30_vHsm_GetStateOfJobRequest(jobRequestId) == CRYPTO_30_VHSM_JOBREQUEST_STATE_RESULT_AVAILABLE) + { + /* #30 Get the corresponding job */ + P2VAR(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) tmpJob = Crypto_30_vHsm_GetCryptoJobOfJobRequest(jobRequestId); + + /* #40 Set the state of the job */ + tmpJob->CRYPTO_30_VHSM_JOB_STATE_MEMBER = Crypto_30_vHsm_GetJobStateOfJobRequest(jobRequestId); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO_JOB_PTR */ + + jobRetVal = (Std_ReturnType)Crypto_30_vHsm_GetResultOfJobRequest(jobRequestId); + Crypto_30_vHsm_SetStateOfJobRequest(jobRequestId, CRYPTO_30_VHSM_JOBREQUEST_STATE_IDLE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_End_Callout( /* PRQA S 0404 */ /* MD_CRYPTO_30_VHSM_0404_VOLATILE_READ */ + CRYPTO_30_VHSM_CALLOUT_ASYNC, + Crypto_30_vHsm_GetHsmObjIdOfObjectInfo(jobRequestId), + Crypto_30_vHsm_GetContextClassOfJobRequest(jobRequestId), + Crypto_30_vHsm_GetContextIdOfJobRequest(jobRequestId)); +#endif + +#if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) + if (Crypto_30_vHsm_GetTimeoutRecoveryStateOfJobRequest(jobRequestId) == CRYPTO_30_VHSM_TIMEOUT_RECOVERY_TRIGGERED) + { + /* This is the response to the cancel job of the timeout recovery. */ + if(jobRetVal == E_OK) + { + /* Cancel was successful. Recovery was successful! */ + + /* Free the job request lock */ + Crypto_30_vHsm_SetLockOfJobRequest(jobRequestId, FALSE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + /* Free the object lock */ + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_3(); + Crypto_30_vHsm_SetDriverObjectLock(jobRequestId, CRYPTO_30_VHSM_ACCEPT_ANY_JOBID); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_3(); + + /* Set recovery state to idle */ + Crypto_30_vHsm_SetTimeoutRecoveryStateOfJobRequest(jobRequestId, CRYPTO_30_VHSM_TIMEOUT_RECOVERY_IDLE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + /* Call timeout recovered callout */ + Crypto_30_vHsm_TimeoutRecovered_Callout(Crypto_30_vHsm_GetHsmObjIdOfObjectInfo(jobRequestId)); + } + else + { + /* Cancel did not work. Set state to pending to try again. */ + Crypto_30_vHsm_SetTimeoutRecoveryStateOfJobRequest(jobRequestId, CRYPTO_30_VHSM_TIMEOUT_RECOVERY_PENDING); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + } + else +#endif /* (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) */ + { + /* #50 Free the job request lock */ + Crypto_30_vHsm_SetLockOfJobRequest(jobRequestId, FALSE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + /* #60 Check if the mode was finish */ + if ((jobRetVal != E_OK) + || ((tmpJob->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode & CRYPTO_OPERATIONMODE_FINISH) == CRYPTO_OPERATIONMODE_FINISH)) + { + /* #70 Remove the lock from the driver object to accept new jobs */ + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_3(); + Crypto_30_vHsm_SetDriverObjectLock(jobRequestId, CRYPTO_30_VHSM_ACCEPT_ANY_JOBID); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_3(); + } + + /* #80 Call the CryIf callback */ + CryIf_CallbackNotification( + tmpJob, /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + jobRetVal); + } + } + } + } + } + } + +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + +} /* Crypto_30_vHsm_Ipc_ProcessCallbacks() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_MainFunctionHandler() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_MainFunctionHandler(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ +#if (CRYPTO_30_VHSM_INTERRUPT_MODE == STD_OFF) + /* #10 Process the job response available in the IPC */ + Crypto_30_vHsm_Ipc_ProcessChannels(partitionIdx); + + /* #20 Process the callbacks of async jobs */ + Crypto_30_vHsm_Ipc_ProcessCallbacks(partitionIdx); +#endif + +#if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) + Crypto_30_vHsm_HandleTimeout(partitionIdx); +#endif + + /* #30 Check Det if error occurred */ + Crypto_30_vHsm_Ipc_HandleDet(partitionIdx); /* PRQA S 2987 */ /* MD_CRYPTO_30_VHSM_2987_HANDLEDET */ +} /* Crypto_30_vHsm_MainFunctionHandler() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_InitMemoryHandler() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_InitMemoryHandler(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ + /* ----- Implementation ----------------------------------------------- */ + /* #10 Set the mode to uninitialized */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + Crypto_30_vHsm_SetPartitionInitialized((uint8)CRYPTO_30_VHSM_UNINIT, partitionIdx); /* SBSW_CRYPTO_30_VHSM_WRITE_PARTITION_DATA */ +#endif + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +} /* Crypto_30_vHsm_InitMemoryHandler() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_HandleDet() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_HandleDet(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) /* PRQA S 3206 */ /* MD_CRYPTO_30_VHSM_3206_SINGLE_PARTITION_IPC_ACCESS */ +{ + if (Crypto_30_vHsm_Ipc_GetDetReportFlag(partitionIdx) == TRUE) /* PRQA S 0310, 3305, 4340 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ + { +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + /* #10 Check if a Det error has been reported */ + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_1(); + if (Crypto_30_vHsm_Ipc_GetDetReportFlag(partitionIdx) == TRUE) /* PRQA S 0310, 3305, 4340 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* COV_CRYPTO_30_VHSM_DOUBLE_CHECK */ + { + uint16 moduleId; + uint8 instanceId, apiId, errorId; + + /* #20 Get the Det parameters */ + Crypto_30_vHsm_Ipc_GetDet(partitionIdx, &moduleId, &instanceId, &apiId, &errorId); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + + /* #30 Acknowledge the forwarding of the Det Error */ + Crypto_30_vHsm_Ipc_SetDetReportFlag(partitionIdx, FALSE); /* PRQA S 0310, 3305, 4404 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_1(); + +# if (CRYPTO_30_VHSM_DET_INSTANCE_MASK != 0) + /* #35 Modify the InstanceId of the Det to distinguish between DET from vHsm and DET from application core */ + instanceId |= CRYPTO_30_VHSM_DET_INSTANCE_MASK; +# endif + + /* #40 Call the Det */ + (void)Det_ReportError(moduleId, instanceId, apiId, errorId); + } + else + { + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_1(); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + /* #50 Acknowledge the forwarding of the Det Error */ + Crypto_30_vHsm_Ipc_SetDetReportFlag(partitionIdx, FALSE); /* PRQA S 0310, 3305, 4404 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ +#endif + +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + } +} /* Crypto_30_vHsm_Ipc_HandleDet() */ + +/********************************************************************************************************************* + * Crypto_30_vHsm_Ipc_ResponseIsrHandler() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_ResponseIsrHandler(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) /* PRQA S 3206 */ /* MD_CRYPTO_30_VHSM_3206_SINGLE_PARTITION_IPC_ACCESS */ +{ + /* ----- Implementation ----------------------------------------------- */ + + /* #10 Clear interrupt flag if not already done by OS */ + Crypto_30_vHsm_ClearInterruptOfPartition(partitionIdx); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ /* SBSW_CRYPTO_30_VHSM_REGISTER_ACCESS */ /*lint !e522 */ + +#if (CRYPTO_30_VHSM_INTERRUPT_MODE == STD_ON) + /* #20 Process the job response available in the IPC */ + Crypto_30_vHsm_Ipc_ProcessChannels(partitionIdx); + + /* #30 Process the callbacks of async jobs */ + Crypto_30_vHsm_Ipc_ProcessCallbacks(partitionIdx); +#endif +} /* Crypto_30_vHsm_Ipc_ResponseIsrHandler() */ + +#define CRYPTO_30_VHSM_STOP_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define CRYPTO_30_VHSM_START_SEC_RAMCODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_WaitForHsmRamForPartition() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_WaitForHsmRamForPartition(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ + /* #10 Get the offset of the ready flag */ + volatile uint32 readyFlagOffsetTmp = Crypto_30_vHsm_Ipc_MemoryLayout.readyFlagOffset; + +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES > 1u) + Crypto_30_vHsm_Ipc_MemoryPtrOfPartition[partitionIdx] = &Crypto_30_vHsm_GetIpcMemoryPtr(partitionIdx)[0U]; /* SBSW_CRYPTO_30_VHSM_IPC_MEMORY_PTR_ARRAY */ +#else + Crypto_30_vHsm_Ipc_MemoryPtrOfPartition[partitionIdx] = &Crypto_30_vHsm_Ipc_Memory[0U]; /* SBSW_CRYPTO_30_VHSM_IPC_MEMORY_PTR_ARRAY */ +#endif + +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_Start_Callout( + CRYPTO_30_VHSM_CALLOUT_HSMREADY, + 0u, + CRYPTO_30_VHSM_CALLOUT_NOT_DEFINED, + 0u); +#endif +#if (CRYPTO_30_VHSM_IS_VTT==STD_OFF) /* COV_CRYPTO_30_VHSM_VTT */ + /* #20 Wait until the ready flag has been set by the vHsm */ + while (Crypto_30_vHsm_CheckForHsmReady()) /* PRQA S 0303, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* FETA_CRYPTO_30_VHSM_WAIT_FOR_HSM_WITH_CALLOUT */ + { +# if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_Loop_Callout( + CRYPTO_30_VHSM_CALLOUT_HSMREADY, + 0u, + CRYPTO_30_VHSM_CALLOUT_NOT_DEFINED, + 0u); +# endif + } +#endif /* (CRYPTO_30_VHSM_IS_VTT==STD_OFF) */ + +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_End_Callout( + CRYPTO_30_VHSM_CALLOUT_HSMREADY, + 0u, + CRYPTO_30_VHSM_CALLOUT_NOT_DEFINED, + 0u); +#endif + +#if (CRYPTO_30_VHSM_IPC_INITIALIZATION == STD_ON) + /* Check if Ipc has already been initialized before */ +# if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES > 1u) + if ((*(volatile uint32*)CRYPTO_30_VHSM_HOST2_HSM_ADDRESS & ((uint32)1u << (uint32)Crypto_30_vHsm_GetIpcInstanceId(partitionIdx))) != ((uint32)1u << (uint32)Crypto_30_vHsm_GetIpcInstanceId(partitionIdx))) /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ +# else + if (Crypto_30_vHsm_IsIpcNotInitialized()) /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ +# endif + { + /* Initialize IPC */ + VStdLib_MemClr(Crypto_30_vHsm_Ipc_MemoryPtrOfPartition[partitionIdx], (uint32)CRYPTO_30_VHSM_IPC_MEMORY_SIZE); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_VHSM_INIT_IPC_MEMORY */ + + /* Indicate that IPC has been initialized. HSM will now be able to use the IPC. */ + Crypto_30_vHsm_IndicateInitializedIpcOfPartition(partitionIdx); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ /* SBSW_CRYPTO_30_VHSM_REGISTER_ACCESS */ + Crypto_30_vHsm_TriggerInterruptOfPartition(partitionIdx); /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_TRIGGER_INTERRUPT */ /* SBSW_CRYPTO_30_VHSM_TRIGGER_INTERRUPT */ /*lint !e522 */ + } +#endif /* (CRYPTO_30_VHSM_IPC_INITIALIZATION == STD_ON) */ +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_Start_Callout( + CRYPTO_30_VHSM_CALLOUT_IPCINIT, + 0u, + CRYPTO_30_VHSM_CALLOUT_NOT_DEFINED, + 0u); +#endif + while ((Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, readyFlagOffsetTmp)) != 0xDEADBEEFu) /* PRQA S 0310, 3305, 0404 */ /* MD_CRYPTO_30_VHSM_0404_VOLATILE_READ */ /* FETA_CRYPTO_30_VHSM_WAIT_FOR_HSM_WITH_CALLOUT */ + { +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_Loop_Callout( + CRYPTO_30_VHSM_CALLOUT_IPCINIT, + 0u, + CRYPTO_30_VHSM_CALLOUT_NOT_DEFINED, + 0u); +#endif + } +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_End_Callout( + CRYPTO_30_VHSM_CALLOUT_IPCINIT, + 0u, + CRYPTO_30_VHSM_CALLOUT_NOT_DEFINED, + 0u); +#endif +} /* Crypto_30_vHsm_Ipc_WaitForHsmRamForPartition() */ + +#define CRYPTO_30_VHSM_STOP_SEC_RAMCODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_vHsm_Ipc.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc.h b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc.h new file mode 100644 index 0000000..dc1bbcd --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc.h @@ -0,0 +1,377 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file Crypto_30_vHsm_Ipc.h + * \brief MICROSAR vHsm Crypto Driver (Crypto) + * + * \details Inter-processor communication between Host and Vector Hardware Security Module Firmware. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_VHSM_IPC_H) +# define CRYPTO_30_VHSM_IPC_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_vHsm_Cfg.h" +# include "Crypto_30_vHsm_Types.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* API services IDs */ +# define CRYPTO_30_VHSM_IPC_SID_TRANSMITJOBREQUEST (0x80u) +# define CRYPTO_30_VHSM_IPC_SID_RECEIVEJOBRESPONSES (0x81u) + +/* Development error types */ +# define CRYPTO_30_VHSM_IPC_E_NO_ERROR (0xFFu) +# define CRYPTO_30_VHSM_IPC_E_PARAM_POINTER (0x81u) +# define CRYPTO_30_VHSM_IPC_E_INVALID_CHANNEL (0x82u) +# define CRYPTO_30_VHSM_IPC_E_CANNOT_ALLOCATE_JOBREQUEST_BUFFER (0x83u) +# define CRYPTO_30_VHSM_IPC_E_CANNOT_COPY_JOBREQUEST_DATA (0x84u) + +# define CRYPTO_30_VHSM_MANAGEMENT_JOBREQUEST_ID Crypto_30_vHsm_GetManagementDriverObjectOfvHsm() +# define CRYPTO_30_VHSM_ACCEPT_ANY_JOBID (0xFFFFFFFFu) + +# define CRYPTO_30_VHSM_JOBREQUEST_ID_BITPOSITION (0u) +# define CRYPTO_30_VHSM_JOBREQUEST_OBJECTID_BITPOSITION (8u) +# define CRYPTO_30_VHSM_JOBREQUEST_REDIRECTION_BITPOSITION (16u) +# define CRYPTO_30_VHSM_JOBREQUEST_COUNTER_BITPOSITION (24u) + +# define CRYPTO_30_VHSM_JOBRESPONSE_ID_BITPOSITION (0u) +# define CRYPTO_30_VHSM_JOBRESPONSE_STATE_BITPOSITION (8u) +# define CRYPTO_30_VHSM_JOBRESPONSE_RESULT_BITPOSITION (16u) +# define CRYPTO_30_VHSM_JOBRESPONSE_COUNTER_BITPOSITION (24u) + +# define CRYPTO_30_VHSM_JOBRESPONSE_ID_MASK (0x000000FFu) +# define CRYPTO_30_VHSM_JOBRESPONSE_COUNTER_MASK (0xFF000000u) + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + +/* IPC */ +/* PRQA S 3453 IpcMacros3543 */ /* MD_CRYPTO_30_VHSM_3453_IPC_MACRO */ +# define Crypto_30_vHsm_Ipc_IsHsmReady(partitionIdx) (Crypto_30_vHsm_Ipc_GetReadyFlag(partitionIdx) == 0xdeadbeefu) +# define Crypto_30_vHsm_Ipc_EndRamExec(partitionIdx) Crypto_30_vHsm_Ipc_SetEndRamExecFlag(partitionIdx, TRUE) +# define Crypto_30_vHsm_Ipc_IsRamExec(partitionIdx) Crypto_30_vHsm_Ipc_GetRamExecFlag(partitionIdx) +# define Crypto_30_vHsm_Ipc_IsDetReported(partitionIdx) Crypto_30_vHsm_Ipc_GetDetReportFlag(partitionIdx) + +# if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES<2) +# define Crypto_30_vHsm_GetPartitionIdxOptimized(partitionIdx) 0u +# else +# define Crypto_30_vHsm_GetPartitionIdxOptimized(partitionIdx) (partitionIdx) +# endif + +# define Crypto_30_vHsm_Ipc_GetMemoryPtr8(partitionIdx, offset) (&(((P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR))Crypto_30_vHsm_Ipc_MemoryPtrOfPartition[Crypto_30_vHsm_GetPartitionIdxOptimized(partitionIdx)])[offset])) +# define Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, offset) (*(volatile uint32*)&(((P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR))Crypto_30_vHsm_Ipc_MemoryPtrOfPartition[Crypto_30_vHsm_GetPartitionIdxOptimized(partitionIdx)])[offset])) + +# define Crypto_30_vHsm_Ipc_GetTxChannelBuffer(partitionIdx, txChannelId) (Crypto_30_vHsm_Ipc_GetMemoryPtr8(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.txChannelMemoryLayout[txChannelId].bufferOffset)) + +# define Crypto_30_vHsm_Ipc_GetTxChannelWriteIdx(partitionIdx, txChannelId) (Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.txChannelMemoryLayout[txChannelId].writeIdxOffset)) + +# define Crypto_30_vHsm_Ipc_GetTxChannelReadIdx(partitionIdx, txChannelId) (Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.txChannelMemoryLayout[txChannelId].readIdxOffset)) + +# define Crypto_30_vHsm_Ipc_GetRxChannelBuffer(partitionIdx, rxChannelId) (Crypto_30_vHsm_Ipc_GetMemoryPtr8(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.rxChannelMemoryLayout[rxChannelId].bufferOffset)) + +# define Crypto_30_vHsm_Ipc_GetRxChannelWriteIdx(partitionIdx, rxChannelId) (Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.rxChannelMemoryLayout[rxChannelId].writeIdxOffset)) + +# define Crypto_30_vHsm_Ipc_GetRxChannelReadIdx(partitionIdx, rxChannelId) (Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.rxChannelMemoryLayout[rxChannelId].readIdxOffset)) + +# define Crypto_30_vHsm_Ipc_GetRamExecFlag(partitionIdx) ((boolean)Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.ramExecFlagOffset)) +# define Crypto_30_vHsm_Ipc_SetEndRamExecFlag(partitionIdx, value) (Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.endRamExecFlagOffset) = (value)) + +# define Crypto_30_vHsm_Ipc_GetReadyFlag(partitionIdx) (Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.readyFlagOffset)) + +# define Crypto_30_vHsm_Ipc_GetDetReportFlag(partitionIdx) ((boolean)Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.detReportFlagOffset)) +# define Crypto_30_vHsm_Ipc_SetDetReportFlag(partitionIdx, value) (Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.detReportFlagOffset) = (value)) +# define Crypto_30_vHsm_Ipc_GetDetModuleId(partitionIdx) ((uint16)Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.detModuleIdOffset)) +# define Crypto_30_vHsm_Ipc_GetDetInstanceId(partitionIdx) ((uint8)Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.detInstanceIdOffset)) +# define Crypto_30_vHsm_Ipc_GetDetApiId(partitionIdx) ((uint8)Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.detApiIdOffset)) +# define Crypto_30_vHsm_Ipc_GetDetErrorId(partitionIdx) ((uint8)Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.detErrorIdOffset)) + +# define Crypto_30_vHsm_Ipc_vHsmProtocolVersion(partitionIdx) (Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.protocolInfoOffset)) +# define Crypto_30_vHsm_Ipc_DriverProtocolVersion(partitionIdx) (Crypto_30_vHsm_Ipc_GetMemoryValue32(partitionIdx, Crypto_30_vHsm_Ipc_MemoryLayout.protocolInfoOffset+4u)) + +/* PRQA L:IpcMacros3543 */ + +# define CRYPTO_30_VHSM_IPC_CHANNELSTATE_FREE (0x00u) +# define CRYPTO_30_VHSM_IPC_CHANNELSTATE_ASYNC (CRYPTO_PROCESSING_ASYNC + 1u) +# define CRYPTO_30_VHSM_IPC_CHANNELSTATE_SYNC (CRYPTO_PROCESSING_SYNC + 1u) + +/*! Serialize a uint32 to the IPC buffer with the offset and increment the offset by 4 afterwards */ +# define Crypto_30_vHsm_Serialize_Uint32(value, bufferPtr) (*(P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR))(bufferPtr)) = (uint32)(value) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ + +/*! Serialize a pointer to the IPC buffer with the offset and increment the offset by 4 afterwards */ +# define Crypto_30_vHsm_Serialize_Ptr32(value, bufferPtr) (*(P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR))(bufferPtr)) = (uint32)(value) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ + +/*! Deserialize a uint32 to the IPC buffer with the offset and increment the offset by 4 afterwards */ +# define Crypto_30_vHsm_Deserialize_Uint32(bufferPtr) (*(P2CONST(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA))(bufferPtr)) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +typedef struct Crypto_30_vHsm_Ipc_Channel_MemoryLayoutTypeStruct +{ + uint32 writeIdxOffset; /*!< Shared memory offset to buffer reserved for write index (value equals index of next free entry) of channel. */ + uint32 readIdxOffset; /*!< Shared memory offset to buffer reserved for read index (value equals index of next pending entry) of channel. */ + uint32 bufferOffset; /*!< Shared memory offset to buffer reserved for all channel entries. */ +} Crypto_30_vHsm_Ipc_Channel_MemoryLayoutType; + +typedef struct Crypto_30_vHsm_Ipc_MemoryLayoutTypeStruct +{ + uint32 protocolInfoOffset; /*!< Shared memory offsets to buffers reserved for vHSM protocol info. */ + Crypto_30_vHsm_Ipc_Channel_MemoryLayoutType txChannelMemoryLayout[CRYPTO_30_VHSM_IPC_CHANNELS]; /*!< Describes the memory layout of all TX channels. */ + Crypto_30_vHsm_Ipc_Channel_MemoryLayoutType rxChannelMemoryLayout[CRYPTO_30_VHSM_IPC_CHANNELS]; /*!< Describes the memory layout of all RX channels. */ + uint32 stackProtectionCanaryPE1Offset; /*!< Shared memory offsets to buffers reserved for vHSM stack protection canary Appl Core 1. */ + uint32 stackProtectionCanaryPE2Offset; /*!< Shared memory offsets to buffers reserved for vHSM stack protection canary Appl Core 2. */ + uint32 seedOffset; /*!< Shared memory offset to buffer reserved for vHSM random seed. */ + uint32 detModuleIdOffset; /*!< Shared memory offsets to buffers reserved for vHSM development error detection (DET module). */ + uint32 detInstanceIdOffset; /*!< Shared memory offsets to buffers reserved for vHSM development error detection (DET instance id). */ + uint32 detApiIdOffset; /*!< Shared memory offsets to buffers reserved for vHSM development error detection (DET api id). */ + uint32 detErrorIdOffset; /*!< Shared memory offsets to buffers reserved for vHSM development error detection (DET error id). */ + uint32 readyFlagOffset; /*!< Shared memory offset to buffer reserved for vHSM Ready flag. */ + uint32 endRamExecFlagOffset; /*!< Shared memory offset to buffer reserved for vHSM End-RAM-Execution flag. */ + uint32 ramExecFlagOffset; /*!< Shared memory offset to buffer reserved for vHSM Is-RAM-Execution flag. */ + uint32 detReportFlagOffset; /*!< Shared memory offset to buffer reserved for vHSM Det-Report flag. */ + +} Crypto_30_vHsm_Ipc_MemoryLayoutType; + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_VHSM_START_SEC_IPC_MEMORY_VAR_NOINIT_32BIT +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define CRYPTO_30_VHSM_STOP_SEC_IPC_MEMORY_VAR_NOINIT_32BIT +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define CRYPTO_30_VHSM_START_SEC_VAR_NOINIT_32BIT +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*! Pointer to the IPC memory */ +extern P2VAR(uint32, CRYPTO_30_VHSM_VAR_NOINIT, CRYPTO_30_VHSM_VAR_NOINIT) Crypto_30_vHsm_Ipc_MemoryPtrOfPartition[CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES]; + +# define CRYPTO_30_VHSM_STOP_SEC_VAR_NOINIT_32BIT +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define CRYPTO_30_VHSM_START_SEC_CONST_UNSPECIFIED +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*! Layout of the IPC memory */ +extern CONST(Crypto_30_vHsm_Ipc_MemoryLayoutType, CRYPTO_30_VHSM_CONST) Crypto_30_vHsm_Ipc_MemoryLayout; + +# define CRYPTO_30_VHSM_STOP_SEC_CONST_UNSPECIFIED +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_VHSM_START_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_TransmitRequest() + *********************************************************************************************************************/ +/*! + * \brief Transmit job request + * \details - + * \param[in] txChannelId Valid TX channel Id + * \param[in] jobRequestId Valid job request Id + * \return TRUE if the job request was correctly transmitted, otherwise E_NOT_OK + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_TransmitRequest( + Crypto_30_vHsm_ChannelIdType txChannelId, + Crypto_30_vHsm_JobRequestIterType jobRequestId); + +# define CRYPTO_30_VHSM_STOP_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define CRYPTO_30_VHSM_START_SEC_RAMCODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_ReceiveResponse() + *********************************************************************************************************************/ +/*! + * \brief Receive job responses + * \details - + * \param[in] partitionIdx Valid partition index + * \param[in] rxChannelId Valid RX channel Id + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_ReceiveResponse( + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx, + Crypto_30_vHsm_ChannelIdType rxChannelId); + +# define CRYPTO_30_VHSM_STOP_SEC_RAMCODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define CRYPTO_30_VHSM_START_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_GetDet() + *********************************************************************************************************************/ +/*! + * \brief Get DET error + * \details - + * \param[in] partitionIdx Valid partitionIdx + * \param[out] moduleId Valid pointer to hold module ID + * \param[out] instanceId Valid pointer to hold instance ID + * \param[out] apiId Valid pointer to hold API ID + * \param[out] errorId Valid pointer to hold error ID + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_GetDet( + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx, + P2VAR(uint16, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) moduleId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) instanceId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) apiId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) errorId); +# endif /* (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_ProcessChannels() + *********************************************************************************************************************/ +/*! + * \brief Process IPC channels + * \details - + * \param[in] partitionIdx Valid partition index + * \pre - + * \context TASK, ISR2 + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_ProcessChannels(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_ProcessCallbacks() + *********************************************************************************************************************/ +/*! + * \brief Process IPC callbacks + * \details - + * \param[in] partitionIdx Valid partitionIdx + * \pre - + * \context TASK, ISR2 + * \reentrant FALSE + * \synchronous TRUE + * \trace CREQ-Crypto-AsyncCallout + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_ProcessCallbacks(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_HandleDet() + *********************************************************************************************************************/ +/*! + * \brief Checks if vHSM invokes a DET error and forwards it to Det module + * \details Gets parameters from IPC, acknowledges the handling and calls Det_ReportError + * \param[in] partitionIdx Valid partitionIdx + * \pre - + * \context TASK, ISR2 + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_HandleDet(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_vHsm_MainFunctionHandler() + *********************************************************************************************************************/ +/*! + * \brief Main function handling the IPC + * \details - + * \param[in] partitionIdx Valid partitionIdx + * \pre - + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_MainFunctionHandler(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_vHsm_InitMemoryHandler() + *********************************************************************************************************************/ +/*! \brief The function initializes partition specific variables, which cannot be initialized with the startup code. + * \details Initialize component variables at power up. + * \param[in] partitionIdx Valid identifier of the partition. + * \pre Module is uninitialized. + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_InitMemoryHandler(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_ResponseIsrHandler() + *********************************************************************************************************************/ +/*! + * \brief Response isr handler called by the ISR + * \details - + * \param[in] partitionIdx Valid partitionIdx + * \pre - + * \context ISR2 + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_ResponseIsrHandler(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +# define CRYPTO_30_VHSM_STOP_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define CRYPTO_30_VHSM_START_SEC_RAMCODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/********************************************************************************************************************** + * Crypto_30_vHsm_Ipc_WaitForHsmRamForPartition() + *********************************************************************************************************************/ +/*! + * \brief Waits in the RAM for the vHsm Ready flag. + * \details This is only needed because the vHsm has no control over the application core startup when a debugger is attached. + * When a debugger is attached, all cores will startup immediately. + * \param[in] partitionIdx Valid Partition Index + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-WaitLoopCallout + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_Ipc_WaitForHsmRamForPartition(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +# define CRYPTO_30_VHSM_STOP_SEC_RAMCODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CRYPTO_30_VHSM_IPC_H) */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_vHsm_Ipc.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc_Types.h b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc_Types.h new file mode 100644 index 0000000..697615c --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Ipc_Types.h @@ -0,0 +1,66 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_vHsm_Ipc_Types.h + * \brief Vector Hardware Security Module Firmware Ipc Types + * + * \details Declares data structures required for interaction with Vector Hardware Security Module Firmware. + * + *********************************************************************************************************************/ + + /********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_VHSM_IPC_TYPES_H) +# define CRYPTO_30_VHSM_IPC_TYPES_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_vHsm_Ipc.h" + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ +# define Crypto_30_vHsm_Ipc_GetTxChannelMemoryOffset(txChannelId) CRYPTO_30_VHSM_IPC_PROTOCOL_INFO_SIZE + CRYPTO_30_VHSM_IPC_GLOBALINFO_MEMORY_SIZE + \ + ((txChannelId) * (CRYPTO_30_VHSM_IPC_TX_CHANNEL_MEMORY_SIZE)) /* PRQA S 3453 */ /* MD_CRYPTO_30_VHSM_3453_IPC_MACRO */ + +# define Crypto_30_vHsm_Ipc_GetRxChannelMemoryOffset(rxChannelId) (Crypto_30_vHsm_Ipc_GetTxChannelMemoryOffset(CRYPTO_30_VHSM_IPC_CHANNELS) + \ + ((rxChannelId) * (CRYPTO_30_VHSM_IPC_RX_CHANNEL_MEMORY_SIZE))) /* PRQA S 3453 */ /* MD_CRYPTO_30_VHSM_3453_IPC_MACRO */ + +# define Crypto_30_vHsm_Ipc_GetTxChannelWriteIndexOffset(txChannelId) Crypto_30_vHsm_Ipc_GetTxChannelMemoryOffset(txChannelId) /* PRQA S 3453 */ /* MD_CRYPTO_30_VHSM_3453_IPC_MACRO */ + +# define Crypto_30_vHsm_Ipc_GetRxChannelWriteIndexOffset(rxChannelId) Crypto_30_vHsm_Ipc_GetRxChannelMemoryOffset(rxChannelId) /* PRQA S 3453 */ /* MD_CRYPTO_30_VHSM_3453_IPC_MACRO */ + +# define Crypto_30_vHsm_Ipc_GetTxChannelReadIndexOffset(txChannelId) (Crypto_30_vHsm_Ipc_GetTxChannelMemoryOffset(txChannelId) + CRYPTO_30_VHSM_IPC_CHANNEL_WRITE_INDEX_MEMORY_SIZE) /* PRQA S 3453 */ /* MD_CRYPTO_30_VHSM_3453_IPC_MACRO */ + +# define Crypto_30_vHsm_Ipc_GetRxChannelReadIndexOffset(rxChannelId) (Crypto_30_vHsm_Ipc_GetRxChannelMemoryOffset(rxChannelId) + CRYPTO_30_VHSM_IPC_CHANNEL_WRITE_INDEX_MEMORY_SIZE) /* PRQA S 3453 */ /* MD_CRYPTO_30_VHSM_3453_IPC_MACRO */ + +# define Crypto_30_vHsm_Ipc_GetTxChannelBufferOffset(txChannelId) (Crypto_30_vHsm_Ipc_GetTxChannelMemoryOffset(txChannelId) + CRYPTO_30_VHSM_IPC_CHANNEL_HEADER_MEMORY_SIZE) /* PRQA S 3453 */ /* MD_CRYPTO_30_VHSM_3453_IPC_MACRO */ + +# define Crypto_30_vHsm_Ipc_GetRxChannelBufferOffset(rxChannelId) (Crypto_30_vHsm_Ipc_GetRxChannelMemoryOffset(rxChannelId) + CRYPTO_30_VHSM_IPC_CHANNEL_HEADER_MEMORY_SIZE) /* PRQA S 3453 */ /* MD_CRYPTO_30_VHSM_3453_IPC_MACRO */ + +# define Crypto_30_vHsm_Ipc_GetGlobalInfoOffset() CRYPTO_30_VHSM_IPC_PROTOCOL_INFO_SIZE + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +#endif /* !defined (CRYPTO_30_VHSM_IPC_TYPES_H) */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_vHsm_Ipc_Types.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Jobs.c b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Jobs.c new file mode 100644 index 0000000..0184829 --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Jobs.c @@ -0,0 +1,2204 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_vHsm_Jobs.c + * \brief Vector Hardware Security Module Firmware Jobs + * + * \details Implementation of the Vector Hardware Security Module Firmware Jobs + * + *********************************************************************************************************************/ + + /********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_JOBS_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Crypto_30_vHsm_Jobs.h" +#include "Crypto_30_vHsm_Ipc.h" + +#include "vstdlib.h" +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) +# include "Det.h" +#endif + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) +# define CRYPTO_30_VHSM_CRYPTO_JOBRESULTTYPE_DESERIALIZED_BUF_SIZE (8u) +# define CRYPTO_30_VHSM_KEYM_JOBRESULTTYPE_DESERIALIZED_BUF_SIZE (4u) +#else +# define CRYPTO_30_VHSM_CRYPTO_JOBRESULTTYPE_DESERIALIZED_BUF_SIZE (12u) +# define CRYPTO_30_VHSM_KEYM_JOBRESULTTYPE_DESERIALIZED_BUF_SIZE (4u) +#endif + +#define CRYPTO_30_VHSM_OUTPUT_BUFFER_NOT_USED (0xFFFFFFFFuL) + +#define CRYPTO_30_VHSM_IO_NONE (0u) +#define CRYPTO_30_VHSM_IO_INPUT (1u) +#define CRYPTO_30_VHSM_IO_SECONDARYINPUT (2u) +#define CRYPTO_30_VHSM_IO_TERTIARYINPUT (4u) +#define CRYPTO_30_VHSM_IO_OUTPUT (8u) +#define CRYPTO_30_VHSM_IO_SECONDARYOUTPUT (16u) +#define CRYPTO_30_VHSM_IO_VERIFYRESULT (32u) +#define CRYPTO_30_VHSM_IO_SECONDARYKEY (64u) +#define CRYPTO_30_VHSM_IO_COPYPARTIAL (128u) + +#define CRYPTO_30_VHSM_INVALID_SERVICES (0x15u) /* CRYPTO_KEYSETINVALID + 1u */ + +#define CRYPTO_30_VHSM_PTRMSK_INPUTS (24u) +#define CRYPTO_30_VHSM_PTRMSK_OUTPUTS (16u) +#define CRYPTO_30_VHSM_PTRMSK_KEYS ( 8u) + +/********************************************************************************************************************** + * LOCAL FUNCTION MACROS + *********************************************************************************************************************/ +#if !defined (CRYPTO_30_VHSM_LOCAL) /* COV_CRYPTO_30_VHSM_LOCAL_DEFINE */ +# define CRYPTO_30_VHSM_LOCAL static +#endif + +#if !defined (CRYPTO_30_VHSM_LOCAL_INLINE) /* COV_CRYPTO_30_VHSM_LOCAL_DEFINE */ +# define CRYPTO_30_VHSM_LOCAL_INLINE LOCAL_INLINE +#endif + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_START_SEC_CONST_UNSPECIFIED +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +CRYPTO_30_VHSM_LOCAL CONST(uint8, CRYPTO_30_VHSM_CONST) Crypto_30_vHsm_JobIOAvailable[CRYPTO_30_VHSM_INVALID_SERVICES] = +{ + /* CRYPTO_HASH */ CRYPTO_30_VHSM_IO_INPUT | CRYPTO_30_VHSM_IO_OUTPUT, + /* CRYPTO_MACGENERATE */ CRYPTO_30_VHSM_IO_INPUT | CRYPTO_30_VHSM_IO_OUTPUT, + /* CRYPTO_MACVERIFY */ CRYPTO_30_VHSM_IO_INPUT | CRYPTO_30_VHSM_IO_SECONDARYINPUT | CRYPTO_30_VHSM_IO_VERIFYRESULT, + /* CRYPTO_ENCRYPT */ CRYPTO_30_VHSM_IO_INPUT | CRYPTO_30_VHSM_IO_OUTPUT, + /* CRYPTO_DECRYPT */ CRYPTO_30_VHSM_IO_INPUT | CRYPTO_30_VHSM_IO_OUTPUT, + /* CRYPTO_AEADENCRYPT */ CRYPTO_30_VHSM_IO_INPUT | CRYPTO_30_VHSM_IO_SECONDARYINPUT | CRYPTO_30_VHSM_IO_OUTPUT | CRYPTO_30_VHSM_IO_SECONDARYOUTPUT, + /* CRYPTO_AEADDECRYPT */ CRYPTO_30_VHSM_IO_INPUT | CRYPTO_30_VHSM_IO_SECONDARYINPUT | CRYPTO_30_VHSM_IO_TERTIARYINPUT | CRYPTO_30_VHSM_IO_OUTPUT | CRYPTO_30_VHSM_IO_VERIFYRESULT, + /* CRYPTO_SIGNATUREGENERATE */ CRYPTO_30_VHSM_IO_INPUT | CRYPTO_30_VHSM_IO_OUTPUT, + /* CRYPTO_SIGNATUREVERIFY */ CRYPTO_30_VHSM_IO_INPUT | CRYPTO_30_VHSM_IO_SECONDARYINPUT | CRYPTO_30_VHSM_IO_VERIFYRESULT, + /* CRYPTO_SECCOUNTERINCREMENT */ CRYPTO_30_VHSM_IO_NONE, + /* CRYPTO_SECCOUNTERREAD */ CRYPTO_30_VHSM_IO_NONE, + /* CRYPTO_RANDOMGENERATE */ CRYPTO_30_VHSM_IO_OUTPUT, + /* CRYPTO_RANDOMSEED */ CRYPTO_30_VHSM_IO_INPUT, + /* CRYPTO_KEYGENERATE */ CRYPTO_30_VHSM_IO_NONE, + /* CRYPTO_KEYDERIVE */ CRYPTO_30_VHSM_IO_NONE | CRYPTO_30_VHSM_IO_SECONDARYKEY, + /* CRYPTO_KEYEXCHANGECALCPUBVAL */ CRYPTO_30_VHSM_IO_OUTPUT, + /* CRYPTO_KEYEXCHANGECALCSECRET */ CRYPTO_30_VHSM_IO_INPUT, + /* CRYPTO_CERTIFICATEPARSE */ CRYPTO_30_VHSM_IO_NONE, /* Not supported by stack */ + /* CRYPTO_CERTIFICATEVERIFY */ CRYPTO_30_VHSM_IO_NONE, /* Not supported by stack */ + /* CRYPTO_KEYSETVALID */ CRYPTO_30_VHSM_IO_NONE, + /* CRYPTO_KEYSETINVALID */ CRYPTO_30_VHSM_IO_NONE +}; + +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) +CRYPTO_30_VHSM_LOCAL CONST(uint8, CRYPTO_30_VHSM_CONST) Crypto_30_vHsm_KeyMIOAvailable[CRYPTO_30_VHSM_NR_OF_KEYM_ACTION] = +{ + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTSET */ CRYPTO_30_VHSM_IO_INPUT, + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTGET */ CRYPTO_30_VHSM_IO_OUTPUT, + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTCOPY */ CRYPTO_30_VHSM_IO_NONE | CRYPTO_30_VHSM_IO_SECONDARYKEY , + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYCOPY */ CRYPTO_30_VHSM_IO_NONE | CRYPTO_30_VHSM_IO_SECONDARYKEY, + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYDERIVE */ CRYPTO_30_VHSM_IO_NONE | CRYPTO_30_VHSM_IO_SECONDARYKEY, + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYGENERATE */ CRYPTO_30_VHSM_IO_NONE, + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYVALIDSET */ CRYPTO_30_VHSM_IO_NONE, + /* CRYPTO_30_VHSM_KEYM_ACTION_RANDOMSEED */ CRYPTO_30_VHSM_IO_INPUT, + /* CRYPTO_30_VHSM_KEYM_ACTION_CERTIFICATEPARSE */ CRYPTO_30_VHSM_IO_NONE, + /* CRYPTO_30_VHSM_KEYM_ACTION_CERTIFICATEVERIFY */ CRYPTO_30_VHSM_IO_OUTPUT, + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYEXCHANGECALCPUBVAL */ CRYPTO_30_VHSM_IO_OUTPUT, + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYEXCHANGECALCSECRET */ CRYPTO_30_VHSM_IO_INPUT, + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTIDSGET */ CRYPTO_30_VHSM_IO_OUTPUT, + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTCOPYPARTIAL */ CRYPTO_30_VHSM_IO_NONE | CRYPTO_30_VHSM_IO_SECONDARYKEY | CRYPTO_30_VHSM_IO_COPYPARTIAL, + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYSETINVALID */ CRYPTO_30_VHSM_IO_NONE, + /* CRYPTO_30_VHSM_KEYM_ACTION_KEYGETSTATUS */ CRYPTO_30_VHSM_IO_OUTPUT +}; +#endif /* (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) */ + +#define CRYPTO_30_VHSM_STOP_SEC_CONST_UNSPECIFIED +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_START_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_IsMemoryValid() + *********************************************************************************************************************/ +/*! + * \brief Check if a pointer points to valid memory. + * \details - + * \param[in] ptr Pointer to memory + * \param[in] length Length of memory region in byte + * \param[in] isInput ptr is input or output + * \return TRUE if memory is valid, otherwise FALSE. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL FUNC(boolean, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_IsMemoryValid( + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) ptr, + uint32 length, + boolean isInput); + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeOutputPtr() + *********************************************************************************************************************/ +/*! + * \brief Serialize an output to the Ipc buffer + * \details - + * \param[in] jobRequestId Valid JobRequestId + * \param[in] outputPtr Output pointer which shall be serialized + * \param[in] outputLengthPtr Size of the data which shall be serialized + * \param[in,out] dataBufferLengthPtr Valid size of the dataBufferPtr + * \param[in,out] ptrBuf Valid pointer to the memory where the pointer shall be serialized. + * Must at least provide 8 byte of storage after the offset. + * \param[out] outputOffset Offset of the output inside the shared buffer + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeOutputPtr( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) outputPtr, + P2CONST(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) outputLengthPtr, +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) dataBufferLengthPtr, +#endif + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf, + P2VAR(volatile uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) outputOffset); + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeInputPtr() + *********************************************************************************************************************/ +/*! + * \brief Serialize an input to the Ipc buffer + * \details If possible and needed, the input data located at an invalid memory area (e.g. local application + * core RAM) will be automatically copied to a valid buffer. + * \param[in] jobRequestId Valid JobRequestId + * \param[in] inputPtr Input pointer which shall be serialized + * \param[in] inputLength Size of the data which shall be serialized + * \param[in,out] ptrBuf Valid pointer to the memory where the pointer shall be serialized. + * Must at least provide 8 byte of storage after the offset. + * \param[in] interpretLengthInBits If TRUE the input size shall be interpreted as bits, otherwise as bytes. + * \return E_OK if the input has been correctly serialized, otherwise E_NOT_OK. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeInputPtr( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) inputPtr, + uint32 inputLength, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf, + boolean interpretLengthInBits); + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeInput() + *********************************************************************************************************************/ +/*! + * \brief Serialize the input or a redirection to the Ipc buffer + * \details The function decides if the input shall be serialized or a redirection is made. + * \param[in] jobRequestId Valid JobRequestId + * \param[in] cryptoJobPtr Valid pointer to the job which shall be serialized + * \param[in,out] ptrBuf Valid pointer to the memory where the pointer shall be serialized. + * Must at least provide 8 byte of storage after the offset. + * \param[in,out] jobRedirectionInfoPtr Valid pointer to the redirection info. + * The availability of this parameter depends on the configuration. + * \return E_OK if the input has been correctly serialized, otherwise E_NOT_OK. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeInput( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr +#endif +); + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeSecondaryInput() + *********************************************************************************************************************/ +/*! + * \brief Serialize the secondary input or a redirection to the Ipc buffer + * \details The function decides if the input shall be serialized or a redirection is made. + * \param[in] jobRequestId Valid JobRequestId + * \param[in] cryptoJobPtr Valid pointer to the job which shall be serialized + * \param[in,out] ptrBuf Valid pointer to the memory where the pointer shall be serialized. + * Must at least provide 8 byte of storage after the offset. + * \param[in,out] jobRedirectionInfoPtr Valid pointer to the redirection info. + * The availability of this parameter depends on the configuration. + * \return E_OK if the input has been correctly serialized, otherwise E_NOT_OK. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeSecondaryInput( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr +#endif +); + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeTertiaryInput() + *********************************************************************************************************************/ +/*! + * \brief Serialize the tertiary input or a redirection to the Ipc buffer + * \details The function decides if the input shall be serialized or a redirection is made. + * \param[in] jobRequestId Valid JobRequestId + * \param[in] cryptoJobPtr Valid pointer to the job which shall be serialized + * \param[in,out] ptrBuf Valid pointer to the memory where the pointer shall be serialized. + * Must at least provide 8 byte of storage after the offset. + * \param[in,out] jobRedirectionInfoPtr Valid pointer to the redirection info. + * The availability of this parameter depends on the configuration. + * \return E_OK if the input has been correctly serialized, otherwise E_NOT_OK. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeTertiaryInput( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr +#endif +); + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeOutput() + *********************************************************************************************************************/ +/*! + * \brief Serialize the output or a redirection to the Ipc buffer + * \details The function decides if the input shall be serialized or a redirection is made. + * \param[in] jobRequestId Valid JobRequestId + * \param[in] cryptoJobPtr Valid pointer to the job which shall be serialized + * \param[in,out] ptrBuf Valid pointer to the memory where the pointer shall be serialized. + * Must at least provide 8 byte of storage after the offset. + * \param[in,out] jobRedirectionInfoPtr Valid pointer to the redirection info. + * The availability of this parameter depends on the configuration. + * \return E_OK if the input has been correctly serialized, otherwise E_NOT_OK. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeOutput( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr +#endif +); + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeSecondaryOutput() + *********************************************************************************************************************/ +/*! + * \brief Serialize the secondary output or a redirection to the Ipc buffer + * \details The function decides if the input shall be serialized or a redirection is made. + * \param[in] jobRequestId Valid JobRequestId + * \param[in] cryptoJobPtr Valid pointer to the job which shall be serialized + * \param[in,out] ptrBuf Valid pointer to the memory where the pointer shall be serialized. + * Must at least provide 8 byte of storage after the offset. + * \param[in,out] jobRedirectionInfoPtr Valid pointer to the redirection info. + * The availability of this parameter depends on the configuration. + * \return E_OK if the input has been correctly serialized, otherwise E_NOT_OK. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeSecondaryOutput( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr +#endif + ); + +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeInputRedirection() + *********************************************************************************************************************/ +/*! + * \brief Serialize an input redirection to the Ipc buffer + * \details - + * \param[in] jobRequestId Valid JobRequestId + * \param[in] keyId Valid key which shall be used as destination for the redirection + * \param[in] keyElementId Valid keyElement which shall be used as destination for the redirection + * \param[in,out] ptrBuf Valid pointer to the memory where the pointer shall be serialized. + * Must at least provide 8 byte of storage after the offset. + * \return E_OK if the input redirection has been correctly serialized, otherwise E_NOT_OK. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeInputRedirection( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + uint32 keyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf); + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeOutputRedirection() + *********************************************************************************************************************/ +/*! + * \brief Serialize an output redirection to the Ipc buffer + * \details - + * \param[in] jobRequestId Valid JobRequestId + * \param[in] keyId Valid key which shall be used source for the redirection + * \param[in] keyElementId Valid keyElement which shall be used as source for the redirection + * \param[in,out] dataBufferLengthPtr Valid pointer to length of the dataBufferPtr + * \param[in,out] ptrBuf Valid pointer to the memory where the pointer shall be serialized. + * Must at least provide 8 byte of storage after the offset. + * \return E_OK if the output redirection has been correctly serialized, otherwise E_NOT_OK. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeOutputRedirection( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + uint32 keyId, + uint32 keyElementId, +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) dataBufferLengthPtr, +# endif + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf); +#endif /* (CRYPTO_30_VHSM_REDIRECTION == STD_ON) */ + +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_CheckBufferReplacementError() + *********************************************************************************************************************/ +/*! + * \brief Check if an error occurred due to a previously performed buffer replacement + * \details - + * \param[in] jobRequestId Valid jobRequestId + * \param[in] jobResult result of the job + * \param[in] notAllowedJobResult Result which will generate a DET if replacement has been performed before + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_CheckBufferReplacementError( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + Std_ReturnType jobResult, + Std_ReturnType notAllowedJobResult); +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_AddUsedBuffer() + *********************************************************************************************************************/ +/*! + * \brief Increment the used buffer size in at least 4 byte steps + * \details This function ensures that following buffers start at an aligned address to have better performance because uint32 memory access can be used. + * \param[in] jobRequestId Valid jobRequest + * \param[in] value Value which shall be added to the usedBuffer + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_AddUsedBuffer( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + uint32 value); + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob_Inputs() + *********************************************************************************************************************/ +/*! + * \brief Serialization of a crypto job inputs + * \details - + * \param[in] jobRequestId Valid jobRequestId + * \param[in] cryptoJobPtr Valid pointer to job object + * \param[in,out] ptrBuf Valid pointer to buffer where the crypto job will be serialized. + * Must be at least of size 24. + * \param[in,out] offsetPtr Offset where the data shall be serialized. Contains the offset which needs to be used to serialize the rest of the data. + * \param[in,out] jobRedirectionInfoPtr Valid pointer to the redirection info. + * The availability of this parameter depends on the configuration. + * \return E_OK if no errors occurred, otherwise E_NOT_OK. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob_Inputs( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) +, P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) offsetPtr +#endif +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr +#endif + ); + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob_Outputs() + *********************************************************************************************************************/ +/*! + * \brief Serialization of a crypto job outputs + * \details - + * \param[in] jobRequestId Valid jobRequestId + * \param[in] cryptoJobPtr Valid pointer to job object + * \param[in,out] ptrBuf Valid pointer to buffer where the crypto job will be serialized. + * Must be at least of size 16. + * \param[in,out] offsetPtr Offset where the data shall be serialized. Contains the offset which needs to be used to serialize the rest of the data. + * \param[in,out] jobRedirectionInfoPtr Valid pointer to the redirection info. + * The availability of this parameter depends on the configuration. + * \return E_OK if no errors occurred, otherwise E_NOT_OK. + * \pre - + * \context TASK, ISR2 + * \reentrant TRUE + * \synchronous TRUE + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob_Outputs( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) +, P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) offsetPtr +#endif +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr +#endif + ); + +#define CRYPTO_30_VHSM_STOP_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_START_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_CheckBufferReplacementError() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_CheckBufferReplacementError( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + Std_ReturnType jobResult, + Std_ReturnType notAllowedJobResult) +{ + /* #10 Check if the buffer size has been replaced by the driver prior to sending the request to the vHsm */ + if (Crypto_30_vHsm_IsTrimmedOutputBufferOfJobRequest(jobRequestId) == FALSE) + { + /* Do nothing. */ + } + /* #11 Check if the error indicating a too small buffer has been issued */ + else if (jobResult != notAllowedJobResult) + { + /* Do nothing */ + } + else + { +# if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + /* #12 Issue DET because the buffer provided by the driver was too small */ + /* If a buffer provided to the driver is not in a valid memory area, the driver provides an own buffer to the vHsm. + This buffer may be smaller than the buffer originally provided by the application. + Upon receiving the response, the driver checks if a buffer replacement has taken place an will issue a DET if the vHsm complains about a too small buffer, because a bigger configured buffer will solve the issue. + If the following DET is triggered, either increase the buffer size of of the driver object with /MICROSAR/Crypto_30_vHsm/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptovHsmBuffer + or directly provide a buffer which is located in a usable memory area so that buffering by the driver is not needed. */ + (void)Det_ReportError(CRYPTO_30_VHSM_MODULE_ID, CRYPTO_30_VHSM_INSTANCE_ID, CRYPTO_30_VHSM_SID_PROCESS_JOB, CRYPTO_E_GLOBAL_BUFFER_TOO_SMALL); +# endif /* (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + } +} /* Crypto_30_vHsm_CheckBufferReplacementError() */ +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_IsMemoryValid() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + */ + /* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +CRYPTO_30_VHSM_LOCAL FUNC( boolean, CRYPTO_30_VHSM_CODE ) Crypto_30_vHsm_IsMemoryValid( + P2CONST( uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) ptr, + uint32 length, + boolean isInput ) +{ + boolean retVal = FALSE; + + if ( (NULL_PTR == ptr) + && (0u == length) ) /* COV_CRYPTO_30_VHSM_ROBUST_POINTER_CHECK */ + { + retVal = TRUE; + } +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_OFF) + else if (length == 0u) + { + retVal = FALSE; + } +#endif + /* Check for overflow */ + else if (&ptr[length] < ptr) /*lint !e613 */ /* PRQA S 2822 */ /* MD_CRYPTO_30_VHSM_2822_DEREFERENCING_NULLPTR */ + { + retVal = FALSE; + } + else + { +#if (CRYPTO_30_VHSM_MEMORYAREA == STD_ON) + Crypto_30_vHsm_MemoryAreaIterType memAreaIdx; + P2CONST( uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) startAddress; + P2CONST( uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) stopAddress; + /* #10 For all memory areas: */ + for (memAreaIdx = 0u; memAreaIdx < Crypto_30_vHsm_GetSizeOfMemoryArea(); memAreaIdx++) + { + /* #20 Check if this is the area we are looking for */ + if ( (isInput == TRUE) +# if (CRYPTO_30_VHSM_READWRITE_AVAILABLE == STD_ON) /* COV_CRYPTO_30_VHSM_READWRITE_AVAILABLE */ + || (Crypto_30_vHsm_GetAreaTypeOfMemoryArea( memAreaIdx ) == CRYPTO_30_VHSM_AREA_HSM_READWRITE_ACCESS) +# endif + ) + { + /* #30 Get the start and stop address */ + startAddress = (P2CONST( uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA))(uint32)Crypto_30_vHsm_GetAreaStartOfMemoryArea( memAreaIdx ); /* PRQA S 0306 */ /* MD_CRYPTO_30_VHSM_0306_CHECK_MEMORY_LAYOUT */ + stopAddress = (P2CONST( uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA))(uint32)Crypto_30_vHsm_GetAreaStopOfMemoryArea( memAreaIdx ); /* PRQA S 0306 */ /* MD_CRYPTO_30_VHSM_0306_CHECK_MEMORY_LAYOUT */ + + /* #40 Check if the pointer and its length are inside the current memory area */ + if ( (&ptr[0] >= startAddress) /*lint !e613 */ /* PRQA S 2822 */ /* MD_CRYPTO_30_VHSM_2822_DEREFERENCING_NULLPTR */ + && (&ptr[length - 1u] <= stopAddress) ) /*lint !e613 */ /* PRQA S 2822 */ /* MD_CRYPTO_30_VHSM_2822_DEREFERENCING_NULLPTR */ + { + retVal = TRUE; + break; + } + } + } +#else /* !(CRYPTO_30_VHSM_MEMORYAREA == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(isInput); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + } + + return retVal; +} /* Crypto_30_vHsm_IsMemoryValid() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_AddUsedBuffer() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_AddUsedBuffer( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + uint32 value) +{ + /* #10 Check if new value is not a multiple of 4 bytes */ + if ((value & 0x3uL) != 0u) + { + /* #11 Set the value to the next value which is a multiple of 4 */ + Crypto_30_vHsm_SetUsedBufferOfJobRequest(jobRequestId, Crypto_30_vHsm_GetUsedBufferOfJobRequest(jobRequestId) + (value & 0xFFFFFFFCuL) + 4u); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + else + { + /* #12 Set the value because it is a multiple of 4 bytes */ + Crypto_30_vHsm_SetUsedBufferOfJobRequest(jobRequestId, Crypto_30_vHsm_GetUsedBufferOfJobRequest(jobRequestId) + value); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } +} /* Crypto_30_vHsm_AddUsedBuffer() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeOutputPtr() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + /* PRQA S 6060 1 */ /* MD_MSR_STPAR */ +CRYPTO_30_VHSM_LOCAL FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeOutputPtr( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) outputPtr, + P2CONST(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) outputLengthPtr, +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) dataBufferLengthPtr, +#endif + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf, + P2VAR(volatile uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) outputOffset) /* PRQA S 3673 */ /* MD_CRYPTO_30_VHSM_3673_API_SPECIFIC */ +{ + /* Get information from the jobRequest */ + uint32 usedBuffer = Crypto_30_vHsm_GetUsedBufferOfJobRequest(jobRequestId); +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + uint32 dataBufferLength; +#endif + + /* #10 Check if outputLengthPtr is not a NULL_PTR */ + if (outputLengthPtr != NULL_PTR) + { + /* #20 Check if NoBuffering shall be applied */ +#if (CRYPTO_30_VHSM_NOBUFFERING_ENABLED == STD_ON) /* COV_CRYPTO_30_VHSM_NOBUFFERING_ENABLED */ + if (Crypto_30_vHsm_IsBufferUsedOfObjectInfo(jobRequestId) == FALSE) + { + /* Set the length to the given value */ +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + dataBufferLength = *outputLengthPtr; +# else + *dataBufferLengthPtr = *outputLengthPtr; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ +# endif + + /* Provide the original pointer to the vHsm */ + Crypto_30_vHsm_Serialize_Ptr32(outputPtr, ptrBuf); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + + /* Indicate that the shared output buffer was not used for this output */ + *outputOffset = CRYPTO_30_VHSM_OUTPUT_BUFFER_NOT_USED; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ + } + else +#endif /* (CRYPTO_30_VHSM_NOBUFFERING_ENABLED == STD_ON) */ + /* #30 ELSE Check if it is shared ram: */ + if (Crypto_30_vHsm_IsMemoryValid(outputPtr, *outputLengthPtr, FALSE) == TRUE) /* SBSW_CRYPTO_30_VHSM_MEMORY_VALID_CHECK */ + { + /* Set the length to the given value */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + dataBufferLength = *outputLengthPtr; +#else + *dataBufferLengthPtr = *outputLengthPtr; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ +#endif + + /* Provide the original pointer to the vHsm */ + Crypto_30_vHsm_Serialize_Ptr32(outputPtr, ptrBuf); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + + /* Indicate that the shared output buffer was not used for this output */ + *outputOffset = CRYPTO_30_VHSM_OUTPUT_BUFFER_NOT_USED; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ + } + else + { + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) dataBufferPtr = Crypto_30_vHsm_GetAddrSharedDataBufferOfDriverObject(jobRequestId, usedBuffer); +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + dataBufferLength = Crypto_30_vHsm_GetSharedDataBufferSizeOfDriverObject(jobRequestId) - usedBuffer; +#else + *dataBufferLengthPtr = Crypto_30_vHsm_GetSharedDataBufferSizeOfDriverObject(jobRequestId) - usedBuffer; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ +#endif + + /* Make sure that the provided buffer size is the maximum, if the global buffer is smaller, use it's size instead. */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + if (*outputLengthPtr < dataBufferLength) + { + dataBufferLength = *outputLengthPtr; + } +#else + if (*outputLengthPtr < *dataBufferLengthPtr) + { + *dataBufferLengthPtr = *outputLengthPtr; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ + } +#endif /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) */ + else + { +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + /* Store the information, that the buffer has been trimmed */ + /* The provided buffer to the vHsm will be smaller than the buffer provided by the application. This may lead to CRYPTO_E_SMALL_BUFFER or CRYPTO_E_KEY_SIZE_MISMATCH although the application has provided a big enough buffer to the driver. + In this case a DET will be triggered and the buffer needs to be increased in the configuration */ + Crypto_30_vHsm_SetTrimmedOutputBufferOfJobRequest(jobRequestId, TRUE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#endif + } + + /* Store the offset to the memory where the output will be redirected */ + *outputOffset = usedBuffer; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ + + /* Add the size of the current output buffer to the fill level of the shared buffer of this driver object */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + Crypto_30_vHsm_AddUsedBuffer(jobRequestId, dataBufferLength); +#else + Crypto_30_vHsm_AddUsedBuffer(jobRequestId, *dataBufferLengthPtr); +#endif + + /* Provide the pointer to a shared buffer to the vHsm */ + Crypto_30_vHsm_Serialize_Ptr32(dataBufferPtr, ptrBuf); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + } + } + else + { + /* set the value to default 0 */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + dataBufferLength = 0u; +#else + *dataBufferLengthPtr = 0u; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ +#endif + + *outputOffset = usedBuffer; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ + + /* #70 Provide NULL_PTR to the vHsm */ + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, ptrBuf); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + } + + /* #80 Serialize the outputLengthPtr */ + /* #90 Serialize the value */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + Crypto_30_vHsm_Serialize_Uint32(dataBufferLength, &ptrBuf[4]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ +#else + Crypto_30_vHsm_Serialize_Ptr32(dataBufferLengthPtr, &ptrBuf[4]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ +#endif + +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_OFF) + CRYPTO_30_VHSM_DUMMY_STATEMENT(jobRequestId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif +} /* Crypto_30_vHsm_SerializeOutputPtr() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeInputPtr() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeInputPtr( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) inputPtr, + uint32 inputLength, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf, + boolean interpretLengthInBits) /* PRQA S 3673 */ /* MD_CRYPTO_30_VHSM_3673_API_SPECIFIC */ +{ + Std_ReturnType retVal = E_OK; + + /* Get information from the jobRequest */ + uint32 usedBuffer = Crypto_30_vHsm_GetUsedBufferOfJobRequest(jobRequestId); + + uint32 inputLengthInBytes = inputLength; + + if (interpretLengthInBits == TRUE) + { + inputLengthInBytes /= 8u; + if ((inputLength % 8u) != 0u) + { + inputLengthInBytes += 1u; + } + } + + /* #10 Serialization of inputPtr */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_OFF) + if ((inputLength != 0u) + && (inputPtr == NULL_PTR)) + { + /* #20 Serialize the inputPtr */ + Crypto_30_vHsm_Serialize_Ptr32(inputPtr, ptrBuf); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + + /* #30 NULL_PTR as input is not allowed when length is not zero */ + retVal = E_NOT_OK; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_OFF) */ + { + /* #40 Check if NoBuffering shall be applied */ +#if (CRYPTO_30_VHSM_NOBUFFERING_ENABLED == STD_ON) /* COV_CRYPTO_30_VHSM_NOBUFFERING_ENABLED */ + if (Crypto_30_vHsm_IsBufferUsedOfObjectInfo(jobRequestId) == FALSE) + { + /* Serialize the inputPtr */ + Crypto_30_vHsm_Serialize_Ptr32(inputPtr, ptrBuf); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + } + else +#endif /* (CRYPTO_30_VHSM_NOBUFFERING_ENABLED == STD_ON) */ + /* #41 ELSE Check if it is accessible memory */ + if (Crypto_30_vHsm_IsMemoryValid(inputPtr, inputLengthInBytes, TRUE) == TRUE) /* SBSW_CRYPTO_30_VHSM_MEMORY_VALID_CHECK */ + { + /* Serialize the inputPtr */ + Crypto_30_vHsm_Serialize_Ptr32(inputPtr, ptrBuf); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + } + else + { + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) dataBufferPtr = Crypto_30_vHsm_GetAddrSharedDataBufferOfDriverObject(jobRequestId, usedBuffer); + uint32 dataBufferLength = Crypto_30_vHsm_GetSharedDataBufferSizeOfDriverObject(jobRequestId) - usedBuffer; + + /* Check if the provided input data can be buffered to the global RAM buffer. */ + if (dataBufferLength >= inputLengthInBytes) + { + /* Copy the input data to a memory location which can be read by the vHsm */ + VStdLib_MemCpy(dataBufferPtr, inputPtr, inputLengthInBytes); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_VHSM_COPY_TO_GLOBAL_BUFFER_FROM_SOURCE */ + + /* Serialize the pointer to the buffer. */ + Crypto_30_vHsm_Serialize_Ptr32(dataBufferPtr, ptrBuf); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_AddUsedBuffer(jobRequestId, inputLengthInBytes); + } + else + { + /* There is not enough space in the buffer to store the input data. */ + Crypto_30_vHsm_Serialize_Ptr32(dataBufferPtr, ptrBuf); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + (void)Det_ReportError(CRYPTO_30_VHSM_MODULE_ID, CRYPTO_30_VHSM_INSTANCE_ID, CRYPTO_30_VHSM_SID_PROCESS_JOB, CRYPTO_E_GLOBAL_BUFFER_TOO_SMALL); +#endif + retVal = E_NOT_OK; + } + } + } + + /* #100 Serialization of inputLength */ + Crypto_30_vHsm_Serialize_Uint32(inputLength, &ptrBuf[4]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + return retVal; +} /* Crypto_30_vHsm_SerializeInputPtr() */ + +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeInputRedirection() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeInputRedirection( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + uint32 keyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf) /* PRQA S 3673 */ /* MD_CRYPTO_30_VHSM_3673_API_SPECIFIC */ +{ + Std_ReturnType retVal = E_OK; + + /* Get information from the jobRequest */ + uint32 usedBuffer = Crypto_30_vHsm_GetUsedBufferOfJobRequest(jobRequestId); + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) dataBufferPtr = Crypto_30_vHsm_GetAddrSharedDataBufferOfDriverObject(jobRequestId, usedBuffer); + uint32 dataBufferLength = Crypto_30_vHsm_GetSharedDataBufferSizeOfDriverObject(jobRequestId) - usedBuffer; + + /* #10 Check if provided buffer is big enough */ + if (dataBufferLength < 8u) + { + /* The provided buffer is not big enough */ + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, ptrBuf); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_Serialize_Uint32(0u, &ptrBuf[4]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + retVal = E_NOT_OK; + } + else + { + /* #20 Store keyId and keyElementId to the global RAM buffer */ + Crypto_30_vHsm_Serialize_Uint32(keyId, dataBufferPtr); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyElementId, &dataBufferPtr[4]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + /* #30 Serialize the data Buffer to the IPC */ + Crypto_30_vHsm_Serialize_Ptr32(dataBufferPtr, ptrBuf); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + + /* #40 Serialize length to the IPC */ + Crypto_30_vHsm_Serialize_Uint32(8u, &ptrBuf[4]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_SetUsedBufferOfJobRequest(jobRequestId, usedBuffer + 8u); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + + return retVal; +} /* Crypto_30_vHsm_SerializeInputRedirection() */ +#endif /* (CRYPTO_30_VHSM_REDIRECTION == STD_ON) */ + +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeOutputRedirection() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeOutputRedirection( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + uint32 keyId, + uint32 keyElementId, +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) dataBufferLengthPtr, +# endif + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf) /* PRQA S 3673 */ /* MD_CRYPTO_30_VHSM_3673_API_SPECIFIC */ +{ + Std_ReturnType retVal = E_OK; + + /* Get information from the jobRequest */ + uint32 usedBuffer = Crypto_30_vHsm_GetUsedBufferOfJobRequest(jobRequestId); + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) dataBufferPtr = Crypto_30_vHsm_GetAddrSharedDataBufferOfDriverObject(jobRequestId, usedBuffer); +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + *dataBufferLengthPtr = (Crypto_30_vHsm_GetSharedDataBufferSizeOfDriverObject(jobRequestId) - usedBuffer); /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ +# else + uint32 dataBufferLength = Crypto_30_vHsm_GetSharedDataBufferSizeOfDriverObject(jobRequestId) - usedBuffer; +# endif + /* #10 Check if provided buffer is big enough */ +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + if (*dataBufferLengthPtr < 8u) + { + /* The provided buffer is not big enough */ + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, ptrBuf); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + *dataBufferLengthPtr = 0u; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ + Crypto_30_vHsm_Serialize_Uint32(dataBufferLengthPtr, &ptrBuf[4]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + retVal = E_NOT_OK; + } +# else /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) */ + if (dataBufferLength < 8u) + { + /* The provided buffer is not big enough */ + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, ptrBuf); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_Serialize_Uint32(0u, &ptrBuf[4]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + retVal = E_NOT_OK; + } +# endif /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) */ + else + { + /* #20 Store keyId and keyElementId to the global RAM buffer */ + Crypto_30_vHsm_Serialize_Uint32(keyId, dataBufferPtr); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyElementId, &dataBufferPtr[4]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + /* #30 Serialize the data Buffer to the IPC */ + Crypto_30_vHsm_Serialize_Ptr32(dataBufferPtr, ptrBuf); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + + /* #40 Serialize length to the IPC */ +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + *dataBufferLengthPtr = 8u; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_CSL */ + Crypto_30_vHsm_Serialize_Ptr32(dataBufferLengthPtr, &ptrBuf[4]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ +# else + Crypto_30_vHsm_Serialize_Ptr32(8u, &ptrBuf[4]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ +# endif + Crypto_30_vHsm_SetUsedBufferOfJobRequest(jobRequestId, usedBuffer + 8u); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + + return retVal; +} /* Crypto_30_vHsm_SerializeOutputRedirection() */ +#endif /* (CRYPTO_30_VHSM_REDIRECTION == STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeInput() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeInput( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +#endif + ) +{ + Std_ReturnType retVal; + +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + if ((jobRedirectionInfoPtr->redirectionConfig & CRYPTO_REDIRECT_CONFIG_PRIMARY_INPUT) == CRYPTO_REDIRECT_CONFIG_PRIMARY_INPUT) + { + /* #10 Serialization of redirection for inputPtr */ + retVal = Crypto_30_vHsm_SerializeInputRedirection( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_REDIRECTION_WITH_GLOBAL_BUFFERS */ + jobRequestId, + jobRedirectionInfoPtr->inputKeyId, + jobRedirectionInfoPtr->inputKeyElementId, + ptrBuf); + } + else +#endif /* (CRYPTO_30_VHSM_REDIRECTION == STD_ON) */ + { + /* #20 Serialization of inputPtr */ + retVal = Crypto_30_vHsm_SerializeInputPtr( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_PTR_WITH_GLOBAL_BUFFERS */ + jobRequestId, + cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputPtr, + cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.inputLength, + ptrBuf, + FALSE); + } + + return retVal; +} /* Crypto_30_vHsm_SerializeInput() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeSecondaryInput() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeSecondaryInput( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +#endif + ) +{ + Std_ReturnType retVal; + +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + if ((jobRedirectionInfoPtr->redirectionConfig & CRYPTO_REDIRECT_CONFIG_SECONDARY_INPUT) == CRYPTO_REDIRECT_CONFIG_SECONDARY_INPUT) + { + /* #10 Serialization of redirection for secondaryInputPtr */ + retVal = Crypto_30_vHsm_SerializeInputRedirection( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_REDIRECTION_WITH_GLOBAL_BUFFERS */ + jobRequestId, + jobRedirectionInfoPtr->secondaryInputKeyId, + jobRedirectionInfoPtr->secondaryInputKeyElementId, + ptrBuf); + } + else +#endif /* (CRYPTO_30_VHSM_REDIRECTION == STD_ON) */ + { + /* #20 Serialization of secondaryInputPtr */ + retVal = Crypto_30_vHsm_SerializeInputPtr( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_PTR_WITH_GLOBAL_BUFFERS */ + jobRequestId, + cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputPtr, + cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryInputLength, + ptrBuf, + (cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->service == CRYPTO_MACVERIFY)); + } + + return retVal; +} /* Crypto_30_vHsm_SerializeSecondaryInput() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeTertiaryInput() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeTertiaryInput( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +#endif + ) +{ + Std_ReturnType retVal; + +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + if ((jobRedirectionInfoPtr->redirectionConfig & CRYPTO_REDIRECT_CONFIG_TERTIARY_INPUT) == CRYPTO_REDIRECT_CONFIG_TERTIARY_INPUT) + { + /* #10 Serialization of redirection for tertiaryInputPtr */ + retVal = Crypto_30_vHsm_SerializeInputRedirection( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_REDIRECTION_WITH_GLOBAL_BUFFERS */ + jobRequestId, + jobRedirectionInfoPtr->tertiaryInputKeyId, + jobRedirectionInfoPtr->tertiaryInputKeyElementId, + ptrBuf); + } + else +#endif /* (CRYPTO_30_VHSM_REDIRECTION == STD_ON) */ + { + /* #20 Serialization of tertiaryInputPtr */ + retVal = Crypto_30_vHsm_SerializeInputPtr( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_PTR_WITH_GLOBAL_BUFFERS */ + jobRequestId, + cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.tertiaryInputPtr, + cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.tertiaryInputLength, + ptrBuf, + FALSE); + } + return retVal; +} /* Crypto_30_vHsm_SerializeTertiaryInput() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeOutput() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeOutput( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +#endif + ) +{ + Std_ReturnType retVal = E_OK; + +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + if ((jobRedirectionInfoPtr->redirectionConfig & CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT) == CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT) + { + /* #10 Serialization of redirection for outputPtr */ + retVal = Crypto_30_vHsm_SerializeOutputRedirection( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_REDIRECTION_WITH_GLOBAL_BUFFERS */ + jobRequestId, + jobRedirectionInfoPtr->outputKeyId, + jobRedirectionInfoPtr->outputKeyElementId, +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId), +# endif + ptrBuf); + } + else +#endif /* (CRYPTO_30_VHSM_REDIRECTION == STD_ON) */ + { + /* #20 Serialization of outputPtr */ + Crypto_30_vHsm_SerializeOutputPtr( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_PTR_WITH_GLOBAL_BUFFERS */ + jobRequestId, + cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, + cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr, +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId), +#endif + ptrBuf, + &Crypto_30_vHsm_GetOutputOffsetOfJobRequest(jobRequestId)); + } + + return retVal; +} /* Crypto_30_vHsm_SerializeOutput() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeSecondaryOutput() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeSecondaryOutput( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +#endif + ) +{ + Std_ReturnType retVal = E_OK; + +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + if ((jobRedirectionInfoPtr->redirectionConfig & CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT) == CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT) + { + /* #10 Serialization of redirection for secondaryOutputPtr */ + retVal = Crypto_30_vHsm_SerializeOutputRedirection( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_REDIRECTION_WITH_GLOBAL_BUFFERS */ + jobRequestId, + jobRedirectionInfoPtr->secondaryOutputKeyId, + jobRedirectionInfoPtr->secondaryOutputKeyElementId, +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_GetAddrSecondaryOutputLengthPtrDataBuffer(jobRequestId), +# endif + ptrBuf); + } + else +#endif /* (CRYPTO_30_VHSM_REDIRECTION == STD_ON) */ + { + /* #20 Serialization of secondaryOutputPtr */ + Crypto_30_vHsm_SerializeOutputPtr( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE_PTR_WITH_GLOBAL_BUFFERS */ + jobRequestId, + cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputPtr, + cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr, +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_GetAddrSecondaryOutputLengthPtrDataBuffer(jobRequestId), +#endif + ptrBuf, + &Crypto_30_vHsm_GetSecondaryOutputOffsetOfJobRequest(jobRequestId)); + } + return retVal; +} /* Crypto_30_vHsm_SerializeSecondaryOutput() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob_Inputs() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob_Inputs( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + , P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) offsetPtr +#endif +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +#endif + ) +{ + Std_ReturnType retVal; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + uint32 offset = *offsetPtr; +#else + uint32 offset = 4; +#endif + + /* #10 Serialization of Input */ + if ((Crypto_30_vHsm_JobIOAvailable[cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->service] & CRYPTO_30_VHSM_IO_INPUT) == CRYPTO_30_VHSM_IO_INPUT) + { + retVal = Crypto_30_vHsm_SerializeInput( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE */ + jobRequestId, + cryptoJobPtr, + &ptrBuf[offset] +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , jobRedirectionInfoPtr +#endif + ); + offset += 8u; + /* #20 Serialization of Secondary Input */ + if ((Crypto_30_vHsm_JobIOAvailable[cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->service] & CRYPTO_30_VHSM_IO_SECONDARYINPUT) == CRYPTO_30_VHSM_IO_SECONDARYINPUT) + { + retVal |= Crypto_30_vHsm_SerializeSecondaryInput( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE */ + jobRequestId, + cryptoJobPtr, + &ptrBuf[offset] +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , jobRedirectionInfoPtr +#endif + ); + offset += 8u; + /* #30 Serialization of Tertiary Input */ + if ((Crypto_30_vHsm_JobIOAvailable[cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->service] & CRYPTO_30_VHSM_IO_TERTIARYINPUT) == CRYPTO_30_VHSM_IO_TERTIARYINPUT) + { + retVal |= Crypto_30_vHsm_SerializeTertiaryInput( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE */ + jobRequestId, + cryptoJobPtr, + &ptrBuf[offset] +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , jobRedirectionInfoPtr +#endif + ); +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + offset += 8u; +#endif + } + else + { +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, &ptrBuf[20]); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_Serialize_Uint32(0u, &ptrBuf[24]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ +#endif + } + } + else + { +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, &ptrBuf[12]); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_Serialize_Uint32(0u, &ptrBuf[16]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, &ptrBuf[20]); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_Serialize_Uint32(0u, &ptrBuf[24]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ +#endif + } + } + else + { +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, &ptrBuf[4]); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_Serialize_Uint32(0u, &ptrBuf[8]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, &ptrBuf[12]); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_Serialize_Uint32(0u, &ptrBuf[16]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, &ptrBuf[20]); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_Serialize_Uint32(0u, &ptrBuf[24]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ +#endif /* (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) */ + + retVal = E_OK; + } + +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + *offsetPtr = offset; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_STACK */ +#endif + + return retVal; +} /* Crypto_30_vHsm_SerializeRequest_CryptoJob_Inputs() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob_Outputs() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob_Outputs( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + , P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) offsetPtr +#endif +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +#endif + ) +{ + Std_ReturnType retVal; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + uint32 offset = *offsetPtr; +#else + uint32 offset = 28u; +#endif + /* #40 Serialization of Output */ + if (((Crypto_30_vHsm_JobIOAvailable[cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->service] & CRYPTO_30_VHSM_IO_OUTPUT) == CRYPTO_30_VHSM_IO_OUTPUT) +#if (CRYPTO_30_VHSM_SUPPORT_SAVE_RESTORE_CONTEXT == STD_ON) + || ((cryptoJobPtr->jobPrimitiveInputOutput.mode & CRYPTO_OPERATIONMODE_SAVE_CONTEXT) == CRYPTO_OPERATIONMODE_SAVE_CONTEXT)) +#else + ) +#endif + { + retVal = Crypto_30_vHsm_SerializeOutput( /* PRQA S 2985 */ /* MD_CRYPTO_30_VHSM_2985_REDUNDANT_OP_WHEN_NO_REDIRECTION */ /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE */ + jobRequestId, + cryptoJobPtr, + &ptrBuf[offset] +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , jobRedirectionInfoPtr +#endif + ); + offset += 8u; + /* #50 Serialization of Secondary Output */ + if ((Crypto_30_vHsm_JobIOAvailable[cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->service] & CRYPTO_30_VHSM_IO_SECONDARYOUTPUT) == CRYPTO_30_VHSM_IO_SECONDARYOUTPUT) + { + retVal |= Crypto_30_vHsm_SerializeSecondaryOutput( /* PRQA S 2985 */ /* MD_CRYPTO_30_VHSM_2985_REDUNDANT_OP_WHEN_NO_REDIRECTION */ /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE */ + jobRequestId, + cryptoJobPtr, + &ptrBuf[offset] +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , jobRedirectionInfoPtr +#endif + ); + /* this addition to the offset is only needed if we are IPCv3 */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + offset+=8u; +#endif + } + else + { + *Crypto_30_vHsm_GetAddrSecondaryOutputLengthPtrDataBuffer(jobRequestId) = 0u; /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, &ptrBuf[36]); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_Serialize_Ptr32(Crypto_30_vHsm_GetAddrSecondaryOutputLengthPtrDataBuffer(jobRequestId), &ptrBuf[40]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ +#endif + } + } + else + { + *Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId) = 0u; /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, &ptrBuf[28]); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_Serialize_Ptr32(Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId), &ptrBuf[32]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ +#endif + + *Crypto_30_vHsm_GetAddrSecondaryOutputLengthPtrDataBuffer(jobRequestId) = 0u; /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_Serialize_Ptr32(NULL_PTR, &ptrBuf[36]); /* PRQA S 0306, 0310, 0326, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + Crypto_30_vHsm_Serialize_Ptr32(Crypto_30_vHsm_GetAddrSecondaryOutputLengthPtrDataBuffer(jobRequestId), &ptrBuf[40]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ +#endif + + retVal = E_OK; + } + +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + *offsetPtr = offset; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_STACK */ +#endif + + return retVal; +} /* Crypto_30_vHsm_SerializeRequest_CryptoJob_Outputs() */ + +#define CRYPTO_30_VHSM_STOP_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_START_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +#endif + ) +{ + Std_ReturnType retVal; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + uint32 offset = 8u; + uint8 numOfInputs; + uint32 inputOffset; + uint8 numOfOutputs; + uint8 numOfConstData = 3u; + uint8 numOfCryptoKeyIds = 0u; + uint32 numOfInOutKeyConst; +#endif /* (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) */ + /* ----- Implementation ----------------------------------------------- */ + /* #05 Check if the request can be serialized to the provided buffer */ + if (cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->service < CRYPTO_30_VHSM_INVALID_SERVICES) + { +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_Serialize_Uint32(Crypto_30_vHsm_GetJobStateOfJobRequest(jobRequestId), ptrBuf); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ +#endif + + /* #10 Serialization of Inputs */ + retVal = Crypto_30_vHsm_SerializeRequest_CryptoJob_Inputs( /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_CryptoJob_Inputs */ + jobRequestId, + cryptoJobPtr, + ptrBuf +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + , &offset +#endif +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , jobRedirectionInfoPtr +#endif + ); + +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + inputOffset = offset; +#endif + /* #40 Serialization of Outputs */ + retVal |= Crypto_30_vHsm_SerializeRequest_CryptoJob_Outputs( /* PRQA S 2985 */ /* MD_CRYPTO_30_VHSM_2985_REDUNDANT_OP_WHEN_NO_REDIRECTION */ /* SBSW_CRYPTO_30_VHSM_ForwardingIpcBufferAsPtr_SerializeRequest_CryptoJob_Outputs */ + jobRequestId, + cryptoJobPtr, + ptrBuf +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + , &offset +#endif +#if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , jobRedirectionInfoPtr +#endif + ); +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + /* Calculate num of input and outputs properly */ + + numOfOutputs = (uint8)(offset-inputOffset) / 8u; + numOfInputs = (uint8)(inputOffset - 4u) / 8u; + + /* Serialize all keyIds, since we have only one here it does not need to be refactored to subfunction */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->cryptoKeyId, &ptrBuf[offset]);/* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + offset += 4u; + numOfCryptoKeyIds++; +# if (CRYPTO_30_VHSM_KEY_DERIVE_JOB_SUPPORT == STD_ON) + if ((Crypto_30_vHsm_JobIOAvailable[cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->service] & CRYPTO_30_VHSM_IO_SECONDARYKEY) == CRYPTO_30_VHSM_IO_SECONDARYKEY) + { + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->targetCryptoKeyId, &ptrBuf[offset]);/* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + offset += 4u; + numOfCryptoKeyIds++; + } +# endif /* (CRYPTO_30_VHSM_KEY_DERIVE_JOB_SUPPORT == STD_ON) */ + + /* Serialize constData */ + /* SHIFT multiple values into one uint32 in IPC to improve performance */ + Crypto_30_vHsm_Serialize_Uint32( /* PRQA S 0310, 3305, 4304, 0404 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO, MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO, MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO, MD_CRYPTO_30_VHSM_0404_VOLATILE_READ */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + ( ((uint32)cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.family) + | ((uint32)cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.mode << 8u) + | ((uint32)cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily << 16u) + | ((uint32)Crypto_30_vHsm_GetProcessingTypeOfJobRequest(jobRequestId) << 24u) + | ((uint32)Crypto_30_vHsm_GetJobStateOfJobRequest(jobRequestId) << 25u) + | ((uint32)Crypto_30_vHsm_IsCancelOfJobRequest(jobRequestId) << 28u) + | ((uint32)cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode << 29u)), + &ptrBuf[offset]); + + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.keyLength, &ptrBuf[offset + 4u]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobInfo->jobId, &ptrBuf[offset + 8u]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ +# if (CRYPTO_30_VHSM_SUPPORT_SAVE_RESTORE_CONTEXT == STD_ON) + Crypto_30_vHsm_Serialize_Uint32(((uint32)cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode), &ptrBuf[offset + 12u]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + numOfConstData++; +# endif + numOfInOutKeyConst = ((uint32)numOfInputs << 24u) | ((uint32)numOfOutputs << 16u) | ((uint32)numOfCryptoKeyIds << 8u) | ((uint32)numOfConstData); + Crypto_30_vHsm_Serialize_Uint32(numOfInOutKeyConst, ptrBuf); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->service, &ptrBuf[4u]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ +#else /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) */ + /* #60 Prepare verifyPtr */ + *Crypto_30_vHsm_GetAddrVerifyPtrDataBuffer(jobRequestId) = 0xFEu; /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + /* #62 Serialize verifyPtr */ + Crypto_30_vHsm_Serialize_Ptr32(Crypto_30_vHsm_GetAddrVerifyPtrDataBuffer(jobRequestId), &ptrBuf[44]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + + /* #70 Serialization of everything else */ + /* PRQA S 0310, 3305 8 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode, &ptrBuf[48]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->service, &ptrBuf[52]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.family, &ptrBuf[56]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.mode, &ptrBuf[60]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily, &ptrBuf[64]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(Crypto_30_vHsm_GetProcessingTypeOfJobRequest(jobRequestId), &ptrBuf[68]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobInfo->jobId, &ptrBuf[72]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->cryptoKeyId, &ptrBuf[76]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ +#endif /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) */ + } + else + { + retVal = E_NOT_OK; + } + + return retVal; +} /* Crypto_30_vHsm_SerializeRequest_CryptoJob() */ + +#if (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob_MacGen() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob_MacGen( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +# if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +# endif +) +{ + Std_ReturnType retVal; + + /* ----- Implementation ----------------------------------------------- */ + Crypto_30_vHsm_Serialize_Uint32(Crypto_30_vHsm_GetJobStateOfJobRequest(jobRequestId), ptrBuf); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + /* #10 Serialization of Input */ + retVal = Crypto_30_vHsm_SerializeInput( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE */ + jobRequestId, + cryptoJobPtr, + &ptrBuf[4] +# if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , jobRedirectionInfoPtr +# endif + ); + + /* #40 Serialization of Output */ + retVal |= Crypto_30_vHsm_SerializeOutput( /* PRQA S 2985 */ /* MD_CRYPTO_30_VHSM_2985_REDUNDANT_OP_WHEN_NO_REDIRECTION */ /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE */ + jobRequestId, + cryptoJobPtr, + &ptrBuf[12] +# if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , jobRedirectionInfoPtr +# endif + ); + + /* #60 Prepare verifyPtr */ + *Crypto_30_vHsm_GetAddrVerifyPtrDataBuffer(jobRequestId) = 0xFEu; /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + /* #70 Serialization of everything else */ + /* PRQA S 0310, 3305 6 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode, &ptrBuf[20]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.family, &ptrBuf[24]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.mode, &ptrBuf[28]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(Crypto_30_vHsm_GetProcessingTypeOfJobRequest(jobRequestId), &ptrBuf[32]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobInfo->jobId, &ptrBuf[36]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->cryptoKeyId, &ptrBuf[40]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + return retVal; +} /* Crypto_30_vHsm_SerializeRequest_CryptoJob_MacGen() */ +#endif /* (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION == STD_ON) */ + +#if (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION== STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob_MacVer() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob_MacVer( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +# if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +# endif +) +{ + Std_ReturnType retVal; + + /* ----- Implementation ----------------------------------------------- */ + Crypto_30_vHsm_Serialize_Uint32(Crypto_30_vHsm_GetJobStateOfJobRequest(jobRequestId), ptrBuf); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + /* #10 Serialization of Input */ + retVal = Crypto_30_vHsm_SerializeInput( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE */ + jobRequestId, + cryptoJobPtr, + &ptrBuf[4] +# if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , jobRedirectionInfoPtr +# endif + ); + + /* #20 Serialization of Secondary Input */ + retVal |= Crypto_30_vHsm_SerializeSecondaryInput( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE */ + jobRequestId, + cryptoJobPtr, + &ptrBuf[12] +# if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) + , jobRedirectionInfoPtr +# endif + ); + + /* #60 Prepare verifyPtr */ + *Crypto_30_vHsm_GetAddrVerifyPtrDataBuffer(jobRequestId) = 0xFEu; /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + /* #62 Serialize verifyPtr */ + Crypto_30_vHsm_Serialize_Ptr32(Crypto_30_vHsm_GetAddrVerifyPtrDataBuffer(jobRequestId), &ptrBuf[20]); /* PRQA S 0306, 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_PTR_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_PTR */ + + /* #70 Serialization of everything else */ + /* PRQA S 0310, 3305 6 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode, &ptrBuf[24]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.family, &ptrBuf[28]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.mode, &ptrBuf[32]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(Crypto_30_vHsm_GetProcessingTypeOfJobRequest(jobRequestId), &ptrBuf[36]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobInfo->jobId, &ptrBuf[40]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->cryptoKeyId, &ptrBuf[44]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + return retVal; +} /* Crypto_30_vHsm_SerializeRequest_CryptoJob_MacVer() */ +#endif /* (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION== STD_ON) */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_KeyMJob() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_KeyMJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_30_vHsm_KeyM_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) keyMJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf) +{ + Std_ReturnType retVal; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + uint32 ptrMask = 0u; + uint8 numOfKeys = 1u; + uint8 numOfConst; + uint32 offset = 8u; +#else + uint32 offset = 20u; +#endif /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) */ + + /* ----- Implementation ----------------------------------------------- */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + retVal = E_OK; +#else + /* PRQA S 0310, 3305 5 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->action, ptrBuf); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->cryptoKeyId, &ptrBuf[4]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->secondaryCryptoKeyId, &ptrBuf[8]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->keyElementId, &ptrBuf[12]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->secondaryKeyElementId, &ptrBuf[16]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ +#endif /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) */ + +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + /* PRQA S 0310, 3305 5 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ + if ((Crypto_30_vHsm_KeyMIOAvailable[keyMJobPtr->action] & CRYPTO_30_VHSM_IO_INPUT) == CRYPTO_30_VHSM_IO_INPUT) + { + ptrMask = ((uint32)1u << CRYPTO_30_VHSM_PTRMSK_INPUTS); +#endif + + /* #10 Serialization of inputPtr */ + retVal = Crypto_30_vHsm_SerializeInputPtr( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE */ + jobRequestId, + keyMJobPtr->inputOutput.inputPtr, + keyMJobPtr->inputOutput.inputLength, + &ptrBuf[offset], + FALSE); + offset += 8u; + +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + } + + if ((Crypto_30_vHsm_KeyMIOAvailable[keyMJobPtr->action] & CRYPTO_30_VHSM_IO_OUTPUT) == CRYPTO_30_VHSM_IO_OUTPUT) + { + ptrMask |= ((uint32)1u << CRYPTO_30_VHSM_PTRMSK_OUTPUTS); +#endif + /* #20 Serialization of outputPtr */ + Crypto_30_vHsm_SerializeOutputPtr( /* SBSW_CRYPTO_30_VHSM_CALL_SERIALIZE */ + jobRequestId, + keyMJobPtr->inputOutput.outputPtr, + keyMJobPtr->inputOutput.outputLengthPtr, +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId), +#endif + &ptrBuf[offset], + &Crypto_30_vHsm_GetOutputOffsetOfJobRequest(jobRequestId)); +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + offset += 8u; + } +#endif + +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->cryptoKeyId, &ptrBuf[offset]);/* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + offset += 4u; + if ((Crypto_30_vHsm_KeyMIOAvailable[keyMJobPtr->action] & CRYPTO_30_VHSM_IO_SECONDARYKEY) == CRYPTO_30_VHSM_IO_SECONDARYKEY) + { + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->secondaryCryptoKeyId, &ptrBuf[offset]);/* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + offset += 4u; + numOfKeys++; + } + + /* PRQA S 0310, 3305 2 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->action, &ptrBuf[offset]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->keyElementId, &ptrBuf[offset + 4u]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->secondaryKeyElementId, &ptrBuf[offset + 8u]);/* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + numOfConst = 3; + if ((Crypto_30_vHsm_KeyMIOAvailable[keyMJobPtr->action] & CRYPTO_30_VHSM_IO_COPYPARTIAL) == CRYPTO_30_VHSM_IO_COPYPARTIAL) + { + /* PRQA S 0310, 3305 3 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->inputOutput.keyElementSourceOffset, &ptrBuf[offset + 12u]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->inputOutput.keyElementTargetOffset, &ptrBuf[offset + 16u]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->inputOutput.keyElementCopyLength, &ptrBuf[offset + 20u]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + numOfConst = 6; + } + + ptrMask |= ((uint32)numOfKeys << CRYPTO_30_VHSM_PTRMSK_KEYS) | numOfConst; + + Crypto_30_vHsm_Serialize_Uint32(ptrMask, &ptrBuf[0]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + /* Serialize invalid service pattern */ + Crypto_30_vHsm_Serialize_Uint32(0xFFFFFFFFuL, &ptrBuf[4u]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ +#endif /* (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) */ + + /* + * Hint: If one of the above functions return E_NOT_OK, it is presumably the case that the provided key data is to big to be buffered. + * Try increasing the buffer size of CryptoDriverObjects/Crypto_30_vHsm_KeyM/CryptovHsmBuffer/CryptoInputBufferSize + */ + return retVal; +} /* Crypto_30_vHsm_SerializeRequest_KeyMJob() */ + +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2) +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_KeyMJob_CopyPartial() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_KeyMJob_CopyPartial( + Crypto_30_vHsm_JobRequestIterType jobRequestId, /* PRQA S 3206 */ /* MD_CRYPTO_30_VHSM_UNUSED_PARAMETER */ + P2CONST(Crypto_30_vHsm_KeyM_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) keyMJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf) +{ + Std_ReturnType retVal; + + /* ----- Implementation ----------------------------------------------- */ + /* PRQA S 0310, 3305 8 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->action, ptrBuf); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->cryptoKeyId, &ptrBuf[4]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->secondaryCryptoKeyId, &ptrBuf[8]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->keyElementId, &ptrBuf[12]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->secondaryKeyElementId, &ptrBuf[16]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->inputOutput.keyElementSourceOffset, &ptrBuf[20]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->inputOutput.keyElementTargetOffset, &ptrBuf[24]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(keyMJobPtr->inputOutput.keyElementCopyLength, &ptrBuf[28]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + retVal = E_OK; + + CRYPTO_30_VHSM_DUMMY_STATEMENT(jobRequestId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + return retVal; +} /* Crypto_30_vHsm_SerializeRequest_KeyMJob_CopyPartial() */ + +# if (CRYPTO_30_VHSM_KEY_DERIVE_JOB_SUPPORT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob_KeyDerive() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob_KeyDerive( + Crypto_30_vHsm_JobRequestIterType jobRequestId, /* PRQA S 3206 */ /* MD_CRYPTO_30_VHSM_UNUSED_PARAMETER */ + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf) +{ + Std_ReturnType retVal; + + /* ----- Implementation ----------------------------------------------- */ + /* #05 Prepare verifyPtr */ + *Crypto_30_vHsm_GetAddrVerifyPtrDataBuffer(jobRequestId) = 0xFEu; /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + + Crypto_30_vHsm_Serialize_Uint32(Crypto_30_vHsm_GetJobStateOfJobRequest(jobRequestId), ptrBuf); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + /* #10 Serialization of key derive job */ + /* PRQA S 0310, 3305 8 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.mode, &ptrBuf[4]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.family, &ptrBuf[8]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.mode, &ptrBuf[12]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobPrimitiveInfo->primitiveInfo->algorithm.secondaryFamily, &ptrBuf[16]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(Crypto_30_vHsm_GetProcessingTypeOfJobRequest(jobRequestId), &ptrBuf[20]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->jobInfo->jobId, &ptrBuf[24]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->targetCryptoKeyId, &ptrBuf[28]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + Crypto_30_vHsm_Serialize_Uint32(cryptoJobPtr->cryptoKeyId, &ptrBuf[32]); /* SBSW_CRYPTO_30_VHSM_IPC_SERIALIZE_UINT32 */ + + retVal = E_OK; + + return retVal; +} /* Crypto_30_vHsm_SerializeRequest_CryptoJob_KeyDerive() */ +# endif /* (CRYPTO_30_VHSM_KEY_DERIVE_JOB_SUPPORT == STD_ON) */ +#endif /* (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2) */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ReceiveResponse_CryptoJob() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ + /* PRQA S 6030, 6080 1 */ /* MD_MSR_STMIF, MD_MSR_STCYC */ +FUNC( void, CRYPTO_30_VHSM_CODE ) Crypto_30_vHsm_ReceiveResponse_CryptoJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + uint32 jobResponseData, +#endif + Crypto_30_vHsm_JobResponseBufferPtrType jobResponseBuffer) /* PRQA S 3673 */ /* MD_CRYPTO_30_VHSM_3673_API_SPECIFIC */ +{ + /* ----- Local Variables ---------------------------------------------- */ + Crypto_30_vHsm_CryptoJobPtr jobTmp; /* PRQA S 3679 */ /* MD_CRYPTO_30_VHSM_3679_JOB_POINTER_AS_VAR */ + Std_ReturnType jobResult; + + /* ----- Implementation ----------------------------------------------- */ + jobTmp = Crypto_30_vHsm_GetCryptoJobOfJobRequest(jobRequestId); + + /* #20 Deserialize job request */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + Crypto_30_vHsm_GetJobStateOfJobRequest(jobRequestId) = (Crypto_JobStateType)Crypto_30_vHsm_Deserialize_Uint32(&jobResponseBuffer[4]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR_WITH_BUFFER */ + jobResult = (uint8)Crypto_30_vHsm_Deserialize_Uint32(&jobResponseBuffer[8]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ + Crypto_30_vHsm_SetResultOfJobRequest(jobRequestId, jobResult); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#else + *Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId) = Crypto_30_vHsm_Deserialize_Uint32(jobResponseBuffer); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + *Crypto_30_vHsm_GetAddrSecondaryOutputLengthPtrDataBuffer(jobRequestId) = Crypto_30_vHsm_Deserialize_Uint32(&jobResponseBuffer[4]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + *Crypto_30_vHsm_GetAddrVerifyPtrDataBuffer(jobRequestId) = (Crypto_VerifyResultType)Crypto_30_vHsm_Deserialize_Uint32(&jobResponseBuffer[8]); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetJobStateOfJobRequest(jobRequestId, (uint8)(jobResponseData >> CRYPTO_30_VHSM_JOBRESPONSE_STATE_BITPOSITION)); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + jobResult = (uint8)(jobResponseData >> CRYPTO_30_VHSM_JOBRESPONSE_RESULT_BITPOSITION); + Crypto_30_vHsm_SetResultOfJobRequest(jobRequestId, jobResult); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#endif /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) */ + + /* #30 Get result of job request */ + /* Info: If the job result was CRYPTO_E_SMALL_BUFFER although a big enough buffer has been provided by the application, make sure that the shared buffer of the driver object is configured big enough. + * It may have been the case that the application provided a buffer not readable by the vHsm. The CRYPTO driver then provides a valid buffer which may be smaller than the original one to the vHsm. + */ + if (E_OK == jobResult) + { + /* Check if the job contains an output */ + if (((((Crypto_30_vHsm_JobIOAvailable[jobTmp->jobPrimitiveInfo->primitiveInfo->service] & CRYPTO_30_VHSM_IO_OUTPUT) == CRYPTO_30_VHSM_IO_OUTPUT) +#if (CRYPTO_30_VHSM_SUPPORT_SAVE_RESTORE_CONTEXT == STD_ON) + || ((jobTmp->jobPrimitiveInputOutput.mode & CRYPTO_OPERATIONMODE_SAVE_CONTEXT) == CRYPTO_OPERATIONMODE_SAVE_CONTEXT)) +#else + ) +#endif + && (Crypto_30_vHsm_IsCancelOfJobRequest(jobRequestId) == FALSE)) /* PRQA S 3415 */ /* MD_CRYPTO_30_VHSM_3415_LOGICAL_OPERATOR */ +#if (CRYPTO_30_VHSM_SUPPORT_SAVE_RESTORE_CONTEXT == STD_ON) + && ((jobTmp->jobPrimitiveInputOutput.mode & CRYPTO_OPERATIONMODE_RESTORE_CONTEXT) != CRYPTO_OPERATIONMODE_RESTORE_CONTEXT)) +#else + ) +#endif + { + if ((jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr != NULL_PTR) + && (jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr != NULL_PTR)) + { +#if (CRYPTO_30_VHSM_READWRITE_AVAILABLE == STD_ON) /* COV_CRYPTO_30_VHSM_READWRITE_AVAILABLE */ + /* Check if the vHsm has written the output to the buffer instead of the original pointer provided within the job */ + if (Crypto_30_vHsm_GetOutputOffsetOfJobRequest(jobRequestId) != CRYPTO_30_VHSM_OUTPUT_BUFFER_NOT_USED) +#else +# if (CRYPTO_30_VHSM_NOBUFFERING_ENABLED == STD_ON) /* COV_CRYPTO_30_VHSM_NOBUFFERING_ENABLED */ + if (Crypto_30_vHsm_IsBufferUsedOfObjectInfo(jobRequestId) == TRUE) +# endif +#endif /* !(CRYPTO_30_VHSM_READWRITE_AVAILABLE == STD_ON) */ + { + /* Check if the vHsm produced a bigger result than the buffer provided by the application */ + if (*Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId) > *jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr) + { + /* Set the length to a safe value to avoid memory corruptions. This should never happen and indicates a wrong behaviour of the vHsm Firmware. */ + *Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId) = 0u; /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetResultOfJobRequest(jobRequestId, E_NOT_OK); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + else + { + /* #40 Copy output to local job object (only if available for service, not for cancel or restore context) */ + VStdLib_MemCpy(jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputPtr, Crypto_30_vHsm_GetAddrSharedDataBufferOfDriverObject(jobRequestId, Crypto_30_vHsm_GetOutputOffsetOfJobRequest(jobRequestId)), *Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_VHSM_COPY_TO_DESTINATION_FROM_GLOBAL_BUFFER */ + } + } + /* Copy the length value to the original destination provided within the job */ + *jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.outputLengthPtr = *Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId); /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + } + + /* Check if the job contains a secondary output */ + /* This will only be the case when a primary output is available. There are no jobs with a secondary output but no primary output. */ + if ((((Crypto_30_vHsm_JobIOAvailable[jobTmp->jobPrimitiveInfo->primitiveInfo->service] & CRYPTO_30_VHSM_IO_SECONDARYOUTPUT) == CRYPTO_30_VHSM_IO_SECONDARYOUTPUT) + && (jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr != NULL_PTR) + && (jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputPtr != NULL_PTR)) +#if (CRYPTO_30_VHSM_SUPPORT_SAVE_RESTORE_CONTEXT == STD_ON) + && ((jobTmp->jobPrimitiveInputOutput.mode & CRYPTO_OPERATIONMODE_SAVE_CONTEXT) != CRYPTO_OPERATIONMODE_SAVE_CONTEXT)) +#else + ) +#endif + { +#if (CRYPTO_30_VHSM_READWRITE_AVAILABLE == STD_ON) /* COV_CRYPTO_30_VHSM_READWRITE_AVAILABLE */ + /* Check if the vHsm has written the output to the buffer instead of the original pointer provided within the job */ + if (Crypto_30_vHsm_GetSecondaryOutputOffsetOfJobRequest(jobRequestId) != CRYPTO_30_VHSM_OUTPUT_BUFFER_NOT_USED) +#else +# if (CRYPTO_30_VHSM_NOBUFFERING_ENABLED == STD_ON) /* COV_CRYPTO_30_VHSM_NOBUFFERING_ENABLED */ + if (Crypto_30_vHsm_IsBufferUsedOfObjectInfo(jobRequestId) == TRUE) +# endif +#endif /* !(CRYPTO_30_VHSM_READWRITE_AVAILABLE == STD_ON) */ + { + /* Check if the vHsm produced a bigger result than the buffer provided by the application */ + if (*Crypto_30_vHsm_GetAddrSecondaryOutputLengthPtrDataBuffer(jobRequestId) > *jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr) + { + /* Set the length to a safe value to avoid memory corruptions. This should never happen and indicates a wrong behaviour of the vHsm Firmware. */ + *Crypto_30_vHsm_GetAddrSecondaryOutputLengthPtrDataBuffer(jobRequestId) = 0u; /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetResultOfJobRequest(jobRequestId, E_NOT_OK); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + else + { + /* #50 Copy secondary output to local job object (only if available for service, not for cancel or save or restore context) */ + VStdLib_MemCpy(jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputPtr, Crypto_30_vHsm_GetAddrSharedDataBufferOfDriverObject(jobRequestId, Crypto_30_vHsm_GetSecondaryOutputOffsetOfJobRequest(jobRequestId)), *Crypto_30_vHsm_GetAddrSecondaryOutputLengthPtrDataBuffer(jobRequestId)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_VHSM_COPY_TO_DESTINATION_FROM_GLOBAL_BUFFER */ + } + } + /* Copy the length value to the original destination provided within the job */ + *jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.secondaryOutputLengthPtr = *Crypto_30_vHsm_GetAddrSecondaryOutputLengthPtrDataBuffer(jobRequestId); /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + } + } + + /* Check if the default value has been overwritten which would indicate that the received value must be written to the provided verifyPtr */ + if (*Crypto_30_vHsm_GetAddrVerifyPtrDataBuffer(jobRequestId) != 0xFEu) + { + if (jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr != NULL_PTR) + { + /* #60 Copy verification pointer to local job object */ + *jobTmp->CRYPTO_30_VHSM_JOB_PRIMITIVE_INPUT_OUTPUT_MEMBER.verifyPtr = *Crypto_30_vHsm_GetAddrVerifyPtrDataBuffer(jobRequestId); /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + } + else + { + Crypto_30_vHsm_SetResultOfJobRequest(jobRequestId, E_NOT_OK); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + (void)Det_ReportError(CRYPTO_30_VHSM_MODULE_ID, CRYPTO_30_VHSM_INSTANCE_ID, CRYPTO_30_VHSM_SID_PROCESS_JOB, CRYPTO_E_PARAM_POINTER); +#endif + } + } + } +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + else + { + /* #70 Check for buffer replacement error */ + Crypto_30_vHsm_CheckBufferReplacementError(jobRequestId, jobResult, CRYPTO_E_SMALL_BUFFER); + } +#endif +} /* Crypto_30_vHsm_ReceiveResponse_CryptoJob() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ReceiveResponse_KeyMJob() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + */ +FUNC( void, CRYPTO_30_VHSM_CODE ) Crypto_30_vHsm_ReceiveResponse_KeyMJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + uint32 jobResponseData, +#endif + Crypto_30_vHsm_JobResponseBufferPtrType jobResponseBuffer) /* PRQA S 3673 */ /* MD_CRYPTO_30_VHSM_3673_API_SPECIFIC */ +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType jobResult; + Crypto_30_vHsm_KeyMJobPtr jobTmp; /* PRQA S 3679 */ /* MD_CRYPTO_30_VHSM_3679_JOB_POINTER_AS_VAR */ + + /* ----- Implementation ----------------------------------------------- */ + + /* #20 Deserialize job request */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + jobResult = (uint8)Crypto_30_vHsm_Deserialize_Uint32(jobResponseBuffer); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ + Crypto_30_vHsm_SetResultOfJobRequest(jobRequestId, jobResult);/* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#else + *Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId) = Crypto_30_vHsm_Deserialize_Uint32(jobResponseBuffer); /* PRQA S 0310, 3305 */ /* MD_CRYPTO_30_VHSM_SERIALIZATION_MACRO */ /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + jobResult = (uint8)(jobResponseData >> CRYPTO_30_VHSM_JOBRESPONSE_RESULT_BITPOSITION); + Crypto_30_vHsm_SetResultOfJobRequest(jobRequestId, jobResult); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#endif /* !(CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) */ + + /* Copy the data only from the buffer to the destination if the job was successful */ + if (E_OK == jobResult) + { + jobTmp = Crypto_30_vHsm_GetKeyMJobOfJobRequest(jobRequestId); + + /* Check if the job contains an output */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + if (((Crypto_30_vHsm_KeyMIOAvailable[jobTmp->action] & CRYPTO_30_VHSM_IO_OUTPUT) == CRYPTO_30_VHSM_IO_OUTPUT) && +#else + if( +#endif + (jobTmp->inputOutput.outputLengthPtr != NULL_PTR) + && (jobTmp->inputOutput.outputPtr != NULL_PTR)) + { +#if (CRYPTO_30_VHSM_READWRITE_AVAILABLE == STD_ON) /* COV_CRYPTO_30_VHSM_READWRITE_AVAILABLE */ + /* Check if the vHsm has written the output to the buffer instead of the original pointer provided within the job */ + if (Crypto_30_vHsm_GetOutputOffsetOfJobRequest(jobRequestId) != CRYPTO_30_VHSM_OUTPUT_BUFFER_NOT_USED) +#endif + { + /* Check if the vHsm produced a bigger result than the buffer provided by the application */ + if (*Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId) > *jobTmp->inputOutput.outputLengthPtr) + { + /* Set the length to a safe value to avoid memory corruptions. This should never happen and indicates a wrong behaviour of the vHsm Firmware. */ + *Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId) = 0u; /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetResultOfJobRequest(jobRequestId, E_NOT_OK); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + else + { + /* #30 Copy output to local job object */ + VStdLib_MemCpy(jobTmp->inputOutput.outputPtr, Crypto_30_vHsm_GetAddrSharedDataBufferOfDriverObject(jobRequestId, Crypto_30_vHsm_GetOutputOffsetOfJobRequest(jobRequestId)), *Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId)); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_VHSM_COPY_TO_DESTINATION_FROM_GLOBAL_BUFFER */ + } + } + /* Copy the length value to the original destination provided within the job */ + *jobTmp->inputOutput.outputLengthPtr = *Crypto_30_vHsm_GetAddrOutputLengthPtrDataBuffer(jobRequestId); /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + } + } +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + else + { + /* #70 Check for buffer replacement error */ + Crypto_30_vHsm_CheckBufferReplacementError(jobRequestId, jobResult, CRYPTO_E_KEY_SIZE_MISMATCH); + } +#endif +} /* Crypto_30_vHsm_ReceiveResponse_KeyMJob() */ + +#define CRYPTO_30_VHSM_STOP_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/********************************************************************************************************************** + * END OF FILE: Crypto_30_vHsm_Jobs.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Jobs.h b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Jobs.h new file mode 100644 index 0000000..84364e0 --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Jobs.h @@ -0,0 +1,257 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_vHsm_Jobs.h + * \brief Vector Hardware Security Module Firmware Jobs + * + * \details Implementation of the Vector Hardware Security Module Firmware Jobs + * + *********************************************************************************************************************/ + + /********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_VHSM_JOBS_H) +# define CRYPTO_30_VHSM_JOBS_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_vHsm.h" + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ +# define Crypto_30_vHsm_GetAddrSharedDataBufferOfDriverObject(objectId, usedBuffer) (&((P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA))Crypto_30_vHsm_GetAddrSharedDataBuffer(Crypto_30_vHsm_GetSharedDataBufferStartIdxOfObjectInfo(objectId)))[(usedBuffer)]) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ +# define Crypto_30_vHsm_GetSharedDataBufferSizeOfDriverObject(objectId) ((uint32)(((uint32)Crypto_30_vHsm_GetSharedDataBufferEndIdxOfObjectInfo(objectId) - (uint32)Crypto_30_vHsm_GetSharedDataBufferStartIdxOfObjectInfo(objectId))*(uint32)4uL)) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +# define CRYPTO_30_VHSM_START_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ReceiveResponse_CryptoJob() + *********************************************************************************************************************/ +/*! + * \brief Receive crypto job response. + * \details - + * \param[in] jobRequestId Valid job request Id + * \param[in] jobResponseData Data containing concatenated information of the job response like the retval and state + * \param[in] jobResponseBuffer Valid job response buffer with at least CRYPTO_30_VHSM_CRYPTO_JOBRESULTTYPE_DESERIALIZED_BUF_SIZE bytes of storage + * \pre - + * \context TASK, ISR2 + * \reentrant FALSE + * \synchronous TRUE + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ReceiveResponse_CryptoJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + uint32 jobResponseData, +# endif + Crypto_30_vHsm_JobResponseBufferPtrType jobResponseBuffer); + +/********************************************************************************************************************** + * Crypto_30_vHsm_ReceiveResponse_KeyMJob() + *********************************************************************************************************************/ +/*! + * \brief Receive key management job response. + * \details - + * \param[in] jobRequestId Valid job request Id + * \param[in] jobResponseData Data containing concatenated information of the job response like the retval + * \param[in] jobResponseBuffer Valid job response buffer with at least CRYPTO_30_VHSM_KEYM_JOBRESULTTYPE_DESERIALIZED_BUF_SIZE bytes of storage + * \pre - + * \context TASK, ISR2 + * \reentrant FALSE + * \synchronous TRUE + */ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ReceiveResponse_KeyMJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + uint32 jobResponseData, +# endif + Crypto_30_vHsm_JobResponseBufferPtrType jobResponseBuffer); + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob() + *********************************************************************************************************************/ +/*! + * \brief Serialization of a crypto job + * \details - + * \param[in] jobRequestId Valid jobRequestId + * \param[in] cryptoJobPtr Valid pointer to job object + * \param[in,out] ptrBuf Valid pointer to buffer where the crypto job will be serialized. + * Must be at least of size 80. + * \param[in,out] jobRedirectionInfoPtr Valid pointer to the redirection info. + * The availability of this parameter depends on the configuration. + * \return E_OK if no errors occurred, otherwise E_NOT_OK. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +# if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr +# endif + ); + +# if (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob_MacGen() + *********************************************************************************************************************/ +/*! + * \brief Serialization of a crypto job + * \details - + * \param[in] jobRequestId Valid jobRequestId + * \param[in] cryptoJobPtr Valid pointer to job object + * \param[in,out] ptrBuf Valid pointer to buffer where the crypto job will be serialized. + * Must be at least of size 44. + * \param[in,out] jobRedirectionInfoPtr Valid pointer to the redirection info. + * The availability of this parameter depends on the configuration. + * \return E_OK if no errors occurred, otherwise E_NOT_OK. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob_MacGen( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +# if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr +# endif + ); +# endif /* (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION == STD_ON) */ + +# if (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob_MacVer() + *********************************************************************************************************************/ +/*! + * \brief Serialization of a crypto job + * \details - + * \param[in] jobRequestId Valid jobRequestId + * \param[in] cryptoJobPtr Valid pointer to job object + * \param[in,out] ptrBuf Valid pointer to buffer where the crypto job will be serialized. + * Must be at least of size 48. + * \param[in,out] jobRedirectionInfoPtr Valid pointer to the redirection info. + * The availability of this parameter depends on the configuration. + * \return E_OK if no errors occurred, otherwise E_NOT_OK. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob_MacVer( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf +# if (CRYPTO_30_VHSM_REDIRECTION == STD_ON) +, P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRedirectionInfoPtr +# endif + ); +# endif /* (CRYPTO_30_VHSM_IPC_MAC_JOB_OPTIMIZATION == STD_ON) */ + +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2) +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_KeyMJob_CopyPartial() + *********************************************************************************************************************/ +/*! + * \brief Serialization of a key management job for key element copy partial + * \details - + * \param[in] jobRequestId Valid jobRequestId + * \param[in] keyMJobPtr Valid pointer to job result object + * \param[in,out] ptrBuf Valid pointer to buffer where the key job will be serialized. + * Must be at least of size 32. + * \return E_OK if no errors occurred, otherwise E_NOT_OK. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_KeyMJob_CopyPartial( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_30_vHsm_KeyM_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) keyMJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf); + +# if (CRYPTO_30_VHSM_KEY_DERIVE_JOB_SUPPORT == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_CryptoJob_KeyDerive() + *********************************************************************************************************************/ +/*! + * \brief Serialization of a key derive job + * \details - + * \param[in] jobRequestId Valid jobRequestId + * \param[in] cryptoJobPtr Valid pointer to job object + * \param[in,out] ptrBuf Valid pointer to buffer where the crypto job will be serialized. + * Must be at least of size 36. + * \return E_OK if no errors occurred, otherwise E_NOT_OK. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_CryptoJob_KeyDerive( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) cryptoJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf); +# endif /* (CRYPTO_30_VHSM_KEY_DERIVE_JOB_SUPPORT == STD_ON) */ +# endif /* (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2) */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_SerializeRequest_KeyMJob() + *********************************************************************************************************************/ +/*! + * \brief Serialization of a key management job + * \details - + * \param[in] jobRequestId Valid jobRequestId + * \param[in] keyMJobPtr Valid pointer to job result object + * \param[in,out] ptrBuf Valid pointer to buffer where the key job will be serialized. + * Must be at least of size 36. + * \return E_OK if no errors occurred, otherwise E_NOT_OK. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_SerializeRequest_KeyMJob( + Crypto_30_vHsm_JobRequestIterType jobRequestId, + P2CONST(Crypto_30_vHsm_KeyM_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) keyMJobPtr, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) ptrBuf); + +# define CRYPTO_30_VHSM_STOP_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CRYPTO_30_VHSM_JOBS_H) */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_vHsm_Jobs.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_KeyManagement.c b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_KeyManagement.c new file mode 100644 index 0000000..b4ec5d2 --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_KeyManagement.c @@ -0,0 +1,1547 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_vHsm_KeyManagement.c + * \brief MICROSAR vHsm Crypto Driver (Crypto) + * + * \details Implementation of the MICROSAR Crypto Driver (Crypto) + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_KEYMANAGEMENT_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Crypto_30_vHsm.h" +#include "Crypto_30_vHsm_Ipc.h" +#include "SchM_Crypto_30_vHsm.h" + +#include "vstdlib.h" +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) +# include "Det.h" +#endif + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_KEYM_JOBID_MASK (0xFF000000u) + +/********************************************************************************************************************** + * LOCAL FUNCTION MACROS + *********************************************************************************************************************/ +#if !defined (CRYPTO_30_VHSM_LOCAL) /* COV_CRYPTO_30_VHSM_LOCAL_DEFINE */ +# define CRYPTO_30_VHSM_LOCAL static +#endif + +#if !defined (CRYPTO_30_VHSM_LOCAL_INLINE) /* COV_CRYPTO_30_VHSM_LOCAL_DEFINE */ +# define CRYPTO_30_VHSM_LOCAL_INLINE LOCAL_INLINE +#endif + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ProcessKeyMJob() + *********************************************************************************************************************/ +/*! \brief Process key management job + * \details Check if vHsm is busy, otherwise execute job + * \param[in] keyMJob Pointer to a valid KeyM job structure. + * \param[in] partitionIdx Valid identifier of the partition. + * \return E_OK Process job successful. + * E_NOT_OK Process job failed. + * \pre - + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ProcessKeyMJob( + P2VAR(Crypto_30_vHsm_KeyM_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) keyMJob, + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_vHsm_AllocateKeyMJob() + *********************************************************************************************************************/ +/*! \brief Find a free job request Id + * \details Locking the driver object has to be done outside this function. + * \param[out] jobRequestIdPtr Pointer to a free jobRequestId which is the same as a free driver object + * \param[in] partitionIdx Valid identifier of the partition. + * \return E_OK Free management driver object has been found + * E_NOT_OK No free management driver objects available + * \pre - + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_AllocateKeyMJob( + P2VAR(Crypto_30_vHsm_JobRequestIterType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRequestIdPtr, + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_vHsm_ReadStatusRegister() + *********************************************************************************************************************/ +/*! \brief Read status register + * \details Read from a given register address into an uint8 array. + * \param[in] registerAddress Address of status register + * \param[out] destPtr Pointer to destination array + * \param[in,out] destLengthPtr Length pointer of the destination array + * \return E_OK Status information are available + * E_NOT_OK Status information could not be stored + * \pre - + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ReadStatusRegister( + uint32 registerAddress, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) destPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) destLengthPtr); + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#define CRYPTO_30_VHSM_START_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_AllocateKeyMJob() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL_INLINE FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_AllocateKeyMJob( + P2VAR(Crypto_30_vHsm_JobRequestIterType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) jobRequestIdPtr, + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ + Std_ReturnType retVal = E_NOT_OK; + Crypto_30_vHsm_KeyMgmObjIterType mngObjectIdx; + + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_0(); + + /* #10 Iterate oder all management driver object references */ + for (mngObjectIdx = 0u; mngObjectIdx < Crypto_30_vHsm_GetSizeOfKeyMgmObj(); mngObjectIdx++) + { + Crypto_30_vHsm_JobRequestIterType jobRequestIdTmp = Crypto_30_vHsm_GetObjectInfoIdxOfKeyMgmObj(mngObjectIdx); + /* #30 Check if the driver object is currently not used */ + if( (Crypto_30_vHsm_GetDriverObjectLock(jobRequestIdTmp) == CRYPTO_30_VHSM_ACCEPT_ANY_JOBID) + && (Crypto_30_vHsm_IsLockOfJobRequest(jobRequestIdTmp) == FALSE) /* PRQA S 3415 */ /* MD_CRYPTO_30_VHSM_3415_LOGICAL_OPERATOR */ +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES > 1u) + && (Crypto_30_vHsm_GetCurrentPartitionIdxOfObjectInfo(jobRequestIdTmp) == partitionIdx) /* Check if that KeyM driver object can be used for the current partition */ +#endif + ) + { + Crypto_30_vHsm_SetDriverObjectLock(jobRequestIdTmp, (CRYPTO_30_VHSM_KEYM_JOBID_MASK | jobRequestIdTmp)); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetLockOfJobRequest(jobRequestIdTmp, TRUE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + *jobRequestIdPtr = jobRequestIdTmp; /* SBSW_CRYPTO_30_VHSM_VARIABLE_ACCESS_PTR_FROM_STACK */ + retVal = E_OK; + break; + } + } + + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_0(); + +#if (CRYPTO_30_VHSM_NUMBER_OF_IPC_INSTANCES < 2u) + CRYPTO_30_VHSM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + /* #40 Return if a free driver object has been found */ + return retVal; +} /* Crypto_30_vHsm_AllocateKeyMJob() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ProcessKeyMJob() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ProcessKeyMJob( + P2VAR(Crypto_30_vHsm_KeyM_JobType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) keyMJob, + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal; + + Crypto_30_vHsm_JobRequestIterType jobRequestId = 0u; + + /* ----- Implementation ----------------------------------------------- */ + if(Crypto_30_vHsm_AllocateKeyMJob(&jobRequestId, partitionIdx) == E_OK) /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + { + if (keyMJob->action == CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTCOPYPARTIAL) + { + Crypto_30_vHsm_SetKindOfJobRequest(jobRequestId, CRYPTO_30_VHSM_KEYMANAGEMENT_COPY_PARTIAL_JOBKIND); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + else + { + Crypto_30_vHsm_SetKindOfJobRequest(jobRequestId, CRYPTO_30_VHSM_KEYMANAGEMENT_JOBKIND); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + } + Crypto_30_vHsm_SetKeyMJobOfJobRequest(jobRequestId, keyMJob); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetCancelOfJobRequest(jobRequestId, FALSE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetProcessingTypeOfJobRequest(jobRequestId, CRYPTO_PROCESSING_SYNC); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_SetContextClassOfJobRequest(jobRequestId, CRYPTO_30_VHSM_CALLOUT_KEYMJOB); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + Crypto_30_vHsm_SetContextIdOfJobRequest(jobRequestId, Crypto_30_vHsm_GetKeyMJobOfJobRequest(jobRequestId)->cryptoKeyId); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ +#endif + + retVal = Crypto_30_vHsm_ProcessJobRequest(jobRequestId, partitionIdx); + + if (retVal == E_OK) + { + retVal = (Std_ReturnType)Crypto_30_vHsm_GetResultOfJobRequest(jobRequestId); + } + +#if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) + if (Crypto_30_vHsm_GetStateOfJobRequest(jobRequestId) != CRYPTO_30_VHSM_JOBREQUEST_STATE_TIMEOUT) +#endif + { + Crypto_30_vHsm_SetLockOfJobRequest(jobRequestId, FALSE); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + SchM_Enter_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_2(); + Crypto_30_vHsm_SetDriverObjectLock(jobRequestId, CRYPTO_30_VHSM_ACCEPT_ANY_JOBID); /* SBSW_CRYPTO_30_VHSM_CSL02_OBJECTINFO */ + SchM_Exit_Crypto_30_vHsm_CRYPTO_30_VHSM_EXCLUSIVE_AREA_2(); + } + } + else + { + retVal = CRYPTO_E_BUSY; + } + + return retVal; +} /* Crypto_30_vHsm_ProcessKeyMJob() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_ReadStatusRegister() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + */ +CRYPTO_30_VHSM_LOCAL FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_ReadStatusRegister( + uint32 registerAddress, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) destPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) destLengthPtr) +{ + Std_ReturnType retVal = E_NOT_OK; + uint32 regVal; + + if (*destLengthPtr >= 4u) + { + regVal = *(volatile P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR))registerAddress; /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ + + VStdLib_MemCpy(destPtr, ®Val, 4u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + + *destLengthPtr = 4u; /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + + retVal = E_OK; + } + return retVal; +} /* Crypto_30_vHsm_ReadStatusRegister() */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyElementIdsGet() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyElementIdsGet( + uint32 cryptoKeyId, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) keyElementIdsPtr, /* PRQA S 3673 */ /* MD_CRYPTO_30_VHSM_3673_API_SPECIFIC */ + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) keyElementIdsLengthPtr) /* PRQA S 3673 */ /* MD_CRYPTO_30_VHSM_3673_API_SPECIFIC */ +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00161] */ + errorId = CRYPTO_E_UNINIT; + } + else if (keyElementIdsPtr == NULL_PTR) + { + /* [SWS_Crypto_00162] */ + errorId = CRYPTO_E_PARAM_HANDLE; + } + else if (keyElementIdsLengthPtr == NULL_PTR) + { + errorId = CRYPTO_E_PARAM_HANDLE; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTIDSGET; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.secondaryCryptoKeyId = 0u; + + /* Set rest of parameters to default values */ + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; +#endif + keyMJob.inputOutput.outputPtr = (P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR))keyElementIdsPtr; /* PRQA S 0310 */ /* MD_CRYPTO_30_VHSM_0310_KEYELEMENT_CONTENT */ + keyMJob.inputOutput.outputLengthPtr = keyElementIdsLengthPtr; + + /* Multiply by 4 because given length is the number of uint32 elements. This way, there is no special handling in the IPC, because the length is now the number of bytes. */ + *keyElementIdsLengthPtr = (uint32)(*keyElementIdsLengthPtr * sizeof(uint32)); /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + + /* Divide by 4 because length should be the number of uint32 elements. This way, there is no special handling in the IPC. */ + *keyElementIdsLengthPtr = (uint32)(*keyElementIdsLengthPtr / sizeof(uint32)); /* SBSW_CRYPTO_30_VHSM_PTR_ACCESS_WITH_DET_CHECK */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_ELEMENT_IDS_GET, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + CRYPTO_30_VHSM_DUMMY_STATEMENT(cryptoKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + return retVal; +} /* Crypto_30_vHsm_KeyElementIdsGet() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyCopy() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyCopy( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Check plausibility of input parameters */ + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00156] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + /* #20 Set the parameters inside the job needed for this command */ + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYCOPY; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.secondaryCryptoKeyId = targetCryptoKeyId; + + /* #21 Set rest of parameters to default values */ + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; + keyMJob.inputOutput.outputPtr = NULL_PTR; + keyMJob.inputOutput.outputLengthPtr = NULL_PTR; +#endif + + /* #22 Execute the job */ + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + /* #30 Report Det if error happened */ + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_COPY, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_KeyCopy() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyElementCopy() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyElementCopy( + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 targetCryptoKeyId, + uint32 targetKeyElementId) +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00149] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTCOPY; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.keyElementId = keyElementId; + keyMJob.secondaryCryptoKeyId = targetCryptoKeyId; + keyMJob.secondaryKeyElementId = targetKeyElementId; + + /* Set rest of parameters to default values */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; + keyMJob.inputOutput.outputPtr = NULL_PTR; + keyMJob.inputOutput.outputLengthPtr = NULL_PTR; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_ELEMENT_COPY, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + return retVal; +} /* Crypto_30_vHsm_KeyElementCopy() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyElementCopyPartial() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ + /* PRQA S 6060 1 */ /* MD_MSR_STPAR */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyElementCopyPartial( + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetCryptoKeyId, + uint32 targetKeyElementId) +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00149] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTCOPYPARTIAL; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.keyElementId = keyElementId; + keyMJob.secondaryCryptoKeyId = targetCryptoKeyId; + keyMJob.secondaryKeyElementId = targetKeyElementId; + keyMJob.inputOutput.keyElementCopyLength = keyElementCopyLength; + keyMJob.inputOutput.keyElementSourceOffset = keyElementSourceOffset; + keyMJob.inputOutput.keyElementTargetOffset = keyElementTargetOffset; + + /* Set rest of parameters to default values */ +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; + keyMJob.inputOutput.outputPtr = NULL_PTR; + keyMJob.inputOutput.outputLengthPtr = NULL_PTR; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_ELEMENT_COPY_PARTIAL, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + return retVal; +} /* Crypto_30_vHsm_KeyElementCopyPartial() */ + +/* [SWS_Crypto_91004] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyElementSet() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ + /* PRQA S 6030, 6080 1 */ /* MD_MSR_STCYC, MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyElementSet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) keyPtr, + uint32 keyLength) +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + errorId = CRYPTO_E_UNINIT; /* [SWS_Crypto_00075] */ + } + else if (keyPtr == NULL_PTR) + { + errorId = CRYPTO_E_PARAM_POINTER; /* [SWS_Crypto_00078] */ + } +# if (CRYPTO_30_VHSM_KEY_ELEMENT_DELETE_SUPPORT == STD_OFF) + else if (keyLength == 0u) + { + errorId = CRYPTO_E_PARAM_VALUE; /* [SWS_Crypto_00079] */ + } +# endif + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* Check if HOST2HSM register shall be set */ + if (keyElementId == CRYPTO_KE_CUSTOM_VHSM_STATUS_HOST2HSM) + { + if (keyLength == 4u) + { + uint32 regVal; + + VStdLib_MemCpy(®Val, keyPtr, 4u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + *(volatile P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR))CRYPTO_30_VHSM_HOST2_HSM_ADDRESS = regVal; /* PRQA S 0303 */ /* MD_CRYPTO_30_VHSM_REGISTER_ACCESS */ /* SBSW_CRYPTO_30_VHSM_REGISTER_ACCESS */ + + retVal = E_OK; + } + } + /* Otherwise process KeyMJob to HSM */ + else + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTSET; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.keyElementId = keyElementId; + keyMJob.inputOutput.inputPtr = keyPtr; + keyMJob.inputOutput.inputLength = keyLength; + + /* Set rest of parameters to default values */ + keyMJob.secondaryCryptoKeyId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.outputPtr = NULL_PTR; + keyMJob.inputOutput.outputLengthPtr = NULL_PTR; +#endif + + /* Check if the code flash operation has finished */ + if ((keyElementId == CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION) + && (keyLength == 1u) + && (keyPtr[0] == CRYPTO_30_VHSM_CODEFLASH_STOP)) + { + /* Indicate the end of the RAM execution */ + Crypto_30_vHsm_Ipc_EndRamExec(partitionIdx); /* PRQA S 0310, 3305, 4404 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* SBSW_CRYPTO_30_VHSM_SET_VALUE_IN_IPC */ + +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_Start_Callout( + CRYPTO_30_VHSM_CALLOUT_EXITRAMLOOP, + 0u, + CRYPTO_30_VHSM_CALLOUT_KEYMJOB, + cryptoKeyId); +#endif + + /* Wait until the vHsm indicates that it is not any longer running in the RAM loop. */ + while (Crypto_30_vHsm_Ipc_IsRamExec(partitionIdx) == TRUE) /* PRQA S 0310, 3305, 4340 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* FETA_CRYPTO_30_VHSM_WAIT_FOR_HSM_WITH_CALLOUT */ + { +#if (CRYPTO_30_VHSM_WAIT_LOOP_CALLOUT_ENABLED == STD_ON) + Crypto_30_vHsm_GetWaitLoopCallout()(); +#endif +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_Loop_Callout( + CRYPTO_30_VHSM_CALLOUT_EXITRAMLOOP, + 0u, + CRYPTO_30_VHSM_CALLOUT_KEYMJOB, + cryptoKeyId); +#endif + } +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_End_Callout( + CRYPTO_30_VHSM_CALLOUT_EXITRAMLOOP, + 0u, + CRYPTO_30_VHSM_CALLOUT_KEYMJOB, + cryptoKeyId); +#endif + } + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + + /* Check if this was the start of a code flash operation */ + if ((keyElementId == CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION) + && (keyLength == 1u) + && (keyPtr[0] == CRYPTO_30_VHSM_CODEFLASH_START) + && (retVal == E_OK)) + { +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_Start_Callout( + CRYPTO_30_VHSM_CALLOUT_ENTERRAMLOOP, + 0u, + CRYPTO_30_VHSM_CALLOUT_KEYMJOB, + cryptoKeyId); +#endif + /* Wait until the vHsm is in the RAM loop. */ + while (Crypto_30_vHsm_Ipc_IsRamExec(partitionIdx) != TRUE) /* PRQA S 0310, 3305, 4340 */ /* MD_CRYPTO_30_VHSM_IPC_MACRO */ /* FETA_CRYPTO_30_VHSM_WAIT_FOR_HSM_WITH_CALLOUT */ + { +#if (CRYPTO_30_VHSM_WAIT_LOOP_CALLOUT_ENABLED == STD_ON) + Crypto_30_vHsm_GetWaitLoopCallout()(); +#endif +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_Loop_Callout( + CRYPTO_30_VHSM_CALLOUT_ENTERRAMLOOP, + 0u, + CRYPTO_30_VHSM_CALLOUT_KEYMJOB, + cryptoKeyId); +#endif + } +#if (CRYPTO_30_VHSM_TIMEOUT_CALLOUT == STD_ON) + Crypto_30_vHsm_TimeoutDetect_End_Callout( + CRYPTO_30_VHSM_CALLOUT_ENTERRAMLOOP, + 0u, + CRYPTO_30_VHSM_CALLOUT_KEYMJOB, + cryptoKeyId); +#endif + } + } + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_ELEMENT_SET, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_KeyElementSet() */ + +/* [SWS_Crypto_91005] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyValidSet() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyValidSet( + uint32 cryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + errorId = CRYPTO_E_UNINIT; /* [SWS_Crypto_00082] */ + } + else +#endif + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYVALIDSET; + keyMJob.cryptoKeyId = cryptoKeyId; + + /* Set rest of parameters to default values */ + keyMJob.secondaryCryptoKeyId = 0u; + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; + keyMJob.inputOutput.outputPtr = NULL_PTR; + keyMJob.inputOutput.outputLengthPtr = NULL_PTR; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_VALID_SET, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_KeyValidSet() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_KeySetInvalid() + *********************************************************************************************************************/ + /*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeySetInvalid( + uint32 cryptoKeyId) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + errorId = CRYPTO_E_UNINIT; + } + else +#endif + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYSETINVALID; + keyMJob.cryptoKeyId = cryptoKeyId; + + /* Set rest of parameters to default values */ + keyMJob.secondaryCryptoKeyId = 0u; + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; + keyMJob.inputOutput.outputPtr = NULL_PTR; + keyMJob.inputOutput.outputLengthPtr = NULL_PTR; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_SET_INVALID, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_KeySetInvalid() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyGetStatus() + *********************************************************************************************************************/ + /*! + * + * Internal comment removed. + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyGetStatus( + uint32 cryptoKeyId, + P2VAR(Crypto_KeyStatusType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) keyStatusPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + errorId = CRYPTO_E_UNINIT; + } + else if (keyStatusPtr == NULL_PTR) + { + errorId = CRYPTO_E_PARAM_POINTER; + } + else +#endif + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + uint32 outputLength = sizeof(Crypto_KeyStatusType); + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYGETSTATUS; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.inputOutput.outputPtr = keyStatusPtr; + keyMJob.inputOutput.outputLengthPtr = &outputLength; + + /* Set rest of parameters to default values */ + keyMJob.secondaryCryptoKeyId = 0u; + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_GET_STATUS, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_KeyGetStatus() */ + +/* [SWS_Crypto_91006] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyElementGet() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ + /* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyElementGet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) resultLengthPtr) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00085] */ + errorId = CRYPTO_E_UNINIT; + } + else if (resultPtr == NULL_PTR) + { + /* [SWS_Crypto_00088] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (resultLengthPtr == NULL_PTR) + { + /* [SWS_Crypto_00089] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (*resultLengthPtr == 0u) + { + /* [SWS_Crypto_00090] */ + errorId = CRYPTO_E_PARAM_VALUE; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* Check if HOST2HSM register shall be read */ + if (keyElementId == CRYPTO_KE_CUSTOM_VHSM_STATUS_HOST2HSM) + { + retVal = Crypto_30_vHsm_ReadStatusRegister(CRYPTO_30_VHSM_HOST2_HSM_ADDRESS, resultPtr, resultLengthPtr); /* SBSW_CRYPTO_30_VHSM_FORWARDING_PTR */ + } + /* Check if HSM2HOST register shall be read */ + else if (keyElementId == CRYPTO_KE_CUSTOM_VHSM_STATUS_HSM2HOST) + { + retVal = Crypto_30_vHsm_ReadStatusRegister(CRYPTO_30_VHSM_HSM2_HOST_ADDRESS, resultPtr, resultLengthPtr); /* SBSW_CRYPTO_30_VHSM_FORWARDING_PTR */ + } + /* Otherwise process KeyMJob to HSM */ + else + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTGET; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.keyElementId = keyElementId; + keyMJob.inputOutput.outputPtr = resultPtr; + keyMJob.inputOutput.outputLengthPtr = resultLengthPtr; + + /* Set rest of parameters to default values */ + keyMJob.secondaryCryptoKeyId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_ELEMENT_GET, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_KeyElementGet() */ + +/* [SWS_Crypto_91013] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_RandomSeed() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_RandomSeed( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) entropyPtr, + uint32 entropyLength) +{ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00128] */ + errorId = CRYPTO_E_UNINIT; + } + else if (entropyPtr == NULL_PTR) + { + /* [SWS_Crypto_00130] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (entropyLength == 0u) + { + /* [SWS_Crypto_00131] */ + errorId = CRYPTO_E_PARAM_VALUE; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_RANDOMSEED; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.inputOutput.inputPtr = (P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA))entropyPtr; + keyMJob.inputOutput.inputLength = entropyLength; + + /* Set rest of parameters to default values */ + keyMJob.secondaryCryptoKeyId = 0u; + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.outputPtr = NULL_PTR; + keyMJob.inputOutput.outputLengthPtr = NULL_PTR; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_RANDOM_SEED, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_RandomSeed() */ + +/* [SWS_Crypto_91007] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyGenerate() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyGenerate( + uint32 cryptoKeyId) +{ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00094] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYGENERATE; + keyMJob.cryptoKeyId = cryptoKeyId; + + /* Set rest of parameters to default values */ + keyMJob.secondaryCryptoKeyId = 0u; + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; + keyMJob.inputOutput.outputPtr = NULL_PTR; + keyMJob.inputOutput.outputLengthPtr = NULL_PTR; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_GENERATE, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_KeyGenerate() */ + +/* [SWS_Crypto_91008] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyDerive() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyDerive( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId) +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00097] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYDERIVE; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.secondaryCryptoKeyId = targetCryptoKeyId; + + /* Set rest of parameters to default values */ + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; + keyMJob.inputOutput.outputPtr = NULL_PTR; + keyMJob.inputOutput.outputLengthPtr = NULL_PTR; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_DERIVE, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_KeyDerive() */ + +/* [SWS_Crypto_91009] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyExchangeCalcPubVal() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyExchangeCalcPubVal( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) publicValueLengthPtr) +{ + uint8 errorId = CRYPTO_E_NO_ERROR; + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00103] */ + errorId = CRYPTO_E_UNINIT; + } + else if (publicValuePtr == NULL_PTR) + { + /* [SWS_Crypto_00105] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (publicValueLengthPtr == NULL_PTR) + { + /* [SWS_Crypto_00106] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (*publicValueLengthPtr == 0u) + { + /* [SWS_Crypto_00107] */ + errorId = CRYPTO_E_PARAM_VALUE; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYEXCHANGECALCPUBVAL; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.inputOutput.outputPtr = publicValuePtr; + keyMJob.inputOutput.outputLengthPtr = publicValueLengthPtr; + + /* Set rest of parameters to default values */ + keyMJob.secondaryCryptoKeyId = 0u; + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_EXCHANGE_CALC_PUB_VAL, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_KeyExchangeCalcPubVal() */ + +/* [SWS_Crypto_91010] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyExchangeCalcSecret() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyExchangeCalcSecret( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00111] */ + errorId = CRYPTO_E_UNINIT; + } + else if (partnerPublicValuePtr == NULL_PTR) + { + /* [SWS_Crypto_00113] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else if (partnerPublicValueLength == 0u) + { + /* [SWS_Crypto_00115] */ + errorId = CRYPTO_E_PARAM_VALUE; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_KEYEXCHANGECALCSECRET; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.inputOutput.inputPtr = (P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA))partnerPublicValuePtr; + keyMJob.inputOutput.inputLength = partnerPublicValueLength; + + /* Set rest of parameters to default values */ + keyMJob.secondaryCryptoKeyId = 0u; + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.outputPtr = NULL_PTR; + keyMJob.inputOutput.outputLengthPtr = NULL_PTR; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_KEY_EXCHANGE_CALC_SECRET, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_KeyExchangeCalcSecret() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_CertificateParse() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_CertificateParse( + uint32 cryptoKeyId) +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00168] */ + errorId = CRYPTO_E_UNINIT; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_CERTIFICATEPARSE; + keyMJob.cryptoKeyId = cryptoKeyId; + + /* Set rest of parameters to default values */ + keyMJob.secondaryCryptoKeyId = 0u; + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; + keyMJob.inputOutput.outputPtr = NULL_PTR; + keyMJob.inputOutput.outputLengthPtr = NULL_PTR; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_CERTIFICATE_PARSE, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_CertificateParse() */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_CertificateVerify() + *********************************************************************************************************************/ +/*! + * + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_CertificateVerify( + uint32 cryptoKeyId, + uint32 verifyCryptoKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) verifyPtr) /* PRQA S 3673 */ /* MD_CRYPTO_30_VHSM_3673_API_SPECIFIC */ +{ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CRYPTO_E_NO_ERROR; + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx = Crypto_30_vHsm_GetCurrentPartitionIdx(); + + /* ----- Development Error Checks ------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) + if (Crypto_30_vHsm_GetPartitionInitialized(partitionIdx) != CRYPTO_30_VHSM_INITIALIZED) + { + /* [SWS_Crypto_00172] */ + errorId = CRYPTO_E_UNINIT; + } + else if (verifyPtr == NULL_PTR) + { + /* [SWS_Crypto_00175] */ + errorId = CRYPTO_E_PARAM_POINTER; + } + else +#endif /* (CRYPTO_30_VHSM_DEV_ERROR_DETECT == STD_ON) */ + { + Crypto_30_vHsm_KeyM_JobType keyMJob; + uint32 verifyLength = sizeof(Crypto_VerifyResultType); + + keyMJob.action = CRYPTO_30_VHSM_KEYM_ACTION_CERTIFICATEVERIFY; + keyMJob.cryptoKeyId = cryptoKeyId; + keyMJob.secondaryCryptoKeyId = verifyCryptoKeyId; + /* OutputPtr is used instead of verifyPtr which is not available for KeyM jobs in the IPC */ + keyMJob.inputOutput.outputLengthPtr = &verifyLength; + keyMJob.inputOutput.outputPtr = (P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR))verifyPtr; + + /* Set rest of parameters to default values */ + keyMJob.keyElementId = 0u; + keyMJob.secondaryKeyElementId = 0u; +#if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 2u) + keyMJob.inputOutput.inputPtr = NULL_PTR; + keyMJob.inputOutput.inputLength = 0u; +#endif + + retVal = Crypto_30_vHsm_ProcessKeyMJob(&keyMJob, partitionIdx); /* SBSW_CRYPTO_30_VHSM_STACK_VARIABLE_AS_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +#if (CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CRYPTO_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CRYPTO_30_VHSM_MODULE_ID, + CRYPTO_30_VHSM_INSTANCE_ID, + CRYPTO_30_VHSM_SID_CERTIFICATE_VERIFY, + errorId); + } +#else /* !(CRYPTO_30_VHSM_DEV_ERROR_REPORT == STD_ON) */ + CRYPTO_30_VHSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* Crypto_30_vHsm_CertificateVerify() */ + +#define CRYPTO_30_VHSM_STOP_SEC_CODE +#include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_vHsm_KeyManagement.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_KeyManagement.h b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_KeyManagement.h new file mode 100644 index 0000000..1b7a2be --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_KeyManagement.h @@ -0,0 +1,465 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_vHsm_KeyManagement.h + * \brief MICROSAR vHsm Crypto Driver (Crypto) + * + * \details Internal header file for service key management function prototypes + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_VHSM_KEYMANAGEMENT_H) +# define CRYPTO_30_VHSM_KEYMANAGEMENT_H +# include "Csm_Types.h" + +# define CRYPTO_30_VHSM_START_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyCopy() + *********************************************************************************************************************/ +/*! \brief Copy the key + * \details Copies a key with all its elements to another key in the same crypto driver. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] targetCryptoKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-131140 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyCopy( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyElementCopy() + *********************************************************************************************************************/ +/*! \brief Copy key element + * \details Copies a key element to another key element in the same crypto driver. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for the + * copy operation. + * \param[in] targetCryptoKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination for + * the copy operation. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_EXTRACT_DENIED Request failed, not allowed to extract key material. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-131141 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyElementCopy( + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 targetCryptoKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyElementCopyPartial() + *********************************************************************************************************************/ +/*! \brief Copy key element partial + * \details Copies a key element to another key element in the same crypto driver. The keyElementSourceOffset + * and keyElementCopyLength allows to copy just a part of the source key element into the destination. + * The offset of the target key is also specified with this function. + * The target key element needs to have partial access. + * The key element can only be copied, if the destination key element write access right is less than + * WA_INTERNAL_COPY. + * Additional the read access right of the source must be less than RA_INTERNAL_COPY and the destination + * read access right must be higher or equal than the source read access right. + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for the + * copy operation. + * \param[in] keyElementSourceOffset Holds the offset of the of the source key element indicating the start index + * of the copy operation. + * \param[in] keyElementTargetOffset Holds the offset of the of the target key element indicating the start index + * of the copy operation. + * \param[in] keyElementCopyLength Holds the number of bytes that shall be copied. + * \param[in] targetCryptoKeyId Holds the identifier of the key whose key element shall be the + * destination element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination for + * the copy operation. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element sizes are not compatible. + * CRYPTO_E_KEY_EMPTY Request failed, uninitialized source key element. + * \pre - + * \context TASK + * \reentrant TRUE, for different crypto keys + * \synchronous TRUE + * \trace CREQ-180788 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyElementCopyPartial( + uint32 cryptoKeyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetCryptoKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyElementIdsGet() + *********************************************************************************************************************/ +/*! \brief Used to retrieve information which key elements are available in a given key. + * \details - + * \param[in] cryptoKeyId Holds the identifier of the key whose available element ids shall be exported. + * \param[out] keyElementIdsPtr Contains the pointer to the array where the ids of the key + * elements shall be stored. + * \param[in,out] keyElementIdsLengthPtr Holds a pointer to the memory location in which the number of key element + * in the given key is stored. On calling this function, this parameter + * shall contain the size of the buffer provided by keyElementIdsPtr. When the + * request has finished, the actual number of key elements is stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-131139 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyElementIdsGet( + uint32 cryptoKeyId, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) keyElementIdsPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) keyElementIdsLengthPtr); + +/* [SWS_Crypto_91004] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyElementSet() + *********************************************************************************************************************/ +/*! \brief Sets a key element + * \details Sets the given key element bytes to the key identified by cryptoKeyId. . + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be set. + * \param[in] keyElementId Holds the identifier of the key element which shall be set. + * \param[in] keyPtr Holds the pointer to the key data which shall be set as key element. + * \param[in] keyLength Contains the length of the key element in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_WRITE_FAIL Request failed, write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the key element size does not match size of provided + * data. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-WaitLoopCallout, CREQ-131144 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyElementSet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) keyPtr, + uint32 keyLength); + +/* [SWS_Crypto_91005] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyValidSet() + *********************************************************************************************************************/ +/*! \brief Sets the key to valid + * \details Sets the key state of the key identified by cryptoKeyId to valid. + * \param[in] cryptoKeyId Holds the identifier of the key whose key elements shall be set to valid. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-131143 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyValidSet( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_vHsm_KeySetInvalid() + *********************************************************************************************************************/ +/*! \brief Sets the key to invalid + * \details Sets the key state of the key identified by cryptoKeyId to invalid. + * \param[in] cryptoKeyId Holds the identifier of the key whose key elements shall be set to invalid. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-KeySetInvalid + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeySetInvalid( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyGetStatus() + *********************************************************************************************************************/ +/*! \brief Returns the key state of the key identified by cryptoKeyId. + * \details - + * \param[in] cryptoKeyId Holds the identifier of the key for which the key state shall be returned. + * \param[out] keyStatusPtr Contains the pointer to the data where the status of the key shall be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-Crypto-KeyGetStatus + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyGetStatus( + uint32 cryptoKeyId, + P2VAR(Crypto_KeyStatusType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) keyStatusPtr); + +/* [SWS_Crypto_91006] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyElementGet() + *********************************************************************************************************************/ +/*! \brief This interface shall be used to get a key element of the key identified by the cryptoKeyId and store + * the key element in the memory location pointed by the result pointer. + * \details - + * \param[in] cryptoKeyId Holds the identifier of the key whose key element shall be returned. + * \param[in] keyElementId Holds the identifier of the key element which shall be returned. + * \param[out] resultPtr Holds the pointer of the buffer for the returned key element + * \param[in,out] resultLengthPtr Holds a pointer to a memory location in which the length information is + * stored. On calling this function this parameter shall contain the size of the + * buffer provided by resultPtr. If the key element is configured to allow + * partial access, this parameter contains the amount of data which should + * be read from the key element. The size may not be equal to the size of + * the provided buffer anymore. When the request has finished, the amount + * of data that has been stored shall be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_KEY_READ_FAIL Request failed, read access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed, the key is not available. + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, the provided buffer is too small to store the result. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-131142 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyElementGet( + uint32 cryptoKeyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) resultLengthPtr); + +/* [SWS_Crypto_91013] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_RandomSeed() + *********************************************************************************************************************/ +/*! \brief Initialize the seed + * \details This function generates the internal seed state using the provided entropy source. + * Furthermore, this function can be used to update the seed state with new entropy + * \param[in] cryptoKeyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] entropyPtr Holds a pointer to the memory location which contains the + * data to feed the entropy. + * \param[in] entropyLength Contains the length of the entropy in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-131137 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_RandomSeed( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) entropyPtr, + uint32 entropyLength); + +/* [SWS_Crypto_91007] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyGenerate() + *********************************************************************************************************************/ +/*! \brief Generates a key + * \details This function shall dispatch the key generate function to the configured crypto driver object. + * \param[in] cryptoKeyId Holds the identifier of the key which is to be updated with the generated + * value. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-155909 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyGenerate( + uint32 cryptoKeyId); + +/* [SWS_Crypto_91008] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyDerive() + *********************************************************************************************************************/ +/*! \brief Derives a key + * \details Derives a new key by using the key elements in the given key identified by the cryptoKeyId. + * The given key contains the key elements for the password, salt. The derived key is stored + * in the key element with the id 1 of the key identified by targetCryptoKeyId. + * The number of iterations is given in the key element CRYPTO_KE_KEYDERIVATION_ITERATIONS. + * \param[in] cryptoKeyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetCryptoKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-132407 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyDerive( + uint32 cryptoKeyId, + uint32 targetCryptoKeyId); + +/* [SWS_Crypto_91009] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyExchangeCalcPubVal() + *********************************************************************************************************************/ +/*! \brief Calculation of the public value + * \details Calculates the public value for the key exchange and stores the public key in the + * memory location pointed by the public value pointer. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-132409 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyExchangeCalcPubVal( + uint32 cryptoKeyId, + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) publicValueLengthPtr); + +/* [SWS_Crypto_91010] */ +/********************************************************************************************************************** + * Crypto_30_vHsm_KeyExchangeCalcSecret() + *********************************************************************************************************************/ +/*! \brief Calculation of the secret + * \details Calculates the shared secret key for the key exchange with the key material of the key identified + * by the cryptoKeyId and the partner public key. The shared secret key is stored + * as a key element in the same key. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partners + * public value. + * \param[in] partnerPublicValueLength Contains the length of the partners public value in bytes. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * CRYPTO_E_SMALL_BUFFER Request failed, the provided buffer is too small to store the result. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-132408 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_KeyExchangeCalcSecret( + uint32 cryptoKeyId, + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * Crypto_30_vHsm_CertificateParse() + *********************************************************************************************************************/ +/*! \brief Parse stored certificate + * \details Parses the certificate data stored in the key element CRYPTO_KE_CERT_DATA and fills the key elements + * CRYPTO_KE_CERT_SIGNEDDATA, CRYPTO_KE_CERT_PARSEDPUBLICKEY and CRYPTO_KE_CERT_SIGNATURE + * \param[in] cryptoKeyId Holds the identifier of the key slot in which the certificate has been + * stored. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-155910 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_CertificateParse( + uint32 cryptoKeyId); + +/********************************************************************************************************************** + * Crypto_30_vHsm_CertificateVerify() + *********************************************************************************************************************/ +/*! \brief Certificate verification + * \details Verifies the certificate stored in the key referenced by verifyCryptoKeyId with the + * certificate stored in the key referenced by cryptoKeyId. + * \param[in] cryptoKeyId Holds the identifier of the key which shall be used to validate the + * certificate. + * \param[in] verifyCryptoKeyId Holds the identifier of the key containing the certificate, which shall be + * verified. + * \param[out] verifyPtr Holds a pointer to the memory location which will contain the result of the + * certificate verification. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-155911 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_CertificateVerify( + uint32 cryptoKeyId, + uint32 verifyCryptoKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) verifyPtr); + +# define CRYPTO_30_VHSM_STOP_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CRYPTO_30_VHSM_KEYMANAGEMENT_H) */ diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Private.h b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Private.h new file mode 100644 index 0000000..7b7d61a --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Private.h @@ -0,0 +1,105 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file Crypto_30_vHsm_Private.h + * \brief MICROSAR vHsm Crypto Driver (Crypto) + * + * \details Private declarations for the module. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_VHSM_PRIVATE_H) +# define CRYPTO_30_VHSM_PRIVATE_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_30_vHsm_Cfg.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ +# define CRYPTO_30_VHSM_START_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) +/********************************************************************************************************************** + * Crypto_30_vHsm_HandleTimeout() + *********************************************************************************************************************/ +/*! + * \brief Poll all timeouted Ipc job requests for an answer of the Hsm. + * \details - + * \param[in] partitionIdx The currently active partition index + * \pre - + * \context TASK, ISR2 + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_HandleTimeout(Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx); + +/********************************************************************************************************************** + * Crypto_30_vHsm_RecoverFromTimeout() + *********************************************************************************************************************/ +/*! + * \brief Frees the Ipc channel of the jobRequestId. Also tries to recover the jobRequest. + * \details Can be callout by inside the loop callout by the user when a timeout is detected. + * \param[in] partitionIdx The currently active partition index + * \param[in] jobRequestId The Id of the timeouted jobRequest + * \param[in] writeIdx The writeIdx of the Hsm response + * \param[in] jobResponseData Data containing concatenated information of the job response like the retval and state + * \param[in] jobResponseBuffer Valid job response buffer with at least CRYPTO_30_VHSM_CRYPTO_JOBRESULTTYPE_DESERIALIZED_BUF_SIZE bytes of storage + * \pre Crypto_30_vHsm_SetChannelOfJobRequest has to have been called for the same jobRequestId. + * \context TASK, ISR2 + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CRYPTO_30_VHSM_CODE) Crypto_30_vHsm_RecoverFromTimeout( + Crypto_30_vHsm_PartitionIdentifiersIterType partitionIdx, + Crypto_30_vHsm_JobRequestIterType jobRequestId, + uint32 writeIdx, +# if (CRYPTO_30_VHSM_IPC_PROTOCOL_VERSION == 3u) + uint32 jobResponseData, +# endif + Crypto_30_vHsm_JobResponseBufferPtrType jobResponseBuffer); +# endif /* (CRYPTO_30_VHSM_TIMEOUT_RECOVERY == STD_ON) */ + +# define CRYPTO_30_VHSM_STOP_SEC_CODE +# include "Crypto_30_vHsm_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CRYPTO_30_VHSM_PRIVATE_H) */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_vHsm_Private.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Types.h b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Types.h new file mode 100644 index 0000000..17b7c7e --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Crypto_30_vHsm_Types.h @@ -0,0 +1,136 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Crypto_30_vHsm_Types.h + * \brief Vector Hardware Security Module Firmware Types + * + * \details Declares data structures required for interaction with Vector Hardware Security Module Firmware. + * + *********************************************************************************************************************/ + + /********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_30_VHSM_TYPES_H) +# define CRYPTO_30_VHSM_TYPES_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Csm_Types.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* vHsm Number of job request kinds */ +# define CRYPTO_30_VHSM_CRYPTO_JOBKIND (0u) /*!< Job kind for Crypto jobs */ +# define CRYPTO_30_VHSM_KEYMANAGEMENT_JOBKIND (1u) /*!< Job kind for Key Management jobs */ +# define CRYPTO_30_VHSM_KEYMANAGEMENT_COPY_PARTIAL_JOBKIND (2u) /*!< Job kind for Key Element Copy Partial jobs */ +# define CRYPTO_30_VHSM_CRYPTO_MACGEN_JOBKIND (3u) /*!< Job kind for MAC Generate jobs */ +# define CRYPTO_30_VHSM_CRYPTO_MACVER_JOBKIND (4u) /*!< Job kind for MAC Verify jobs */ +# define CRYPTO_30_VHSM_KEYMANAGEMENT_KEYDERIVEJOB_JOBKIND (5u) /*!< Job kind for MAC Verify jobs */ +# define CRYPTO_30_VHSM_JOBKIND_INVALID (6u) /*!< Invalid Job kind */ +# define CRYPTO_30_VHSM_NR_OF_JOBKINDS (CRYPTO_30_VHSM_JOBKIND_INVALID) /*!< Number of valid job kinds */ + +/* vHsm Key management actions */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTSET (0x00u) /*!< Action for Crypto_30_KeyElementSet() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTGET (0x01u) /*!< Action for Crypto_30_KeyElementGet() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTCOPY (0x02u) /*!< Action for Crypto_30_KeyElementCopy() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYCOPY (0x03u) /*!< Action for Crypto_30_KeyCopy() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYDERIVE (0x04u) /*!< Action for Crypto_30_KeyDerive() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYGENERATE (0x05u) /*!< Action for Crypto_30_KeyGenerate() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYVALIDSET (0x06u) /*!< Action for Crypto_30_KeyValidSet() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_RANDOMSEED (0x07u) /*!< Action for Crypto_30_RandomSeed() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_CERTIFICATEPARSE (0x08u) /*!< Action for Crypto_30_CertificateParse() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_CERTIFICATEVERIFY (0x09u) /*!< Action for Crypto_30_CertificateVerify() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYEXCHANGECALCPUBVAL (0x0Au) /*!< Action for Crypto_30_KeyExchangeCalcPubVal() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYEXCHANGECALCSECRET (0x0Bu) /*!< Action for Crypto_30_KeyExchangeCalcSecret() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTIDSGET (0x0Cu) /*!< Action for Crypto_30_KeyElementIdsGet() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYELEMENTCOPYPARTIAL (0x0Du) /*!< Action for Crypto_30_KeyElementCopyPartial() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYSETINVALID (0x0Eu) /*!< Action for Crypto_30_KeySetInvalid() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_KEYGETSTATUS (0x0Fu) /*!< Action for Crypto_30_KeyGetStatus() */ +# define CRYPTO_30_VHSM_KEYM_ACTION_INVALID (0x10u) /*!< Invalid Job kind */ +# define CRYPTO_30_VHSM_NR_OF_KEYM_ACTION (CRYPTO_30_VHSM_KEYM_ACTION_INVALID) /*!< Number of valid job kinds */ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +typedef uint8 Crypto_30_vHsm_ChannelIdType; + +typedef P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) Crypto_30_vHsm_JobRequestBufferPtrType; +typedef P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) Crypto_30_vHsm_JobResponseBufferPtrType; + +typedef uint32 Crypto_30_vHsm_JobResponseBufferSizeType; +typedef uint32 Crypto_30_vHsm_JobRequestBufferSizeType; + +typedef uint32 Crypto_30_vHsm_KeyM_ActionType; + +/*! Struct containing the input and output information of a KeyM job */ +typedef struct Crypto_30_vHsm_KeyM_InputOutputTypeStruct +{ + P2CONST(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_DATA) inputPtr; /*!< Pointer for the input data */ + uint32 inputLength; /*!< Size of the input data */ + P2VAR(uint8, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) outputPtr; /*!< Pointer for the output data */ + P2VAR(uint32, AUTOMATIC, CRYPTO_30_VHSM_APPL_VAR) outputLengthPtr; /*!< Size of the output data */ + uint32 keyElementSourceOffset; /*!< offset for the source key element during key element copy partial */ + uint32 keyElementTargetOffset; /*!< offset for the target key element during key element copy partial */ + uint32 keyElementCopyLength; /*!< Number of bytes to copy during key element copy partial */ +} Crypto_30_vHsm_KeyM_InputOutputType; + +/*! Struct containing basic information about a KeyM job */ +typedef struct Crypto_30_vHsm_KeyM_JobTypeStruct +{ + Crypto_30_vHsm_KeyM_ActionType action; /*!< action which shall be performed (e.g. KeyElementGet, KeyElementSet,...) */ + uint32 cryptoKeyId; /*!< Id of they key */ + uint32 secondaryCryptoKeyId; /*!< Id of they secondary key */ + uint32 keyElementId; /*!< Id of they key element */ + uint32 secondaryKeyElementId; /*!< Id of they secondary key element */ + Crypto_30_vHsm_KeyM_InputOutputType inputOutput; /*!< struct containing the input and output information */ +} Crypto_30_vHsm_KeyM_JobType; + +typedef uint8 Crypto_30_vHsm_JobKindType; + +typedef enum +{ + CRYPTO_30_VHSM_CALLOUT_JOBREQUEST = 0, + CRYPTO_30_VHSM_CALLOUT_HSMREADY, + CRYPTO_30_VHSM_CALLOUT_IPCINIT, + CRYPTO_30_VHSM_CALLOUT_ENTERRAMLOOP, + CRYPTO_30_VHSM_CALLOUT_EXITRAMLOOP, + CRYPTO_30_VHSM_CALLOUT_ASYNC +} Crypto_30_vHsm_CalloutIdType; + +typedef enum +{ + CRYPTO_30_VHSM_CALLOUT_CRYPTOJOB = CRYPTO_30_VHSM_CRYPTO_JOBKIND, + CRYPTO_30_VHSM_CALLOUT_KEYMJOB = CRYPTO_30_VHSM_KEYMANAGEMENT_JOBKIND, + CRYPTO_30_VHSM_CALLOUT_NOT_DEFINED +} Crypto_30_vHsm_CalloutContextClassType; + +typedef enum +{ + CRYPTO_30_VHSM_TIMEOUT_RECOVERY_IDLE = 0, + CRYPTO_30_VHSM_TIMEOUT_RECOVERY_PENDING, + CRYPTO_30_VHSM_TIMEOUT_RECOVERY_TRIGGERED +} Crypto_30_vHsm_TimeoutRecoveryStateType; + +#endif /* !defined (CRYPTO_30_VHSM_TYPES_H) */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_30_vHsm_Types.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_cfg.mak b/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_cfg.mak new file mode 100644 index 0000000..da8768a --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_cfg.mak @@ -0,0 +1,81 @@ +############################################################################### +# File Name : Crypto_30_vHsm_cfg.mak +# Description: Configuration makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Crypto_30_vHsm_rules.mak file. +############################################################################### + +############################################################## +# CAN_CONFIG_PATH: (not used for Vector) +# The Variable CAN_CONFIG_PATH is optional. It allows the +# configuration of the directory, where you can also find the +# generated source files. Generally they should be in the +# directory $(PROJECT_ROOT)\source\networks. +# But if the application should run on several hardware +# targets, then different CAN configurations of different +# directories will be necessary. Therefor the variable +# CAN_CONFIG_PATH should be used. +# +# For example: +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\st10 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# + +#_CONFIG_PATH = + + +############################################################## +# CAN_DRIVER_MODE: (not used for Vector) +# This Variable contains the name of the can driver module. At +# the moment the Standard Software Core Supports the two driver +# can_drv.c (single CAN) and can_drvm.c (multi CAN). Other +# values are not allowed. +# +# For example: +# CAN_DRIVER_MODE = singlechannel/multichannel +# + +#_DRIVER_MODE = singlechannel + + +############################################################### +# REQUIRED +# +# No Other resources are required to write a Configuration +# Makefile. +# +############################################################### + + +############################################################### +# PROVIDE +# +# A Configuration Makefile does not provide resources for other +# basic software bundles or the base_make package +# +############################################################### + + +############################################################### +# REGISTRY +# +# Like the Provide-Section this block is empty. +# +############################################################### + + +############################################################### +# SPECIFIC +# +# All variables in the _cfg makefile are "Specific" variables, +# because they should only be used in the *_check.mak, +# *_defs.mak and *_rules.mak Makefiles of the same basic +# software bundle. +############################################################### diff --git a/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_check.mak b/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_check.mak new file mode 100644 index 0000000..cf9bb7c --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_check.mak @@ -0,0 +1,79 @@ +############################################################################### +# File Name : Crypto_30_vHsm_check.mak +# Description: Configuration check makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Crypto_30_vHsm_rules.mak file. +############################################################################### + +############################################################### +# REGISTRY +# + +#e.g.: PREPARE_CONFIGURATION_INTERFACE += CAN_MODULES +PREPARE_CONFIGURATION_INTERFACE += + +CHECK_VARS_WHICH_ARE_REQUIRED += + +CHECK_VARS_WHICH_ARE_OPTIONAL += + +CHECK_VARS_WHICH_ARE_OBSOLETE += + +CHECK_VARS_WITH_ONE_CC_FILE += +CHECK_VARS_WITH_MORE_CC_FILES += + +CHECK_VARS_WITH_ONE_CPP_FILE += +CHECK_VARS_WITH_MORE_CPP_FILES += + +CHECK_VARS_WITH_ONE_ASM_FILE += +CHECK_VARS_WITH_MORE_ASM_FILES += + +CHECK_VARS_WITH_ONE_LIB_FILE += +CHECK_VARS_WITH_MORE_LIB_FILES += + +CHECK_VARS_WITH_ONE_OBJ_FILE += +CHECK_VARS_WITH_MORE_OBJ_FILES += + +#e.g: CHECK_VARS_WITH_ONE_DIRECTORY += $(DIRECTORIES_TO_CREATE) +# $(DIRECTORIES_TO_CREATE) = C:\demo\drv (this var is defined in _rules.mak) +CHECK_VARS_WITH_ONE_DIRECTORY += +CHECK_VARS_WITH_MORE_DIRECTORIES += + +CHECK_VARS_WITH_ONE_FILE += +CHECK_VARS_WITH_MORE_FILES += + +CHECK_VARS_WITH_MAX_LENGTH_ONE += + +############################################################### +# SPECIFIC +# +#ifneq ($(CAN_DRIVER_MODE),singlechannel) +#ifneq ($(CAN_DRIVER_MODE),multichannel) +#$(error The value of the variable CAN_DRIVER_MODE is not valid. \ +# Please use singlechannel or multichannel) +#endif +#endif + + +############################################################### +# REQUIRED +# +# No other resources are required for a Configuration Check +# Makefile +# +############################################################### + + +############################################################### +# PROVIDE +# +# A configuration Makefile does not provide resources for other +# basic software bundles or the base-make package. +# +############################################################### + diff --git a/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_defs.mak b/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_defs.mak new file mode 100644 index 0000000..29255ca --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_defs.mak @@ -0,0 +1,81 @@ +############################################################################### +# File Name : Crypto_30_vHsm_defs.mak +# Description: Public makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Crypto_30_vHsm_rules.mak file. +############################################################################### + +############################################################### +# INTERNAL REQUIRED CONFIGURATION (in can_cfg.mak) +# +# CAN_MODULES (required) (not necessary for Vector) +# CAN_DRIVER_MODE (required) (not necessary for Vector) +# CAN_PROJECT_PATH (optional) +# CAN_BUILD_LIBRARY (required) + + +############################################################### +# REQUIRED (defined in base_make) +# +# PROJECT_ROOT +# SSC_ROOT +############################################################### + + +############################################################### +# SPECIFIC +# Specific variables which were defined here are only for local use in this Makefile +# if for example additional includes are necessary, these vars can be defined and used in the REGISTRY-Part. +# e.g.: $(CAN_CORE_PATH) = $(SSC_ROOT)\Can could be used for CPP_INCLUDE_PATH += $(CAN_CORE_PATH)\CPP_FILES\... +CRYPTO_30_VHSM_CORE_PATH = +# e.g.: CAN_OUTPUT_PATH = $(GENDATA_DIR) +CRYPTO_30_VHSM_OUTPUT_PATH = $(GENDATA_DIR) + +#CAN_TOOL_PATH = $(PROJECT_ROOT)\core\com\can\gentool + +# it is also possible to generate own configurations with some checks like the following example +# ifneq ( $(CAN_CONFIG_PATH),) +# CAN_PROJECT_PATH = $(CAN_CONFIG_PATH) +# else +# CAN_PROJECT_PATH = $(PROJECT_ROOT)\source\network\can +# endif + + +############################################################### +# REGISTRY +# +# $(SSC_PLUGINS) is a list of the components. Here can is added (not necessary for Vector, whole component-list also exists in Global.makefile.target.make...) +# e.g.: SSC_PLUGINS += can +SSC_PLUGINS += +#e.g.: can_DEPENDENT_PLUGINS = +CRYPTO_30_VHSM_DEPENDENT_PLUGINS = + +#----------------------------------------------------------------------------------------- +# MakeSupport usually includes all header-files which were in the same +# directory as the source-files automatically, but to ensure that the +# Asr-Makefiles will also work with other Basic-Make-Packages, +# it is necessary to define all include directories for this Module +# e.g.: CC_INCLUDE_PATH += $(CAN_CORE_PATH) +#------------------------------------------------------------------------------------------ +CC_INCLUDE_PATH += Crypto_30_vHsm$(BSW_SRC_DIR) +CPP_INCLUDE_PATH += +ASM_INCLUDE_PATH += + +#PREPROCESSOR_DEFINES+= drivermode + +#drivermode_KEY = CAN_MODE +#drivermode_VALUE = $(CAN_DRIVER_MODE) + + +############################################################### +# PROVIDE +# +# A Public Makefile does not provide resources for other basic +# software bundles or the base_make package. +############################################################### diff --git a/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_rules.mak b/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_rules.mak new file mode 100644 index 0000000..e2216e6 --- /dev/null +++ b/Source/bsw/Crypto_30_vHsm/Make/Crypto_30_vHsm_rules.mak @@ -0,0 +1,102 @@ +############################################################################### +# File Name : Crypto_30_vHsm_rules.mak +# Description: Rules makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Version Date Author Description +#------------------------------------------------------------------------------ +# 1.00.00 2015-05-22 vistof Creation for ASR 4.0.3 +# 1.01.00 2015-08-03 vistof Added Crypto_SheKeyWrapSym +# 1.01.01 2015-09-29 vistof Corrected reference to Crypto_SheKeyWrapSym.c +# 1.02.00 2019-02-06 vircbl Added support of component-based SIP structure +#------------------------------------------------------------------------------ +# TemplateVersion = 1.02 +############################################################################### + + +############################################################### +# REGISTRY +# + +#e.g.: LIBRARIES_TO_BUILD += $(LIB_OUPUT_PATH)\vendorx_canlib1.$(LIB_FILE_SUFFIX) +LIBRARIES_TO_BUILD += Crypto_30_vHsm +Crypto_30_vHsm_FILES = Crypto_30_vHsm$(BSW_SRC_DIR)\Crypto_30_vHsm*.c + +# e.g.: CC_FILES_TO_BUILD += drv\can_drv.c +CC_FILES_TO_BUILD += Crypto_30_vHsm$(BSW_SRC_DIR)\Crypto_30_vHsm*.c +CPP_FILES_TO_BUILD += +ASM_FILES_TO_BUILD += + +#LIBRARIES_LINK_ONLY += (not yet supported) +#OBJECTS_LINK_ONLY += (not yet supported) + +#------------------------------------------------------------------------------------------------- +#only define new dirs, OBJ, LIB, LOG were created automaticly +#------------------------------------------------------------------------------------------------- +DIRECTORIES_TO_CREATE += + +#DEPEND_GCC_OPTS += (not yet supported) + +# e.g.: GENERATED_SOURCE_FILES += $(GENDATA_DIR)\drv_par.c +GENERATED_SOURCE_FILES += $(GENDATA_DIR)\Crypto_30_vHsm_Cfg.c + +#e.g.: COMMON_SOURCE_FILES += $(GENDATA_DIR)\v_par.c +COMMON_SOURCE_FILES += + +#------------------------------------------------------------------------------------------------- +# .dep & .lnk & .bin and..... +# all in err\ & obj\ & lst\ & lib\ & log\ will be deleted by clean-rule automaticly +# so in this clean-rule it is only necessary to define additional files which +# were not delete automaticly. +# e.g.: $()\can_test.c +#------------------------------------------------------------------------------------------------- +MAKE_CLEAN_RULES += +#MAKE_GENERATE_RULES += +#MAKE_COMPILER_RULES += +#MAKE_DEBUG_RULES += +#MAKE_CONFIG_RULES += +#MAKE_ADD_RULES += + + +############################################################### +# REQUIRED (defined in BaseMake (global.Makefile.target.make...)) +# +# SSC_ROOT (required) +# PROJECT_ROOT (required) +# +# LIB_OUTPUT_PATH (optional) +# OBJ_OUTPUT_PATH (optional) +# +# OBJ_FILE_SUFFIX +# LIB_FILE_SUFFIX +# +############################################################### + + +############################################################### +# PROVIDE this Section can be used to define own additional rules +# +# In vendorx_can_cfg.mak: +# Please configure the project file: +#CAN_CONFIG_FILE = $(PROJECT_ROOT)\source\network\can\my_can_config.cfg + +#In vendorx_can_config : +#generate_can_config: + #$(SSC_ROOT)\core\com\can\tools\canconfiggen.exe -o $(CAN_CONFIG_FILE) + + +############################################################### +# SPECIFIC +# +# There are no rules defined for the Specific part of the +# Rules-Makefile. Each author is free to create temporary +# variables or to use other resources of GNU-MAKE +# +############################################################### + + diff --git a/Source/bsw/Csm/Crypto_GeneralTypes.h b/Source/bsw/Csm/Crypto_GeneralTypes.h new file mode 100644 index 0000000..943c94a --- /dev/null +++ b/Source/bsw/Csm/Crypto_GeneralTypes.h @@ -0,0 +1,837 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file Crypto_GeneralTypes.h + * \brief MICROSAR Crypto Service Manager (CSM) + * + * \details This header is used to provide the type declarations of the Crypto stack. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file (Csm.h). + * + * FILE VERSION + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the VERSION CHECK below. + *********************************************************************************************************************/ + +#if !defined (CRYPTO_GENERALTYPES_H) +# define CRYPTO_GENERALTYPES_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Std_Types.h" +# include "Csm_Generated_Types.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* Crypto Stack Error Codes [SWS_Csm_01069] [SWS_Crypto_00042] */ +# if !defined (CRYPTO_E_BUSY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_BUSY 2u +# endif + +# if !defined (CRYPTO_E_SMALL_BUFFER) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_SMALL_BUFFER 3u +# endif + +# if !defined (CRYPTO_E_ENTROPY_EXHAUSTED) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_ENTROPY_EXHAUSTED 4u +# endif + +# if !defined (CRYPTO_E_ENTROPY_EXHAUSTION) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_ENTROPY_EXHAUSTION CRYPTO_E_ENTROPY_EXHAUSTED +# endif + +# if !defined (CRYPTO_E_QUEUE_FULL) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_QUEUE_FULL 5u +# endif + +# if !defined (CRYPTO_E_KEY_READ_FAIL) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_KEY_READ_FAIL 6u +# endif + +# if !defined (CRYPTO_E_KEY_WRITE_FAIL) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_KEY_WRITE_FAIL 7u +# endif + +# if !defined (CRYPTO_E_KEY_NOT_AVAILABLE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_KEY_NOT_AVAILABLE 8u +# endif + +# if !defined (CRYPTO_E_KEY_NOT_VALID) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_KEY_NOT_VALID 9u +# endif + +# if !defined (CRYPTO_E_KEY_SIZE_MISMATCH) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_KEY_SIZE_MISMATCH 10u +# endif + +# if !defined (CRYPTO_E_COUNTER_OVERFLOW) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_COUNTER_OVERFLOW 11u +# endif + +# if !defined (CRYPTO_E_JOB_CANCELED) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_JOB_CANCELED 12u +# endif + +# if !defined (CRYPTO_E_KEY_EMPTY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_KEY_EMPTY 13u +# endif + +# if (CSM_JOB_TYPE_LAYOUT_VAR_MEMBERS == STD_ON) +# define CSM_DEPENDENT_CONST(type) VAR(type, AUTOMATIC) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ +# else +# define CSM_DEPENDENT_CONST(type) CONST(type, AUTOMATIC) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ +# endif + +# if !defined (CSM_E_PENDING) /* COV_CSM_USER_DEFINES */ +# if defined (E_PENDING) /* COV_CSM_USER_DEFINES */ +# define CSM_E_PENDING E_PENDING +# else +# define CSM_E_PENDING 2u +# endif +# endif + +/* Key Elements [SWS_Csm_01022] */ +# if !defined (CRYPTO_KE_MAC_KEY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_MAC_KEY 1u +# endif + +# if !defined (CRYPTO_KE_MAC_PROOF) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_MAC_PROOF 2u +# endif + +# if !defined (CRYPTO_KE_SIGNATURE_KEY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_SIGNATURE_KEY 1u +# endif + +# if !defined (CRYPTO_KE_SIGNATURE_CURVETYPE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_SIGNATURE_CURVETYPE 29u +# endif + +# if !defined (CRYPTO_KE_RANDOM_SEED_STATE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_RANDOM_SEED_STATE 3u +# endif + +# if !defined (CRYPTO_KE_RANDOM_ALGORITHM) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_RANDOM_ALGORITHM 4u +# endif + +# if !defined (CRYPTO_KE_CIPHER_KEY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CIPHER_KEY 1u +# endif + +# if !defined (CRYPTO_KE_CIPHER_IV) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CIPHER_IV 5u +# endif + +# if !defined (CRYPTO_KE_CIPHER_PROOF) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CIPHER_PROOF 6u +# endif + +# if !defined (CRYPTO_KE_CIPHER_2NDKEY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CIPHER_2NDKEY 7u +# endif + +# if !defined (CRYPTO_KE_KEYEXCHANGE_BASE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYEXCHANGE_BASE 8u +# endif + +# if !defined (CRYPTO_KE_KEYEXCHANGE_PRIVKEY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYEXCHANGE_PRIVKEY 9u +# endif + +# if !defined (CRYPTO_KE_KEYEXCHANGE_OWNPUBKEY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYEXCHANGE_OWNPUBKEY 10u +# endif + +# if !defined (CRYPTO_KE_KEYEXCHANGE_SHAREDVALUE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYEXCHANGE_SHAREDVALUE 1u +# endif + +# if !defined (CYRPTO_KE_KEYEXCHANGE_SHAREDVALUE) +/* ASR define with typo - without define is above */ +# define CYRPTO_KE_KEYEXCHANGE_SHAREDVALUE 1u +# endif + +# if !defined (CRYPTO_KE_KEYEXCHANGE_ALGORITHM) /* COV_CSM_USER_DEFINES */ +/* e.g. X25519, RSA, ... */ +# define CRYPTO_KE_KEYEXCHANGE_ALGORITHM 12u +# endif + +# if !defined (CRYPTO_KE_KEYEXCHANGE_CURVETYPE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYEXCHANGE_CURVETYPE 29u +# endif + +# if !defined (CRYPTO_KE_KEYDERIVATION_PASSWORD) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYDERIVATION_PASSWORD 1u +# endif + +# if !defined (CRYPTO_KE_KEYDERIVATION_SALT) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYDERIVATION_SALT 13u +# endif + +# if !defined (CRYPTO_KE_KEYDERIVATION_ITERATIONS) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYDERIVATION_ITERATIONS 14u +# endif + +# if !defined (CRYPTO_KE_KEYDERIVATION_ALGORITHM) /* COV_CSM_USER_DEFINES */ +/* e.g. KDF2, KDFX963, ... */ +# define CRYPTO_KE_KEYDERIVATION_ALGORITHM 15u +# endif + +# if !defined (CRYPTO_KE_KEYDERIVATION_CURVETYPE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYDERIVATION_CURVETYPE 29u +# endif + +# if !defined (CRYPTO_KE_KEYGENERATE_KEY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYGENERATE_KEY 1u +# endif + +# if !defined (CRYPTO_KE_KEYGENERATE_SEED) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYGENERATE_SEED 16u +# endif + +# if !defined (CRYPTO_KE_KEYGENERATE_ALGORITHM) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYGENERATE_ALGORITHM 17u +# endif + +# if !defined (CRYPTO_KE_KEYGENERATE_CURVETYPE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYGENERATE_CURVETYPE 29u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_DATA) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_DATA 0u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_PARSING_FORMAT) /* COV_CSM_USER_DEFINES */ +/* e.g. X.509, C2X */ +# define CRYPTO_KE_CERTIFICATE_PARSING_FORMAT 18u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_CURRENT_TIME) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_CURRENT_TIME 19u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_VERSION) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_VERSION 20u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_SERIALNUMBER) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_SERIALNUMBER 21u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_SIGNATURE_ALGORITHM) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_SIGNATURE_ALGORITHM 22u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_ISSUER) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_ISSUER 23u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_VALIDITY_NOT_BEFORE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_VALIDITY_NOT_BEFORE 24u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_VALIDITY_NOT_AFTER) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_VALIDITY_NOT_AFTER 25u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_SUBJECT) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_SUBJECT 26u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_SUBJECT_PUBLIC_KEY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_SUBJECT_PUBLIC_KEY 1u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_EXTENSIONS) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_EXTENSIONS 27u +# endif + +# if !defined (CRYPTO_KE_CERTIFICATE_SIGNATURE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_CERTIFICATE_SIGNATURE 28u +# endif + +# if !defined (CRYPTO_KE_KEYWRAP_KEY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYWRAP_KEY 1u +# endif + +# if !defined (CRYPTO_KE_KEYWRAP_HEADER) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KE_KEYWRAP_HEADER 2u +# endif + +/* [SWS_Csm_01028] Crypto_JobStateType */ +typedef uint8 Crypto_JobStateType; +# define CRYPTO_JOBSTATE_IDLE 0u +# define CRYPTO_JOBSTATE_ACTIVE 1u +# define CRYPTO_JOBSTATE_PROGRESSING 2u + +/* [SWS_Csm_01028] Crypto_ServiceInfoType */ +typedef uint8 Crypto_ServiceInfoType; +# if !defined (CRYPTO_HASH) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_HASH 0x00u +# endif +# if !defined (CRYPTO_MACGENERATE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_MACGENERATE 0x01u +# endif +# if !defined (CRYPTO_MACVERIFY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_MACVERIFY 0x02u +# endif +# if !defined (CRYPTO_ENCRYPT) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ENCRYPT 0x03u +# endif +# if !defined (CRYPTO_DECRYPT) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_DECRYPT 0x04u +# endif +# if !defined (CRYPTO_AEADENCRYPT) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_AEADENCRYPT 0x05u +# endif +# if !defined (CRYPTO_AEADDECRYPT) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_AEADDECRYPT 0x06u +# endif +# if !defined (CRYPTO_SIGNATUREGENERATE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_SIGNATUREGENERATE 0x07u +# endif +# if !defined (CRYPTO_SIGNATUREVERIFY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_SIGNATUREVERIFY 0x08u +# endif +# if !defined (CRYPTO_SECCOUNTERINCREMENT) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_SECCOUNTERINCREMENT 0x09u +# endif +# if !defined (CRYPTO_SECCOUNTERREAD) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_SECCOUNTERREAD 0x0Au +# endif +# if !defined (CRYPTO_RANDOMGENERATE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_RANDOMGENERATE 0x0Bu +# endif +# if !defined (CRYPTO_RANDOMSEED) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_RANDOMSEED 0x0Cu +# endif +# if !defined (CRYPTO_KEYGENERATE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KEYGENERATE 0x0Du +# endif +# if !defined (CRYPTO_KEYDERIVE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KEYDERIVE 0x0Eu +# endif +# if !defined (CRYPTO_KEYEXCHANGECALCPUBVAL) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KEYEXCHANGECALCPUBVAL 0x0Fu +# endif +# if !defined (CRYPTO_KEYEXCHANGECALCSECRET) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KEYEXCHANGECALCSECRET 0x10u +# endif +# if !defined (CRYPTO_CERTIFICATEPARSE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_CERTIFICATEPARSE 0x11u +# endif +# if !defined (CRYPTO_CERTIFICATEVERIFY) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_CERTIFICATEVERIFY 0x12u +# endif +# if !defined (CRYPTO_KEYSETVALID) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KEYSETVALID 0x13u +# endif +# if !defined (CRYPTO_KEYSETINVALID) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KEYSETINVALID 0x14u +# endif +# if !defined (CRYPTO_CUSTOM_SERVICE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_CUSTOM_SERVICE 0x15u +# endif +# if !defined (CRYPTO_KEYWRAP) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KEYWRAP 0x16u +# endif +# if !defined (CRYPTO_KEYUNWRAP) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KEYUNWRAP 0x17u +# endif + +# if !defined (CRYPTO_RANDOM) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_RANDOM CRYPTO_RANDOMGENERATE +# endif +# if !defined (CRYPTO_SECURECOUNTERREAD) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_SECURECOUNTERREAD CRYPTO_SECCOUNTERREAD +# endif +# if !defined (CRYPTO_SECURECOUNTERINCREMENT) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_SECURECOUNTERINCREMENT CRYPTO_SECCOUNTERINCREMENT +# endif + +/* [SWS_Csm_01047] Crypto_AlgorithmFamilyType */ +typedef uint8 Crypto_AlgorithmFamilyType; +typedef uint8 Crypto_AlgorithmSecondaryFamilyType; +# if !defined (CRYPTO_ALGOFAM_NOT_SET) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_NOT_SET 0x00u +# endif +# if !defined (CRYPTO_ALGOFAM_SHA1) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA1 0x01u +# endif +# if !defined (CRYPTO_ALGOFAM_SHA2_224) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_224 0x02u +# endif +# if !defined (CRYPTO_ALGOFAM_SHA2_256) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_256 0x03u +# endif +# if !defined (CRYPTO_ALGOFAM_SHA2_384) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_384 0x04u +# endif +# if !defined (CRYPTO_ALGOFAM_SHA2_512) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_512 0x05u +# endif +# if !defined (CRYPTO_ALGOFAM_SHA2_512_224) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_512_224 0x06u +# endif +# if !defined (CRYPTO_ALGOFAM_SHA2_512_256) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA2_512_256 0x07u +# endif +# if !defined (CRYPTO_ALGOFAM_SHA3_224) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA3_224 0x08u +# endif +# if !defined (CRYPTO_ALGOFAM_SHA3_256) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA3_256 0x09u +# endif +# if !defined (CRYPTO_ALGOFAM_SHA3_384) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA3_384 0x0Au +# endif +# if !defined (CRYPTO_ALGOFAM_SHA3_512) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA3_512 0x0Bu +# endif +# if !defined (CRYPTO_ALGOFAM_SHAKE128) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHAKE128 0x0Cu +# endif +# if !defined (CRYPTO_ALGOFAM_SHAKE256) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHAKE256 0x0Du +# endif +# if !defined (CRYPTO_ALGOFAM_RIPEMD160) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_RIPEMD160 0x0Eu +# endif +# if !defined (CRYPTO_ALGOFAM_BLAKE_1_256) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_BLAKE_1_256 0x0Fu +# endif +# if !defined (CRYPTO_ALGOFAM_BLAKE_1_512) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_BLAKE_1_512 0x10u +# endif +# if !defined (CRYPTO_ALGOFAM_BLAKE_2s_256) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_BLAKE_2s_256 0x11u +# endif +# if !defined (CRYPTO_ALGOFAM_BLAKE_2s_512) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_BLAKE_2s_512 0x12u +# endif +# if !defined (CRYPTO_ALGOFAM_3DES) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_3DES 0x13u +# endif +# if !defined (CRYPTO_ALGOFAM_AES) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_AES 0x14u +# endif +# if !defined (CRYPTO_ALGOFAM_CHACHA) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_CHACHA 0x15u +# endif +# if !defined (CRYPTO_ALGOFAM_RSA) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_RSA 0x16u +# endif +# if !defined (CRYPTO_ALGOFAM_ED25519) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ED25519 0x17u +# endif +# if !defined (CRYPTO_ALGOFAM_BRAINPOOL) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_BRAINPOOL 0x18u +# endif +# if !defined (CRYPTO_ALGOFAM_ECCNIST) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECCNIST 0x19u +# endif +# if !defined (CRYPTO_ALGOFAM_SECURECOUNTER) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SECURECOUNTER 0x1Au +# endif +# if !defined (CRYPTO_ALGOFAM_RNG) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_RNG 0x1Bu +# endif +# if !defined (CRYPTO_ALGOFAM_SIPHASH) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SIPHASH 0x1Cu +# endif +# if !defined (CRYPTO_ALGOFAM_ECIES) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECIES 0x1Du +# endif +# if !defined (CRYPTO_ALGOFAM_ECCANSI) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECCANSI 0x1Eu +# endif +# if !defined (CRYPTO_ALGOFAM_ECCSEC) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECCSEC 0x1Fu +# endif +# if !defined (CRYPTO_ALGOFAM_DRBG) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_DRBG 0x20u +# endif +# if !defined (CRYPTO_ALGOFAM_FIPS186) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_FIPS186 0x21u +# endif +# if !defined (CRYPTO_ALGOFAM_PADDING_PKCS7) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_PADDING_PKCS7 0x22u +# endif +# if !defined (CRYPTO_ALGOFAM_PADDING_ONEWITHZEROS) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_PADDING_ONEWITHZEROS 0x23u +# endif +# if !defined (CRYPTO_ALGOFAM_PBKDF2) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_PBKDF2 0x24u +# endif +# if !defined (CRYPTO_ALGOFAM_KDFX963) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_KDFX963 0x25u +# endif +# if !defined (CRYPTO_ALGOFAM_DH) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_DH 0x26u +# endif +# if !defined (CRYPTO_ALGOFAM_SM2) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SM2 0x27u +# endif +# if !defined (CRYPTO_ALGOFAM_EEA3) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_EEA3 0x28u +# endif +# if !defined (CRYPTO_ALGOFAM_SM3) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SM3 0x29u +# endif +# if !defined (CRYPTO_ALGOFAM_EIA3) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_EIA3 0x2Au +# endif +# if !defined (CRYPTO_ALGOFAM_HKDF) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_HKDF 0x2Bu +# endif +# if !defined (CRYPTO_ALGOFAM_ECDSA) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECDSA 0x2Cu +# endif +# if !defined (CRYPTO_ALGOFAM_POLY1305) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_POLY1305 0x2Du +# endif + +/* Backward compatibility: + The define was corrected to CRYPTO_ALGOFAM_POLY1305 */ +# if !defined (CRYPTO_ALGOFAM_POLY13) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_POLY13 0x2Du +# endif + +# if !defined (CRYPTO_ALGOFAM_X25519) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_X25519 0x2Eu +# endif +# if !defined (CRYPTO_ALGOFAM_ECDH) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_ECDH 0x2Fu +# endif +# if !defined (CRYPTO_ALGOFAM_CUSTOM) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_CUSTOM 0xFFu +# endif + +/* Keep previous definition for backward compatibility */ +# if !defined (CRYPTO_ALGOFAM_FIPS) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_FIPS CRYPTO_ALGOFAM_FIPS186 +# endif + +/* Until AUTOSAR 4.4.0, there was an inconsistency in the standard where CRYPTO_ALGOFAM_SHAKE would + * sometimes be referred to as CRYPTO_ALGOFAM_SHA3_SHAKE128. We want to support both. */ +# if !defined (CRYPTO_ALGOFAM_SHA3_SHAKE128) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA3_SHAKE128 CRYPTO_ALGOFAM_SHAKE128 +# endif +# if !defined (CRYPTO_ALGOFAM_SHA3_SHAKE256) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOFAM_SHA3_SHAKE256 CRYPTO_ALGOFAM_SHAKE256 +# endif + +/* [SWS_Csm_01048] Crypto_AlgorithmModeType */ +typedef uint8 Crypto_AlgorithmModeType; +# if !defined (CRYPTO_ALGOMODE_NOT_SET) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_NOT_SET 0x00u +# endif +# if !defined (CRYPTO_ALGOMODE_ECB) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_ECB 0x01u +# endif +# if !defined (CRYPTO_ALGOMODE_CBC) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CBC 0x02u +# endif +# if !defined (CRYPTO_ALGOMODE_CFB) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CFB 0x03u +# endif +# if !defined (CRYPTO_ALGOMODE_OFB) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_OFB 0x04u +# endif +# if !defined (CRYPTO_ALGOMODE_CTR) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CTR 0x05u +# endif +# if !defined (CRYPTO_ALGOMODE_XTS) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_XTS 0x06u +# endif +# if !defined (CRYPTO_ALGOMODE_GCM) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_GCM 0x07u +# endif +# if !defined (CRYPTO_ALGOMODE_RSAES_OAEP) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_RSAES_OAEP 0x08u +# endif +# if !defined (CRYPTO_ALGOMODE_RSAES_PKCS1_v1_5) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_RSAES_PKCS1_v1_5 0x09u +# endif +# if !defined (CRYPTO_ALGOMODE_RSASSA_PSS) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_RSASSA_PSS 0x0Au +# endif +# if !defined (CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 0x0Bu +# endif +# if !defined (CRYPTO_ALGOMODE_8ROUNDS) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_8ROUNDS 0x0Cu +# endif +# if !defined (CRYPTO_ALGOMODE_12ROUNDS) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_12ROUNDS 0x0Du +# endif +# if !defined (CRYPTO_ALGOMODE_20ROUNDS) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_20ROUNDS 0x0Eu +# endif +# if !defined (CRYPTO_ALGOMODE_HMAC) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_HMAC 0x0Fu +# endif +# if !defined (CRYPTO_ALGOMODE_CMAC) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CMAC 0x10u +# endif +# if !defined (CRYPTO_ALGOMODE_GMAC) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_GMAC 0x11u +# endif +# if !defined (CRYPTO_ALGOMODE_CTRDRBG) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CTRDRBG 0x12u +# endif +# if !defined (CRYPTO_ALGOMODE_SIPHASH_2_4) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_SIPHASH_2_4 0x13u +# endif +# if !defined (CRYPTO_ALGOMODE_SIPHASH_4_8) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_SIPHASH_4_8 0x14u +# endif +# if !defined (CRYPTO_ALGOMODE_PXXXR1) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_PXXXR1 0x15u +# endif +# if !defined (CRYPTO_ALGOMODE_AESKEYWRAP) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_AESKEYWRAP 0x16u +# endif + +# if !defined (CRYPTO_ALGOMODE_CUSTOM) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_ALGOMODE_CUSTOM 0xFFu +# endif + +/* [SWS_Csm_91024] Crypto_InputOutputRedirectionConfigType */ +typedef uint8 Crypto_InputOutputRedirectionConfigType; +# define CRYPTO_REDIRECT_CONFIG_PRIMARY_INPUT 0x01u +# define CRYPTO_REDIRECT_CONFIG_SECONDARY_INPUT 0x02u +# define CRYPTO_REDIRECT_CONFIG_TERTIARY_INPUT 0x04u +# define CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT 0x10u +# define CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT 0x20u + +/* [SWS_Csm_01008] Crypto_AlgorithmInfoType */ +typedef struct +{ + Crypto_AlgorithmFamilyType family; + Crypto_AlgorithmSecondaryFamilyType secondaryFamily; + uint32 keyLength; + Crypto_AlgorithmModeType mode; +} Crypto_AlgorithmInfoType; + +/* Operation Modes */ +# if !defined (Rte_TypeDef_Crypto_OperationModeType) +typedef uint8 Crypto_OperationModeType; +# endif + +# if !defined (CRYPTO_OPERATIONMODE_START) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_OPERATIONMODE_START 1u +# endif +# if !defined (CRYPTO_OPERATIONMODE_UPDATE) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_OPERATIONMODE_UPDATE 2u +# endif +# if !defined (CRYPTO_OPERATIONMODE_FINISH) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_OPERATIONMODE_FINISH 4u +# endif + +/* [SWS_Crypto_00016] */ /* [SWS_Crypto_00017] */ +# if !defined (CRYPTO_OPERATIONMODE_STREAMSTART) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_OPERATIONMODE_STREAMSTART ( CRYPTO_OPERATIONMODE_START | CRYPTO_OPERATIONMODE_UPDATE ) +# endif +# if !defined (CRYPTO_OPERATIONMODE_SINGLECALL) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_OPERATIONMODE_SINGLECALL ( CRYPTO_OPERATIONMODE_START | CRYPTO_OPERATIONMODE_UPDATE | CRYPTO_OPERATIONMODE_FINISH ) +# endif + +# if !defined (CRYPTO_OPERATIONMODE_SAVE_CONTEXT) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_OPERATIONMODE_SAVE_CONTEXT 8u +# endif + +# if !defined (CRYPTO_OPERATIONMODE_RESTORE_CONTEXT) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_OPERATIONMODE_RESTORE_CONTEXT 16u +# endif + +/* [SWS_Csm_01049] Crypto_ProcessingType */ +typedef uint8 Crypto_ProcessingType; +# define CRYPTO_PROCESSING_ASYNC 0u +# define CRYPTO_PROCESSING_SYNC 1u + +# define CSM_ASYNCHRONOUS CRYPTO_PROCESSING_ASYNC +# define CSM_SYNCHRONOUS CRYPTO_PROCESSING_SYNC + +/* [SWS_Csm_01024] Crypto_VerifyResultType */ +# if !defined (Rte_TypeDef_Crypto_VerifyResultType) +typedef uint8 Crypto_VerifyResultType; +# endif + +# if !defined (CRYPTO_E_VER_OK) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_VER_OK 0u +# endif +# if !defined (CRYPTO_E_VER_NOT_OK) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_E_VER_NOT_OK 1u +# endif + +# if !defined (CSM_E_VER_OK) /* COV_CSM_USER_DEFINES */ +# define CSM_E_VER_OK CRYPTO_E_VER_OK +# endif +# if !defined (CSM_E_VER_NOT_OK) /* COV_CSM_USER_DEFINES */ +# define CSM_E_VER_NOT_OK CRYPTO_E_VER_NOT_OK +# endif + +/* [SWS_Csm_91044] Crypto_ResultType */ +# if !defined (Rte_TypeDef_Crypto_ResultType) +typedef uint8 Crypto_ResultType; +# endif + +/* [SWS_Csm_91001] Csm_ResultType */ +# if !defined (Rte_TypeDef_Csm_ResultType) +typedef uint8 Csm_ResultType; +# endif + +/* [SWS_Csm_91102] Crypto_KeyStatusType */ +# if !defined (Rte_TypeDef_Crypto_KeyStatusType) +typedef uint8 Crypto_KeyStatusType; +# endif + +# if !defined (CRYPTO_KEYSTATUS_INVALID) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KEYSTATUS_INVALID 0u +# endif + +# if !defined (CRYPTO_KEYSTATUS_VALID) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KEYSTATUS_VALID 1u +# endif + +# if !defined (CRYPTO_KEYSTATUS_UPDATE_IN_PROGRESS) /* COV_CSM_USER_DEFINES */ +# define CRYPTO_KEYSTATUS_UPDATE_IN_PROGRESS 2u +# endif + +/* [SWS_Csm_00930] Each crypto primitive configuration shall be realized as a constant structure of type Crypto_PrimitiveInfoType. */ +/* [SWS_Csm_01011] */ +typedef struct +{ +# if (CSM_JOB_TYPE_LAYOUT_RESULT_LENGTH == STD_ON) + /* ResultLength was removed in ASR R20-11 */ + CSM_DEPENDENT_CONST(uint32) resultLength; +# endif + CSM_DEPENDENT_CONST(Crypto_ServiceInfoType) service; + CSM_DEPENDENT_CONST(Crypto_AlgorithmInfoType) algorithm; +} Crypto_PrimitiveInfoType; + +/* [SWS_Csm_00932] Each user primitive configuration shall be realized as a constant structure of type Crypto_JobPrimitiveInfoType. */ +/* [SWS_Csm_01012] */ +typedef struct +{ + CSM_DEPENDENT_CONST(uint32) callbackId; + P2CONST(Crypto_PrimitiveInfoType, AUTOMATIC, CSM_CONST) primitiveInfo; +# if (CSM_JOB_TYPE_LAYOUT_SECURE_COUNTER_ID == STD_ON) + /* secureCounterId was removed in ASR 4.4.0 */ + CSM_DEPENDENT_CONST(uint32) secureCounterId; +# endif + CSM_DEPENDENT_CONST(uint32) cryIfKeyId; + CSM_DEPENDENT_CONST(Crypto_ProcessingType) processingType; +# if (CSM_JOB_TYPE_LAYOUT_CALLBACK_UPDATE_NOTIFICATION == STD_ON) + /* callbackUpdateNotification was removed in ASR R19-11 */ + CSM_DEPENDENT_CONST(boolean) callbackUpdateNotification; +# endif +} Crypto_JobPrimitiveInfoType; + +/* [SWS_Csm_01009] Crypto_JobPrimitiveInputOutputType */ +typedef struct +{ + P2CONST(uint8, AUTOMATIC, CSM_APPL_CONST) inputPtr; + uint32 inputLength; + P2CONST(uint8, AUTOMATIC, CSM_APPL_CONST) secondaryInputPtr; + uint32 secondaryInputLength; + P2CONST(uint8, AUTOMATIC, CSM_APPL_CONST) tertiaryInputPtr; + uint32 tertiaryInputLength; + + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) outputPtr; + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) outputLengthPtr; + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) secondaryOutputPtr; + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) secondaryOutputLengthPtr; + +# if (CSM_JOB_TYPE_LAYOUT_INPUT64 == STD_ON) + uint64 input64; +# endif + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr; +# if (CSM_JOB_TYPE_LAYOUT_OUTPUT64_PTR == STD_ON) + P2VAR(uint64, AUTOMATIC, CSM_APPL_VAR) output64Ptr; +# endif + Crypto_OperationModeType mode; + + /* Following members were added in ASR 4.4.0 */ + uint32 cryIfKeyId; + uint32 targetCryIfKeyId; +} Crypto_JobPrimitiveInputOutputType; + +typedef struct +{ + CSM_DEPENDENT_CONST(uint32) jobId; + CSM_DEPENDENT_CONST(uint32) jobPriority; +} Crypto_JobInfoType; + +/* [SWC_Csm_91026] Crypto_JobRedirectionInfoType */ +typedef struct +{ + uint8 redirectionConfig; + uint32 inputKeyId; + uint32 inputKeyElementId; + uint32 secondaryInputKeyId; + uint32 secondaryInputKeyElementId; + uint32 tertiaryInputKeyId; + uint32 tertiaryInputKeyElementId; + uint32 outputKeyId; + uint32 outputKeyElementId; + uint32 secondaryOutputKeyId; + uint32 secondaryOutputKeyElementId; +} Crypto_JobRedirectionInfoType; + +/* [SWS_Csm_01013] Crypto_JobType */ +typedef struct +{ + /* Members of ASR 4.3.0 resp. 4.3.1 */ + uint32 jobId; + Crypto_JobStateType jobState; + Crypto_JobPrimitiveInputOutputType jobPrimitiveInputOutput; + P2CONST(Crypto_JobPrimitiveInfoType, AUTOMATIC, CSM_CONST) jobPrimitiveInfo; +# if (CSM_JOB_TYPE_LAYOUT_REDIRECTION_INFO_REF == STD_ON) && (CSM_JOB_TYPE_LAYOUT_FIELD_ORDERING == CSM_ASR_VERSION_R21_11) + P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CSM_VAR_NOINIT) jobRedirectionInfoRef; +# endif +# if (CSM_JOB_TYPE_LAYOUT_JOB_INFO_PTR == STD_ON) + P2CONST(Crypto_JobInfoType, AUTOMATIC, CSM_CONST) jobInfo; +# endif + uint32 cryptoKeyId; + /* Following members were added in ASR 4.4.0 */ +# if (CSM_JOB_TYPE_LAYOUT_REDIRECTION_INFO_REF == STD_ON) && (CSM_JOB_TYPE_LAYOUT_FIELD_ORDERING == CSM_ASR_VERSION_4_03) + P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CSM_VAR_NOINIT) jobRedirectionInfoRef; +# endif + uint32 targetCryptoKeyId; + /* The jobPriority was added in ASR R20-11 as replacement of the jobInfo pointer. */ + uint32 jobPriority; +# if (CSM_JOB_TYPE_LAYOUT_ASR430_COMPATIBILITY == STD_ON) + /* ASR 4.3.0 compatibility - same content as jobState and jobPrimitiveInputOutput but accessible for 4.3.0 crypto drivers. */ + Crypto_JobStateType state; + Crypto_JobPrimitiveInputOutputType PrimitiveInputOutput; +# endif +} Crypto_JobType; + +/* End of Service Config Types */ + +#endif /* !defined (CRYPTO_GENERALTYPES_H) */ + +/********************************************************************************************************************** + * END OF FILE: Crypto_GeneralTypes.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Csm/Csm.c b/Source/bsw/Csm/Csm.c new file mode 100644 index 0000000..4cdafea --- /dev/null +++ b/Source/bsw/Csm/Csm.c @@ -0,0 +1,5728 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file Csm.c + * \brief MICROSAR Crypto Service Manager (CSM) + * + * \details Implementation of the MICROSAR Crypto Service Manager (CSM) + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + * + * FILE VERSION + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the VERSION CHECK below. + *********************************************************************************************************************/ + +#define CSM_SOURCE +/* PRQA S 6060 EOF */ /* MD_MSR_STPAR */ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Csm.h" +#include "Csm_Cbk.h" +#include "CryIf.h" +#include "SchM_Csm.h" + +#if (CSM_DEV_ERROR_REPORT == STD_ON) +# include "Det.h" +#endif + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ + + /* Check the version of CSM header file */ +#if ( (CSM_SW_MAJOR_VERSION != (9u)) \ + || (CSM_SW_MINOR_VERSION != (1u)) \ + || (CSM_SW_PATCH_VERSION != (1u))) +# error "Vendor specific version numbers of Csm.c and Csm.h are inconsistent" +#endif + +/* AUTOSAR version information check has to match definition in header file */ +#if ((CSM_AR_RELEASE_MAJOR_VERSION != (4u)) \ + || (CSM_AR_RELEASE_MINOR_VERSION != (7u)) \ + || (CSM_AR_RELEASE_REVISION_VERSION != (0u))) +# error "AUTOSAR Specification Version numbers of Csm.c and Csm.h are inconsistent!" +#endif + +/* Check the version of the configuration header file to ensure that the generated files match the static files. */ +#if ( (CSM_CFG_MAJOR_VERSION != (9u)) \ + || (CSM_CFG_MINOR_VERSION != (1u)) \ + || (CSM_CFG_PATCH_VERSION != (1u)) ) +# error "Version numbers of Csm.c and Csm_Cfg.h are inconsistent!" +#endif + +/* Check the version of the generator. */ +#if ( (CSM_GENERATOR_MAJOR_VERSION != (9u)) \ + || (CSM_GENERATOR_MINOR_VERSION != (1u)) ) +# error "Version numbers of Csm.c and Csm_Cfg.h (generator version) are inconsistent!" +#endif + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ + +/*! Callback is idle and must not be notified to RTE. */ +#define CSM_CALLBACK_IDLE (0xFEu) + +/*! Job ID which is used to mark Job as empty/free for usage. */ +#define CSM_EMPTY_JOB (0xFFFFFFFFu) + +/* States used for internal job state of Csm. */ + +/*! Job is IDLE - Ready to be used by application */ +#define CSM_JOB_STATE_IDLE CRYPTO_JOBSTATE_IDLE + +/*! Job is Active - That means it was started but waits for a further UPDATE or the FINISH call */ +#define CSM_JOB_STATE_ACTIVE CRYPTO_JOBSTATE_ACTIVE + +/*! Job is currently progressing in lower layer - Csm is waiting for function to return or for callback notification. */ +#define CSM_JOB_STATE_PROGRESSING CRYPTO_JOBSTATE_PROGRESSING + +/*! An asynchronous job was passed to lower layer - Csm is waiting for the callback, job is now cancelable as known by + * lower layer */ +#define CSM_JOB_STATE_WAITING 3u + +/*! Asynchronous job is on QUEUE */ +#define CSM_JOB_STATE_QUEUED 4u + +/*! Job canceling pending - currently the job is tried to be canceled in lower layer */ +#define CSM_JOB_STATE_CANCELING 5u + +/*! Asynchronous Job was cancelled in lower layer but CallbackNotification is required to complete cancellation. */ +#define CSM_JOB_STATE_CANCELED 6u + +/*! Asynchronous job's callback has occurred */ +#define CSM_JOB_STATE_CALLBACK_OCCURRED 64u + +/*! Clear mask for state Asynchronous job's callback has occurred */ +#define CSM_JOB_STATE_CALLBACK_OCCURRED_CLEAR_MASK 191u /* = ~CSM_JOB_STATE_CALLBACK_OCCURRED */ + +/*! State of asynchronous job retriggering */ +#define CSM_ASYNC_JOB_RETRIGGER_STATE_IDLE (0x00u) +#define CSM_ASYNC_JOB_RETRIGGER_STATE_PENDING (0x01u) + +/*! Determine which return value shall be used if queue is full. + * Since ASR 4.4, CRYPTO_E_BUSY is used instead of CRYPTO_E_QUEUE_FULL. */ +#if !defined (CSM_QUEUE_FULL_RETVAL) /* COV_CSM_ASR_COMPATIBILITY_DEFINE */ +# define CSM_QUEUE_FULL_RETVAL CRYPTO_E_BUSY +#endif + +/********************************************************************************************************************** + * LOCAL FUNCTION MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +#if !defined (CSM_LOCAL) /* COV_CSM_LOCAL_DEFINE */ +# define CSM_LOCAL static +#endif + +#if !defined (CSM_LOCAL_INLINE) /* COV_CSM_LOCAL_DEFINE */ +# define CSM_LOCAL_INLINE LOCAL_INLINE +#endif + +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define CSM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (CSM_JOB == STD_ON) +/********************************************************************************************************************** + * Csm_ProcessJob() + *********************************************************************************************************************/ +/*! \brief Process the received job + * \details This function unifies all external calls to call CryIf_ProcessJob. + * \param[in,out] job Pointer to the configuration of the job. Contains structures with user and + * primitive relevant information. + * \param[in] partition Id of the current active partition. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_READ_FAIL Request failed, not allowed to extract key element + * CRYPTO_E_KEY_WRITE_FAIL Request failed, not allowed to write key element + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy of random number generator is exhausted + * \pre Param queueIdx needs to be a valid index. + * \pre Job must point to a valid job object. + * \pre CSM_EXCLUSIVE_AREA_0 must be entered as it is left inside this function. + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL FUNC(Std_ReturnType, CSM_CODE) Csm_ProcessJob( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Csm_SizeOfPartitionIdentifiersType partition); + +/********************************************************************************************************************** + * Csm_GetJobObj() + *********************************************************************************************************************/ +/*! \brief Fetches the job object for the given job id. + * \details Job has either a dedicated object or it is received from the job pool + * \param[in] jobId Holds the identifier of the job. + * \param[in] partition Id of the current active partition. + * \param[out] jobObjId Pointer which will hold the id of the job object to use. + * \return E_OK Request successful. + * E_NOT_OK Request failed. + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy or queue is full. + * \pre Should only be called with locked interrupts + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL FUNC(Std_ReturnType, CSM_CODE) Csm_GetJobObj( + uint32 jobId, + Csm_SizeOfPartitionIdentifiersType partition, + P2VAR(Csm_SizeOfJobType, AUTOMATIC, AUTOMATIC) jobObjId); + +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) +/********************************************************************************************************************** + * Csm_PrepareJobObj() + *********************************************************************************************************************/ +/*! \brief Set all fields of the given job structure to the data of the given job id. + * \details - + * \param[in] jobId Holds the identifier of the job. + * \param[out] job Pointer to a job which will be adapted to the given job id. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(void, CSM_CODE) Csm_PrepareJobObj( + uint32 jobId, + P2VAR(Crypto_JobType, AUTOMATIC, AUTOMATIC) job); +# endif /* (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) */ + +# if (CSM_ASYNC_PROCESSING == STD_ON) +/********************************************************************************************************************** + * Csm_EnqueueJob() + *********************************************************************************************************************/ +/*! \brief Enqueue Job. + * \details This function is enqueuing a job to the given queue directly sorting by its priority. + * \param[in] queueIdx Holds the identifier of the queue info. + * \param[in,out] job Pointer to a job that shall be enqueued. + * \param[in] partition Id of the current active partition. + * \return E_OK Request successful. + * CRYPTO_E_BUSY Request failed, the queue is full. + * \pre Param queueIdx needs to be a valid index. + * \pre Job must point to a valid job object. + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \note Shall only be called with locked interrupts + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(Std_ReturnType, CSM_CODE) Csm_EnqueueJob( + Csm_QueueInfoIterType queueIdx, + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Csm_SizeOfPartitionIdentifiersType partition); + +/********************************************************************************************************************** + * Csm_DequeueJob() + *********************************************************************************************************************/ +/*! \brief Dequeue Job. + * \details This function removes a given job id from the queue filling gaps. + * \param[in] queueIdx Holds the identifier of the queue. + * \param[in] jobId Id of the job that shall be removed. + * \param[in] partition Id of the current active partition. + * \pre Param queueIdx needs to be a valid index. + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \note Shall only be called with locked interrupts + * \context TASK|ISR + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL FUNC(void, CSM_CODE) Csm_DequeueJob( + Csm_QueueInfoIterType queueIdx, + uint32 jobId, + Csm_SizeOfPartitionIdentifiersType partition); + +/********************************************************************************************************************** + * Csm_TriggerAsynchJobProcessing() + *********************************************************************************************************************/ +/*! \brief Triggers the Processing of asynchronous jobs + * \details This function checks for the given queue if an asynchronous job is available. If so, it triggers the + * CryIf to process this asynchronous job. + * \param[in] queueIdx Holds the identifier of the queue. + * \pre Param queueIdx needs to be a valid index. + * Must be called within CSM_EXCLUSIVE_AREA_0. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL FUNC(void, CSM_CODE) Csm_TriggerAsynchJobProcessing(Csm_QueueInfoIterType queueIdx); + +/********************************************************************************************************************** + * Csm_HandleCryIfCancelResultInStateCanceling() + *********************************************************************************************************************/ +/*! \brief Handles result of CryIf_CancelJob is job state in CANCELING. + * \details Depending on CryIf_CancelJob result, the necessary steps for canceling an asynchronous jobs are executed. + * \param[in] partition Id of the current active partition. + * \param[in] jobId Holds the identifier of the job. + * \param[in] cryIfRetVal Return value of CryIf_CancelJob + * \param[in] cancelFailedState Job state which shall be entered if cancel failed + * \return TRUE Notify via callback + * FALSE Do not notify via callback + * \pre CSM_EXCLUSIVE_AREA_0 must be entered as is is left inside this function. + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \pre Param jobId needs to be a valid index. + * \pre Job state must be CANCELING + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL FUNC(boolean, CSM_CODE) Csm_HandleCryIfCancelResultInStateCanceling( + Csm_SizeOfPartitionIdentifiersType partition, + uint32 jobId, + Std_ReturnType cryIfRetVal, + uint8 cancelFailedState); + +# if (CSM_CANCELATION_DURING_PROCESSING == STD_ON) +/********************************************************************************************************************** + * Csm_HandleCryIfCancelResultStateHasChanged() + *********************************************************************************************************************/ +/*! \brief Handles result of CryIf_CancelJob if job state has changed. + * \details Depending on CryIf_CancelJob result, the necessary steps for canceling an asynchronous jobs are executed. + * \param[in] partition Id of the current active partition. + * \param[in] jobId Holds the identifier of the job. + * \param[in] cryIfRetVal Return value of CryIf_CancelJob + * \pre CSM_EXCLUSIVE_AREA_0 must be entered as is is left inside this function. + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \pre Param jobId needs to be a valid index. + * \pre Job state must not be CANCELING + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(void, CSM_CODE) Csm_HandleCryIfCancelResultStateHasChanged( + Csm_SizeOfPartitionIdentifiersType partition, + uint32 jobId, + Std_ReturnType cryIfRetVal); +# endif /* (CSM_CANCELATION_DURING_PROCESSING == STD_ON) */ + +/********************************************************************************************************************** + * Csm_CancelAsynchronousJob() + *********************************************************************************************************************/ +/*! \brief Cancels an asynchronous job + * \details Depending on job state, the necessary steps for canceling an asynchronous jobs are executed + * \param[in,out] job Holds the asynchronous job object which shall be cancelled + * \param[in] partition Id of the current active partition. + * \return E_OK Request successful - Job was cancelled or was already Idle + * E_NOT_OK Request failed - Job could not be cancelled + * CRYPTO_E_JOB_CANCELED Request pending - Job will be cancelled with next callback notification + * \pre CSM_EXCLUSIVE_AREA_0 must be entered as is is left inside this function. + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(Std_ReturnType, CSM_CODE) Csm_CancelAsynchronousJob( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Csm_SizeOfPartitionIdentifiersType partition); + +/********************************************************************************************************************** + * Csm_HandleCallbackNotification() + *********************************************************************************************************************/ +/*! \brief Handle the Callback Notification from the lower layer + * \details Handle the result of an asynchronous job and forwards the notification to the application. + * \param[in,out] job Holds a pointer to the job which has been finished. + * \param[in] result Contains the result of the cryptographic operation. + * \param[out] runtimeErrorIdPtr Pointer to store the ID of the detected runtime development error. + * \pre All pointers must be valid. + * job's processing type must be set to CRYPTO_PROCESSING_ASYNC + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(void, CSM_CODE) Csm_HandleCallbackNotification( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Crypto_ResultType result, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) runtimeErrorIdPtr); + +/********************************************************************************************************************** + * Csm_HandleApplicationCallback() + *********************************************************************************************************************/ +/*! \brief Handles the application callback. + * \details Calls the configured user callback function. + * \param[in,out] job Holds a pointer to the job, which has finished. + * \param[in] result Contains the result of the cryptographic operation. + * \param[in] partition Id of the current active partition. + * \pre CSM_EXCLUSIVE_AREA_0 must be entered as it is left inside this function. + * job's processing type must be set to CRYPTO_PROCESSING_ASYNC + * job must have a valid callback function configured + * \context TASK, ISR + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(void, CSM_CODE) Csm_HandleApplicationCallback( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Std_ReturnType result, + Csm_SizeOfPartitionIdentifiersType partition); + +# if (CSM_RTECALLBACK == STD_ON) +/********************************************************************************************************************** + * Csm_HandleRteCallbacks() + *********************************************************************************************************************/ +/*! \brief Handles the RTE callbacks. + * \details Calls the RTE callback functions. + * \param[in] partition The current partition index. + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(void, CSM_CODE) Csm_HandleRteCallbacks(Csm_SizeOfPartitionIdentifiersType partition); +# endif /* (CSM_RTECALLBACK == STD_ON) */ + +# endif /* (CSM_ASYNC_PROCESSING == STD_ON) */ + +/********************************************************************************************************************** + * Csm_HandleJobProcessing() + *********************************************************************************************************************/ +/*! \brief Triggers the CryIf to process the given job. + * \details This function triggers the CryIf to process the corresponding job. Furthermore, pre- and post-job + * callouts are called from this function if enabled. + * \param[in] channelId Holds the identifier of the queue. + * \param[in,out] job Pointer to the corresponding job + * \param[in] partition Id of the current active partition. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_READ_FAIL Request failed, not allowed to extract key element + * CRYPTO_E_KEY_WRITE_FAIL Request failed, not allowed to write key element + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy of random number generator is exhausted + * \pre Param channelId needs to be a valid CryIf channel. + * \pre Param Job needs to be a valid pointer to a job object. + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL FUNC(Std_ReturnType, CSM_CODE) Csm_HandleJobProcessing( + Csm_ChannelIdOfQueueInfoType channelId, + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Csm_SizeOfPartitionIdentifiersType partition); + +/********************************************************************************************************************** + * Csm_AppendRedirectionToJob() + *********************************************************************************************************************/ +/*! \brief Appends redirection info to job object. + * \details If the job is configured to use an in-out redirection, it is appended to the job object in this function. + * \param[in,out] job Pointer to the corresponding job. + * \param[in] partition Id of the current active partition. + * \pre Param job needs to point to a valid job object. + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL FUNC(void, CSM_CODE) Csm_AppendRedirectionToJob( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Csm_SizeOfPartitionIdentifiersType partition); + +/********************************************************************************************************************** + * Csm_GetPartitionIdx() + *********************************************************************************************************************/ +/*! \brief Provide the currently active partition index. + * \details The partition index is determined by the OS application id. + * \return The executing partition index or Csm_GetSizeOfPartitionIdentifiers() if application was not found. + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(Csm_SizeOfPartitionIdentifiersType, CSM_CODE) Csm_GetPartitionIdx(void); + +# if (CSM_DEV_ERROR_DETECT == STD_ON) +/********************************************************************************************************************** + * Csm_VerifyJobParam() + *********************************************************************************************************************/ +/*! \brief Verifies the provided jobId, the requested service and the partition's initialization state + * \details - + * \param[in] jobId Id of the job which shall be verified + * \param[in,out] errorId Pointer to the errorId. If an error occurs, the errorId is set + * respectively + * \param[in] service Service which is called for the Job + * \return E_OK Request successful + * E_NOT_OK Request failed + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL FUNC(Std_ReturnType, CSM_CODE) Csm_VerifyJobParam( + uint32 jobId, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + Crypto_ServiceInfoType service); + +/********************************************************************************************************************** + * Csm_VerifyJobParamAndMode() + *********************************************************************************************************************/ +/*! \brief Compares the provided operation mode of the job to possible operation mode restrictions of the + * queue the job is mapped to + * \details In addition, this function does the same checks as Csm_VerifyJobParam(). + * \param[in] jobId Id of the job which shall be verified + * \param[in,out] errorId Pointer to the errorId. If an error occurs, the errorId is set + * respectively + * \param[in] service Service which is called for the Job + * \param[in] mode Indicates which operation mode(s) to perform. + * \return E_OK Request successful + * E_NOT_OK Request failed + * \pre - + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(Std_ReturnType, CSM_CODE) Csm_VerifyJobParamAndMode( + uint32 jobId, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + Crypto_ServiceInfoType service, + Crypto_OperationModeType mode); + +/********************************************************************************************************************** + * Csm_VerifyInitAndPartition() + *********************************************************************************************************************/ +/*! \brief Verify the initialization state of the related partition + * \details - + * \param[in] jobId Id of the job which shall be checked + * \param[in,out] errorId Pointer to the errorId. If an error occurs, the errorId is set + * respectively + * \return E_OK Request successful + * E_NOT_OK Request failed + * \pre jobId has to be verified to be in range of the configured jobs. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(Std_ReturnType, CSM_CODE) Csm_VerifyInitAndPartition( + uint32 jobId, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId); +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + +/********************************************************************************************************************** + * Csm_GetPartitionOfJob() + *********************************************************************************************************************/ +/*! \brief Provides the partition on which the job is configured + * \details - + * \param[in] jobId Id of Job from which the partitionIndex is returned. + * \return The partition index configured for the requested job + * \pre jobId must be verified before this function is used. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(Csm_SizeOfPartitionIdentifiersType, CSM_CODE) Csm_GetPartitionOfJob(uint32 jobId); +#endif /* (CSM_JOB == STD_ON) */ + +#if (CSM_CALLOUT == STD_ON) +/********************************************************************************************************************** + * Csm_CallPreJobCallout() + *********************************************************************************************************************/ +/*! \brief Triggers the calling of the configured pre-job callout. + * \details This function checks for the given job if an pre-job callout has to be called. If so, it triggers the + * call. + * \param[in,out] job Pointer to the corresponding job. + * \param[in] partition Id of the current active partition. + * \return E_OK Request successful + * E_NOT_OK Request failed + * \pre Param job needs to point to a valid job object. + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL_INLINE FUNC(Std_ReturnType, CSM_CODE) Csm_CallPreJobCallout( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Csm_SizeOfPartitionIdentifiersType partition); + +/********************************************************************************************************************** + * Csm_CallPostJobCallout() + *********************************************************************************************************************/ +/*! \brief Triggers the calling of the configured post-job callout. + * \details This function checks for the given job if an post-job callout has to be called. If so, it triggers + * the call. + * \param[in,out] job Pointer to the job. + * \param[in,out] retValFromProcessing Pointer to the processing result of the corresponding job. It can be + * overwritten by the post-job callout. + * \param[in] partition Id of the current active partition. + * \pre Param job needs to point to a valid job object. + * \pre Param retValFromProcessing needs to point to a valid location. + * \pre Param partition must be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() -1) + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + *********************************************************************************************************************/ +CSM_LOCAL FUNC(void, CSM_CODE) Csm_CallPostJobCallout( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + P2VAR(Std_ReturnType, AUTOMATIC, AUTOMATIC) retValFromProcessing, + Csm_SizeOfPartitionIdentifiersType partition); +#endif /* (CSM_CALLOUT == STD_ON) */ +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#if (CSM_CALLOUT == STD_ON) +/********************************************************************************************************************** + * Csm_CallPostJobCallout() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +CSM_LOCAL FUNC(void, CSM_CODE) Csm_CallPostJobCallout( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + P2VAR(Std_ReturnType, AUTOMATIC, AUTOMATIC) retValFromProcessing, + Csm_SizeOfPartitionIdentifiersType partition) +{ + Csm_CalloutInfoIdxOfJobTableType calloutInfoId; + + calloutInfoId = Csm_GetCalloutInfoIdxOfJobTable(job->jobId); + + /* #10 Check if post-job callout is configured for the given job. */ + if (calloutInfoId < Csm_GetSizeOfCalloutInfo()) + { + /* #20 Call post-job callout and reset the callout state to IDLE. */ + (void)Csm_GetPostJobCalloutFuncOfCallout(Csm_GetCalloutIdxOfCalloutInfo(calloutInfoId))( /* SBSW_CSM_FUNCTION_POINTER */ + job, + CSM_CALLOUT_STATE_POST_INITIAL, + retValFromProcessing); + + Csm_SetCalloutStateOfCalloutState(calloutInfoId, CSM_CALLOUT_STATE_IDLE, partition); /* SBSW_CSM_WRITE_TO_CALLOUT_STATE_BY_SIZE_AND_PARTITION */ + } +# if (CSM_NUMBER_OF_PARTITIONS <= 1u) + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_NUMBER_OF_PARTITIONS <= 1u) */ +} /* Csm_CallPostJobCallout() */ + +/********************************************************************************************************************** + * Csm_CallPreJobCallout() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +CSM_LOCAL_INLINE FUNC(Std_ReturnType, CSM_CODE) Csm_CallPreJobCallout( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Csm_SizeOfPartitionIdentifiersType partition) +{ + Csm_CalloutInfoIdxOfJobTableType calloutInfoId; + Std_ReturnType retVal = E_OK; + + /* Retrieve reference to callout for given job */ + calloutInfoId = Csm_GetCalloutInfoIdxOfJobTable(job->jobId); + + /* Check if pre-job callout is configured for the given job. */ + if (calloutInfoId < Csm_GetSizeOfCalloutInfo()) + { +# if (CSM_ASYNC_PROCESSING == STD_ON) + uint8 calloutState = Csm_GetCalloutStateOfCalloutState(calloutInfoId, partition); + + if( job->jobPrimitiveInfo->processingType == CRYPTO_PROCESSING_ASYNC) + { + /* If no callout has been called before or callout did not finish yet, call pre-job. */ + if ((calloutState == CSM_CALLOUT_STATE_IDLE) || (calloutState == CSM_CALLOUT_STATE_PRE_PENDING)) + { + /* Call pre-job callout */ + retVal = Csm_GetPreJobCalloutFuncOfCallout(Csm_GetCalloutIdxOfCalloutInfo(calloutInfoId))( /* SBSW_CSM_FUNCTION_POINTER */ + job, + (calloutState == CSM_CALLOUT_STATE_IDLE) ? (CSM_CALLOUT_STATE_PRE_INITIAL) : (CSM_CALLOUT_STATE_PRE_PENDING)); + + /* Set state according to return value of callout. */ + switch (retVal) + { + case E_OK: + { + /* pre-job callout has finished, Processing can start */ + Csm_SetCalloutStateOfCalloutState(calloutInfoId, CSM_CALLOUT_STATE_PROCESSING, partition); /* SBSW_CSM_WRITE_TO_CALLOUT_STATE_BY_SIZE_AND_PARTITION */ + break; + } + + case CSM_E_PENDING: + { + /* pre-job callout has not yet finished, this is only possible in asynchronous job configurations */ + Csm_SetCalloutStateOfCalloutState(calloutInfoId, CSM_CALLOUT_STATE_PRE_PENDING, partition); /* SBSW_CSM_WRITE_TO_CALLOUT_STATE_BY_SIZE_AND_PARTITION */ + break; + } + + default: + { + Csm_SetCalloutStateOfCalloutState(calloutInfoId, CSM_CALLOUT_STATE_PROCESSING_ABORTED_BY_CALLOUT, partition); /* SBSW_CSM_WRITE_TO_CALLOUT_STATE_BY_SIZE_AND_PARTITION */ + /* Change retVal to E_OK to remove job from queue since processing shall never be started */ + retVal = E_OK; + break; + } + } + } + } + else +# endif /* (CSM_ASYNC_PROCESSING == STD_ON) */ + { + /* Call pre-job callout. */ + retVal = Csm_GetPreJobCalloutFuncOfCallout(Csm_GetCalloutIdxOfCalloutInfo(calloutInfoId))(job, CSM_CALLOUT_STATE_PRE_INITIAL); /* SBSW_CSM_FUNCTION_POINTER */ + + /* Set state according to return value of callout. */ + if(retVal == E_OK) + { + /* If return value is equal to E_OK, the job shall be executed as without callout. */ + Csm_SetCalloutStateOfCalloutState(calloutInfoId, CSM_CALLOUT_STATE_PROCESSING, partition); /* SBSW_CSM_WRITE_TO_CALLOUT_STATE_BY_SIZE_AND_PARTITION */ + } + else + { + /* If return value is different to E_OK, processing of the job shall be suppressed. */ + Csm_SetCalloutStateOfCalloutState(calloutInfoId, CSM_CALLOUT_STATE_POST_INITIAL, partition); /* SBSW_CSM_WRITE_TO_CALLOUT_STATE_BY_SIZE_AND_PARTITION */ + /* Call post-job callout. */ + Csm_CallPostJobCallout(job, &retVal, partition); /* SBSW_CSM_PASS_JOB_STACK_AND_PARTITION */ + } + } + } + return retVal; +} /* Csm_CallPreJobCallout() */ +#endif /* (CSM_CALLOUT == STD_ON) */ + +#if (CSM_JOB == STD_ON) +/********************************************************************************************************************** + * Csm_AppendRedirectionToJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +CSM_LOCAL FUNC(void, CSM_CODE) Csm_AppendRedirectionToJob( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + Csm_SizeOfPartitionIdentifiersType partition) +{ +# if (CSM_INOUTREDIRECTION == STD_ON) + uint32 jobId = job->jobId; + + /* #10 If job in- or output shall be redirected, copy corresponding redirection sources and destinations to the job object. */ + if(Csm_IsInOutRedirectionMapUsedOfJobTable(jobId)) + { + Csm_SizeOfInOutJobRedirectionTableType indexOfInOutRedirectionTable = Csm_GetInOutJobRedirectionTableIdxOfInOutRedirectionMap(Csm_GetInOutRedirectionMapIdxOfJobTable(jobId), partition); + Csm_RedirectionConfigValueOfInOutJobRedirectionTableType redirectionConfigValue = Csm_GetRedirectionConfigValueOfInOutJobRedirectionTable(indexOfInOutRedirectionTable); + + job->jobRedirectionInfoRef = Csm_GetAddrInOutRedirection(Csm_GetInOutRedirectionMapIdxOfJobTable(jobId), partition); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + job->jobRedirectionInfoRef->redirectionConfig = redirectionConfigValue; /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + + if((redirectionConfigValue & ((uint8)CRYPTO_REDIRECT_CONFIG_PRIMARY_INPUT)) == (uint8)CRYPTO_REDIRECT_CONFIG_PRIMARY_INPUT) + { + job->jobRedirectionInfoRef->inputKeyElementId = Csm_GetInputKeyElementIdOfInOutJobRedirectionTable(indexOfInOutRedirectionTable); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + job->jobRedirectionInfoRef->inputKeyId = Csm_GetCryIfKeyIdOfKey(Csm_GetInputKeyIdOfInOutJobRedirectionTable(indexOfInOutRedirectionTable)); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + } + + if((redirectionConfigValue & ((uint8)CRYPTO_REDIRECT_CONFIG_SECONDARY_INPUT)) == (uint8)CRYPTO_REDIRECT_CONFIG_SECONDARY_INPUT) + { + job->jobRedirectionInfoRef->secondaryInputKeyElementId = Csm_GetSecondaryInputKeyElementIdOfInOutJobRedirectionTable(indexOfInOutRedirectionTable); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + job->jobRedirectionInfoRef->secondaryInputKeyId = Csm_GetCryIfKeyIdOfKey(Csm_GetSecondaryInputKeyIdOfInOutJobRedirectionTable(indexOfInOutRedirectionTable)); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + } + + if((redirectionConfigValue & ((uint8)CRYPTO_REDIRECT_CONFIG_TERTIARY_INPUT)) == (uint8)CRYPTO_REDIRECT_CONFIG_TERTIARY_INPUT) + { + job->jobRedirectionInfoRef->tertiaryInputKeyElementId = Csm_GetTertiaryInputKeyElementIdOfInOutJobRedirectionTable(indexOfInOutRedirectionTable); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + job->jobRedirectionInfoRef->tertiaryInputKeyId = Csm_GetCryIfKeyIdOfKey(Csm_GetTertiaryInputKeyIdOfInOutJobRedirectionTable(indexOfInOutRedirectionTable)); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + } + + if((redirectionConfigValue & ((uint8)CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT)) == (uint8)CRYPTO_REDIRECT_CONFIG_PRIMARY_OUTPUT) + { + job->jobRedirectionInfoRef->outputKeyElementId = Csm_GetOutputKeyElementIdOfInOutJobRedirectionTable(indexOfInOutRedirectionTable); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + job->jobRedirectionInfoRef->outputKeyId = Csm_GetCryIfKeyIdOfKey(Csm_GetOutputKeyIdOfInOutJobRedirectionTable(indexOfInOutRedirectionTable)); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + } + + if((redirectionConfigValue & ((uint8)CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT)) == (uint8)CRYPTO_REDIRECT_CONFIG_SECONDARY_OUTPUT) + { + job->jobRedirectionInfoRef->secondaryOutputKeyElementId = Csm_GetSecondaryOutputKeyElementIdOfInOutJobRedirectionTable(indexOfInOutRedirectionTable); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + job->jobRedirectionInfoRef->secondaryOutputKeyId = Csm_GetCryIfKeyIdOfKey(Csm_GetSecondaryOutputKeyIdOfInOutJobRedirectionTable(indexOfInOutRedirectionTable)); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + } + } + else +# endif /* (CSM_INOUTREDIRECTION == STD_ON) */ + { + /* #20 Else set redirection to dummy value. */ +# if (CSM_JOB_TYPE_LAYOUT_REDIRECTION_INFO_REF == STD_ON) + job->jobRedirectionInfoRef = (P2VAR(Crypto_JobRedirectionInfoType, AUTOMATIC, CSM_VAR_NOINIT)) (NULL_PTR); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ +# else + CSM_DUMMY_STATEMENT(job); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + } +# if (CSM_NUMBER_OF_PARTITIONS <= 1u) + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_NUMBER_OF_PARTITIONS <= 1u) */ +} /* Csm_AppendRedirectionToJob() */ + +/********************************************************************************************************************** + * Csm_HandleJobProcessing() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +CSM_LOCAL FUNC(Std_ReturnType, CSM_CODE) Csm_HandleJobProcessing( + Csm_ChannelIdOfQueueInfoType channelId, + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Csm_SizeOfPartitionIdentifiersType partition) +{ + Std_ReturnType retVal; + +# if (CSM_CALLOUT == STD_ON) + Csm_CalloutInfoIdxOfJobTableType calloutInfoId; + + /* Retrieve reference to callout for given job */ + calloutInfoId = Csm_GetCalloutInfoIdxOfJobTable(job->jobId); + + /* #10 Call preJobCallout */ + retVal = Csm_CallPreJobCallout(job, partition); /* SBSW_CSM_PASS_JOB_POINTER_AND_PARTITION_API_REQUIREMENT */ + + if ((calloutInfoId >= Csm_GetSizeOfCalloutInfo()) || (Csm_GetCalloutStateOfCalloutState(calloutInfoId, partition) == CSM_CALLOUT_STATE_PROCESSING)) +# endif /* (CSM_CALLOUT == STD_ON) */ + { + /* #20 Call CryIf to process given job */ + retVal = CryIf_ProcessJob(channelId, job); /* SBSW_CSM_PASS_JOB_POINTER_API_REQUIREMENT */ +# if (CSM_CALLOUT == STD_ON) + if (calloutInfoId < Csm_GetSizeOfCalloutInfo()) + { + /* Job has finished, either successful (E_OK) or not */ +# if (CSM_ASYNC_PROCESSING == STD_ON) + if (job->jobPrimitiveInfo->processingType == CRYPTO_PROCESSING_SYNC) +# endif + { + /* We need to call the post callout routine */ + Csm_SetCalloutStateOfCalloutState(calloutInfoId, CSM_CALLOUT_STATE_POST_INITIAL, partition); /* SBSW_CSM_WRITE_TO_CALLOUT_STATE_BY_SIZE_AND_PARTITION */ + Csm_CallPostJobCallout(job, &retVal, partition); /* SBSW_CSM_PASS_JOB_POINTER_PARTITION_AND_STACK_API_REQUIREMENT */ + } + } +# else /* !(CSM_CALLOUT == STD_ON) */ + CSM_DUMMY_STATEMENT_CONST(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + } + return retVal; +} /* Csm_HandleJobProcessing() */ + +/********************************************************************************************************************** + * Csm_ProcessJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6030, 6080 1 */ /* MD_MSR_STCYC, MD_MSR_STMIF */ +CSM_LOCAL FUNC(Std_ReturnType, CSM_CODE) Csm_ProcessJob( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Csm_SizeOfPartitionIdentifiersType partition) +{ + Std_ReturnType retVal; + uint32 jobId = job->jobId; + Csm_QueueInfoIterType queueInfoIdx = Csm_GetQueueInfoIdxOfJobTable(jobId); + Csm_ChannelIdOfQueueInfoType channelId = Csm_GetChannelIdOfQueueInfo(queueInfoIdx); + +# if (CSM_ASYNC_PROCESSING == STD_ON) + Crypto_JobStateType combinedJobState = job->jobState; + +# if (CSM_JOB_TYPE_LAYOUT_ASR430_COMPATIBILITY == STD_ON) + combinedJobState |= job->state; +# endif +# endif + + /* #05 Append job redirection to job object */ + Csm_AppendRedirectionToJob(job, partition); /* SBSW_CSM_PASS_JOB_POINTER_AND_PARTITION_API_REQUIREMENT */ + + /* Switch depending on whether there is asynchronous processing at all */ +# if (CSM_ASYNC_PROCESSING == STD_ON) + /* Check if the job is asynchronous. */ + if (job->jobPrimitiveInfo->processingType == CRYPTO_PROCESSING_ASYNC) + { + boolean gotLockOfQueue = (Csm_GetLockOfQueueState(queueInfoIdx, partition) == 0u) ? TRUE : FALSE; + /* Job is asynchronous */ + /* #19 Check if the job's processing mode matches the processing mode of the queue the job is mapped to */ + if (Csm_GetProcessingModeOfQueueInfo(Csm_GetQueueInfoIdxOfJobTable(jobId)) == CRYPTO_PROCESSING_SYNC) + { + retVal = E_NOT_OK; + } + /* #20 Determine if queue is empty or job is already active and queue is not locked + * (e.g. by this function) and call Csm_HandleJobProcessing if so */ + else if ((gotLockOfQueue == TRUE) && + ((Csm_GetQueueIdxOfQueueState(queueInfoIdx, partition) == Csm_GetQueueStartIdxOfQueueInfo(queueInfoIdx)) + || ((combinedJobState & CRYPTO_JOBSTATE_ACTIVE) == CRYPTO_JOBSTATE_ACTIVE))) + { + Csm_SetJobState(jobId, CSM_JOB_STATE_PROGRESSING, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ + Csm_IncLockOfQueueState(queueInfoIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ */ +# if (CSM_TRIGGERASYNCHJOBSINCALLBACKOFQUEUEINFO == STD_ON) + Csm_SetRetriggeringOfQueueState(queueInfoIdx, CSM_ASYNC_JOB_RETRIGGER_STATE_IDLE, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ */ +# endif + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + /* Call CryIf_ProcessJob() */ + retVal = Csm_HandleJobProcessing(channelId, job, partition); /* SBSW_CSM_PASS_CHANNEL_JOB_POINTER_AND_PARTITION_API_REQUIREMENT */ + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + Csm_DecLockOfQueueState(queueInfoIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ */ + } + else + { + /* Set retVal temporarily to busy to force enqueuing */ + retVal = CRYPTO_E_BUSY; + } + + /* #22 Enqueuing necessary if return value is either BUSY or QUEUE_FULL */ + if ((retVal == CRYPTO_E_BUSY) || (retVal == CRYPTO_E_QUEUE_FULL)) + { + /* #23 Append job redirection to job object again to overwrite changes that were made during last processing attempt */ + Csm_AppendRedirectionToJob(job, partition); /* SBSW_CSM_PASS_JOB_POINTER_AND_PARTITION_API_REQUIREMENT */ + + /* #24 Enqueue job or return QUEUE_FULL */ + retVal = Csm_EnqueueJob(queueInfoIdx, job, partition); /* SBSW_CSM_PASS_JOB_POINTER_AND_PARTITION_API_REQUIREMENT */ +# if (CSM_TRIGGERASYNCHJOBSINCALLBACKOFQUEUEINFO == STD_ON) + if (Csm_IsTriggerAsynchJobsInCallbackOfQueueInfo(queueInfoIdx)) /* PRQA S 4304 */ /* MD_MSR_AutosarBoolean */ + { + /* #25 If triggering asynchronous jobs is enabled for the queue handle the retriggering depending on whether + * getting the queue lock failed or not. */ + if (!gotLockOfQueue) + { + Csm_SetRetriggeringOfQueueState(queueInfoIdx, CSM_ASYNC_JOB_RETRIGGER_STATE_PENDING, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ */ + } + else if (Csm_GetRetriggeringOfQueueState(queueInfoIdx, partition) == CSM_ASYNC_JOB_RETRIGGER_STATE_PENDING) + { + Csm_TriggerAsynchJobProcessing(queueInfoIdx); + } + else + { + /* Do nothing */ + } + } +# endif /* (CSM_TRIGGERASYNCHJOBSINCALLBACKOFQUEUEINFO == STD_ON) */ + } + /* #26 Request has been successfully passed to lower layer */ + else if (retVal == E_OK) + { + /* #27 Check if the job is still in state PROGRESSING or callback already occurred */ + if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_PROGRESSING) + { + Csm_SetJobState(jobId, CSM_JOB_STATE_WAITING, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ + } + else + { + /* Callback already occurred but was not ready to process the application callback - do that now. */ + /* Lock queue to prevent a recursive call of Csm_ProcessJob from the application callback function */ + Csm_IncLockOfQueueState(queueInfoIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + Csm_CallbackNotification(job, Csm_GetJobState(jobId, partition) & CSM_JOB_STATE_CALLBACK_OCCURRED_CLEAR_MASK); /* SBSW_CSM_PASS_JOB_POINTER_AND_PARTITION_API_REQUIREMENT */ + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + Csm_DecLockOfQueueState(queueInfoIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ */ + } + } + else + { + Csm_SetJobState(jobId, CSM_JOB_STATE_IDLE, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) + job->jobId = CSM_EMPTY_JOB; /* SBSW_CSM_WRITE_TO_JOB_POINTER */ +# endif + } + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + else + { + /* The job is synchronous */ + /* #35 If any jobs are queued and job is not active, compare the job priority with the highest priority in the queue + * (This is relevant for queues which process both synchronous and asynchronous jobs.) */ + if ((Csm_GetProcessingModeOfQueueInfo(queueInfoIdx) != CRYPTO_PROCESSING_SYNC) + && (Csm_GetQueueIdxOfQueueState(queueInfoIdx, partition) != Csm_GetQueueStartIdxOfQueueInfo(queueInfoIdx)) + && ((combinedJobState & CRYPTO_JOBSTATE_ACTIVE) != CRYPTO_JOBSTATE_ACTIVE) + ) + { + /* #37 Call Csm_HandleJobProcessing function if job priority is higher than the highest priority in the queue, + * otherwise return busy */ + if (job->jobPriority > (Csm_GetQueue((Csm_QueueIdxOfQueueStateType)(Csm_GetQueueIdxOfQueueState(queueInfoIdx, partition) - 1u), partition)->jobPriority)) + { + Csm_SetJobState(jobId, CSM_JOB_STATE_PROGRESSING, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ + Csm_IncLockOfQueueState(queueInfoIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + retVal = Csm_HandleJobProcessing(channelId, job, partition); /* SBSW_CSM_PASS_CHANNEL_JOB_POINTER_AND_PARTITION_API_REQUIREMENT */ + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + Csm_DecLockOfQueueState(queueInfoIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ */ + } + else + { + retVal = CRYPTO_E_BUSY; + } + + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + else +# else /* !(CSM_ASYNC_PROCESSING == STD_ON) */ + { +# endif + { + /* #40 Process synchronous job if queue is empty or job is active */ + Csm_SetJobState(jobId, CSM_JOB_STATE_PROGRESSING, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + /* Call CryIf_ProcessJob() */ + retVal = Csm_HandleJobProcessing(channelId, job, partition); /* SBSW_CSM_PASS_CHANNEL_JOB_POINTER_AND_PARTITION_API_REQUIREMENT */ + } + + /* #41 Free object if job finishes or is rejected, otherwise set to active */ + if ((retVal != E_OK) || ((job->jobPrimitiveInputOutput.mode & CRYPTO_OPERATIONMODE_FINISH) == CRYPTO_OPERATIONMODE_FINISH) +# if (CSM_OPERATIONMODELIMITATIONOFQUEUEINFO == STD_ON) + || (Csm_IsOperationModeLimitationOfQueueInfo(queueInfoIdx)) +# endif + ) + { + Csm_SetJobState(jobId, CSM_JOB_STATE_IDLE, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) + job->jobId = CSM_EMPTY_JOB; /* SBSW_CSM_WRITE_TO_JOB_POINTER */ +# endif + } + else + { + Csm_SetJobState(jobId, CSM_JOB_STATE_ACTIVE, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ + } + } + + return retVal; +} /* Csm_ProcessJob() */ + +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) +/********************************************************************************************************************** + * Csm_PrepareJobObj() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +CSM_LOCAL_INLINE FUNC(void, CSM_CODE) Csm_PrepareJobObj( + uint32 jobId, + P2VAR(Crypto_JobType, AUTOMATIC, AUTOMATIC) job) +{ + job->jobId = jobId; /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + job->jobPrimitiveInfo = Csm_GetAddrJobPrimitiveInfo(Csm_GetJobPrimitiveInfoIdxOfJobTable(jobId)); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ +# if (CSM_JOB_TYPE_LAYOUT_JOB_INFO_PTR == STD_ON) + job->jobInfo = Csm_GetAddrJobInfo(Csm_GetJobInfoIdxOfJobTable(jobId)); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ +# endif + job->jobPriority = Csm_GetPriorityOfJobTable(jobId); /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + job->jobState = CRYPTO_JOBSTATE_IDLE; /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + +# if (CSM_JOB_TYPE_LAYOUT_ASR430_COMPATIBILITY == STD_ON) + job->PrimitiveInputOutput = job->jobPrimitiveInputOutput; /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + job->state = job->jobState; /* SBSW_CSM_WRITE_TO_JOB_POINTER */ +# endif +} /* Csm_PrepareJobObj() */ +# endif /* (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) */ + +/********************************************************************************************************************** + * Csm_GetJobObj() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +CSM_LOCAL FUNC(Std_ReturnType, CSM_CODE) Csm_GetJobObj( + uint32 jobId, + Csm_SizeOfPartitionIdentifiersType partition, + P2VAR(Csm_SizeOfJobType, AUTOMATIC, AUTOMATIC) jobObjId) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = CRYPTO_E_BUSY; + + /* #10 Differ between job states */ + if (Csm_GetJobState(jobId, partition) >= CSM_JOB_STATE_PROGRESSING) + { + /* #11 Job is currently in use, e.g. queued or in driver, reject request with busy */ + /* retval is already set. */ + } + else if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_ACTIVE) + { + /* #12 Job is active but is waiting for further input. Job object was reserved already - return it. */ + *jobObjId = Csm_GetJobToObjMap(jobId, partition); /* SBSW_WRITE_TO_PASSED_LOCAL_STACK_VARIABLE */ + retVal = E_OK; + } +# if (CSM_JOBIDXOFJOBTABLE == STD_ON) + else +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) + if (Csm_IsJobUsedOfJobTable(jobId)) +# endif + { + /* #20 Job has a dedicated job object, return it. */ + *jobObjId = Csm_GetJobIdxOfJobTable(jobId); /* SBSW_WRITE_TO_PASSED_LOCAL_STACK_VARIABLE */ + Csm_SetJobToObjMap(jobId, *jobObjId, partition); /* SBSW_WRITE_TO_OBJECTMAP_BY_JOBID */ +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) + Csm_GetAddrJob(*jobObjId, partition)->jobId = jobId; /* SBSW_CSM_WRITE_TO_JOB_POINTER */ +# endif + retVal = E_OK; + } +# endif /* (CSM_JOBIDXOFJOBTABLE == STD_ON) */ +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) + else + { + /* #21 Job Sharing: Find a free slot and return it, return busy if there is none */ + Csm_QueueInfoIterType queueInfoIdx = Csm_GetQueueInfoIdxOfJobTable(jobId); + Csm_SizeOfJobType idx; +# if (CSM_ASYNC_PROCESSING == STD_ON) + /* If it is an asynchronous job fetch the next job object from the pool which is free for usage. */ + if (Csm_IsAsynchronousOfJobTable(jobId)) + { + retVal = CSM_QUEUE_FULL_RETVAL; + + for (idx = Csm_GetJobPoolStartIdxOfQueueInfo(queueInfoIdx); idx < Csm_GetJobPoolEndIdxOfQueueInfo(queueInfoIdx); idx++) /* FETA_CSM_STRICTLY_INCREASING_BY_ONE */ + { + if (Csm_GetJob(idx, partition).jobId == CSM_EMPTY_JOB) + { + *jobObjId = idx; /* SBSW_WRITE_TO_PASSED_LOCAL_STACK_VARIABLE */ + Csm_SetJobToObjMap(jobId, idx, partition); /* SBSW_WRITE_TO_OBJECTMAP_BY_JOBID */ + Csm_PrepareJobObj(jobId, Csm_GetAddrJob(idx, partition)); /* SBSW_CSM_PASS_JOB */ + retVal = E_OK; + break; + } + } +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (retVal == CSM_QUEUE_FULL_RETVAL) + { + /* #22 Report runtime error if no free slot is available equivalent to queue is full */ + (void)Det_ReportRuntimeError(CSM_MODULE_ID, CSM_INSTANCE_ID, CSM_GENERIC_JOB_PROCESSING_ID, CSM_E_QUEUE_FULL); + } +# endif + } + else +# endif /* (CSM_ASYNC_PROCESSING == STD_ON) */ + { + /* Fetch the one job object reserved for all synchronous jobs for this queue and check if it is free for usage. */ + idx = Csm_GetJobObjSynchronousIdxOfQueueInfo(queueInfoIdx); + if (Csm_GetJob(idx, partition).jobId == CSM_EMPTY_JOB) + { + *jobObjId = idx; /* SBSW_WRITE_TO_PASSED_LOCAL_STACK_VARIABLE */ + Csm_SetJobToObjMap(jobId, idx, partition); /* SBSW_WRITE_TO_OBJECTMAP_BY_JOBID */ + Csm_PrepareJobObj(jobId, Csm_GetAddrJob(idx, partition)); /* SBSW_CSM_PASS_JOB */ + retVal = E_OK; + } + } + } +# endif /* (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) */ + +# if (CSM_NUMBER_OF_PARTITIONS <= 1u) + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_NUMBER_OF_PARTITIONS <= 1u) */ + + return retVal; +} /* Csm_GetJobObj() */ + +# if (CSM_ASYNC_PROCESSING == STD_ON) +/********************************************************************************************************************** + * Csm_EnqueueJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +CSM_LOCAL_INLINE FUNC(Std_ReturnType, CSM_CODE) Csm_EnqueueJob( + Csm_QueueInfoIterType queueIdx, + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Csm_SizeOfPartitionIdentifiersType partition) +{ + Std_ReturnType retVal = E_OK; + Csm_QueueIterType i, j; + + /* #5 Check if job that shall be enqueued is active and if queue has an empty place.*/ + if ((Csm_GetJobState(job->jobId, partition) == CSM_JOB_STATE_ACTIVE) && (Csm_GetQueueIdxOfQueueState(queueIdx, partition) < Csm_GetQueueEndIdxOfQueueInfo(queueIdx))) + { + Csm_SetQueue(Csm_GetQueueIdxOfQueueState(queueIdx, partition), job, partition); /* SBSW_CSM_WRITE_TO_QUEUE_API_REQ */ + + Csm_IncQueueIdxOfQueueState(queueIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_API_REQ */ + } + /* #10 Check if queue has two empty places, so that there is always one empty place for an active job, + * otherwise return QUEUE_FULL and report runtime error. */ + else if (Csm_GetQueueIdxOfQueueState(queueIdx, partition) < (Csm_GetQueueEndIdxOfQueueInfo(queueIdx) - 1u)) + { + for (i = Csm_GetQueueStartIdxOfQueueInfo(queueIdx); i <= Csm_GetQueueIdxOfQueueState(queueIdx, partition); i++) /* FETA_CSM_STRICTLY_INCREASING_BY_ONE_WITH_PRE_CHECK */ + { + /* #11 If end of queue is reached, new job has the highest priority. Simply add new job at the end. */ + if (i == Csm_GetQueueIdxOfQueueState(queueIdx, partition)) + { + Csm_SetQueue(i, job, partition); /* SBSW_CSM_WRITE_TO_QUEUE_BY_LOCALIDX */ + } + /* #12 If job priority of job is lower or equal to the one in the queue, + * or if the one in the queue is active, take its place. */ + else if ((job->jobPriority <= Csm_GetQueue(i, partition)->jobPriority) || (Csm_GetJobState(Csm_GetQueue(i, partition)->jobId, partition) == CSM_JOB_STATE_ACTIVE)) + { + /* Place found in which job needs to be inserted */ + /* #13 Move all remaining jobs, which are already sorted, by one place to the right. */ + for (j = Csm_GetQueueIdxOfQueueState(queueIdx, partition); j > i; j--) /* FETA_CSM_STRICTLY_DECREASING_BY_ONE */ + { + Csm_SetQueue(j, Csm_GetQueue(j - 1u, partition), partition); /* PRQA S 2841 */ /* MD_CSM_QUEUE_BY_QUEUEIDX */ /* SBSW_CSM_WRITE_TO_QUEUE_BY_LOCALIDX */ + } + + /* #14 Insert new job into the freed place. */ + Csm_SetQueue(i, job, partition); /* SBSW_CSM_WRITE_TO_QUEUE_BY_LOCALIDX */ + break; + } + else + { + /* Priority of job to insert is higher, check next slot of queue. */ + } + } + + Csm_SetJobState(job->jobId, CSM_JOB_STATE_QUEUED, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ + Csm_IncQueueIdxOfQueueState(queueIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_API_REQ */ + } + else + { + retVal = CSM_QUEUE_FULL_RETVAL; +# if (CSM_DEV_ERROR_REPORT == STD_ON) + (void)Det_ReportRuntimeError(CSM_MODULE_ID, CSM_INSTANCE_ID, CSM_GENERIC_JOB_PROCESSING_ID, CSM_E_QUEUE_FULL); +# endif + } + +# if (CSM_NUMBER_OF_PARTITIONS <= 1u) + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_NUMBER_OF_PARTITIONS <= 1u) */ + + return retVal; +} /* Csm_EnqueueJob() */ + +/********************************************************************************************************************** + * Csm_DequeueJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +CSM_LOCAL FUNC(void, CSM_CODE) Csm_DequeueJob( + Csm_QueueInfoIterType queueIdx, + uint32 jobId, + Csm_SizeOfPartitionIdentifiersType partition) +{ + Csm_QueueIterType i, j; + + /* #10 Iterate over enqueued jobs. */ + for (i = Csm_GetQueueIdxOfQueueState(queueIdx, partition); i > Csm_GetQueueStartIdxOfQueueInfo(queueIdx); i--) /* FETA_CSM_STRICTLY_DECREASING_BY_ONE */ + { + if (jobId == Csm_GetQueue(i - 1u, partition)->jobId) + { + /* #20 Fill the possible gap by shifting remaining jobs to the left. */ + for (j = i; j < Csm_GetQueueIdxOfQueueState(queueIdx, partition); j++) /* FETA_CSM_STRICTLY_INCREASING_BY_ONE */ + { + Csm_SetQueue(j - 1u, Csm_GetQueue(j, partition), partition); /* PRQA S 2841 */ /* MD_CSM_QUEUE_BY_QUEUEIDX */ /* SBSW_CSM_WRITE_TO_QUEUE_BY_LOCALIDX */ + } + + /* #21 Decrease queue size to finalize dequeuing. */ + Csm_DecQueueIdxOfQueueState(queueIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ */ + + break; + } + } + +# if (CSM_NUMBER_OF_PARTITIONS <= 1u) + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_NUMBER_OF_PARTITIONS <= 1u) */ + +} /* Csm_DequeueJob() */ + +/********************************************************************************************************************** + * Csm_TriggerAsynchJobProcessing() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +CSM_LOCAL FUNC(void, CSM_CODE) Csm_TriggerAsynchJobProcessing(Csm_QueueInfoIterType queueIdx) +{ + /* ----- Local Variables ---------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + uint32 jobId; + Std_ReturnType retVal; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionConfigIdxOfQueueInfo(queueIdx); + + /* ----- Implementation ----------------------------------------------- */ + + /* #10 Check if queue has entries and processing is possible (queue not locked due to an active request): */ + if ((Csm_GetLockOfQueueState(queueIdx, partition) == 0u) && (Csm_GetQueueIdxOfQueueState(queueIdx, partition) != Csm_GetQueueStartIdxOfQueueInfo(queueIdx))) + { + job = Csm_GetQueue(Csm_GetQueueIdxOfQueueState(queueIdx, partition) - 1u, partition); + jobId = job->jobId; + +# if (CSM_TRIGGERASYNCHJOBSINCALLBACKOFQUEUEINFO == STD_ON) + Csm_SetRetriggeringOfQueueState(queueIdx, CSM_ASYNC_JOB_RETRIGGER_STATE_IDLE, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_PARTITION_DEPENDENT */ +# endif + + if (jobId < Csm_GetSizeOfJobState(partition)) + { + /* #20 Lock queue temporarily and pass job to underlying crypto. */ + Csm_SetJobState(jobId, CSM_JOB_STATE_PROGRESSING, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + Csm_IncLockOfQueueState(queueIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_SIZE */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + retVal = Csm_HandleJobProcessing(Csm_GetChannelIdOfQueueInfo(queueIdx), job, partition); /* SBSW_CSM_PASS_JOB */ + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + Csm_DecLockOfQueueState(queueIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_SIZE */ + + /* #31 If Job was successfully passed to lower layer remove it from queue. */ + if (retVal == E_OK) + { + Csm_DequeueJob(queueIdx, jobId, partition); + /* #32 Check if the job is still in state PROGRESSING or callback already occurred. */ + if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_PROGRESSING) + { + Csm_SetJobState(jobId, CSM_JOB_STATE_WAITING, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + } + else + { + /* Callback already occurred but was not ready to process the application callbacks - do that now */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + Csm_CallbackNotification(job, Csm_GetJobState(jobId, partition) & CSM_JOB_STATE_CALLBACK_OCCURRED_CLEAR_MASK); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + /* #33 If job cannot be processed because of busy driver or full queue. Let job in queue and try again later. */ + else if ((retVal == CRYPTO_E_BUSY) || (retVal == CRYPTO_E_QUEUE_FULL)) + { + /* #34 Append job redirection to job object again to overwrite changes that were made during last processing attempt */ + Csm_AppendRedirectionToJob(job, partition); /* SBSW_CSM_PASS_JOB_POINTER_AND_PARTITION_API_REQUIREMENT */ + + Csm_SetJobState(jobId, CSM_JOB_STATE_QUEUED, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + } + else + { + /* #40 If lower layer returns an error remove job from queue and notify application. */ + Csm_DequeueJob(queueIdx, jobId, partition); + /* change to state waiting for correct handling in callback notification */ + Csm_SetJobState(jobId, CSM_JOB_STATE_WAITING, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + Csm_CallbackNotification(job, retVal); /* SBSW_CSM_PASS_JOB_POINTER_LOCAL */ + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + else + { + /* job invalid - throw it away */ + Csm_DecQueueIdxOfQueueState(queueIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_SIZE */ + } + } +} /* Csm_TriggerAsynchJobProcessing() */ + +/********************************************************************************************************************** + * Csm_HandleCryIfCancelResultInStateCanceling() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +CSM_LOCAL FUNC(boolean, CSM_CODE) Csm_HandleCryIfCancelResultInStateCanceling( + Csm_SizeOfPartitionIdentifiersType partition, + uint32 jobId, + Std_ReturnType cryIfRetVal, + uint8 cancelFailedState) +{ + boolean notifyByCallback = FALSE; + + if (cryIfRetVal == E_OK) + { + notifyByCallback = TRUE; + } + else if (cryIfRetVal == CRYPTO_E_JOB_CANCELED) + { + /* No immediate cancellation in lower layer possible, wait for next Csm_CallbackNotification */ + Csm_SetJobState(jobId, CSM_JOB_STATE_CANCELED, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ + } + else + { + /* Canceling failed, restore state */ + Csm_SetJobState(jobId, cancelFailedState, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ + } + +# if (CSM_NUMBER_OF_PARTITIONS <= 1u) + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_NUMBER_OF_PARTITIONS <= 1u) */ + + return notifyByCallback; +} + +# if (CSM_CANCELATION_DURING_PROCESSING == STD_ON) +/********************************************************************************************************************** + * Csm_HandleCryIfCancelResultStateHasChanged() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +CSM_LOCAL_INLINE FUNC(void, CSM_CODE) Csm_HandleCryIfCancelResultStateHasChanged( + Csm_SizeOfPartitionIdentifiersType partition, + uint32 jobId, + Std_ReturnType cryIfRetVal) +{ + + if (cryIfRetVal == E_OK) + { + /* Nothing to do, callback already occurred */ + } + else if (cryIfRetVal == CRYPTO_E_JOB_CANCELED) + { + /* No immediate cancellation in lower layer possible, wait for next Csm_CallbackNotification */ + Csm_SetJobState(jobId, CSM_JOB_STATE_CANCELED, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ + } + else + { + /* Job State has changed due to callback. Leave the state as it is. */ + } + +# if (CSM_NUMBER_OF_PARTITIONS <= 1u) + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_NUMBER_OF_PARTITIONS <= 1u) */ + +} +# endif /* (CSM_CANCELATION_DURING_PROCESSING == STD_ON) */ + +/********************************************************************************************************************** + * Csm_CancelAsynchronousJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6030 1 */ /* MD_MSR_STCYC */ +CSM_LOCAL_INLINE FUNC(Std_ReturnType, CSM_CODE) Csm_CancelAsynchronousJob( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Csm_SizeOfPartitionIdentifiersType partition) +{ + uint32 jobId = job->jobId; + Std_ReturnType retVal = E_NOT_OK; + Csm_QueueInfoIterType queueInfoIdx = Csm_GetQueueInfoIdxOfJobTable(jobId); + + boolean notifyByCallback = FALSE; + +# if (CSM_CANCELATION_DURING_PROCESSING == STD_ON) + if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_WAITING) + { + /* #10 Object is in driver and could call Csm_Notification at any time. Even if lower layer returns, + * driver could have already invoked the Csm_CallbackNotification function or be on the way. */ + + Csm_SetJobState(jobId, CSM_JOB_STATE_CANCELING, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + + /* #12 Cancel job in lower layer */ + retVal = CryIf_CancelJob(Csm_GetChannelIdOfQueueInfo(queueInfoIdx), job); /* SBSW_CSM_PASS_JOB */ + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + + if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_CANCELING) + { + notifyByCallback = Csm_HandleCryIfCancelResultInStateCanceling(partition, jobId, retVal, CSM_JOB_STATE_WAITING); + } + else + { + Csm_HandleCryIfCancelResultStateHasChanged(partition, jobId, retVal); + } + } + else +# endif /* (CSM_CANCELATION_DURING_PROCESSING == STD_ON) */ + if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_QUEUED) + { + /* #21 If Job is not started yet, cancellation can be done in Csm only, otherwise cancellation in lower layer required. */ + if ((job->jobPrimitiveInputOutput.mode & CRYPTO_OPERATIONMODE_START) == CRYPTO_OPERATIONMODE_START) + { + retVal = E_OK; + } + else + { + /* Job was already started and waits for input in driver - cancel it in lower layer too */ + /* #23 Pause processing when canceling in lower layer. Otherwise job could be passed to lower layer in between */ + Csm_IncLockOfQueueState(queueInfoIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + retVal = CryIf_CancelJob(Csm_GetChannelIdOfQueueInfo(queueInfoIdx), job); /* SBSW_CSM_PASS_JOB */ + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + Csm_DecLockOfQueueState(queueInfoIdx, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ */ + } + + if (retVal == E_OK) + { + /* #24 Remove job from queue in case of successful cancellation */ + Csm_DequeueJob(queueInfoIdx, jobId, partition); + notifyByCallback = TRUE; + } + } + else if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_ACTIVE) + { + Csm_SetJobState(jobId, CSM_JOB_STATE_CANCELING, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + + /* #32 Cancel job in lower layer */ + retVal = CryIf_CancelJob(Csm_GetChannelIdOfQueueInfo(queueInfoIdx), job); /* SBSW_CSM_PASS_JOB */ + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + + if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_CANCELING) + { + notifyByCallback = Csm_HandleCryIfCancelResultInStateCanceling(partition, jobId, retVal, CSM_JOB_STATE_ACTIVE); + } + else + { + /* Job State was modified in between so Csm_CallbackNotification already occurred */ + retVal = E_OK; + } + } + else + { + /* Job is in mode which cannot be cancelled - retVal already set */ + } + + /* #40 If job was canceled, call configured callback notification function */ + if (notifyByCallback) + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + Csm_CallbackNotification(job, CRYPTO_E_JOB_CANCELED); /* SBSW_CSM_FORWARDING_PTR */ + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + } + + return retVal; +} /* Csm_CancelAsynchronousJob() */ + +/********************************************************************************************************************** + * Csm_HandleCallbackNotification() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + */ +CSM_LOCAL_INLINE FUNC(void, CSM_CODE) Csm_HandleCallbackNotification( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + Crypto_ResultType result, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) runtimeErrorIdPtr +) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType resultCopy = result; + boolean notify = TRUE; + + /* Keep jobId local to still have it availabe after clearing the job object in case of a shared job object */ + uint32 jobId = job->jobId; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) + Csm_SizeOfJobType jobObjId = Csm_GetSizeOfJob(partition); +# endif + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); +# if (CSM_CANCELATION_DURING_PROCESSING == STD_ON) + /* #21 Check if job was cancelled in between and update return value accordingly */ + if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_CANCELED) + { + resultCopy = CRYPTO_E_JOB_CANCELED; + Csm_SetJobState(jobId, CSM_JOB_STATE_IDLE, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + } + else +# endif /* (CSM_CANCELATION_DURING_PROCESSING == STD_ON) */ + if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_IDLE) + { + /* Job is not running - Illegal function call, ignore it */ + notify = FALSE; + *runtimeErrorIdPtr = CSM_E_UNEXPECTED_CALLBACK; /* SBSW_WRITE_TO_PASSED_LOCAL_STACK_VARIABLE */ + } + /* #22 If not yet in state waiting but in state progressing due to preemption, + * save result and call callback in initial call. */ + else if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_PROGRESSING) + { + Csm_SetJobState(jobId, CSM_JOB_STATE_CALLBACK_OCCURRED | resultCopy, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + notify = FALSE; + } + /* #23 Update state to accept new request directly triggered in callback of application. + Set new state to idle or active depending on whether operation mode contains operation mode finish. */ + else if ((resultCopy == E_OK) && ((job->jobPrimitiveInputOutput.mode & CRYPTO_OPERATIONMODE_FINISH) != CRYPTO_OPERATIONMODE_FINISH)) + { + Csm_SetJobState(jobId, CSM_JOB_STATE_ACTIVE, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + } + else + { +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) + /* Get Csm object since passed job object could be a copy made by crypto driver */ + jobObjId = Csm_GetJobToObjMap(jobId, partition); +# endif + Csm_SetJobState(jobId, CSM_JOB_STATE_IDLE, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + } + + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + + /* #24 Check wether user is already to be notified and shared object is to be freed */ + if (notify) + { +# if (CSM_CALLOUT == STD_ON) + Csm_CallPostJobCallout(job, &resultCopy, partition); /* SBSW_CSM_PASS_JOB_STACK_AND_PARTITION */ +# endif /* (CSM_CALLOUT == STD_ON) */ + + /* #30 Call user callback function */ + Csm_HandleApplicationCallback(job, resultCopy, partition); /* SBSW_CSM_PASS_JOB_POINTER_API_REQUIREMENT_AND_STACK */ + + /* #31 Free object if job finishes or is rejected if job has no dedicated object */ +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) + if ((jobObjId < Csm_GetSizeOfJob(partition)) +# if (CSM_JOBIDXOFJOBTABLE == STD_ON) + && (!(Csm_IsJobUsedOfJobTable(jobId))) +# endif + ) + { + Csm_GetAddrJob(jobObjId, partition)->jobId = CSM_EMPTY_JOB; /* SBSW_CSM_WRITE_TO_JOB_POINTER */ + } +# endif /* (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) */ + +# if (CSM_TRIGGERASYNCHJOBSINCALLBACKOFQUEUEINFO == STD_ON) + { + /* #40 Trigger new asynchronous job. Derive the retrigger state depending on whether getting queue lock succeeded + * or failed. */ + Csm_QueueInfoIterType queueInfoIdx; + queueInfoIdx = Csm_GetQueueInfoIdxOfJobTable(jobId); + + if (Csm_IsTriggerAsynchJobsInCallbackOfQueueInfo(queueInfoIdx)) /* PRQA S 4304 */ /* MD_MSR_AutosarBoolean */ + { + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + Csm_SetRetriggeringOfQueueState(queueInfoIdx, CSM_ASYNC_JOB_RETRIGGER_STATE_PENDING, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_PARTITION_DEPENDENT */ + Csm_TriggerAsynchJobProcessing(queueInfoIdx); /* SBSW_CSM_PASS_QUEUESTATEINDEX */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } +# endif /* (CSM_TRIGGERASYNCHJOBSINCALLBACKOFQUEUEINFO == STD_ON) */ + } +# if (CSM_NUMBER_OF_PARTITIONS <= 1u) + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_NUMBER_OF_PARTITIONS <= 1u) */ + +} /* Csm_HandleCallbackNotification() */ + +/********************************************************************************************************************** + * Csm_HandleApplicationCallback() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + */ +CSM_LOCAL_INLINE FUNC(void, CSM_CODE) Csm_HandleApplicationCallback( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + Std_ReturnType result, + Csm_SizeOfPartitionIdentifiersType partition) +{ + /* #10 Call configured user callback function */ +# if (CSM_CALLBACK_START_NOTIFICATION == STD_OFF) + if ((((job->jobPrimitiveInputOutput.mode & CRYPTO_OPERATIONMODE_UPDATE) == CRYPTO_OPERATIONMODE_UPDATE) + && Csm_IsPrimitiveCallbackUpdateNotificationOfJobTable(job->jobId)) + || ((job->jobPrimitiveInputOutput.mode & CRYPTO_OPERATIONMODE_FINISH) == CRYPTO_OPERATIONMODE_FINISH) + || (result == CRYPTO_E_JOB_CANCELED)) +# endif /* (CSM_CALLBACK_START_NOTIFICATION == STD_OFF) */ + { +# if (CSM_CALLBACKFUNC43OFBSWCALLBACKS == STD_ON) + if (Csm_IsBswCallbacksUsedOfJobTable(job->jobId) && (Csm_GetCallbackFunc43OfBswCallbacks(Csm_GetBswCallbacksIdxOfJobTable(job->jobId)) != NULL_PTR)) + { + Csm_GetCallbackFunc43OfBswCallbacks(Csm_GetBswCallbacksIdxOfJobTable(job->jobId))(job, result); /* SBSW_CSM_FUNCTION_POINTER */ + } + else +# endif /* (CSM_CALLBACKFUNC43OFBSWCALLBACKS == STD_ON) */ + +# if(CSM_CALLBACKFUNC44OFBSWCALLBACKS == STD_ON) + if (Csm_IsBswCallbacksUsedOfJobTable(job->jobId) && (Csm_GetCallbackFunc44OfBswCallbacks(Csm_GetBswCallbacksIdxOfJobTable(job->jobId)) != NULL_PTR)) + { + Csm_GetCallbackFunc44OfBswCallbacks(Csm_GetBswCallbacksIdxOfJobTable(job->jobId))(job->jobId, result); /* SBSW_CSM_FUNCTION_POINTER */ + } + else +# endif /* (CSM_CALLBACKFUNC44OFBSWCALLBACKS == STD_ON) */ + +# if(CSM_CALLBACKFUNC45OFBSWCALLBACKS == STD_ON) + if (Csm_IsBswCallbacksUsedOfJobTable(job->jobId) && (Csm_GetCallbackFunc45OfBswCallbacks(Csm_GetBswCallbacksIdxOfJobTable(job->jobId)) != NULL_PTR)) + { + Csm_GetCallbackFunc45OfBswCallbacks(Csm_GetBswCallbacksIdxOfJobTable(job->jobId))(job, result); /* SBSW_CSM_FUNCTION_POINTER */ + } + else +# endif /* (CSM_CALLBACKFUNC45OFBSWCALLBACKS == STD_ON) */ + +# if(CSM_CALLBACKFUNC46OFBSWCALLBACKS == STD_ON) + /* Coming to this line Csm_GetCallbackFunc46OfBswCallbacks is always != NULL_PTR */ + if (Csm_IsBswCallbacksUsedOfJobTable(job->jobId)) + { + Csm_GetCallbackFunc46OfBswCallbacks(Csm_GetBswCallbacksIdxOfJobTable(job->jobId))(job->jobId, result); /* SBSW_CSM_FUNCTION_POINTER */ + } + else +# endif /* (CSM_CALLBACKFUNC46OFBSWCALLBACKS == STD_ON) */ + +# if (CSM_RTECALLBACK == STD_ON) + { + Csm_SetRteResult(Csm_GetRteCallbackIdxOfJobTable(job->jobId), result, partition); /* SBSW_CSM_WRITE_TO_RTERESULT_BY_JOBID */ + Csm_SetRteCallbackOccurred(TRUE, partition); /* SBSW_CSM_CSL_VAR_ACCESS */ + } +# endif /* (CSM_RTECALLBACK == STD_ON) */ + { + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + } + } +} /* Csm_HandleApplicationCallback() */ + +# if (CSM_RTECALLBACK == STD_ON) +/********************************************************************************************************************** + * Csm_HandleRteCallbacks() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CSM_LOCAL_INLINE FUNC(void, CSM_CODE) Csm_HandleRteCallbacks(Csm_SizeOfPartitionIdentifiersType partition) +{ + /* Rte Notifications */ + if (Csm_IsRteCallbackOccurred(partition)) + { + Csm_RteCallbackIterType callbackIdx; + Std_ReturnType retVal; + + Csm_SetRteCallbackOccurred(FALSE, partition); /* SBSW_CSM_CSL_VAR_ACCESS */ + for (callbackIdx = 0u; callbackIdx < Csm_GetSizeOfRteCallback(partition); callbackIdx++) + { + retVal = Csm_GetRteResult(callbackIdx, partition); + if (retVal != CSM_CALLBACK_IDLE) + { + Csm_SetRteResult(callbackIdx, CSM_CALLBACK_IDLE, partition); /* SBSW_CSM_WRITE_TO_RTERESULT_BY_SIZE_API_REQ */ + (void)Csm_GetRteCallback(callbackIdx, partition)(retVal); /* SBSW_CSM_FUNCTION_POINTER */ + } + } + } + + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +} /* Csm_HandleRteCallbacks() */ +# endif /* (CSM_RTECALLBACK == STD_ON) */ + +# endif /* (CSM_ASYNC_PROCESSING == STD_ON) */ + +# if (CSM_DEV_ERROR_DETECT == STD_ON) +/********************************************************************************************************************** + * Csm_VerifyJobParam() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +CSM_LOCAL FUNC(Std_ReturnType, CSM_CODE) Csm_VerifyJobParam( + uint32 jobId, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + Crypto_ServiceInfoType service) +{ + uint8 retVal = E_NOT_OK; + + /* Check if the provided job id is in range of the configured jobs */ + if (jobId >= Csm_GetSizeOfJobTable()) + { + *errorId = CSM_E_PARAM_HANDLE; /* SBSW_WRITE_TO_PASSED_LOCAL_STACK_VARIABLE */ + } + /* Check if the requested service matches the configured one */ + else if (Csm_GetJobPrimitiveInfo(Csm_GetJobPrimitiveInfoIdxOfJobTable(jobId)).primitiveInfo->service != service) + { + *errorId = CSM_E_SERVICE_TYPE; /* SBSW_WRITE_TO_PASSED_LOCAL_STACK_VARIABLE */ + } + /* Check if the current partition is active and initialized */ + else + { + retVal = Csm_VerifyInitAndPartition(jobId, errorId); /* SBSW_CSM_FORWARDING_PTR */ + } + + return retVal; +} /* Csm_VerifyJobParam() */ + +/********************************************************************************************************************** + * Csm_VerifyJobParamAndMode() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +CSM_LOCAL_INLINE FUNC(Std_ReturnType, CSM_CODE) Csm_VerifyJobParamAndMode( + uint32 jobId, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId, + Crypto_ServiceInfoType service, + Crypto_OperationModeType mode) +{ + uint8 retVal = Csm_VerifyJobParam(jobId, errorId, service); /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + +# if (CSM_OPERATIONMODELIMITATIONOFQUEUEINFO == STD_ON) + if (retVal == E_OK) + { + if ((mode != CRYPTO_OPERATIONMODE_SINGLECALL) && (Csm_IsOperationModeLimitationOfQueueInfo(Csm_GetQueueInfoIdxOfJobTable(jobId)))) + { + *errorId = CSM_E_PROCESSING_MODE; /* SBSW_WRITE_TO_PASSED_LOCAL_STACK_VARIABLE */ + retVal = E_NOT_OK; + } + } +# else + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_OPERATIONMODELIMITATIONOFQUEUEINFO == STD_ON) */ + + return retVal; +} /* Csm_VerifyJobParamAndMode() */ + +/********************************************************************************************************************** + * Csm_VerifyInitAndPartition() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +CSM_LOCAL_INLINE FUNC(Std_ReturnType, CSM_CODE) Csm_VerifyInitAndPartition( + uint32 jobId, + P2VAR(uint8, AUTOMATIC, AUTOMATIC) errorId) +{ + Std_ReturnType retVal = E_NOT_OK; + + /* Job id is reliable - Get the partition from the job */ + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + /* Check the initialization state of the partition */ + if (Csm_GetPartitionDataInitialized(partition) != CSM_INITIALIZED) + { + *errorId = CSM_E_UNINIT; /* SBSW_WRITE_TO_PASSED_LOCAL_STACK_VARIABLE */ + } +# if (CSM_MULTI_PARTITION_RUNTIME_CHECKS == STD_ON) + /* Check if the currently executing partition matches the configured partition */ + else if (Csm_GetPartitionIdx() != partition) + { + *errorId = CSM_E_INVALID_PARTITION; /* SBSW_WRITE_TO_PASSED_LOCAL_STACK_VARIABLE */ + } +# endif + else + { + retVal = E_OK; + } + +# if (CSM_NUMBER_OF_PARTITIONS <= 1u) + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_NUMBER_OF_PARTITIONS <= 1u) */ + + return retVal; +} /* Csm_VerifyInitAndPartition() */ +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + +/********************************************************************************************************************** + * Csm_GetPartitionOfJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +CSM_LOCAL_INLINE FUNC(Csm_SizeOfPartitionIdentifiersType, CSM_CODE) Csm_GetPartitionOfJob(uint32 jobId) +{ + return Csm_GetPartitionConfigIdxOfQueueInfo(Csm_GetQueueInfoIdxOfJobTable(jobId)); +} +#endif /* (CSM_JOB == STD_ON) */ + +#if ((CSM_DEV_ERROR_DETECT == STD_ON) || (CSM_JOB == STD_ON)) +/********************************************************************************************************************** + * Csm_GetPartitionIdx() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +CSM_LOCAL_INLINE FUNC(Csm_SizeOfPartitionIdentifiersType, CSM_CODE) Csm_GetPartitionIdx(void) +{ + Csm_SizeOfPartitionIdentifiersType partIdx = Csm_GetSizeOfPartitionIdentifiers(); + +# if (CSM_NUMBER_OF_PARTITIONS > 1u) + ApplicationType currentApplicationId = GetApplicationID(); + + /* Iterate over all available partitions */ + Csm_SizeOfPartitionIdentifiersType index = 0u; + + for (index = 0u; index < Csm_GetSizeOfPartitionIdentifiers(); index++) + { + /* Check if the application id match with one of the configured application id's */ + if (currentApplicationId == Csm_GetPartitionSNVOfPartitionIdentifiers(index)) + { + partIdx = index; + break; + } + } +# else /* !(CSM_NUMBER_OF_PARTITIONS > 1u) */ + partIdx = 0u; +# endif + /* Return the index of the configured partition */ + return partIdx; +} /* Csm_GetPartitionIdx() */ +#endif /* ((CSM_DEV_ERROR_DETECT == STD_ON) || (CSM_JOB == STD_ON)) */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * Csm_InitMemory_Local() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +FUNC(void, CSM_CODE) Csm_InitMemory_Local(Csm_SizeOfPartitionIdentifiersType partition) +{ + /* ----- Implementation ----------------------------------------------- */ +#if (CSM_DEV_ERROR_DETECT == STD_ON) + /* Initialize the initialization flag of the calling partition. */ + Csm_SetPartitionDataInitialized(CSM_UNINIT, partition); /* SBSW_CSM_WRITE_PARTITION_DATA */ +#endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +} /* Csm_InitMemory_Local() */ + +/********************************************************************************************************************** + * Csm_Init() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6010, 6030, 6080 1 */ /* MD_MSR_STPTH */ /* MD_MSR_STCYC */ /* MD_MSR_STMIF */ +FUNC(void, CSM_CODE) Csm_Init(void) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CSM_E_NO_ERROR; + +#if ((CSM_DEV_ERROR_DETECT == STD_ON) || (CSM_JOB == STD_ON)) + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionIdx(); +#endif + /* ----- Development Error Checks ------------------------------------- */ +#if (CSM_DEV_ERROR_DETECT == STD_ON) +# if (CSM_NUMBER_OF_PARTITIONS > 1u) + /* #10 Check initialization state */ + if (partition >= Csm_GetSizeOfPartitionIdentifiers()) + { + errorId = CSM_E_INVALID_PARTITION; + } + else +# endif /* (CSM_NUMBER_OF_PARTITIONS > 1u) */ + if (Csm_GetPartitionDataInitialized(partition) == (uint8)CSM_INITIALIZED) + { + errorId = CSM_E_ALREADY_INITIALIZED; + } + else +#endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { +#if (CSM_JOB == STD_ON) + uint32_least index; + P2VAR(Crypto_JobType, AUTOMATIC, AUTOMATIC) job; + /* ----- Implementation ----------------------------------------------- */ + /* #20 Initialize job input/output buffer */ + for (index = 0u; index < Csm_GetSizeOfJob(partition); index++) + { + job = Csm_GetAddrJob(index, partition); + job->jobState = CRYPTO_JOBSTATE_IDLE; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.inputPtr = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.inputLength = 0u; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.secondaryInputPtr = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.secondaryInputLength = 0u; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.tertiaryInputPtr = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.tertiaryInputLength = 0u; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.outputPtr = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.outputLengthPtr = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.secondaryOutputPtr = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.secondaryOutputLengthPtr = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.verifyPtr = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ +# if (CSM_JOB_TYPE_LAYOUT_INPUT64 == STD_ON) + job->jobPrimitiveInputOutput.input64 = 0u; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ +# endif +# if (CSM_JOB_TYPE_LAYOUT_OUTPUT64_PTR == STD_ON) + job->jobPrimitiveInputOutput.output64Ptr = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ +# endif + job->jobPrimitiveInputOutput.mode = 0u; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->cryptoKeyId = 0u; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobId = CSM_EMPTY_JOB; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPriority = 0u; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ +# if (CSM_JOB_TYPE_LAYOUT_ASR430_COMPATIBILITY == STD_ON) + job->PrimitiveInputOutput = job->jobPrimitiveInputOutput; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->state = CRYPTO_JOBSTATE_IDLE; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ +# endif + + /* The following initialization is not necessarily needed and done for consistency. */ + job->jobPrimitiveInputOutput.cryIfKeyId = 0u; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInputOutput.targetCryIfKeyId = 0u; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->jobPrimitiveInfo = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + job->targetCryptoKeyId = 0u; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ + +# if (CSM_JOB_TYPE_LAYOUT_REDIRECTION_INFO_REF == STD_ON) && (CSM_JOB_TYPE_LAYOUT_FIELD_ORDERING == CSM_ASR_VERSION_R21_11) + job->jobRedirectionInfoRef = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ +# endif +# if (CSM_JOB_TYPE_LAYOUT_REDIRECTION_INFO_REF == STD_ON) && (CSM_JOB_TYPE_LAYOUT_FIELD_ORDERING == CSM_ASR_VERSION_4_03) + job->jobRedirectionInfoRef = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ +# endif +# if (CSM_JOB_TYPE_LAYOUT_JOB_INFO_PTR == STD_ON) + job->jobInfo = NULL_PTR; /* SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION */ +# endif + } + + for (index = 0u; index < Csm_GetSizeOfJobTable(); index++) + { +# if (CSM_NUMBER_OF_PARTITIONS > 1u) + /* #21 Check if the job relates to the current application */ + if (Csm_GetPartitionOfJob((uint32)index) == partition) +# endif + { +# if (CSM_JOBIDXOFJOBTABLE == STD_ON) +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) + if (Csm_IsJobUsedOfJobTable(index) == TRUE) +# endif + { + job = Csm_GetAddrJob(Csm_GetJobIdxOfJobTable(index), partition); + job->jobPrimitiveInfo = Csm_GetAddrJobPrimitiveInfo(Csm_GetJobPrimitiveInfoIdxOfJobTable(index)); /* SBSW_CSM_WRITE_TO_JOB_BY_JOBTABLE */ +# if (CSM_JOB_TYPE_LAYOUT_JOB_INFO_PTR == STD_ON) + job->jobInfo = Csm_GetAddrJobInfo(Csm_GetJobInfoIdxOfJobTable(index)); /* SBSW_CSM_WRITE_TO_JOB_BY_JOBTABLE */ +# endif + job->jobId = (uint32)index; /* SBSW_CSM_WRITE_TO_JOB_BY_JOBTABLE */ + job->jobPriority = Csm_GetPriorityOfJobTable(index); /* SBSW_CSM_WRITE_TO_JOB_BY_JOBTABLE */ + } +# endif /* (CSM_JOBIDXOFJOBTABLE == STD_ON) */ + Csm_SetJobState(index, CSM_JOB_STATE_IDLE, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + } + } + + /* #30 Init queues */ + for (index = 0u; index < Csm_GetSizeOfQueueInfo(); index++) + { +# if (CSM_NUMBER_OF_PARTITIONS > 1u) + /* Check if the queue relates to the current application */ + if (Csm_GetPartitionConfigIdxOfQueueInfo(index) == partition) +# endif + { + Csm_SetQueueIdxOfQueueState(index, Csm_GetQueueStartIdxOfQueueInfo(index), partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_PARTITION_DEPENDENT_SEARCHED */ + Csm_SetLockOfQueueState(index, 0u, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_PARTITION_DEPENDENT_SEARCHED */ + +# if ((CSM_ASYNC_PROCESSING == STD_ON) && (CSM_TRIGGERASYNCHJOBSINCALLBACKOFQUEUEINFO == STD_ON)) + if (Csm_IsTriggerAsynchJobsInCallbackOfQueueInfo(index)) /* PRQA S 4304 */ /* MD_MSR_AutosarBoolean */ + { + Csm_SetRetriggeringOfQueueState(index, CSM_ASYNC_JOB_RETRIGGER_STATE_IDLE, partition); /* SBSW_CSM_WRITE_TO_QUEUESTATE_PARTITION_DEPENDENT_SEARCHED */ + } +# endif + } + } + +# if (CSM_CALLOUT == STD_ON) + /* Initialize Callout State */ + for (index = 0u; index < Csm_GetSizeOfCalloutState(partition); index++) + { + Csm_SetCalloutStateOfCalloutState(index, CSM_CALLOUT_STATE_IDLE, partition); /* SBSW_CSM_WRITE_TO_CALLOUT_STATE_BY_SIZE_AND_PARTITION */ + } +# endif /* (CSM_CALLOUT == STD_ON) */ + +# if (CSM_RTECALLBACK == STD_ON) + Csm_SetRteCallbackOccurred(FALSE, partition); /* SBSW_CSM_CSL_VAR_ACCESS */ + for (index = 0u; index < Csm_GetSizeOfRteResult(partition); index++) + { + Csm_SetRteResult(index, CSM_CALLBACK_IDLE, partition); /* SBSW_CSM_WRITE_TO_RTERESULT_BY_SIZE */ + } +# endif /* (CSM_RTECALLBACK == STD_ON) */ + +#endif /* (CSM_JOB == STD_ON) */ + +#if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #40 Set CSM initialization state to initialized */ + Csm_SetPartitionDataInitialized(CSM_INITIALIZED, partition); /* SBSW_CSM_WRITE_PARTITION_DATA */ +#endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + + } + /* ----- Development Error Report --------------------------------------- */ +#if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError(CSM_MODULE_ID, CSM_INSTANCE_ID, CSM_INIT_ID, errorId); + } +#else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* (CSM_DEV_ERROR_REPORT == STD_ON) */ +#if ((CSM_DEV_ERROR_DETECT == STD_ON) || (CSM_JOB == STD_ON)) + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif +} /* Csm_Init() */ + +#if (CSM_VERSION_INFO_API == STD_ON) +/********************************************************************************************************************** + * Csm_GetVersionInfo() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, CSM_CODE) Csm_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, CSM_APPL_VAR) versioninfo) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + if (versioninfo == NULL_PTR) + { + errorId = CSM_E_PARAM_POINTER; + } + else +# endif /* (CSM_DEV_ERROR_REPORT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + versioninfo->vendorID = (uint16)CSM_VENDOR_ID; /* SBSW_CSM_GETVERSIONINFO */ + versioninfo->moduleID = (uint8)CSM_MODULE_ID; /* SBSW_CSM_GETVERSIONINFO */ + versioninfo->sw_major_version = (uint8)CSM_SW_MAJOR_VERSION; /* SBSW_CSM_GETVERSIONINFO */ + versioninfo->sw_minor_version = (uint8)CSM_SW_MINOR_VERSION; /* SBSW_CSM_GETVERSIONINFO */ + versioninfo->sw_patch_version = (uint8)CSM_SW_PATCH_VERSION; /* SBSW_CSM_GETVERSIONINFO */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)CSM_GETVERSIONINFO_ID, errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ +} /* Csm_GetVersionInfo() */ +#endif /* (CSM_VERSION_INFO_API == STD_ON) */ + +/********************************************************************************************************************** + * Csm_MainFunction_Local() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080, 6030 1 */ /* MD_MSR_STMIF */ /* MD_MSR_STCYC */ +FUNC(void, CSM_CODE) Csm_MainFunction_Local(Csm_SizeOfPartitionIdentifiersType partition) +{ +#if (CSM_JOB == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + if (partition >= Csm_GetSizeOfPartitionIdentifiers()) + { + errorId = CSM_E_INVALID_PARTITION; + } + /* #10 Check initialization state */ + else if (Csm_GetPartitionDataInitialized(partition) != CSM_INITIALIZED) + { + errorId = CSM_E_UNINIT; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { +# if (CSM_ASYNC_PROCESSING == STD_ON) + + Csm_QueueInfoIterType queueInfoIdx; +# if (CSM_TRIGGERASYNCHJOBSINCALLBACKOFQUEUEINFO == STD_ON) + Csm_QueueIterType triggerCounter; +# endif + + /* ----- Implementation ----------------------------------------------- */ + + /* #20 Loop over configured queues and trigger asynchronous job processing */ + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + for (queueInfoIdx = 0u; queueInfoIdx < Csm_GetSizeOfQueueInfo(); queueInfoIdx++) + { +# if (CSM_NUMBER_OF_PARTITIONS > 1u) + if (Csm_GetPartitionConfigIdxOfQueueInfo(queueInfoIdx) == partition) +# endif + { +# if (CSM_TRIGGERASYNCHJOBSINCALLBACKOFQUEUEINFO == STD_ON) + if (Csm_IsTriggerAsynchJobsInCallbackOfQueueInfo(queueInfoIdx)) /* PRQA S 4304 */ /* MD_MSR_AutosarBoolean */ + { + /* #30 Check whether retriggering of asynchronous job processing has halted. If so, trigger it again. */ + /* The following difference is calculated from generated table values and assumed to be always greater or equal than 0 */ + for (triggerCounter = 0u; triggerCounter < ((Csm_QueueIterType)(Csm_GetQueueEndIdxOfQueueInfo(queueInfoIdx)) - (Csm_QueueIterType)(Csm_GetQueueStartIdxOfQueueInfo(queueInfoIdx))); triggerCounter++) /* FETA_CSM_STRICTLY_INCREASING_BY_ONE */ + { + Csm_TriggerAsynchJobProcessing(queueInfoIdx); + + if (Csm_GetRetriggeringOfQueueState(queueInfoIdx, partition) == CSM_ASYNC_JOB_RETRIGGER_STATE_IDLE) + { + break; + } + } + } + else +# endif /* (CSM_TRIGGERASYNCHJOBSINCALLBACKOFQUEUEINFO == STD_ON) */ + { + Csm_TriggerAsynchJobProcessing(queueInfoIdx); + } + } + } + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + + /* #40 Handle callback notifications if processing has been aborted by callouts */ +# if (CSM_CALLOUT == STD_ON) + { + Csm_CalloutInfoIterType calloutInfoIdx; + for (calloutInfoIdx = 0u; calloutInfoIdx < Csm_GetSizeOfCalloutInfo(); calloutInfoIdx++) + { + if (Csm_GetCalloutStateOfCalloutState(calloutInfoIdx, partition) == CSM_CALLOUT_STATE_PROCESSING_ABORTED_BY_CALLOUT) + { + Csm_CallbackNotification(Csm_GetAddrJob(Csm_GetJobToObjMap(Csm_GetJobTableIdxOfCalloutInfo(calloutInfoIdx), partition), partition), E_NOT_OK); /* SBSW_CSM_PASS_JOB_POINTER_CSL03 */ + } + } + } +# endif /* (CSM_CALLOUT == STD_ON) */ + +# if (CSM_RTECALLBACK == STD_ON) + Csm_HandleRteCallbacks(partition); +# endif + +# endif /* (CSM_ASYNC_PROCESSING == STD_ON) */ + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_MAINFUNCTION_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ +#endif /* (CSM_JOB == STD_ON) */ + + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +} /* Csm_MainFunction_Local() */ + +/********************************************************************************************************************** + * Csm_CallbackNotification() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ + /* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(void, CSM_CODE) Csm_CallbackNotification( + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + Crypto_ResultType result) +{ +#if (CSM_JOB == STD_ON) && (CSM_ASYNC_PROCESSING == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = CSM_E_NO_ERROR; + uint8 runtimeErrorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* Verify the job pointer */ + if (job == NULL_PTR) + { + errorId = CSM_E_PARAM_POINTER; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) + /* Ignore not used sharing jobs */ + if (job->jobId == CSM_EMPTY_JOB) + { + /* Ignore Call, job is not used anymore */ + runtimeErrorId = CSM_E_UNEXPECTED_CALLBACK; + } + else +# endif +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* Verify provided jobId */ + if (job->jobId >= Csm_GetSizeOfJobTable()) + { + errorId = CSM_E_PARAM_HANDLE; + } + /* Verify initialization state */ + else if (Csm_VerifyInitAndPartition(job->jobId, &errorId) != E_OK) /* SBSW_CSM_PASS_JOBID_AND_STACK */ + { + /* errorId already set in subfunction */ + } + /* For synchronous jobs, return an error */ + else if (Csm_GetJobPrimitiveInfo(Csm_GetJobPrimitiveInfoIdxOfJobTable(job->jobId)).processingType == CRYPTO_PROCESSING_SYNC) + { + errorId = CSM_E_PARAM_METHOD_INVALID; + } + else if ((result & CSM_JOB_STATE_CALLBACK_OCCURRED) != 0u) + { + errorId = CSM_E_PARAM_METHOD_INVALID; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + Csm_HandleCallbackNotification(job, result, &runtimeErrorId); /* SBSW_CSM_PASS_JOB_POINTER_API_REQUIREMENT_AND_STACK */ + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_CALLBACKNOTIFICATION_ID), errorId); + } + + if (runtimeErrorId != CSM_E_NO_ERROR) + { + (void)Det_ReportRuntimeError(CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_CALLBACKNOTIFICATION_ID), runtimeErrorId); + } +# else + CSM_DUMMY_STATEMENT(job); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(runtimeErrorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_DEV_ERROR_REPORT == STD_ON) */ +#else /* !(CSM_JOB == STD_ON) && (CSM_ASYNC_PROCESSING == STD_ON) */ + CSM_DUMMY_STATEMENT(job); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(result); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif /* (CSM_JOB == STD_ON) && (CSM_ASYNC_PROCESSING == STD_ON) */ + +} /* Csm_CallbackNotification() */ + +/* Csm Key Management Functions */ +/********************************************************************************************************************** + * Csm_KeyElementSet() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementSet( + uint32 keyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) keyPtr, + uint32 keyLength) +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check for null pointers */ + if (keyPtr == NULL_PTR) + { + errorId = CSM_E_PARAM_POINTER; + } + /* #30 Check key range */ + else if (keyId >= Csm_GetSizeOfKey()) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #40 Call of CryIf_KeyElementSet function */ + retVal = CryIf_KeyElementSet(Csm_GetCryIfKeyIdOfKey(keyId), keyElementId, keyPtr, keyLength); /* SBSW_CSM_FORWARDING_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYELEMENTSET_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(keyElementId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT_CONST(keyPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(keyLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_KeyElementSet() */ + +/********************************************************************************************************************** + * Csm_KeySetValid() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeySetValid(uint32 keyId) +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check key range */ + if (keyId >= Csm_GetSizeOfKey()) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #30 Call of CryIf_KeySetValid function */ + retVal = CryIf_KeySetValid(Csm_GetCryIfKeyIdOfKey(keyId)); + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYSETVALID_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_KeySetValid() */ + +/********************************************************************************************************************** + * Csm_KeySetInvalid() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeySetInvalid(uint32 keyId) +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check key range */ + if (keyId >= Csm_GetSizeOfKey()) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #30 Call of CryIf_KeySetInvalid function */ + retVal = CryIf_KeySetInvalid(Csm_GetCryIfKeyIdOfKey(keyId)); + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYSETINVALID_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_KeySetInvalid() */ + +/********************************************************************************************************************** + * Csm_KeyGetStatus() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyGetStatus( + uint32 keyId, + P2VAR(Crypto_KeyStatusType, AUTOMATIC, CSM_APPL_VAR) keyStatusPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check for null pointers */ + if (keyStatusPtr == NULL_PTR) + { + errorId = CSM_E_PARAM_POINTER; + } + /* #30 Check key range */ + else if (keyId >= Csm_GetSizeOfKey()) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #40 Call of CryIf_KeyGetStatus function */ + retVal = CryIf_KeyGetStatus(Csm_GetCryIfKeyIdOfKey(keyId), keyStatusPtr); /* SBSW_CSM_FORWARDING_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYGETSTATUS_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(keyStatusPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_KeyGetStatus() */ + +/********************************************************************************************************************** + * Csm_KeyElementGet() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementGet( + uint32 keyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) keyPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) keyLengthPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check for null pointers */ + if ((keyPtr == NULL_PTR) + || (keyLengthPtr == NULL_PTR)) + { + errorId = CSM_E_PARAM_POINTER; + } + /* #30 Check key range */ + else if (keyId >= Csm_GetSizeOfKey()) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #40 Call of CryIf_KeyElementGet function */ + retVal = CryIf_KeyElementGet(Csm_GetCryIfKeyIdOfKey(keyId), keyElementId, keyPtr, keyLengthPtr); /* SBSW_CSM_FORWARDING_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYELEMENTGET_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(keyElementId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(keyPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(keyLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_KeyElementGet() */ + +/********************************************************************************************************************** + * Csm_KeyElementCopy() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementCopy( + uint32 keyId, + uint32 keyElementId, + uint32 targetKeyId, + uint32 targetKeyElementId) +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check key range */ + if ((keyId >= Csm_GetSizeOfKey()) || (targetKeyId >= Csm_GetSizeOfKey())) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #30 Call of CryIf_KeyElementCopy function */ + retVal = CryIf_KeyElementCopy(Csm_GetCryIfKeyIdOfKey(keyId), keyElementId, Csm_GetCryIfKeyIdOfKey(targetKeyId), targetKeyElementId); + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYELEMENTCOPY_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(keyElementId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(targetKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(targetKeyElementId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_KeyElementCopy() */ + +/********************************************************************************************************************** + * Csm_KeyElementCopyPartial() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementCopyPartial( + uint32 keyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetKeyId, + uint32 targetKeyElementId) +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check key range */ + if ((keyId >= Csm_GetSizeOfKey()) || (targetKeyId >= Csm_GetSizeOfKey())) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #30 Call of CryIf_KeyElementCopyPartial function */ + retVal = CryIf_KeyElementCopyPartial(Csm_GetCryIfKeyIdOfKey(keyId), keyElementId, keyElementSourceOffset, keyElementTargetOffset, keyElementCopyLength, Csm_GetCryIfKeyIdOfKey(targetKeyId), targetKeyElementId); + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYELEMENTCOPYPARTIAL_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(keyElementId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(keyElementSourceOffset); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(keyElementTargetOffset); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(keyElementCopyLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(targetKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(targetKeyElementId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_KEY == STD_ON) */ +} /* Csm_KeyElementCopyPartial() */ + +/********************************************************************************************************************** + * Csm_KeyCopy() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyCopy( + uint32 keyId, + uint32 targetKeyId) +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check key range */ + if ((keyId >= Csm_GetSizeOfKey()) || (targetKeyId >= Csm_GetSizeOfKey())) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #30 Call of CryIf_KeyCopy function */ + retVal = CryIf_KeyCopy(Csm_GetCryIfKeyIdOfKey(keyId), Csm_GetCryIfKeyIdOfKey(targetKeyId)); + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYCOPY_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(targetKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_KeyCopy() */ + +/********************************************************************************************************************** + * Csm_RandomSeed() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_RandomSeed( + uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) seedPtr, + uint32 seedLength) +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check for null pointers */ + if (seedPtr == NULL_PTR) + { + errorId = CSM_E_PARAM_POINTER; + } + /* #30 Check key range */ + else if (keyId >= Csm_GetSizeOfKey()) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #40 Call of CryIf_RandomSeed function */ + retVal = CryIf_RandomSeed(Csm_GetCryIfKeyIdOfKey(keyId), seedPtr, seedLength); /* SBSW_CSM_FORWARDING_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_RANDOMSEED_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT_CONST(seedPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(seedLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_RandomSeed() */ + +/********************************************************************************************************************** + * Csm_KeyGenerate() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyGenerate(uint32 keyId) +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check key range */ + if (keyId >= Csm_GetSizeOfKey()) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #30 Call of CryIf_KeyGenerate function */ + retVal = CryIf_KeyGenerate(Csm_GetCryIfKeyIdOfKey(keyId)); + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYGENERATE_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_KeyGenerate() */ + +/********************************************************************************************************************** + * Csm_KeyDerive() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyDerive( + uint32 keyId, + uint32 targetKeyId) +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check key range */ + if ((keyId >= Csm_GetSizeOfKey()) || (targetKeyId >= Csm_GetSizeOfKey())) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #30 Call of CryIf_KeyDerive function */ + retVal = CryIf_KeyDerive(Csm_GetCryIfKeyIdOfKey(keyId), Csm_GetCryIfKeyIdOfKey(targetKeyId)); + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYDERIVE_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(targetKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_KeyDerive() */ + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcPubVal() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcPubVal( + uint32 keyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check for null pointers */ + if ((publicValuePtr == NULL_PTR) + || (publicValueLengthPtr == NULL_PTR)) + { + errorId = CSM_E_PARAM_POINTER; + } + /* #30 Check key range */ + else if (keyId >= Csm_GetSizeOfKey()) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #40 Call of CryIf_KeyExchangeCalcPubVal function */ + retVal = CryIf_KeyExchangeCalcPubVal(Csm_GetCryIfKeyIdOfKey(keyId), publicValuePtr, publicValueLengthPtr); /* SBSW_CSM_FORWARDING_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYEXCHANGECALCPUBVAL_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(publicValuePtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(publicValueLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_KeyExchangeCalcPubVal() */ + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcSecret() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcSecret( + uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check for null pointers */ + if (partnerPublicValuePtr == NULL_PTR) + { + errorId = CSM_E_PARAM_POINTER; + } + /* #30 Check key range */ + else if (keyId >= Csm_GetSizeOfKey()) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #40 Call of CryIf_KeyExchangeCalcSecret function */ + retVal = CryIf_KeyExchangeCalcSecret(Csm_GetCryIfKeyIdOfKey(keyId), partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CSM_FORWARDING_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_KEYEXCHANGECALCSECRET_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(partnerPublicValuePtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(partnerPublicValueLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_KeyExchangeCalcSecret() */ + +/********************************************************************************************************************** + * Csm_CertificateParse() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_CertificateParse(uint32 keyId) +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check key range */ + if (keyId >= Csm_GetSizeOfKey()) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #30 Call of CryIf_CertificateParse function */ + retVal = CryIf_CertificateParse(Csm_GetCryIfKeyIdOfKey(keyId)); + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_CERTIFICATEPARSE_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_CertificateParse() */ + +/********************************************************************************************************************** + * Csm_CertificateVerify() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_CertificateVerify( + uint32 keyId, + uint32 verifyKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_KEY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #20 Check for null pointers */ + if (verifyPtr == NULL_PTR) + { + errorId = CSM_E_PARAM_POINTER; + } + /* #30 Check key range */ + else if ((keyId >= Csm_GetSizeOfKey()) || (verifyKeyId >= Csm_GetSizeOfKey())) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + /* #40 Call of CryIf_CertificateVerify function */ + retVal = CryIf_CertificateVerify(Csm_GetCryIfKeyIdOfKey(keyId), Csm_GetCryIfKeyIdOfKey(verifyKeyId), verifyPtr); /* SBSW_CSM_FORWARDING_PTR */ + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_CERTIFICATEVERIFY_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_KEY == STD_ON) */ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(verifyKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(verifyPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_KEY == STD_ON) */ +} /* Csm_CertificateVerify() */ + +/********************************************************************************************************************** + * Csm_CancelJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJob( + uint32 jobId, + Crypto_OperationModeType mode) +{ +#if (CSM_JOB == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided jobId */ + if (jobId >= Csm_GetSizeOfJobTable()) + { + errorId = CSM_E_PARAM_HANDLE; + } + /* #20 Verify initialization state */ + else if (Csm_VerifyInitAndPartition(jobId, &errorId) != E_OK) /* SBSW_CSM_PASS_JOBID_AND_STACK */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + + if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_IDLE) + { + /* #30 If Job is idle - No canceling needed */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + retVal = E_OK; + } + else + { + /* Job is running, object exists */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job = Csm_GetAddrJob(Csm_GetJobToObjMap(jobId, partition), partition); + +# if (CSM_ASYNC_PROCESSING == STD_ON) + if (Csm_IsAsynchronousOfJobTable(jobId)) + { + retVal = Csm_CancelAsynchronousJob(job, partition); /* SBSW_CSM_PASS_JOB_AND_PARTITION */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + else +# endif /* (CSM_ASYNC_PROCESSING == STD_ON) */ + if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_ACTIVE) + { + Csm_SetJobState(jobId, CSM_JOB_STATE_CANCELING, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + + /* #55 Cancel Job in lower layer */ + retVal = CryIf_CancelJob(Csm_GetChannelIdOfQueueInfo(Csm_GetQueueInfoIdxOfJobTable(jobId)), job); /* SBSW_CSM_PASS_JOB */ + + if (retVal == E_OK) + { + /* #56 Canceling successful - Call post-job callout and free job oject */ +# if (CSM_CALLOUT == STD_ON) + /* retVal only acts as information for post job callout that job was cancelled. + * Set it back to E_OK in each case as canceling was already performed. */ + retVal = CRYPTO_E_JOB_CANCELED; + Csm_CallPostJobCallout(job, &retVal, partition); /* SBSW_CSM_PASS_JOB_STACK_AND_PARTITION */ + retVal = E_OK; +# endif +# if (CSM_JOBSHARINGOFQUEUEINFO == STD_ON) + job->jobId = CSM_EMPTY_JOB; /* SBSW_CSM_WRITE_TO_JOB_POINTER */ +# endif + Csm_SetJobState(jobId, CSM_JOB_STATE_IDLE, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + } + else + { + /* #57 Canceling failed, set active again */ + Csm_SetJobState(jobId, CSM_JOB_STATE_ACTIVE, partition); /* SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION */ + } + } + else + { + /* #60 Job cancelation is not possible as the job is currently in or on the way to the lower layer. + * If job is currently on the way to the lower layer, Crypto would return E_OK as it does not know the job yet + * Due to this, Csm cannot rely on the return value. + */ + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + /* retVal already set to E_NOT_OK */ + } + } +# if (CSM_NUMBER_OF_PARTITIONS <= 1u) + CSM_DUMMY_STATEMENT(partition); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* (CSM_NUMBER_OF_PARTITIONS <= 1u) */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_CANCELJOB_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + return retVal; +#else /* !(CSM_JOB == STD_ON) */ + + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_JOB == STD_ON) */ +} /* Csm_CancelJob() */ + +/* Csm Service Functions */ + +/********************************************************************************************************************** + * Csm_Hash() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_Hash( + uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_EXIST_HASH == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParamAndMode(jobId, &errorId, CRYPTO_HASH, mode) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = mode; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = dataPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = dataLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputPtr = resultPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputLengthPtr = resultLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_HASH_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_HASH == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(resultPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(resultLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_EXIST_HASH == STD_ON) */ +} /* Csm_Hash() */ + +/********************************************************************************************************************** + * Csm_MacGenerate() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerate( + uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_EXIST_MACGENERATE == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParamAndMode(jobId, &errorId, CRYPTO_MACGENERATE, mode) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = mode; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = dataPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = dataLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputPtr = macPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputLengthPtr = macLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_MACGENERATE_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_MACGENERATE == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(macPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(macLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_EXIST_MACGENERATE == STD_ON) */ +} /* Csm_MacGenerate() */ + +/********************************************************************************************************************** + * Csm_MacVerify() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerify( + uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_EXIST_MACVERIFY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParamAndMode(jobId, &errorId, CRYPTO_MACVERIFY, mode) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = mode; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = dataPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = dataLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryInputPtr = macPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryInputLength = macLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.verifyPtr = verifyPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_MACVERIFY_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_MACVERIFY == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(macPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(macLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(verifyPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_EXIST_MACVERIFY == STD_ON) */ +} /* Csm_MacVerify() */ + +/********************************************************************************************************************** + * Csm_Encrypt() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_Encrypt( + uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_EXIST_ENCRYPT == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParamAndMode(jobId, &errorId, CRYPTO_ENCRYPT, mode) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = mode; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = dataPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = dataLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputPtr = resultPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputLengthPtr = resultLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_ENCRYPT_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_ENCRYPT == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(resultPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(resultLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_EXIST_ENCRYPT == STD_ON) */ +} /* Csm_Encrypt() */ + +/********************************************************************************************************************** + * Csm_Decrypt() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_Decrypt( + uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_EXIST_DECRYPT == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParamAndMode(jobId, &errorId, CRYPTO_DECRYPT, mode) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = mode; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = dataPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = dataLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputPtr = resultPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputLengthPtr = resultLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_DECRYPT_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_DECRYPT == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(resultPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(resultLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_EXIST_DECRYPT == STD_ON) */ +} /* Csm_Decrypt() */ + +/********************************************************************************************************************** + * Csm_AEADEncrypt() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncrypt( + uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_EXIST_AEADENCRYPT == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParamAndMode(jobId, &errorId, CRYPTO_AEADENCRYPT, mode) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = mode; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = plaintextPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = plaintextLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryInputPtr = associatedDataPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryInputLength = associatedDataLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputPtr = ciphertextPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputLengthPtr = ciphertextLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryOutputPtr = tagPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryOutputLengthPtr = tagLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_AEADENCRYPT_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_AEADENCRYPT == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(plaintextPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(plaintextLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(associatedDataPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(associatedDataLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(ciphertextPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(ciphertextLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(tagPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(tagLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_EXIST_AEADENCRYPT == STD_ON) */ +} /* Csm_AEADEncrypt() */ + +/********************************************************************************************************************** + * Csm_AEADDecrypt() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecrypt( + uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_EXIST_AEADDECRYPT == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParamAndMode(jobId, &errorId, CRYPTO_AEADDECRYPT, mode) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = mode; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = ciphertextPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = ciphertextLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryInputPtr = associatedDataPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryInputLength = associatedDataLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.tertiaryInputPtr = tagPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.tertiaryInputLength = tagLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputPtr = plaintextPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputLengthPtr = plaintextLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.verifyPtr = verifyPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_AEADDECRYPT_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_AEADDECRYPT == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(ciphertextPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(ciphertextLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(associatedDataPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(associatedDataLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(tagPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(tagLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(plaintextPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(plaintextLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(verifyPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_EXIST_AEADDECRYPT == STD_ON) */ +} /* Csm_AEADDecrypt() */ + +/********************************************************************************************************************** + * Csm_SignatureGenerate() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerate( + uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_EXIST_SIGNATUREGENERATE == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParamAndMode(jobId, &errorId, CRYPTO_SIGNATUREGENERATE, mode) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = mode; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = dataPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = dataLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputPtr = resultPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputLengthPtr = resultLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_SIGNATUREGENERATE_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_SIGNATUREGENERATE == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(resultPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(resultLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_EXIST_SIGNATUREGENERATE == STD_ON) */ +} /* Csm_SignatureGenerate() */ + +/********************************************************************************************************************** + * Csm_SignatureVerify() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerify( + uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_EXIST_SIGNATUREVERIFY == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParamAndMode(jobId, &errorId, CRYPTO_SIGNATUREVERIFY, mode) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = mode; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = dataPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = dataLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryInputPtr = signaturePtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryInputLength = signatureLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.verifyPtr = verifyPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_SIGNATUREVERIFY_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_SIGNATUREVERIFY == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(mode); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(dataLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(signaturePtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(signatureLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(verifyPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_EXIST_SIGNATUREVERIFY == STD_ON) */ +} /* Csm_SignatureVerify() */ + +/********************************************************************************************************************** + * Csm_RandomGenerate() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_RandomGenerate( + uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_EXIST_RANDOMGENERATE == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParam(jobId, &errorId, CRYPTO_RANDOMGENERATE) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputPtr = resultPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputLengthPtr = resultLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_RANDOMGENERATE_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_RANDOMGENERATE == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(resultPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(resultLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_EXIST_RANDOMGENERATE == STD_ON) */ +} /* Csm_RandomGenerate() */ + +/********************************************************************************************************************** + * Csm_JobKeySetValid() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobKeySetValid( uint32 jobId ) +{ +#if (CSM_EXIST_JOBKEYSETVALID == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParam(jobId, &errorId, CRYPTO_KEYSETVALID) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.cryIfKeyId = job->jobPrimitiveInfo->cryIfKeyId; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError( (uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_JOBKEYSETVALID_ID), errorId ); + } +# else + CSM_DUMMY_STATEMENT( errorId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_JOBKEYSETVALID == STD_ON) */ + CSM_DUMMY_STATEMENT( jobId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_EXIST_JOBKEYSETVALID == STD_ON) */ +} /* Csm_JobKeySetValid() */ + +/********************************************************************************************************************** + * Csm_JobKeySetValid44x() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobKeySetValid44x( uint32 jobId, uint32 keyId ) +{ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + return Csm_JobKeySetValid(jobId); +} /* Csm_JobKeySetValid44x() */ + +/********************************************************************************************************************** + * Csm_JobKeySetInvalid() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeySetInvalid(uint32 jobId) +{ +#if (CSM_EXIST_JOBKEYSETINVALID == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParam(jobId, &errorId, CRYPTO_KEYSETINVALID) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.cryIfKeyId = job->jobPrimitiveInfo->cryIfKeyId; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_JOBKEYSETINVALID_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_JOBKEYSETINVALID == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_EXIST_JOBKEYSETVALID == STD_ON) */ +} /* Csm_JobKeySetInvalid() */ + +/********************************************************************************************************************** + * Csm_JobKeySetInvalid44x() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobKeySetInvalid44x( uint32 jobId, uint32 keyId ) +{ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + return Csm_JobKeySetInvalid(jobId); +} /* Csm_JobKeySetInvalid44x() */ + +/********************************************************************************************************************** + * Csm_JobRandomSeed() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobRandomSeed( + uint32 jobId, P2CONST( uint8, AUTOMATIC, CSM_APPL_VAR ) seedPtr, + uint32 seedLength) +{ +#if (CSM_EXIST_JOBRANDOMSEED == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParam(jobId, &errorId, CRYPTO_RANDOMSEED) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.cryIfKeyId = job->jobPrimitiveInfo->cryIfKeyId; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = seedPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = seedLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError( (uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_JOBRANDOMSEED_ID), errorId ); + } +# else + CSM_DUMMY_STATEMENT( errorId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_JOBRANDOMSEED == STD_ON) */ + CSM_DUMMY_STATEMENT_CONST( jobId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT_CONST( seedPtr ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT( seedLength ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_EXIST_JOBRANDOMSEED == STD_ON) */ +} /* Csm_JobRandomSeed() */ + +/********************************************************************************************************************** + * Csm_JobRandomSeed44x() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobRandomSeed44x( + uint32 jobId, + uint32 keyId, + P2CONST( uint8, AUTOMATIC, CSM_APPL_VAR ) seedPtr, + uint32 seedLength ) +{ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + return Csm_JobRandomSeed(jobId, seedPtr, seedLength); /* SBSW_CSM_FORWARDING_PTR */ +} /* Csm_JobRandomSeed44x() */ + +/********************************************************************************************************************** + * Csm_JobKeyGenerate() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobKeyGenerate( uint32 jobId ) +{ +#if (CSM_EXIST_JOBKEYGENERATE == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParam(jobId, &errorId, CRYPTO_KEYGENERATE) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.cryIfKeyId = job->jobPrimitiveInfo->cryIfKeyId; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError( (uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_JOBKEYGENERATE_ID), errorId ); + } +# else + CSM_DUMMY_STATEMENT( errorId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_JOBKEYGENERATE == STD_ON) */ + CSM_DUMMY_STATEMENT( jobId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_EXIST_JOBKEYGENERATE == STD_ON) */ +} /* Csm_JobKeyGenerate() */ + +/********************************************************************************************************************** + * Csm_JobKeyGenerate44x() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobKeyGenerate44x( uint32 jobId, uint32 keyId ) +{ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + return Csm_JobKeyGenerate(jobId); +} /* Csm_JobKeyGenerate44x() */ + +/********************************************************************************************************************** + * Csm_JobKeyDerive() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobKeyDerive( + uint32 jobId, + uint32 targetKeyId) +{ +#if (CSM_EXIST_JOBKEYDERIVE == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParam(jobId, &errorId, CRYPTO_KEYDERIVE) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else if (targetKeyId >= Csm_GetSizeOfKey()) + { + errorId = CSM_E_PARAM_HANDLE; + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.cryIfKeyId = job->jobPrimitiveInfo->cryIfKeyId; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.targetCryIfKeyId = Csm_GetCryIfKeyIdOfKey( targetKeyId ); /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError( (uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_JOBKEYDERIVE_ID), errorId ); + } +# else + CSM_DUMMY_STATEMENT( errorId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_JOBKEYDERIVE == STD_ON) */ + CSM_DUMMY_STATEMENT( jobId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT( targetKeyId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_EXIST_JOBKEYDERIVE == STD_ON) */ +} /* Csm_JobKeyDerive() */ + +/********************************************************************************************************************** + * Csm_JobKeyDerive44x() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobKeyDerive44x( uint32 jobId, uint32 keyId, uint32 targetKeyId ) +{ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + return Csm_JobKeyDerive(jobId, targetKeyId); +} /* Csm_JobKeyDerive44x() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubVal() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobKeyExchangeCalcPubVal( + uint32 jobId, + P2VAR( uint8, AUTOMATIC, CSM_APPL_VAR ) publicValuePtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR( uint32, AUTOMATIC, CSM_APPL_VAR ) publicValueLengthPtr ) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_EXIST_JOBKEYEXCHANGECALCPUBVAL == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParam(jobId, &errorId, CRYPTO_KEYEXCHANGECALCPUBVAL) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.cryIfKeyId = job->jobPrimitiveInfo->cryIfKeyId; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputPtr = publicValuePtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputLengthPtr = publicValueLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError( (uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_JOBKEYEXCHANGECALCPUBVAL_ID), errorId ); + } +# else + CSM_DUMMY_STATEMENT( errorId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_JOBKEYEXCHANGECALCPUBVAL == STD_ON) */ + CSM_DUMMY_STATEMENT( jobId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT( publicValuePtr ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT( publicValueLengthPtr ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_EXIST_JOBKEYEXCHANGECALCPUBVAL == STD_ON) */ +} /* Csm_JobKeyExchangeCalcPubVal() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubVal44x() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobKeyExchangeCalcPubVal44x( + uint32 jobId, + uint32 keyId, + P2VAR( uint8, AUTOMATIC, CSM_APPL_VAR ) publicValuePtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR( uint32, AUTOMATIC, CSM_APPL_VAR ) publicValueLengthPtr ) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + return Csm_JobKeyExchangeCalcPubVal(jobId, publicValuePtr, publicValueLengthPtr); /* SBSW_CSM_FORWARDING_PTR */ +} /* Csm_JobKeyExchangeCalcPubVal44x() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecret() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +/* PRQA S 6080 */ /* MD_MSR_STMIF */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobKeyExchangeCalcSecret( + uint32 jobId, + P2CONST( uint8, AUTOMATIC, CSM_APPL_VAR ) partnerPublicValuePtr, + uint32 partnerPublicValueLength ) +{ +#if (CSM_EXIST_JOBKEYEXCHANGECALCSECRET == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParam(jobId, &errorId, CRYPTO_KEYEXCHANGECALCSECRET) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.cryIfKeyId = job->jobPrimitiveInfo->cryIfKeyId; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = partnerPublicValuePtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = partnerPublicValueLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError( (uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_JOBKEYEXCHANGECALCSECRET_ID), errorId ); + } +# else + CSM_DUMMY_STATEMENT( errorId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_JOBKEYEXCHANGECALCSECRET == STD_ON) */ + CSM_DUMMY_STATEMENT( jobId ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT( partnerPublicValuePtr ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT( partnerPublicValueLength ); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_EXIST_JOBKEYEXCHANGECALCSECRET == STD_ON) */ +} /* Csm_JobKeyExchangeCalcSecret() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecret44x() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC( Std_ReturnType, CSM_CODE ) Csm_JobKeyExchangeCalcSecret44x( + uint32 jobId, + uint32 keyId, + P2CONST( uint8, AUTOMATIC, CSM_APPL_VAR ) partnerPublicValuePtr, + uint32 partnerPublicValueLength ) +{ + CSM_DUMMY_STATEMENT(keyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + + return Csm_JobKeyExchangeCalcSecret(jobId, partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CSM_FORWARDING_PTR */ +} /* Csm_JobKeyExchangeCalcSecret44x() */ + +/********************************************************************************************************************** + * Csm_JobKeyWrap() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyWrap(uint32 jobId, + uint32 sourceKeyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) authenticatorPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) authenticatorLengthPtr) +{ +#if (CSM_EXIST_JOBKEYWRAP == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParam(jobId, &errorId, CRYPTO_KEYWRAP) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + job->jobPrimitiveInputOutput.outputPtr = ciphertextPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputLengthPtr = ciphertextLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryOutputPtr = authenticatorPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryOutputLengthPtr = authenticatorLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + job->jobPrimitiveInputOutput.targetCryIfKeyId = Csm_GetCryIfKeyIdOfKey(sourceKeyId); /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.cryIfKeyId = job->jobPrimitiveInfo->cryIfKeyId; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_JOBKEYWRAP_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_JOBKEYWRAP == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(sourceKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(ciphertextPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(ciphertextLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(authenticatorPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(authenticatorLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_EXIST_JOBKEYWRAP == STD_ON) */ +} + +/********************************************************************************************************************** + * Csm_JobKeyUnwrap() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyUnwrap(uint32 jobId, + uint32 targetKeyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) authenticatorPtr, + uint32 authenticatorLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ +#if (CSM_EXIST_JOBKEYUNWRAP == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id, service and partition */ + if (Csm_VerifyJobParam(jobId, &errorId, CRYPTO_KEYUNWRAP) != E_OK) /* SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST */ + { + /* errorId already set in subfunction */ + } + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = ciphertextPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = ciphertextLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + job->jobPrimitiveInputOutput.secondaryInputPtr = authenticatorPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.secondaryInputLength = authenticatorLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + job->jobPrimitiveInputOutput.verifyPtr = verifyPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + job->jobPrimitiveInputOutput.cryIfKeyId = job->jobPrimitiveInfo->cryIfKeyId; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.targetCryIfKeyId = Csm_GetCryIfKeyIdOfKey(targetKeyId); /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_JOBKEYUNWRAP_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_EXIST_JOBKEYUNWRAP == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(targetKeyId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(ciphertextPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(ciphertextLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(authenticatorPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(authenticatorLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(verifyPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* !(CSM_EXIST_JOBKEYUNWRAP == STD_ON) */ +} + + +/********************************************************************************************************************** + * Csm_SaveContextJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SaveContextJob( + uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) contextBufferPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) contextBufferLengthPtr ) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if (CSM_JOB == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided job id */ + if (jobId >= Csm_GetSizeOfJobTable()) + { + errorId = CSM_E_PARAM_HANDLE; + } + /* #11 Verify initialization states */ + else if (Csm_VerifyInitAndPartition(jobId, &errorId) != E_OK) /* SBSW_CSM_PASS_JOBID_AND_STACK */ + { + /* Error already set in subfunction */ + } + /* #12 Check for Null Pointer */ + else if ((contextBufferPtr == NULL_PTR) || (contextBufferLengthPtr == NULL_PTR)) + { + errorId = CSM_E_PARAM_POINTER; + } + /* #13 Check if the correct API was called for the corresponding service */ + else if (Csm_GetJobPrimitiveInfo(Csm_GetJobPrimitiveInfoIdxOfJobTable(jobId)).primitiveInfo->service > CRYPTO_SIGNATUREVERIFY) + { + errorId = CSM_E_SERVICE_TYPE; + } +# if (CSM_OPERATIONMODELIMITATIONOFQUEUEINFO == STD_ON) + /* #14 Check if the queue is limited to jobs in mode single call */ + else if (Csm_IsOperationModeLimitationOfQueueInfo(Csm_GetQueueInfoIdxOfJobTable(jobId))) + { + errorId = CSM_E_PROCESSING_MODE; + } +# endif + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + /* #15 Check if the job state is active */ + if (Csm_GetJobState(jobId, partition) == CSM_JOB_STATE_IDLE) + { + /* retVal is already set to E_NOT_OK */ + } + else + { + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SAVE_CONTEXT; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputPtr = contextBufferPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.outputLengthPtr = contextBufferLengthPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_SAVECONTEXTJOB_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_JOB == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(contextBufferPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(contextBufferLengthPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_JOB == STD_ON) */ +} /* Csm_SaveContextJob() */ + +/********************************************************************************************************************** + * Csm_RestoreContextJob() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(Std_ReturnType, CSM_CODE) Csm_RestoreContextJob( + uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) contextBufferPtr, /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ + uint32 contextBufferLength ) +{ +#if (CSM_JOB == STD_ON) + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + uint8 errorId = CSM_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (CSM_DEV_ERROR_DETECT == STD_ON) + /* #10 Verify provided jobId */ + if (jobId >= Csm_GetSizeOfJobTable()) + { + errorId = CSM_E_PARAM_HANDLE; + } + /* #11 Verify initialization states */ + else if (Csm_VerifyInitAndPartition(jobId, &errorId) != E_OK) /* SBSW_CSM_PASS_JOBID_AND_STACK */ + { + /* Error already set in subfunction */ + } + /* #12 Check for Null Pointer */ + else if (contextBufferPtr == NULL_PTR) + { + errorId = CSM_E_PARAM_POINTER; + } + /* #13 Check if the correct API was called for the corresponding service */ + else if (Csm_GetJobPrimitiveInfo(Csm_GetJobPrimitiveInfoIdxOfJobTable(jobId)).primitiveInfo->service > CRYPTO_SIGNATUREVERIFY) + { + errorId = CSM_E_SERVICE_TYPE; + } +# if (CSM_OPERATIONMODELIMITATIONOFQUEUEINFO == STD_ON) + /* #14 Check if the queue is not limited to jobs in mode single call, since in this case restoring +* any context does not make sense */ + else if (Csm_IsOperationModeLimitationOfQueueInfo(Csm_GetQueueInfoIdxOfJobTable(jobId))) + { + errorId = CSM_E_PROCESSING_MODE; + } +# endif + else +# endif /* (CSM_DEV_ERROR_DETECT == STD_ON) */ + { + /* ----- Implementation ----------------------------------------------- */ + P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job; + Csm_SizeOfJobType jobObjId = 0u; + Csm_SizeOfPartitionIdentifiersType partition = Csm_GetPartitionOfJob(jobId); + + SchM_Enter_Csm_CSM_EXCLUSIVE_AREA_0(); + /* #20 Get and fill job object */ + retVal = Csm_GetJobObj(jobId, partition, &jobObjId); /* SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE */ + if (retVal == E_OK) + { + job = Csm_GetAddrJob(jobObjId, partition); + + job->jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_RESTORE_CONTEXT; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputPtr = contextBufferPtr; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + job->jobPrimitiveInputOutput.inputLength = contextBufferLength; /* SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ */ + + /* #21 Process job */ + retVal = Csm_ProcessJob(job, partition); /* SBSW_CSM_PASS_JOB */ + /* SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0 is left in Csm_ProcessJob */ + } + else + { + SchM_Exit_Csm_CSM_EXCLUSIVE_AREA_0(); + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (CSM_DEV_ERROR_REPORT == STD_ON) + if (errorId != CSM_E_NO_ERROR) + { + (void)Det_ReportError((uint16)CSM_MODULE_ID, CSM_INSTANCE_ID, (uint8)(CSM_RESTORECONTEXTJOB_ID), errorId); + } +# else + CSM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif /* !(CSM_DEV_ERROR_REPORT == STD_ON) */ + + return retVal; +#else /* !(CSM_JOB == STD_ON) */ + CSM_DUMMY_STATEMENT(jobId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(contextBufferPtr); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + CSM_DUMMY_STATEMENT(contextBufferLength); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ + return E_NOT_OK; +#endif /* (CSM_JOB == STD_ON) */ +} /* Csm_RestoreContextJob() */ + +#define CSM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Module specific MISRA deviations + *********************************************************************************************************************/ +/* Module specific MISRA deviations: + MD_CSM_QUEUE_BY_QUEUEIDX: + Reason: If Queue variable has only a size of 1, accessing with any index + 1 causes this message. + Risk: Access could be executed causing an invalid memory access. + Prevention: During runtime, loop is only entered if Queue is at least two since index is checked against localQueueIndex. Covered by code review. + + MD_CSM_0316: + Reason: Cast is needed since upper layer Rte expects super type as parameter. + Risk: Wrong type is casted or size does not match. + Prevention: Covered by code review. + + MD_CSM_CALLBACK_DECLARATIONS: + Description: Rule 8.5: An external object or function shall be declared once in one and only one file + Reason: MICROSAR Csm declares its callbacks and pre and post job callouts in its Cfg.h. Modules that also declares them see a double declaration. + Risk: Compile warning or error due to declaration mismatch. + Prevention: Not necessary + */ + +/* SBSW_JUSTIFICATION_BEGIN + + \ID SBSW_CSM_GETVERSIONINFO + \DESCRIPTION The function Csm_GetVersionInfo writes to the object referenced by parameter VersionInfoPtr + \COUNTERMEASURE \N The caller ensures that the pointer passed to the parameter VersionInfoPtr is valid. + + \ID SBSW_CSM_FUNCTION_POINTER + \DESCRIPTION The API call is made using a function pointer which is read using ComStackLib macros. + Pointer might be forwarded. + \COUNTERMEASURE \N The function pointer is read using the passed Id and ComStackLib macros (CSL03). + The pointer are forwarded and assumed to be valid. + + \ID SBSW_CSM_FORWARDING_PTR + \DESCRIPTION Passing received pointer to called function. + \COUNTERMEASURE \N The pointer is forwarded and assumed to be valid. + + \ID SBSW_CSM_PASS_UNCHECKED_JOBID_STACKPTR_AND_CONST + \DESCRIPTION The function passes an unchecked job identifier to a subfunction for verification. Since an unchecked job identifier + is expected, this is safe. Furthermore a pointer to a stack variable of expected size is passed to a synchronous function. + The const value is of the expected size but only used for comparision. + \COUNTERMEASURE \N The job id is verified in the called function. The pointer to the stack variable is of expected size. + [CM_CSM_STACK_VARIABLE] + + \ID SBSW_CSM_PASS_CHECKED_JOBID_PARTITION_AND_STACK_VARIABLE + \DESCRIPTION The function passes a checked job id and a partition read by using job id (CSL03). + Furthermore, a pointer to a stack variable of expected size is passed to the synchronous function. + \COUNTERMEASURE \R The job id was checked and the partition is read using the passed job id and ComStackLib macros (CSL03). + [CM_CSM_STACK_VARIABLE] + + \ID SBSW_CSM_PASS_JOB + \DESCRIPTION A job pointer is passed to the function. This pointer was originally determined by the given and + checked job id. This is done by accessing the job structure from the global job array via + indirection over JobTable or using one of the shared job objects. The shared job objects are + determined by accessing the QueueInfo via indirection over the JobTable. Having the QueueInfo index, + accesses to the global job strucure is done via indirection of QueueInfo. Therefore the pointer always + points to a valid job structure, that is safe to pass to an asynchronous function. + \COUNTERMEASURE \N The job pointer is set using the passed Id and ComStackLib macros (CSL03). + + \ID SBSW_CSM_PASS_JOB_AND_PARTITION + \DESCRIPTION A job pointer is passed to the function. This pointer was originally determined by the given and + checked job id. This is done by accessing the job structure from the global job array via + indirection over JobTable or using one of the shared job objects. The shared job objects are + determined by accessing the QueueInfo via indirection over the JobTable. Having the QueueInfo index, + accesses to the global job strucure is done via indirection of QueueInfo. Therefore the pointer always + points to a valid job structure, that is safe to pass to an asynchronous function + The partition is derived from the job id. + \COUNTERMEASURE \N The job pointer is set using the passed Id and ComStackLib macros (CSL03). + The index for the Partition specific data is either fixed (for single partition use case) or provided by searching the current application id + in the PartitionIdentifiers and using its corresponding partitionIdx (Qualified use-case CSL05 of ComStackLib). + If no partitionIdx can be found, usage of an invalid index is prevented by checking the index to be in acceptable range. + Therefore it is always guaranteed to be in the acceptable range. + + \ID SBSW_CSM_PASS_JOBID_AND_STACK + \DESCRIPTION The function passes a checked job id and a pointer to a stack variable of expected size to a synchronous function. + \COUNTERMEASURE \R The job id was checked if it is in range. + [CM_CSM_STACK_VARIABLE] + + \ID SBSW_CSM_PASS_JOB_STACK_AND_PARTITION + \DESCRIPTION The function passes a checked job pointer (see [SBSW_CSM_PASS_JOB]), a pointer to a stack + variable of expected size and a checked partition index to an synchronous function. + \COUNTERMEASURE \N The function pointer is read using the passed Id and ComStackLib macros (CSL03). + [CM_CSM_STACK_VARIABLE] + + \ID SBSW_CSM_PASS_JOB_POINTER_LOCAL + \DESCRIPTION The function passes a pointer referencing a job. The passed pointer has been initialized and points to a valid job object. + \COUNTERMEASURE \N The pointer is initialized from a local queue. The queue is only filled with valid job objects and therefore always contains valid jobs except when it is empty. In this case, the function is not called. + + \ID SBSW_CSM_PASS_JOB_POINTER_AND_PARTITION_API_REQUIREMENT + \DESCRIPTION The function passes a pointer referencing a job. The passed pointer has been passed by the caller. The API requires that the referenced job is valid. + The function passes a partition index. The passed partition index has been passed by the caller. The API requires that the partition index is valid. + \COUNTERMEASURE \N The caller ensures that the pointer passed as parameter is valid and references a valid object. + The caller ensures that the partition index passed as parameter is valid and references a valid object. + + \ID SBSW_CSM_PASS_JOB_POINTER_PARTITION_AND_STACK_API_REQUIREMENT + \DESCRIPTION The function passes a pointer referencing a job. The passed pointer has been passed by the caller. The API requires that the referenced job is valid. + The function passes a pointer to a stack variable of expected size to an synchronous function. + The function passes a partition index. The passed partition index has been passed by the caller. The API requires that the partition index is valid. + \COUNTERMEASURE \N The caller ensures that the pointer passed as parameter is valid and references a valid object. + The passed stack variable is of expected size + The caller ensures that the partition index passed as parameter is valid and references a valid object. + + \ID SBSW_CSM_PASS_JOB_POINTER_API_REQUIREMENT_AND_STACK + \DESCRIPTION The function passes a pointer referencing a job. The passed pointer has been passed by the caller. The API requires that the referenced job is valid. + The function also passes a pointer to a stack variable of expected size to an synchronous function. + \COUNTERMEASURE \N The caller ensures that the pointer passed as parameter is valid and references a valid object. + + \ID SBSW_CSM_PASS_JOB_POINTER_API_REQUIREMENT + \DESCRIPTION The function passes a pointer referencing a job. The passed pointer has been passed by the caller. The API requires that the referenced job is valid. + \COUNTERMEASURE \N The caller ensures that the pointer passed as parameter is valid and references a valid object. + + \ID SBSW_CSM_PASS_JOB_POINTER_CSL03 + \DESCRIPTION The function passes a pointer referencing a job. The passed pointer is valid since it is an indirection to Job via CalloutInfo. + \COUNTERMEASURE \N Qualified use-case CSL03 of ComStackLib + + \ID SBSW_CSM_PASS_CHANNEL_JOB_POINTER_AND_PARTITION_API_REQUIREMENT + \DESCRIPTION The function passes a pointer referencing a job. The passed pointer has been passed by the caller. The API requires that the referenced job is valid. + The function passes a partition index. The passed partition index has been passed by the caller. The API requires that the partition index is valid. + The channel id is retrieved by the ComStackLib from the qualified job, passed by the caller. + \COUNTERMEASURE \N The caller ensures that the pointer passed as parameter is valid and references a valid object. + The caller ensures that the partition index passed as parameter is valid and references a valid object. + + \ID SBSW_CSM_PASS_QUEUESTATEINDEX + \DESCRIPTION The function passes a queue state index qualified by size. + \COUNTERMEASURE \N Qualified use-case CSL02 of ComStackLib + + \ID SBSW_CSM_WRITE_TO_JOB_POINTER + \DESCRIPTION The function does a write access on the job pointer. See [SBSW_CSM_PASS_JOB] for checking validity of job pointer. + \COUNTERMEASURE \R The pointer is checked when it was passed to the service. + + \ID SBSW_CSM_WRITE_TO_JOB_POINTER_FROM_JOBOBJ + \DESCRIPTION The function does a write access on the job pointer. The job pointer is retrieved from a job object by the ComStackLib. + The job object is qualified by a function. + The used partition index is retrieved by the ComStackLib. + \COUNTERMEASURE \R Qualified use-case CSL 05 of ComStackLib + The job object is verified in the function "Csm_GetJobObj" and inside verified by CSL 02. + + \ID SBSW_WRITE_TO_PASSED_LOCAL_STACK_VARIABLE + \DESCRIPTION The function writes to a pointer which is passed by local caller and located on the stack. + \COUNTERMEASURE \R The calling function ensures that the pointer passed as parameter is valid and references a valid object. + + \ID SBSW_CSM_WRITE_TO_CALLOUT_STATE_BY_SIZE + \DESCRIPTION Access of CalloutState using ComStackLib + \COUNTERMEASURE \N Qualified use-case CSL01 of ComStackLib + + \ID SBSW_CSM_WRITE_TO_CALLOUT_STATE_BY_SIZE_AND_PARTITION + \DESCRIPTION Access of CalloutState using ComStackLib + The used partition index has been passed by the caller. The API requires that the partition index is valid. + \COUNTERMEASURE \N Qualified use-case CSL02, CSL05 of ComStackLib + The caller ensures that the partition index passed as parameter is valid and references a valid object. + + \ID SBSW_CSM_WRITE_TO_JOB_BY_SIZE_OF_PARTITION + \DESCRIPTION Access of Job using ComStackLib + Write of partition specific data using ComStackLib. + \COUNTERMEASURE \N Qualified use-case CSL01 of ComStackLib + The index for the partition specific data is either fixed (for single partition use case) or provided by searching the current application id + in the partitionIdentifiers and using its corresponding partitionIdx (Qualified use-case CSL05 of ComStackLib). + If no partitionIdx can be found, usage of an invalid index is prevented by checking the index to be in acceptable range. + Therefore it is always guaranteed to be in the acceptable range. + + \ID SBSW_CSM_WRITE_TO_JOB_BY_JOBTABLE + \DESCRIPTION Access to Job via indirection over JobTable. + \COUNTERMEASURE \N Qualified use-case CSL03 of ComStackLib + + \ID SBSW_CSM_WRITE_TO_QUEUESTATE_BY_SIZE + \DESCRIPTION Access of QueueState using ComStackLib + \COUNTERMEASURE \N Qualified use-case CSL01 of ComStackLib + + \ID SBSW_CSM_WRITE_TO_QUEUESTATE_API_REQ + \DESCRIPTION Access of QueueState using passed parameters from the caller. The API requires those parameters to be valid. + \COUNTERMEASURE \N The caller ensures that the parameters passed are valid. + + \ID SBSW_CSM_WRITE_TO_QUEUESTATE_BY_JOBID_AND_PARTITION_API_REQ + \DESCRIPTION Access to QueueState via indirection over JobTable. + The used partition index has been passed by the caller. The API requires that the partition index is valid. + \COUNTERMEASURE \N Qualified use-case CSL03 of ComStackLib + The caller ensures that the partition index passed as parameter is valid and references a valid object. + + \ID SBSW_CSM_WRITE_TO_QUEUESTATE_PARTITION_DEPENDENT + \DESCRIPTION Access of QueueState using multi-partition indirection over QueueInfo + \COUNTERMEASURE \N Qualified use-case CSL05 of ComStackLib + + \ID SBSW_CSM_WRITE_TO_QUEUESTATE_PARTITION_DEPENDENT_SEARCHED + \DESCRIPTION Access of QueueState using ComStackLib + Write of partition specific data using ComStackLib. + \COUNTERMEASURE \N Qualified use-case CSL01 of ComStackLib for the queue state index + The index for the partition specific data is either fixed (for single partition use case) or provided by searching the current application id + in the partitionIdentifiers and using its corresponding partitionIdx (Qualified use-case CSL05 of ComStackLib). + If no partitionIdx can be found, usage of an invalid index is prevented by checking the index to be in acceptable range. + Therefore it is always guaranteed to be in the acceptable range. + + \ID SBSW_CSM_WRITE_TO_RTERESULT_BY_SIZE_API_REQ + \DESCRIPTION Access of RteCallback and RteResult with same index using ComStackLib + The used partition index has been passed by the caller. The API requires that the partition index is valid. + \COUNTERMEASURE \N Qualified use-case CSL02 of ComStackLib + The caller ensures that the partition index passed as parameter is valid and references a valid object. + + \ID SBSW_CSM_WRITE_TO_RTERESULT_BY_SIZE + \DESCRIPTION Access of RteCallback and RteResult with same index using ComStackLib + Write of partition specific data using ComStackLib. + \COUNTERMEASURE \N Qualified use-case CSL02 of ComStackLib + The index for the partition specific data is either fixed (for single partition use case) or provided by searching the current application id + in the partitionIdentifiers and using its corresponding partitionIdx (Qualified use-case CSL05 of ComStackLib). + If no partitionIdx can be found, usage of an invalid index is prevented by checking the index to be in acceptable range. + Therefore it is always guaranteed to be in the acceptable range. + + \ID SBSW_CSM_WRITE_TO_RTERESULT_BY_JOBID + \DESCRIPTION Access to RteResult via indirection over JobTable. + The partition id is retrieved from the jobId by the ComStackLib + \COUNTERMEASURE \N Qualified use-case CSL03 of ComStackLib + + \ID SBSW_CSM_WRITE_TO_QUEUE_BY_LOCALIDX + \DESCRIPTION Access to Queue via localQueueIndex which is always checked against its size via indirection over QueueInfo. + The used partition index has been passed by the caller. The API requires that the partition index is valid. + \COUNTERMEASURE \N Qualified use-case CSL03 of ComStackLib + The caller ensures that the partition index passed as parameter is valid and references a valid object. + + \ID SBSW_CSM_WRITE_TO_QUEUE_API_REQ + \DESCRIPTION Access of the queue using passed parameters from the caller. The API requires those parameters to be valid. + \COUNTERMEASURE \N The caller ensures that the parameters passed are valid. + + \ID SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION_API_REQ + \DESCRIPTION Access of JobState and JobTable with same index using ComStackLib + The used partition index has been passed by the caller. The API requires that the partition index is valid. + \COUNTERMEASURE \N Qualified use-case CSL02, CSL05 of ComStackLib + The caller ensures that the partition index passed as parameter is valid and references a valid object. + + \ID SBSW_CSM_WRITE_TO_JOBSTATE_BY_JOBID_AND_PARTITION + \DESCRIPTION Access of JobState and JobTable with same index using ComStackLib + The used partition index is qualified to be in range of 0 to (Csm_GetSizeOfPartitionIdentifiers() - 1) + \COUNTERMEASURE \N Qualified use-case CSL02, CSL05 of ComStackLib + + \ID SBSW_WRITE_TO_OBJECTMAP_BY_JOBID + \DESCRIPTION Access of ObjectMap and JobTable with same index using ComStackLib + \COUNTERMEASURE \N Qualified use-case CSL02 of ComStackLib + + \ID SBSW_CSM_CSL_VAR_ACCESS + \DESCRIPTION A ComStackLib generated variable is accessed. + The used partition index has been passed by the caller. The API requires that the partition index is valid. + \COUNTERMEASURE \N The variable is written using a generated macro of the CSL. It immediately dereferences the variables address without pointer arithmetic. + + \ID SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER + \DESCRIPTION The API call is forwarded to an existing API function. + The API is called with one or more pointers passed from the wrapper API function. + \COUNTERMEASURE \N The called functions in the wrapper functions are API functions that are supposed to be silent. + + \ID SBSW_CSM_WRITE_PARTITION_DATA + \DESCRIPTION Write of partition specific data using ComStackLib. + \COUNTERMEASURE \N The index for the partition specific data is either fixed (for single partition use case) or provided by searching the current application id + in the partitionIdentifiers and using its corresponding partitionIdx. + Therefore the index is guaranteed to be in the acceptable range. +SBSW_JUSTIFICATION_END */ + +/* COUNTERMEASURES_BEGIN + + \CM CM_CSM_STACK_VARIABLE The address of the stack variable is always valid for synchronous call context. + +COUNTERMEASURES_END */ + +/* COV_JUSTIFICATION_BEGIN + \ID COV_CSM_USER_DEFINES + \ACCEPT TX + \ACCEPT XF + \REASON Ifndef is present for redefinition prevention. This allows the user or RTE to manually override this value + while also ensuring that the constant is present if the user or RTE does not override it. + + \ID COV_CSM_LOCAL_DEFINE + \ACCEPT TX + \REASON CSM_LOCAL is not defined externally. + + \ID COV_CSM_ASR_COMPATIBILITY_DEFINE + \ACCEPT XF + \ACCEPT TX + \REASON The behavior was changed in AUTOSAR. To support older AUTOSAR versions, the the defines can be overwritten. + Standard is the behavior of latest AUTOSAR version. + + \ID COV_CSM_ASR_COMPATIBILITY_FUNCTIONS + \ACCEPT XF + \ACCEPT TX + \REASON The Csm header provides function declarations based on the configured AUTOSAR version for the including + module. When Csm implementation itself includes the header, always the newest supported version is set. + +COV_JUSTIFICATION_END */ + +/********************************************************************************************************************** + * FETA JUSTIFICATIONS + *********************************************************************************************************************/ + +/* FETA_JUSTIFICATION_BEGIN + + \ID FETA_CSM_STRICTLY_INCREASING_BY_ONE + \DESCRIPTION Loop is strictly monotonically increasing. Loop variable is only increased by one in each iteration. + Types of loop variable and upper bound are of same same size and overflow is excluded by not + including the highest possible upper bound value in the comparison (e.g. usage of < 255 and not <= 255). + \COUNTERMEASURE \N No countermeasure necessary, loop is terminating. + + \ID FETA_CSM_STRICTLY_DECREASING_BY_ONE + \DESCRIPTION Loop is strictly monotonically decreasing. Loop variable is only decreased by one in each iteration. + Types of loop variable and lower bound are of same same size and overflow is excluded by not + including the lowest possible lower bound value in the comparison (e.g. usage of > 0 and not >= 0). + \COUNTERMEASURE \N No countermeasure necessary, loop is terminating. + + \ID FETA_CSM_STRICTLY_INCREASING_BY_ONE_WITH_PRE_CHECK + \DESCRIPTION Loop is strictly monotonically increasing. Loop variable is only increased by one in each iteration. + Types of loop variable and upper bound are of same same size but overflow is possible due to including + the highest possible value in the comparison (e.g. <= 255). + \COUNTERMEASURE \R A runtime check before the loop limits the upper boundary. + +FETA_JUSTIFICATION_END */ + +/********************************************************************************************************************** + * END OF FILE: Csm.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Csm/Csm.h b/Source/bsw/Csm/Csm.h new file mode 100644 index 0000000..e7e9fa1 --- /dev/null +++ b/Source/bsw/Csm/Csm.h @@ -0,0 +1,1586 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file Csm.h + * \brief MICROSAR Crypto Service Manager (CSM) + * + * \details Implementation of the MICROSAR Crypto Service Manager (CSM) + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2016-10-31 vismss Major rework for ASR 4.3 + * 01.00.01 2016-12-06 vismss Adaption to the specification + * 01.00.02 2016-12-16 vismss ESCAN00093323 Correction of Csm_RandomGenerate + * 01.00.03 2017-01-04 vismss ESCAN00093383 Encapsulation of RTE related types + * 01.00.04 2017-01-12 vismss ESCAN00093703 Adaption of Csm_Types.h to the specification + * 01.01.00 2017-02-16 visgut FEATC-814 Support CSM 4.3 + * Introduce Exclusive Areas to protect queue resources + * Add missing DET Checks + * Support Csm_CancelJob + * Remove lower layer queue handling structures from Csm_Types.h + * Remove declaration of Csm_MainFunction as will be declared in SchM_Csm.h + * 01.02.00 2017-05-05 vismss FEATC-1227 Added/Corrected Doxygen comments + * Adapted code to MISRA + * Adapted null pointer checks to operation modes + * Improved job queueing + * 01.02.01 2017-05-25 vismss ESCAN00095301 Correction of DET null pointer exceptions + * 01.03.00 2017-06-08 vismaw FEAT-2500 SafeBSW for CSM 4.3 + * ESCAN00095452 Job sorting is only triggered during MainFunction + * ESCAN00094770 Csm_GetSizeOfJob() macro definition is missing if no job is configured + * 02.03.00 2017-08-22 visrpp ESCAN00096371 After cancellation, job is executed anyway or ECU results in + * unexpected behavior + * ESCAN00096373 Synchronous job is executed even if there were asynchronous jobs with + * higher priority queued before + * ESCAN00096489 Callbacks are not notified to the RTE + * 02.03.01 2018-03-13 visrpp ESCAN00097686 Added jobId to Crypto_JobType to increase compatibility to 3rd party + Crypto drivers + * ESCAN00098768 Jobs are not executed/passed to wrong channel if queue size is > 255 + * 03.00.00 2018-08-03 vismaw STORYC-5809 Introduce pre-and post job callouts + * STORYC-5999 Process new async job in callback + * ESCAN00100309 Application is not notified if a queued job is rejected by CryIf + * ESCAN00099325 Compiler warning: Csm.c: '<' : signed/unsigned mismatch + * 03.01.00 2018-08-20 vismaw STORYC-6300 Misra 2012 for Csm + * 03.01.01 2018-10-23 vismwe ESCAN00100873 CryIf_CertificateVerify is called with wrong verifyCryIfKeyId + * 04.00.00 2018-11-07 vismaw STORYC-6542 Support redirection of input/output buffers from/to key elements + * STORYC-6545 Support partial key element copy + * 04.01.00 2019-03-06 vismaw STORYC-7653 Release of CSM 4.x + * 04.01.01 2019-06-28 vismaw ESCAN00102925 Crypto_JobType is not declared as specified in ASR 4.3.x + * 04.02.00 2019-07-25 vismaw SEC-675 Add possibility to configure const members of job type as var + * 05.00.00 2019-10-30 visenc SEC-21 Add Asynchronous Key Handling + * SEC-907 CSM SWC according ASR 4.4 + * ESCAN00104302 Mapped Csm_ServiceToApiIdTable to CONST_8BIT memory section + * SEC-1001 Support ASR 4.4- and 4.5-style Callbacks + * 05.00.01 2020-01-20 visewl ESCAN00105342 Set operation mode for key management jobs always to single call + * ESCAN00105391 Resolve compiler warning that typedef name has already been declared + * ESCAN00105395 Resolve compiler warning that var. was declared but never referenced + * 2020-02-12 visewl ESCAN00105626 Resolve compiler errors due to possible loss of data using least types + * 05.01.00 2020-07-07 visrpp SEC-1454 Revised switches used for defining layout of Crypto_JobType structure + * SEC-1584 Reduce footprint through shared job objects + * SEC-1645 Call post job callout also for skipped synchronous jobs + * SEC-1655 Canceling of jobs according ASR 4.4 + * ESCAN00105993 Add field input64 to Crypto_JobPrimitiveInputOutputType + * ESCAN00106799 Add CYRPTO_KE_KEYEXCHANGE_SHAREDVALUE with typo as defined in AUTOSAR + * 06.00.00 2021-01-20 vismxe SEC-1889 Update algorithm modes and families to AUTOSAR R20-11 + * 06.01.00 2021-03-16 visenc SEC-2474 Save and restore context for running crypto operations + * ESCAN00108742 Execution of queued jobs might be delayed + * 06.01.01 2021-06-07 visrpp ESCAN00109411 Enqueued job might get lost + * 06.02.00 2021-11-25 visewl ESCAN00110824 Correct job state handling for asynchronous jobs + * ESCAN00110897 Free only shared job objects in callback function + * SEC-3604 Improve retriggering of asynchronous job processing + * 06.03.00 2022-03-10 visrpp SEC-4254 Speed up retriggering of asynchronous job if queue was empty + * 07.00.00 2023-01-18 visrpp SEC-5797 Use CRYPTO_E_BUSY instead of CRYPTO_E_QUEUE_FULL according ASR 4.4 + * SEC-5476 Remove keyId parameter from JobKey APIs according ASR R21-11 + * SEC-5478 CSM SWC according ASR R21-11 + * SEC-5804 Adapt types according ASR R21-11 and move them to Crypto_GeneralTypes.h + * SEC-5472 Introduce APIs KeyGetStatus, KeySetInvalid and JobKeySetInvalid + * SEC-5802 Adapt error reporting to ASR R21/11 + * SEC-4188 Finite Execution Time Analysis for Csm + * 07.01.00 2023-01-18 visrpp HSM-3724 Add multi-core/multi-partition support + * 07.02.00 2023-06-13 visfnn ESCAN00114839 Fix unreferenced variables + * HSM-4388 Rework Csm_InitMemory + * ESCAN00114847 Rename incorrect define CRYPTO_ALGOFAM_POLY13 to CRYPTO_ALGOFAM_POLY1305 + * 07.02.01 2024-02-15 visrpp ESCAN00116232 Prefix swc interface error codes with CRYPTO_E starting from ASR R19-11 + * vismwe ESCAN00115844 Avoid duplicated call of Csm_CallbackNotification during Csm_CancelJob + * vismwe CRY-508 Add CRYPTO_KEYSTATUS_UPDATE_IN_PROGRESS as value for KeyStatusType + * mapelt ESCAN00116539 Redirection might fail during asynchronous job processing + * main-1 2024-06-14 viseag CRY-715 Change history is maintained in the global ChangeHistory.txt file + * starting with this release. + *********************************************************************************************************************/ + +#if !defined (CSM_H) +# define CSM_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Csm_Cfg.h" +# include "Csm_Cbk.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* Vendor and module identification */ +# define CSM_VENDOR_ID (30u) +# define CSM_MODULE_ID (110u) +# define CSM_INSTANCE_ID (0u) + +/* AUTOSAR Software specification version information */ +# define CSM_AR_RELEASE_MAJOR_VERSION (0x04u) +# define CSM_AR_RELEASE_MINOR_VERSION (0x07u) +# define CSM_AR_RELEASE_REVISION_VERSION (0x00u) + +/* ----- Component version information (decimal version of ALM implementation package) ----- */ +# define CSM_SW_MAJOR_VERSION (9u) +# define CSM_SW_MINOR_VERSION (1u) +# define CSM_SW_PATCH_VERSION (1u) + +/* ----- API service IDs ----- */ +/* Service ID: Csm_Init() */ +# define CSM_INIT_ID (0x00u) +/* Service ID: Csm_MainFunction() */ +# define CSM_MAINFUNCTION_ID (0x01u) +/* Service ID: Csm_GetVersionInfo() */ +# define CSM_GETVERSIONINFO_ID (0x3Bu) +/* Service ID: Csm_KeyElementSet() */ +# define CSM_KEYELEMENTSET_ID (0x78u) +/* Service ID: Csm_KeySetValid() */ +# define CSM_KEYSETVALID_ID (0x67u) +/* Service ID: Csm_JobKeySetValid() */ +# define CSM_JOBKEYSETVALID_ID (0x7Au) +/* Service ID: Csm_KeySetInvalid() */ +# define CSM_KEYSETINVALID_ID (0x85u) +/* Service ID: Csm_JobKeySetInvalid() */ +# define CSM_JOBKEYSETINVALID_ID (0x84u) +/* Service ID: Csm_KeyGetStatus() */ +# define CSM_KEYGETSTATUS_ID (0x83u) +/* Service ID: Csm_KeyElementGet() */ +# define CSM_KEYELEMENTGET_ID (0x68u) +/* Service ID: Csm_KeyElementCopy() */ +# define CSM_KEYELEMENTCOPY_ID (0x71u) +/* Service ID: Csm_KeyElementCopyPartial() */ +# define CSM_KEYELEMENTCOPYPARTIAL_ID (0x79u) +/* Service ID: Csm_KeyCopy() */ +# define CSM_KEYCOPY_ID (0x73u) +/* Service ID: Csm_RandomSeed() */ +# define CSM_RANDOMSEED_ID (0x69u) +/* Service ID: Csm_JobRandomSeed() */ +# define CSM_JOBRANDOMSEED_ID (0x7Bu) +/* Service ID: Csm_KeyGenerate() */ +# define CSM_KEYGENERATE_ID (0x6Au) +/* Service ID: Csm_JobKeyGenerate() */ +# define CSM_JOBKEYGENERATE_ID (0x7Cu) +/* Service ID: Csm_KeyDerive() */ +# define CSM_KEYDERIVE_ID (0x6Bu) +/* Service ID: Csm_JobKeyDerive() */ +# define CSM_JOBKEYDERIVE_ID (0x7Du) +/* Service ID: Csm_KeyExchangeCalcPubVal() */ +# define CSM_KEYEXCHANGECALCPUBVAL_ID (0x6Cu) +/* Service ID: Csm_JobKeyExchangeCalcPubVal() */ +# define CSM_JOBKEYEXCHANGECALCPUBVAL_ID (0x7Eu) +/* Service ID: Csm_KeyExchangeCalcSecret() */ +# define CSM_KEYEXCHANGECALCSECRET_ID (0x6Du) +/* Service ID: Csm_JobKeyExchangeCalcSecret() */ +# define CSM_JOBKEYEXCHANGECALCSECRET_ID (0x7Fu) +/* Service ID: Csm_CertificateParse() */ +# define CSM_CERTIFICATEPARSE_ID (0x6Eu) +/* Service ID: Csm_CertificateVerify() */ +# define CSM_CERTIFICATEVERIFY_ID (0x74u) +/* Service ID: Csm_Hash() */ +# define CSM_HASH_ID (0x5Du) +/* Service ID: Csm_MacGenerate() */ +# define CSM_MACGENERATE_ID (0x60u) +/* Service ID: Csm_MacVerify() */ +# define CSM_MACVERIFY_ID (0x61u) +/* Service ID: Csm_Encrypt() */ +# define CSM_ENCRYPT_ID (0x5Eu) +/* Service ID: Csm_Decrypt() */ +# define CSM_DECRYPT_ID (0x5Fu) +/* Service ID: Csm_AEADEncrypt() */ +# define CSM_AEADENCRYPT_ID (0x62u) +/* Service ID: Csm_AEADDecrypt() */ +# define CSM_AEADDECRYPT_ID (0x63u) +/* Service ID: Csm_SignatureGenerate() */ +# define CSM_SIGNATUREGENERATE_ID (0x76u) +/* Service ID: Csm_SignatureVerify() */ +# define CSM_SIGNATUREVERIFY_ID (0x64u) +/* Service ID: Csm_SecureCounterIncrement() */ +# define CSM_SECURECOUNTERINCREMENT_ID (0x65u) +/* Service ID: Csm_SecureCounterRead() */ +# define CSM_SECURECOUNTERREAD_ID (0x66u) +/* Service ID: Csm_RandomGenerate() */ +# define CSM_RANDOMGENERATE_ID (0x72u) +/* Service ID: Csm_CancelJob() */ +# define CSM_CANCELJOB_ID (0x6Fu) +/* Service ID: Csm_CallbackNotification() */ +# define CSM_CALLBACKNOTIFICATION_ID (0x70u) +/* Service ID: Csm_SaveContextJob() */ +# define CSM_SAVECONTEXTJOB_ID (0x86u) +/* Service ID: Csm_RestoreContextJob() */ +# define CSM_RESTORECONTEXTJOB_ID (0x87u) +/* Service ID: Csm_JobKeyWrap() */ +# define CSM_JOBKEYWRAP_ID (0x89u) +/* Service ID: Csm_JobKeyUnwrap() */ +# define CSM_JOBKEYUNWRAP_ID (0x8Au) +/* Service ID: This id is notified to DET if e.g. an error occurs during + job processing which is not related to a specific API. */ +# define CSM_GENERIC_JOB_PROCESSING_ID (0xFFu) + +/* ----- Error codes ----- */ +/* Error Code: Used to check if no error occurred */ +# define CSM_E_NO_ERROR (0x00u) +/* Error Code: API request called with invalid parameter (null pointer) */ +# define CSM_E_PARAM_POINTER (0x01u) +/* Error Code: API request called with invalid parameter (invalid method for selected service) */ +# define CSM_E_PARAM_METHOD_INVALID (0x03u) +/* Error Code: API request called with Csm configuration ID out of range */ +# define CSM_E_PARAM_HANDLE (0x04u) +/* Error Code: API request called before initialization of CSM module */ +# define CSM_E_UNINIT (0x05u) +/* Error Code: Initialization of CSM module failed */ +# define CSM_E_INIT_FAILED (0x07u) +/* Error Code: API request called with invalid processing mode */ +# define CSM_E_PROCESSING_MODE (0x08u) +/* Error Code: Mismatch between the called API request and the service type of the job */ +# define CSM_E_SERVICE_TYPE (0x09u) +/* Error code: The service Csm_Init() is called while the module is already initialized */ +# define CSM_E_ALREADY_INITIALIZED (0x11u) +/* Error code: API request called on wrong partition */ +# define CSM_E_INVALID_PARTITION (0x12u) + +/* Runtime Error code: Queue overrun - More jobs have been requested than the queue can store */ +# define CSM_E_QUEUE_FULL (0x01u) +/* Runtime Error code: Unexpected callback from lower layer */ +# define CSM_E_UNEXPECTED_CALLBACK (0x81u) + +/* ----- Modes ----- */ +/* State: Uninitialized */ +# define CSM_UNINIT (0x00u) +/* State: Initialized */ +# define CSM_INITIALIZED (0x01u) + +# define CSM_CALLOUT_STATE_IDLE (0x00u) +# define CSM_CALLOUT_STATE_PRE_INITIAL (0x01u) +# define CSM_CALLOUT_STATE_PRE_PENDING (0x02u) +# define CSM_CALLOUT_STATE_PROCESSING (0x03u) +# define CSM_CALLOUT_STATE_PROCESSING_ABORTED_BY_CALLOUT (0x04u) +# define CSM_CALLOUT_STATE_POST_INITIAL (0x05u) +# define CSM_CALLOUT_STATE_POST_PENDING (0x06u) + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +# define CSM_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* General Function Prototypes */ +/********************************************************************************************************************** + * Csm_Init() + *********************************************************************************************************************/ +/*! \brief Initializes the CSM module. + * \details Set all service states to initial idle. + * \pre None + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + *********************************************************************************************************************/ +FUNC(void, CSM_CODE) Csm_Init(void); + +# if (CSM_VERSION_INFO_API == STD_ON) +/********************************************************************************************************************** + * Csm_GetVersionInfo() + *********************************************************************************************************************/ +/*! \brief Returns the version information of this module. + * \details Stores version information, i.e. Module Id, Vendor Id, Vendor specific version numbers to structure + * pointed by versioninfo. + * \param[out] versioninfo Pointer where the version info data shall be stored. + * \pre GetVersionInfo API is enabled via pre-compile configuration. + * \context TASK + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-129269 + *********************************************************************************************************************/ +FUNC(void, CSM_CODE) Csm_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, CSM_APPL_VAR) versioninfo); +# endif /* (CSM_VERSION_INFO_API == STD_ON) */ + +/********************************************************************************************************************** + * Csm_CancelJob() + *********************************************************************************************************************/ +/*! \brief Cancels the job processing from asynchronous or streaming jobs. + * \details Removes the job in the Csm Queue and calls the job's callback with the result + * CRYPTO_E_JOB_CANCELED. It also passes the cancellation command to the + * CryIf to try to cancel the job in the Crypto Driver. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Not used, just for interface compatibility provided + * \return E_OK Request successful - Job was cancelled or was already Idle + * E_NOT_OK Request failed - Job could not be cancelled + * CRYPTO_E_JOB_CANCELED Request pending - Job will be cancelled with next callback notification + * \pre - + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with E_NOT_OK) + * \synchronous TRUE + * \note For cancellation of asynchronous jobs the application must be able to handle two callbacks. + * It is possible that the normal job callback notification will be called while cancelling. + * The cancel callback notification can be identified by contained result CRYPTO_E_JOB_CANCELED. + * \trace CREQ-129244 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJob(uint32 jobId, Crypto_OperationModeType mode); + +/* Key Management Function Prototypes */ +/********************************************************************************************************************** + * Csm_KeyElementSet() + *********************************************************************************************************************/ +/*! \brief Sets the given key element bytes to the key identified by keyId. + * \details If the values of a key element are modified with Csm_KeyElementSet(), the key needs to be + * re-validated by calling Csm_KeySetValid() before using it for a cryptographic operation. + * \param[in] keyId Holds the identifier of the key for which a new material shall be set. + * \param[in] keyElementId Holds the identifier of the key element to be written. + * \param[in] keyPtr Holds the pointer to the key element bytes to be processed. + * \param[in] keyLength Contains the number of key element bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element size does not match size of provided data. + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129256 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementSet(uint32 keyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) keyPtr, + uint32 keyLength); + +/********************************************************************************************************************** + * Csm_KeySetValid() + *********************************************************************************************************************/ +/*! \brief Sets the key state of the key identified by keyId to valid. + * \details - + * \param[in] keyId Holds the identifier of the key for which a new material shall be validated. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \trace CREQ-129255 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeySetValid(uint32 keyId); + +/********************************************************************************************************************** + * Csm_KeySetInvalid() + *********************************************************************************************************************/ +/*! \brief Sets the key status to invalid. The key cannot be used any longer for cryptographic operations + * until it has been set to valid state again. + * \details - + * \param[in] keyId Holds the identifier of the key which shall be invalidated. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-3000000 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeySetInvalid(uint32 keyId); + +/********************************************************************************************************************** + * Csm_KeyGetStatus() + *********************************************************************************************************************/ +/*! \brief Returns the key state of the key identified by keyId. + * \details - + * \param[in] keyId Holds the identifier of the key for which the key state shall be returned. + * \param[out] keyStatusPtr Contains the pointer to the data where the status of the key shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-3000001 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyGetStatus(uint32 keyId, P2VAR(Crypto_KeyStatusType, AUTOMATIC, CSM_APPL_VAR) keyStatusPtr); + +/********************************************************************************************************************** + * Csm_KeyElementGet() + *********************************************************************************************************************/ +/*! \brief Retrieves the key element bytes from a specific key element of the key identified by the keyId and + * stores the key element in the memory location pointed by the key pointer. + * \details - + * \param[in] keyId Holds the identifier of the key from which a key element shall be + * extracted. + * \param[in] keyElementId Holds the identifier of the key element to be extracted. + * \param[out] keyPtr Holds the pointer to the memory location where the key shall be copied + * to. + * \param[in,out] keyLengthPtr Holds a pointer to the memory location in which the output buffer length + * in bytes is stored. On calling this function, this parameter shall + * contain the buffer length in bytes of the keyPtr. When the request has + * finished, the actual size of the written input bytes shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129254 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementGet(uint32 keyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) keyPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) keyLengthPtr); + +/********************************************************************************************************************** + * Csm_KeyElementCopy() + *********************************************************************************************************************/ +/*! \brief This function shall copy a key elements from one key to a target key. + * \details - + * \param[in] keyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for + * the copy operation. + * \param[in] targetKeyId Holds the identifier of the key whose key element shall be the + * destination element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination + * for the copy operation. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129253 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementCopy(uint32 keyId, + uint32 keyElementId, + uint32 targetKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * Csm_KeyElementCopyPartial() + *********************************************************************************************************************/ +/*! \brief This function copies a key element partially from one key to a target key. + * \details The function copies a specific chunk of the source key element to a specific location of the target key. + * The locations are given through the parameters. + * \param[in] keyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for the + * copy operation. + * \param[in] keyElementSourceOffset This is the offset of the source key element indicating the start index + * of the copy operation. + * \param[in] keyElementTargetOffset This is the offset of the destination key element indicating the start index + * of the copy operation. + * \param[in] keyElementCopyLength Specifies the number of bytes that shall be copied. + * \param[in] targetKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination for + * the copy operation. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-185644 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementCopyPartial(uint32 keyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * Csm_KeyCopy() + *********************************************************************************************************************/ +/*! \brief This function shall copy all key elements from the source key to a target key. + * \details - + * \param[in] keyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] targetKeyId Holds the identifier of the key whose key element shall be the + * destination element. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element size does not match size of provided data + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129252 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyCopy(uint32 keyId, + uint32 targetKeyId); + +/********************************************************************************************************************** + * Csm_RandomSeed() + *********************************************************************************************************************/ +/*! \brief Feeds the key element CRYPTO_KE_RANDOM_SEED with a random seed. + * \details - + * \param[in] keyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] seedPtr Holds a pointer to the memory location which contains the data to feed the + * seed. + * \param[in] seedLength Contains the length of the seed in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129251 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_RandomSeed(uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) seedPtr, + uint32 seedLength); + +/********************************************************************************************************************** + * Csm_KeyGenerate() + *********************************************************************************************************************/ +/*! \brief Generates new key material and store it in the key identified by keyId. + * \details - + * \param[in] keyId Holds the identifier of the key for which a new material shall be generated. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129250 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyGenerate(uint32 keyId); + +/********************************************************************************************************************** + * Csm_KeyDerive() + *********************************************************************************************************************/ +/*! \brief Derives a new key by using the key elements in the given key identified by the keyId. The given key + * contains the key elements for the password and salt. The derived key is stored in the key element + * with the id 1 of the key identified by targetCryptoKeyId. + * \details - + * \param[in] keyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_READ_FAIL Request failed, not allowed to extract key element + * CRYPTO_E_KEY_WRITE_FAIL Request failed, not allowed to write key element + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129249 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyDerive(uint32 keyId, + uint32 targetKeyId); + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcPubVal() + *********************************************************************************************************************/ +/*! \brief Calculates the public value of the current user for the key exchange and stores the public key in + * the memory location pointed by the public value pointer. + * \details - + * \param[in] keyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER Request failed because the provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129248 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcPubVal(uint32 keyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr); + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcSecret() + *********************************************************************************************************************/ +/*! \brief Calculates the shared secret key for the key exchange with the key material of the key identified by + * the keyId and the partner public key. The shared secret key is stored as a key element in the same + * key. + * \details - + * \param[in] keyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partner's + * public value. + * \param[in] partnerPublicValueLength Contains the length of the partner's public value in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129247 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcSecret(uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * Csm_CertificateParse() + *********************************************************************************************************************/ +/*! \brief This function shall dispatch the certificate parse function to the CryIf. + * \details - + * \param[in] keyId Holds the identifier of the key to be used for the certificate parsing. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \trace CREQ-129246 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_CertificateParse(uint32 keyId); + +/********************************************************************************************************************** + * Csm_CertificateVerify() + *********************************************************************************************************************/ +/*! \brief Verifies the certificate stored in the key referenced by verifyKeyId with the certificate stored in + * the key referenced by keyId. Note: Only certificates stored in the same Crypto Driver can be + * verified against each other. If the key element CRYPTO_KE_CERTIFICATE_CURRENT_TIME is used for the + * verification of the validity period of the certificate identified by verifyKeyId, it shall have the + * same format as the timestamp in the certificate. + * \details - + * \param[in] keyId Holds the identifier of the key which shall be used to validate the certificate. + * \param[in] verifyKeyId Holds the identifier of the key containing the certificate to be verified. + * \param[out] verifyPtr Holds a pointer to the memory location which will contain the result of the certificate + * verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \trace CREQ-129245 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_CertificateVerify(uint32 keyId, + uint32 verifyKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/* CSM Service Function Prototypes */ +/********************************************************************************************************************** + * Csm_Hash() + *********************************************************************************************************************/ +/*! \brief Uses the given data to perform the hash calculation and stores the hash in the memory location + * pointed to by the result pointer. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the hash shall be computed. + * \param[in] dataLength Contains the number of bytes to be hashed. + * \param[out] resultPtr Contains the pointer to the data where the hash value shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer provided by resultPtr. When the request has finished, the actual length of + * the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129268 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_Hash(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_MacGenerate() + *********************************************************************************************************************/ +/*! \brief Uses the given data to perform a MAC generation and stores the MAC in the memory location pointed to + * by the MAC pointer. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be computed. + * \param[in] dataLength Contains the number of bytes for the MAC generation. + * \param[out] macPtr Contains the pointer to the data where the MAC shall be stored. + * \param[in,out] macLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer provided by macPtr. When the request has finished, the actual length of + * the returned MAC shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerate(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr); + +/********************************************************************************************************************** + * Csm_MacVerify() + *********************************************************************************************************************/ +/*! \brief Verifies the given MAC by comparing if the MAC is generated with the given data. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be verified. + * \param[in] dataLength Contains the number of data bytes for which the MAC shall be verified. + * \param[in] macPtr Holds a pointer to the MAC to be verified. + * \param[in] macLength Contains the MAC length in BITS to be verified. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the MAC + * verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerify(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_Encrypt() + *********************************************************************************************************************/ +/*! \brief Encrypts the given data and store the ciphertext in the memory location pointed by the result + * pointer. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be encrypted. + * \param[in] dataLength Contains the number of bytes to encrypt. + * \param[out] resultPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129265 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_Encrypt(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_Decrypt() + *********************************************************************************************************************/ +/*! \brief Decrypts the given encrypted data and store the decrypted plaintext in the memory location pointed + * by the result pointer. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be decrypted. + * \param[in] dataLength Contains the number of bytes to decrypt. + * \param[out] resultPtr Contains the pointer to the data where the decrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129264 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_Decrypt(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_AEADEncrypt() + *********************************************************************************************************************/ +/*! \brief Uses the given input data to perform a AEAD encryption and stores the ciphertext and the MAC in the + * memory locations pointed by the ciphertext pointer and Tag pointer. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] plaintextPtr Contains the pointer to the data to be encrypted. + * \param[in] plaintextLength Contains the number of bytes to encrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[out] ciphertextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] ciphertextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the ciphertext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by ciphertextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in,out] tagLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the Tag is stored. On calling this function, this parameter shall contain the + * size of the buffer in bytes provided by tagPtr. When the request has + * finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129263 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncrypt(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr); + +/********************************************************************************************************************** + * Csm_AEADDecrypt() + *********************************************************************************************************************/ +/*! \brief Uses the given data to perform an AEAD decryption and stores the plaintext and the result of + * verification in the memory locations pointed by the plaintext pointer and verifyPtr pointer. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] ciphertextPtr Contains the pointer to the data to be decrypted. + * \param[in] ciphertextLength Contains the number of bytes to decrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[in] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in] tagLength Contains the length in bytes of the Tag to be verified. + * \param[out] plaintextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] plaintextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the plaintext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by plaintextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] verifyPtr Contains the pointer to the result of the verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129262 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecrypt(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_SignatureGenerate() + *********************************************************************************************************************/ +/*! \brief Uses the given data to perform the signature calculation and stores the signature in the memory + * location pointed by the result pointer. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be signed. + * \param[in] dataLength Contains the number of bytes to sign. + * \param[out] resultPtr Contains the pointer to the data where the signature shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer in bytes provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129261 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerate(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_SignatureVerify() + *********************************************************************************************************************/ +/*! \brief Verifies the given MAC by comparing if the signature is generated with the given data. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be verified. + * \param[in] dataLength Contains the number of bytes to be verified. + * \param[in] signaturePtr Holds a pointer to the signature to be verified. + * \param[in] signatureLength Contains the signature length in bytes. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the + * signature verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129260 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerify(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_RandomGenerate() + *********************************************************************************************************************/ +/*! \brief Generate a random number and stores it in the memory location pointed by the result pointer. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[out] resultPtr Holds a pointer to the memory location which will hold the result of the + * random number generation. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the result length in bytes + * is stored. On calling this function, this parameter shall contain the + * number of random bytes, which shall be stored to the buffer provided by + * resultPtr. When the request has finished, the actual length of the returned + * value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy of random number generator is exhausted + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129257 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_RandomGenerate(uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +# if (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) /* COV_CSM_ASR_COMPATIBILITY_FUNCTIONS */ +/********************************************************************************************************************** + * Csm_JobKeySetValid() + *********************************************************************************************************************/ +/*! \brief Stores the key if necessary and sets the key state of the key configured in the job to valid. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129255 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeySetValid(uint32 jobId); +# endif /* (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) */ + +/********************************************************************************************************************** + * Csm_JobKeySetValid44x() + *********************************************************************************************************************/ +/*! \brief Stores the key if necessary and sets the key state of the key configured in the job to valid. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129255 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeySetValid44x(uint32 jobId, uint32 keyId); + +# if (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) /* COV_CSM_ASR_COMPATIBILITY_FUNCTIONS */ +/********************************************************************************************************************** + * Csm_JobKeySetInvalid() + *********************************************************************************************************************/ +/*! \brief Sets the key status to invalid. The key cannot be used any longer for cryptographic operations + * until it has been set to valid state again. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * \context TASK + * \reentrant TRUE + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-3000000 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeySetInvalid(uint32 jobId); +# endif /* (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) */ + +/********************************************************************************************************************** + * Csm_JobKeySetInvalid44x() + *********************************************************************************************************************/ +/*! \brief Sets the key status to invalid. The key cannot be used any longer for cryptographic operations + * until it has been set to valid state again. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-3000000 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeySetInvalid44x(uint32 jobId, uint32 keyId); + +# if (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) /* COV_CSM_ASR_COMPATIBILITY_FUNCTIONS */ +/********************************************************************************************************************** + * Csm_JobRandomSeed() + *********************************************************************************************************************/ +/*! \brief This function shall dispatch the random seed function to the configured Crypto Driver object. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] seedPtr Holds a pointer to the memory location which contains the data to feed the seed. + * \param[in] seedLength Contains the length of the seed in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129251 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobRandomSeed(uint32 jobId, P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) seedPtr, uint32 seedLength); +# endif /* (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) */ + +/********************************************************************************************************************** + * Csm_JobRandomSeed44x() + *********************************************************************************************************************/ +/*! \brief This function shall dispatch the random seed function to the configured Crypto Driver object. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[in] seedPtr Holds a pointer to the memory location which contains the data to feed the seed. + * \param[in] seedLength Contains the length of the seed in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129251 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobRandomSeed44x(uint32 jobId, uint32 keyId, P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) seedPtr, uint32 seedLength); + +# if (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) /* COV_CSM_ASR_COMPATIBILITY_FUNCTIONS */ +/********************************************************************************************************************** + * Csm_JobKeyGenerate() + *********************************************************************************************************************/ +/*! \brief Generates new key material and stores it in the key configured in the job. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129250 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyGenerate(uint32 jobId); +# endif /* (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) */ + +/********************************************************************************************************************** + * Csm_JobKeyGenerate44x() + *********************************************************************************************************************/ +/*! \brief Generates new key material and stores it in the key identified by keyId. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129250 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyGenerate44x(uint32 jobId, uint32 keyId); + +# if (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) /* COV_CSM_ASR_COMPATIBILITY_FUNCTIONS */ +/********************************************************************************************************************** + * Csm_JobKeyDerive() + *********************************************************************************************************************/ +/*! \brief Derives a new key by using the key elements in the key configured in the job. + * The key contains the key elements for the password and salt. The derived key is + * stored in the key element with the id 1 of the key identified by targetKeyId. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] targetKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_READ_FAIL Request failed, not allowed to extract key element + * CRYPTO_E_KEY_WRITE_FAIL Request failed, not allowed to write key element + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129249 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyDerive(uint32 jobId, uint32 targetKeyId); +# endif /* (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) */ + +/********************************************************************************************************************** + * Csm_JobKeyDerive44x() + *********************************************************************************************************************/ +/*! \brief Derives a new key by using the key elements in the key configured in the job. + * The key contains the key elements for the password and salt. The derived key is + * stored in the key element with the id 1 of the key identified by targetKeyId. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[in] targetKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_READ_FAIL Request failed, not allowed to extract key element + * CRYPTO_E_KEY_WRITE_FAIL Request failed, not allowed to write key element + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129249 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyDerive44x(uint32 jobId, uint32 keyId, uint32 targetKeyId); + +# if (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) /* COV_CSM_ASR_COMPATIBILITY_FUNCTIONS */ +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubVal() + *********************************************************************************************************************/ +/*! \brief Calculates the public value of the current user for the key exchange and stores the + * public key in the memory location pointed by the public value pointer. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length information + * is stored. On calling this function, this parameter shall contain the size of the buffer provided + * by publicValuePtr. When the request has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129248 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcPubVal(uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr); +# endif /* (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubVal44x() + *********************************************************************************************************************/ +/*! \brief Calculates the public value of the current user for the key exchange and stores the + * public key in the memory location pointed by the public value pointer. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length information + * is stored. On calling this function, this parameter shall contain the size of the buffer provided + * by publicValuePtr. When the request has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129248 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcPubVal44x(uint32 jobId, + uint32 keyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr); + +# if (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) /* COV_CSM_ASR_COMPATIBILITY_FUNCTIONS */ +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecret() + *********************************************************************************************************************/ +/*! \brief Calculates the shared secret key for the key exchange with the key material of the key configured in + * the job and the partner public key. The shared secret key is stored as a key element in the same key. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partner's public value. + * \param[in] partnerPublicValueLength Contains the length of the partner's public value in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129247 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcSecret(uint32 jobId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); +# endif /* (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_R21_11) */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecret44x() + *********************************************************************************************************************/ +/*! \brief Calculates the shared secret key for the key exchange with the key material of the key configured in + * the job and the partner public key. The shared secret key is stored as a key element in the same key. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partner's public value. + * \param[in] partnerPublicValueLength Contains the length of the partner's public value in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-129247 + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcSecret44x(uint32 jobId, + uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * Csm_JobKeyWrap() + *********************************************************************************************************************/ +/*! \brief Wraps the plaintext key given by sourceKeyId (in the key element with the id 1) with the key + * wrapping key associated with the jobId. The wrapped key will be written to ciphertextPtr. If the + * algorithm does provide an authenticator this will be written to authenticatorPtr. If the algorithm + * has no authenticator or the algorithm has an authenticator and no authentication shall be done, + * authenticatorLengthPtr shall be set to zero. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] sourceKeyId Holds the identifier of the key to be wrapped. + * \param[in] ciphertextPtr References the data of the wrapped key. + * \param[in,out] ciphertextLengthPtr Contains the length in bytes of the wrapped key. + * \param[in] authenticatorPtr References the data of the authenticator - NOT USED. + * \param[in,out] authenticatorLengthPtr Contains the length in bytes of the authenticator. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_READ_FAIL Request failed, not allowed to extract key element + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_JOB_CANCELED Request failed because the job has been canceled. + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-Csm-KeyWrap + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyWrap(uint32 jobId, + uint32 sourceKeyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) authenticatorPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) authenticatorLengthPtr); + +/********************************************************************************************************************** + * Csm_JobKeyUnwrap() + *********************************************************************************************************************/ +/*! \brief Unwraps the wrapped key given by the ciphertextPtr with the key wrapping key associated with + * the jobId. The unwrapped key will be written to targetKeyId in the element with the Id 1. If an + * authentication shall be done, the authenticator shall be referenced with authenticatorPtr. If the + * algorithm has no authenticator or the algorithm has an authenticator and no authentication shall + * be done, authenticatorLengthPtr shall be set to zero. If the algorithm has no authentication, + * verifyPtr will be set to CRYPTO_E_VER_OK. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] targetKeyId Holds the identifier of the slot where the plaintext key shall be + * written. + * \param[in] ciphertextPtr References the data of the wrapped key. + * \param[in] ciphertextLength Contains the length in bytes of the wrapped key. + * \param[in] authenticatorPtr References the data of the authenticator - NOT USED. + * \param[in] authenticatorLength Contains the length in bytes of the authenticator. + * \param[out] verifyPtr Contains the pointer to the result of the verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_WRITE_FAIL Request failed, not allowed to write key element + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_JOB_CANCELED Request failed because the job has been canceled + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + * \trace CREQ-Csm-KeyUnwrap + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyUnwrap(uint32 jobId, + uint32 targetKeyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) authenticatorPtr, + uint32 authenticatorLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_SaveContextJob() + *********************************************************************************************************************/ +/*! \brief The Crypto Driver stores the internal context of the respective crypto operation to the contextBuffer. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[out] contextBufferPtr Pointer to the buffer in the application where the context data shall be + * stored to. + * \param[in,out] contextBufferLengthPtr Pointer to the buffer, where the length value is located.As input data it + * provides the maximum length of data available in contextBufferPtr.As + * output data it provides the actual length of data located in context + * BufferPtr(or 0 in case of a failure) + * \return E_OK Context data successfully provided. + * E_NOT_OK Context data could not be provided, values are not valid. + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_SaveContextJob(uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) contextBufferPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) contextBufferLengthPtr); + +/********************************************************************************************************************** + * Csm_RestoreContextJob() + *********************************************************************************************************************/ +/*! \brief The Crypto Driver extracts the context data from the contextBuffer and restores the + * internal state so that further crypto operation of this crypto service will continue at + * the exact point when the context was taken. + * \details - + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] contextBufferPtr Pointer to the buffer, where the context data are located that + * shall be restored. + * \param[in] contextBufferLength Provides the length of context data that are located in contextBufferPtr. + * \return E_OK Context data successfully restored. + * E_NOT_OK Context data could not be restored. + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, CSM_CODE) Csm_RestoreContextJob(uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) contextBufferPtr, + uint32 contextBufferLength); + +# define CSM_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* AUTOSAR Compatibility Block */ +# if (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_4_04) /* COV_CSM_ASR_COMPATIBILITY_FUNCTIONS */ +# define Csm_JobKeySetValid Csm_JobKeySetValid44x +# define Csm_JobKeySetInvalid Csm_JobKeySetInvalid44x +# define Csm_JobRandomSeed Csm_JobRandomSeed44x +# define Csm_JobKeyGenerate Csm_JobKeyGenerate44x +# define Csm_JobKeyDerive Csm_JobKeyDerive44x +# define Csm_JobKeyExchangeCalcPubVal Csm_JobKeyExchangeCalcPubVal44x +# define Csm_JobKeyExchangeCalcSecret Csm_JobKeyExchangeCalcSecret44x +# endif /* (CSM_JOB_KEY_API_VERSION == CSM_ASR_VERSION_4_04) */ + +/*! + * \exclusivearea CSM_EXCLUSIVE_AREA_0 + * Ensures consistency of global RAM variables. + * \protects Job state and queue handling variables. + * \usedin Csm_Hash, Csm_MacGenerate, Csm_MacVerify, Csm_Encrypt, Csm_Decrypt, Csm_AEADEncrypt, Csm_AEADDecrypt, + * Csm_SignatureGenerate, Csm_SignatureVerify, Csm_RandomGenerate, Csm_JobKeySetValid, Csm_JobKeySetInvalid, + * Csm_JobRandomSeed, Csm_JobKeyGenerate, Csm_JobKeyDerive, Csm_JobKeyExchangeCalcPubVal, + * Csm_JobKeyExchangeCalcSecret, Csm_SaveContextJob, Csm_RestoreContextJob, Csm_CallbackNotification, + * Csm_CancelJob, Csm_MainFunction + * \exclude All functions in which this exclusive area is used in. + * \length MEDIUM for Job state and queue handling. + * \endexclusivearea + */ + +#endif /* !defined (CSM_H) */ +/********************************************************************************************************************** + * END OF FILE: Csm.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Csm/Csm_Cbk.h b/Source/bsw/Csm/Csm_Cbk.h new file mode 100644 index 0000000..6ac7c47 --- /dev/null +++ b/Source/bsw/Csm/Csm_Cbk.h @@ -0,0 +1,65 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file Csm_Cbk.h + * \brief MICROSAR Crypto Service Manager (CSM) + * + * \details Implementation of the MICROSAR Crypto Service Manager (CSM) + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file (Csm.h). + *********************************************************************************************************************/ + +#if !defined (CSM_CBK_H) +# define CSM_CBK_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Csm_Types.h" + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPE + *********************************************************************************************************************/ +# define CSM_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Csm_CallbackNotification() + *********************************************************************************************************************/ +/*! \brief Callback Notification + * \details Notifies the Csm that a job has finished. This function is used by the underlying layer (CryIf) + * \param[in,out] job Holds a pointer to the job, which has finished. + * \param[in] result Contains the result of the cryptographic operation. + * The second most important bit of result must not be set. It must always be zero. + * \pre - + * \context TASK|ISR2|ISR1 + * \reentrant TRUE + * \synchronous TRUE + * \trace CREQ-129243 + *********************************************************************************************************************/ +FUNC(void, CSM_CODE) Csm_CallbackNotification(P2VAR(Crypto_JobType, AUTOMATIC, CSM_APPL_VAR) job, + Crypto_ResultType result); + +# define CSM_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* !defined (CSM_CBK_H) */ + +/********************************************************************************************************************** + * END OF FILE: Csm_Cbk.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Csm/Csm_Rte.c b/Source/bsw/Csm/Csm_Rte.c new file mode 100644 index 0000000..fc2304a --- /dev/null +++ b/Source/bsw/Csm/Csm_Rte.c @@ -0,0 +1,1861 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file Csm_Rte.c + * \brief MICROSAR Crypto Service Manager (CSM) RTE + * + * \details Implementation of the MICROSAR Crypto Service Manager (CSM) service APIs used only by RTE + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + * + * FILE VERSION + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the VERSION CHECK below. + *********************************************************************************************************************/ + +#define CSM_RTE_SOURCE +/* PRQA S 6060 EOF */ /* MD_MSR_STPAR */ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Csm_Rte.h" + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +#if (CSM_RTE_PORTS == STD_ON) + +# define CSM_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Csm_HashAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_HashAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Hash */ + return Csm_Hash(jobId, mode, dataPtr, dataLength, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_HashAsr4_03() */ + +/********************************************************************************************************************** + * Csm_HashDataRefAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_HashDataRefAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Hash */ + return Csm_Hash(jobId, mode, dataPtr, dataLength, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_HashDataRefAsr4_03() */ + +/********************************************************************************************************************** + * Csm_HashDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_HashDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Hash */ + return Csm_Hash(jobId, mode, dataPtr, dataLength, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_HashDataRefAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_HashDataRef() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_HashDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Hash */ + return Csm_Hash(jobId, + mode, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))dataPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + dataLength, + (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))resultPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_HashDataRef() */ + +/********************************************************************************************************************** + * Csm_MacGenerateAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerateAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr) +{ + /* #10 Call Csm_MacGenerate */ + return Csm_MacGenerate(jobId, mode, dataPtr, dataLength, macPtr, macLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_MacGenerateAsr4_03() */ + +/********************************************************************************************************************** + * Csm_MacGenerateAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerateAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr) +{ + /* #10 Call Csm_MacGenerate */ + return Csm_MacGenerate(jobId, mode, dataPtr, dataLength, macPtr, macLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_MacGenerateAsr4_04() */ + +/********************************************************************************************************************** + * Csm_MacGenerateDataRefAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerateDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr) +{ + /* #10 Call Csm_MacGenerate */ + return Csm_MacGenerate(jobId, mode, dataPtr, dataLength, macPtr, macLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_MacGenerateDataRefAsr4_04() */ + +/********************************************************************************************************************** + * Csm_MacGenerateDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerateDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr) +{ + /* #10 Call Csm_MacGenerate */ + return Csm_MacGenerate(jobId, mode, dataPtr, dataLength, macPtr, macLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_MacGenerateDataRefAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_MacGenerateDataRef() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerateDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) macPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr) +{ + /* #10 Call Csm_MacGenerate */ + return Csm_MacGenerate(jobId, + mode, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))dataPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + dataLength, + (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))macPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + macLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_MacGenerateDataRef() */ + +/********************************************************************************************************************** + * Csm_MacVerifyAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerifyAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_MacVerify */ + return Csm_MacVerify(jobId, mode, dataPtr, dataLength, macPtr, macLength, verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_MacVerifyAsr4_03() */ + +/********************************************************************************************************************** + * Csm_MacVerifyAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerifyAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_MacVerify */ + return Csm_MacVerify(jobId, mode, dataPtr, dataLength, macPtr, macLength, verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_MacVerifyAsr4_04() */ + +/********************************************************************************************************************** + * Csm_MacVerifyDataRefAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerifyDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_MacVerify */ + return Csm_MacVerify(jobId, mode, dataPtr, dataLength, macPtr, macLength, verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_MacVerifyDataRefAsr4_04() */ + +/********************************************************************************************************************** + * Csm_MacVerifyDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerifyDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_MacVerify */ + return Csm_MacVerify(jobId, mode, dataPtr, dataLength, macPtr, macLength, verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_MacVerifyDataRefAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_MacVerifyDataRef() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerifyDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_MacVerify */ + return Csm_MacVerify(jobId, + mode, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))dataPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + dataLength, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))macPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + macLength, + verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_MacVerifyDataRef() */ + +/********************************************************************************************************************** + * Csm_EncryptAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_EncryptAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Encrypt */ + return Csm_Encrypt(jobId, mode, dataPtr, dataLength, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_EncryptAsr4_03() */ + +/********************************************************************************************************************** + * Csm_EncryptAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_EncryptAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Encrypt */ + return Csm_Encrypt(jobId, mode, dataPtr, dataLength, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_EncryptAsr4_04() */ + +/********************************************************************************************************************** + * Csm_EncryptDataRefAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_EncryptDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Encrypt */ + return Csm_Encrypt(jobId, mode, dataPtr, dataLength, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_EncryptDataRefAsr4_04() */ + +/********************************************************************************************************************** + * Csm_EncryptDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_EncryptDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Encrypt */ + return Csm_Encrypt(jobId, mode, dataPtr, dataLength, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_EncryptDataRefAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_EncryptDataRef() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_EncryptDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Encrypt */ + return Csm_Encrypt(jobId, + mode, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))dataPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + dataLength, + (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))resultPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_EncryptDataRef() */ + +/********************************************************************************************************************** + * Csm_DecryptAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_DecryptAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Decrypt */ + return Csm_Decrypt(jobId, mode, dataPtr, dataLength, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_DecryptAsr4_03() */ + +/********************************************************************************************************************** + * Csm_DecryptAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_DecryptAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Decrypt */ + return Csm_Decrypt(jobId, mode, dataPtr, dataLength, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_DecryptAsr4_04() */ + +/********************************************************************************************************************** + * Csm_DecryptDataRefAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_DecryptDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Decrypt */ + return Csm_Decrypt(jobId, mode, dataPtr, dataLength, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_DecryptDataRefAsr4_04() */ + +/********************************************************************************************************************** + * Csm_DecryptDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_DecryptDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Decrypt */ + return Csm_Decrypt(jobId, mode, dataPtr, dataLength, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_DecryptDataRefAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_DecryptDataRef() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_DecryptDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_Decrypt */ + return Csm_Decrypt(jobId, + mode, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))dataPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + dataLength, + (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))resultPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_DecryptDataRef() */ + +/********************************************************************************************************************** + * Csm_AEADEncryptAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncryptAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr) +{ + /* #10 Call Csm_AEADEncrypt */ + return Csm_AEADEncrypt(jobId, + mode, + plaintextPtr, + plaintextLength, + associatedDataPtr, + associatedDataLength, + ciphertextPtr, + ciphertextLengthPtr, + tagPtr, + tagLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_AEADEncryptAsr4_03() */ + +/********************************************************************************************************************** + * Csm_AEADEncryptAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncryptAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr) +{ + /* #10 Call Csm_AEADEncrypt */ + return Csm_AEADEncrypt(jobId, + mode, + plaintextPtr, + plaintextLength, + associatedDataPtr, + associatedDataLength, + ciphertextPtr, + ciphertextLengthPtr, + tagPtr, + tagLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_AEADEncryptAsr4_04() */ + +/********************************************************************************************************************** + * Csm_AEADEncryptDataRefAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncryptDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr) +{ + /* #10 Call Csm_AEADEncrypt */ + return Csm_AEADEncrypt(jobId, + mode, + plaintextPtr, + plaintextLength, + associatedDataPtr, + associatedDataLength, + ciphertextPtr, + ciphertextLengthPtr, + tagPtr, + tagLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_AEADEncryptDataRefAsr4_04() */ + +/********************************************************************************************************************** + * Csm_AEADEncryptDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncryptDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr) +{ + /* #10 Call Csm_AEADEncrypt */ + return Csm_AEADEncrypt(jobId, + mode, + plaintextPtr, + plaintextLength, + associatedDataPtr, + associatedDataLength, + ciphertextPtr, + ciphertextLengthPtr, + tagPtr, + tagLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_AEADEncryptDataRefAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_AEADEncryptDataRef() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncryptDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) tagPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr) +{ + /* #10 Call Csm_AEADEncrypt */ + return Csm_AEADEncrypt(jobId, + mode, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))plaintextPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + plaintextLength, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))associatedDataPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + associatedDataLength, + (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))ciphertextPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + ciphertextLengthPtr, + (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))tagPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + tagLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_AEADEncryptDataRef() */ + +/********************************************************************************************************************** + * Csm_AEADDecryptAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecryptAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_AEADDecrypt */ + return Csm_AEADDecrypt(jobId, + mode, + ciphertextPtr, + ciphertextLength, + associatedDataPtr, + associatedDataLength, + tagPtr, + tagLength, + plaintextPtr, + plaintextLengthPtr, + verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_AEADDecryptAsr4_03() */ + +/********************************************************************************************************************** + * Csm_AEADDecryptAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecryptAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_AEADDecrypt */ + return Csm_AEADDecrypt(jobId, + mode, + ciphertextPtr, + ciphertextLength, + associatedDataPtr, + associatedDataLength, + tagPtr, + tagLength, + plaintextPtr, + plaintextLengthPtr, + verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_AEADDecryptAsr4_04() */ + +/********************************************************************************************************************** + * Csm_AEADDecryptDataRefAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecryptDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_AEADDecrypt */ + return Csm_AEADDecrypt(jobId, + mode, + ciphertextPtr, + ciphertextLength, + associatedDataPtr, + associatedDataLength, + tagPtr, + tagLength, + plaintextPtr, + plaintextLengthPtr, + verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_AEADDecryptDataRefAsr4_04() */ + +/********************************************************************************************************************** + * Csm_AEADDecryptDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecryptDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_AEADDecrypt */ + return Csm_AEADDecrypt(jobId, + mode, + ciphertextPtr, + ciphertextLength, + associatedDataPtr, + associatedDataLength, + tagPtr, + tagLength, + plaintextPtr, + plaintextLengthPtr, + verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_AEADDecryptDataRefAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_AEADDecryptDataRef() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecryptDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_AEADDecrypt */ + return Csm_AEADDecrypt(jobId, + mode, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))ciphertextPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + ciphertextLength, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))associatedDataPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + associatedDataLength, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))tagPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + tagLength, + (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))plaintextPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + plaintextLengthPtr, + verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_AEADDecryptDataRef() */ + +/********************************************************************************************************************** + * Csm_SignatureGenerateAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerateAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) signatureLengthPtr) +{ + /* #10 Call Csm_SignatureGenerate */ + return Csm_SignatureGenerate(jobId, mode, dataPtr, dataLength, signaturePtr, signatureLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_SignatureGenerateAsr4_03() */ + +/********************************************************************************************************************** + * Csm_SignatureGenerateAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerateAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) signatureLengthPtr) +{ + /* #10 Call Csm_SignatureGenerate */ + return Csm_SignatureGenerate(jobId, mode, dataPtr, dataLength, signaturePtr, signatureLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_SignatureGenerateAsr4_04() */ + +/********************************************************************************************************************** + * Csm_SignatureGenerateDataRefAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerateDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) signatureLengthPtr) +{ + /* #10 Call Csm_SignatureGenerate */ + return Csm_SignatureGenerate(jobId, mode, dataPtr, dataLength, signaturePtr, signatureLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_SignatureGenerateDataRefAsr4_04() */ + +/********************************************************************************************************************** + * Csm_SignatureGenerateDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerateDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) signatureLengthPtr) +{ + /* #10 Call Csm_SignatureGenerate */ + return Csm_SignatureGenerate(jobId, mode, dataPtr, dataLength, signaturePtr, signatureLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_SignatureGenerateDataRefAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_SignatureGenerateDataRef() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerateDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) signatureLengthPtr) +{ + /* #10 Call Csm_SignatureGenerate */ + return Csm_SignatureGenerate(jobId, + mode, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))dataPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + dataLength, + (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))signaturePtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + signatureLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_SignatureGenerateDataRef() */ + +/********************************************************************************************************************** + * Csm_SignatureVerifyAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerifyAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_SignatureVerify */ + return Csm_SignatureVerify(jobId, mode, dataPtr, dataLength, signaturePtr, signatureLength, verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_SignatureVerifyAsr4_03() */ + +/********************************************************************************************************************** + * Csm_SignatureVerifyAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerifyAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_SignatureVerify */ + return Csm_SignatureVerify(jobId, mode, dataPtr, dataLength, signaturePtr, signatureLength, verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_SignatureVerifyAsr4_04() */ + +/********************************************************************************************************************** + * Csm_SignatureVerifyDataRefAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerifyDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_SignatureVerify */ + return Csm_SignatureVerify(jobId, mode, dataPtr, dataLength, signaturePtr, signatureLength, verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_SignatureVerifyDataRefAsr4_04() */ + +/********************************************************************************************************************** + * Csm_SignatureVerifyDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerifyDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_SignatureVerify */ + return Csm_SignatureVerify(jobId, mode, dataPtr, dataLength, signaturePtr, signatureLength, verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_SignatureVerifyDataRefAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_SignatureVerifyDataRef() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerifyDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_SignatureVerify */ + return Csm_SignatureVerify(jobId, + mode, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))dataPtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + dataLength, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))signaturePtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + signatureLength, + verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_SignatureVerifyDataRef() */ + +/********************************************************************************************************************** + * Csm_RandomGenerateAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_RandomGenerateAsr4_03(uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_RandomGenerate */ + return Csm_RandomGenerate(jobId, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_RandomGenerateAsr4_03() */ + +/********************************************************************************************************************** + * Csm_RandomGenerateDataRefAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_RandomGenerateDataRefAsr4_03(uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_RandomGenerate */ + return Csm_RandomGenerate(jobId, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_RandomGenerateDataRefAsr4_03() */ + +/********************************************************************************************************************** + * Csm_RandomGenerateDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_RandomGenerateDataRefAsrR19_11(uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_RandomGenerate */ + return Csm_RandomGenerate(jobId, resultPtr, resultLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_RandomGenerateDataRefAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_RandomGenerateDataRef() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_RandomGenerateDataRef(uint32 jobId, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr) +{ + /* #10 Call Csm_RandomGenerate */ + return Csm_RandomGenerate(jobId, (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))resultPtr, resultLengthPtr); /* PRQA S 0316 */ /* MD_CSM_0316 */ /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_RandomGenerateDataRef() */ + +/********************************************************************************************************************** + * Csm_CancelJobAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJobAsr4_03(uint32 jobId, Crypto_OperationModeType mode) +{ + /* #10 Call Csm_CancelJob */ + return Csm_CancelJob(jobId, mode); +} /* Csm_CancelJobAsr4_03() */ + +/********************************************************************************************************************** + * Csm_CancelJobAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJobAsr4_04(uint32 jobId, Crypto_OperationModeType mode) +{ + /* #10 Call Csm_CancelJob */ + return Csm_CancelJob(jobId, mode); +} /* Csm_CancelJobAsr4_04() */ + +/********************************************************************************************************************** + * Csm_CancelJobNoOpMode() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJobNoOpMode(uint32 jobId) +{ + /* #10 Call Csm_CancelJob */ + return Csm_CancelJob(jobId, CRYPTO_OPERATIONMODE_SINGLECALL); +} /* Csm_CancelJobNoOpMode() */ + +/********************************************************************************************************************** + * Csm_CancelJobNoOpModeAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJobNoOpModeAsr4_03(uint32 jobId) +{ + /* #10 Call Csm_CancelJob */ + return Csm_CancelJob(jobId, CRYPTO_OPERATIONMODE_SINGLECALL); +} /* Csm_CancelJobNoOpModeAsr4_03() */ + +/********************************************************************************************************************** + * Csm_CancelJobNoOpModeAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJobNoOpModeAsr4_04(uint32 jobId) +{ + /* #10 Call Csm_CancelJob */ + return Csm_CancelJob(jobId, CRYPTO_OPERATIONMODE_SINGLECALL); +} /* Csm_CancelJobNoOpModeAsr4_04() */ + +/********************************************************************************************************************** + * Csm_JobKeyDeriveAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyDeriveAsr4_03(uint32 jobId, uint32 keyId, uint32 targetKeyId) +{ + /* #10 Call Csm_JobKeyDerive44x */ + return Csm_JobKeyDerive44x(jobId, keyId, targetKeyId); +} /* Csm_JobKeyDeriveAsr4_03() */ + +/********************************************************************************************************************** + * Csm_JobKeyDeriveAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyDeriveAsrR19_11(uint32 jobId, uint32 keyId, uint32 targetKeyId) +{ + /* #10 Call Csm_JobKeyDerive44x */ + return Csm_JobKeyDerive44x(jobId, keyId, targetKeyId); +} /* Csm_JobKeyDeriveAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubValAsrR21_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcPubValAsrR21_11(uint32 jobId, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr) +{ + /* #10 Call Csm_JobKeyExchangeCalcPubVal */ + return Csm_JobKeyExchangeCalcPubVal(jobId, (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))publicValuePtr, publicValueLengthPtr); /* PRQA S 0316 */ /* MD_CSM_0316 */ /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_JobKeyExchangeCalcPubValAsrR21_11() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubValAsrR20_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcPubValAsrR20_11(uint32 jobId, + uint32 keyId, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr) +{ + /* #10 Call Csm_JobKeyExchangeCalcPubVal44x */ + return Csm_JobKeyExchangeCalcPubVal44x(jobId, + keyId, + (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))publicValuePtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + publicValueLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_JobKeyExchangeCalcPubValAsrR20_11() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubValAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcPubValAsr4_03(uint32 jobId, + uint32 keyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr) +{ + /* #10 Call Csm_JobKeyExchangeCalcPubVal44x */ + return Csm_JobKeyExchangeCalcPubVal44x(jobId, keyId, publicValuePtr, publicValueLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_JobKeyExchangeCalcPubValAsr4_03() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubValAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcPubValAsrR19_11(uint32 jobId, + uint32 keyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr) +{ + /* #10 Call Csm_JobKeyExchangeCalcPubVal44x */ + return Csm_JobKeyExchangeCalcPubVal44x(jobId, keyId, publicValuePtr, publicValueLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_JobKeyExchangeCalcPubValAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecretAsrR21_11_A() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcSecretAsrR21_11_A(uint32 jobId, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + /* #10 Call Csm_JobKeyExchangeCalcSecret */ + return Csm_JobKeyExchangeCalcSecret(jobId, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))partnerPublicValuePtr, /* PRQA S 0316 */ /* MD_CSM_0316 */ + partnerPublicValueLength); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_JobKeyExchangeCalcSecretAsrR21_11_A() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecretAsrR21_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcSecretAsrR21_11(uint32 jobId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + /* #10 Call Csm_JobKeyExchangeCalcSecret */ + return Csm_JobKeyExchangeCalcSecret(jobId, partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_JobKeyExchangeCalcSecretAsrR21_11() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecretAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcSecretAsr4_03(uint32 jobId, + uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + /* #10 Call Csm_JobKeyExchangeCalcSecret44x */ + return Csm_JobKeyExchangeCalcSecret44x(jobId, keyId, partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_JobKeyExchangeCalcSecretAsr4_03() */ + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecretAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcSecretAsrR19_11(uint32 jobId, + uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + /* #10 Call Csm_JobKeyExchangeCalcSecret44x */ + return Csm_JobKeyExchangeCalcSecret44x(jobId, keyId, partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_JobKeyExchangeCalcSecretAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_JobKeyGenerateAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyGenerateAsr4_03(uint32 jobId, uint32 keyId) +{ + /* #10 Call Csm_JobKeyGenerate44x */ + return Csm_JobKeyGenerate44x(jobId, keyId); +} /* Csm_JobKeyGenerateAsr4_03() */ + +/********************************************************************************************************************** + * Csm_JobKeyGenerateAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyGenerateAsrR19_11(uint32 jobId, uint32 keyId) +{ + /* #10 Call Csm_JobKeyGenerate44x */ + return Csm_JobKeyGenerate44x(jobId, keyId); +} /* Csm_JobKeyGenerateAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_JobKeySetInvalidAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeySetInvalidAsr4_03(uint32 jobId, uint32 keyId) +{ + /* #10 Call Csm_JobKeySetInvalid44x */ + return Csm_JobKeySetInvalid44x(jobId, keyId); +} /* Csm_JobKeySetInvalidAsr4_03() */ + +/********************************************************************************************************************** + * Csm_JobKeySetValidAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeySetValidAsr4_03(uint32 jobId, uint32 keyId) +{ + /* #10 Call Csm_JobKeySetValid44x */ + return Csm_JobKeySetValid44x(jobId, keyId); +} /* Csm_JobKeySetValidAsr4_03() */ + +/********************************************************************************************************************** + * Csm_JobKeySetValidAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeySetValidAsrR19_11(uint32 jobId, uint32 keyId) +{ + /* #10 Call Csm_JobKeySetValid44x */ + return Csm_JobKeySetValid44x(jobId, keyId); +} /* Csm_JobKeySetValidAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_JobRandomSeedAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobRandomSeedAsr4_03(uint32 jobId, + uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) seedPtr, + uint32 seedLength) +{ + /* #10 Call Csm_JobRandomSeed44x */ + return Csm_JobRandomSeed44x(jobId, keyId, seedPtr, seedLength); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_JobRandomSeedAsr4_03() */ + +/********************************************************************************************************************** + * Csm_JobRandomSeedAsrR19_11() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_JobRandomSeedAsrR19_11(uint32 jobId, + uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) seedPtr, + uint32 seedLength) +{ + /* #10 Call Csm_JobRandomSeed44x */ + return Csm_JobRandomSeed44x(jobId, keyId, seedPtr, seedLength); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_JobRandomSeedAsrR19_11() */ + +/********************************************************************************************************************** + * Csm_CertificateParseAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_CertificateParseAsr4_03(uint32 keyId) +{ + /* #10 Call Csm_CertificateParse */ + return Csm_CertificateParse(keyId); +} /* Csm_CertificateParseAsr4_03() */ + +/********************************************************************************************************************** + * Csm_CertificateVerifyAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_CertificateVerifyAsr4_03(uint32 keyId, + uint32 verifyKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr) +{ + /* #10 Call Csm_CertificateVerify */ + return Csm_CertificateVerify(keyId, verifyKeyId, verifyPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_CertificateVerifyAsr4_03() */ + +/********************************************************************************************************************** + * Csm_KeyCopyAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyCopyAsr4_03(uint32 keyId, uint32 targetKeyId) +{ + /* #10 Call Csm_KeyCopy */ + return Csm_KeyCopy(keyId, targetKeyId); +} /* Csm_KeyCopyAsr4_03() */ + +/********************************************************************************************************************** + * Csm_KeyCopyAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyCopyAsr4_04(uint32 keyId, uint32 targetKeyId) +{ + /* #10 Call Csm_KeyCopy */ + return Csm_KeyCopy(keyId, targetKeyId); +} /* Csm_KeyCopyAsr4_04() */ + +/********************************************************************************************************************** + * Csm_KeyDeriveAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyDeriveAsr4_03(uint32 keyId, uint32 targetKeyId) +{ + /* #10 Call Csm_KeyDerive */ + return Csm_KeyDerive(keyId, targetKeyId); +} /* Csm_KeyDeriveAsr4_03() */ + +/********************************************************************************************************************** + * Csm_KeyDeriveAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyDeriveAsr4_04(uint32 keyId, uint32 targetKeyId) +{ + /* #10 Call Csm_KeyDerive */ + return Csm_KeyDerive(keyId, targetKeyId); +} /* Csm_KeyDeriveAsr4_04() */ + +/********************************************************************************************************************** + * Csm_KeyElementCopyAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementCopyAsr4_03(uint32 keyId, + uint32 keyElementId, + uint32 targetKeyId, + uint32 targetKeyElementId) +{ + /* #10 Call Csm_KeyElementCopy */ + return Csm_KeyElementCopy(keyId, keyElementId, targetKeyId, targetKeyElementId); +} /* Csm_KeyElementCopyAsr4_03() */ + +/********************************************************************************************************************** + * Csm_KeyElementCopyAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementCopyAsr4_04(uint32 keyId, + uint32 keyElementId, + uint32 targetKeyId, + uint32 targetKeyElementId) +{ + /* #10 Call Csm_KeyElementCopy */ + return Csm_KeyElementCopy(keyId, keyElementId, targetKeyId, targetKeyElementId); +} /* Csm_KeyElementCopyAsr4_04() */ + +/********************************************************************************************************************** + * Csm_KeyElementCopyPartialAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementCopyPartialAsr4_03(uint32 keyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetKeyId, + uint32 targetKeyElementId) +{ + /* #10 Call Csm_KeyElementCopyPartial */ + return Csm_KeyElementCopyPartial(keyId, + keyElementId, + keyElementSourceOffset, + keyElementTargetOffset, + keyElementCopyLength, + targetKeyId, + targetKeyElementId); +} /* Csm_KeyElementCopyPartialAsr4_03() */ + +/********************************************************************************************************************** + * Csm_KeyElementGetAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementGetAsr4_03(uint32 keyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) keyPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) keyLengthPtr) +{ + /* #10 Call Csm_KeyElementGet */ + return Csm_KeyElementGet(keyId, keyElementId, keyPtr, keyLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_KeyElementGetAsr4_03() */ + +/********************************************************************************************************************** + * Csm_KeyElementGetAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementGetAsr4_04(uint32 keyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) keyPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) keyLengthPtr) +{ + /* #10 Call Csm_KeyElementGet */ + return Csm_KeyElementGet(keyId, keyElementId, keyPtr, keyLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_KeyElementGetAsr4_04() */ + +/********************************************************************************************************************** + * Csm_KeyElementSetAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementSetAsr4_03(uint32 keyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) keyPtr, + uint32 keyLength) +{ + /* #10 Call Csm_KeyElementSet */ + return Csm_KeyElementSet(keyId, keyElementId, keyPtr, keyLength); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_KeyElementSetAsr4_03() */ + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcPubValAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcPubValAsr4_03(uint32 keyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr) +{ + /* #10 Call Csm_KeyExchangeCalcPubVal */ + return Csm_KeyExchangeCalcPubVal(keyId, publicValuePtr, publicValueLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_KeyExchangeCalcPubValAsr4_03() */ + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcPubValAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcPubValAsr4_04(uint32 keyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr) +{ + /* #10 Call Csm_KeyExchangeCalcPubVal */ + return Csm_KeyExchangeCalcPubVal(keyId, publicValuePtr, publicValueLengthPtr); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_KeyExchangeCalcPubValAsr4_04() */ + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcSecretAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcSecretAsr4_03(uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + /* #10 Call Csm_KeyExchangeCalcSecret */ + return Csm_KeyExchangeCalcSecret(keyId, partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_KeyExchangeCalcSecretAsr4_03() */ + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcSecretAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcSecretAsr4_04(uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength) +{ + /* #10 Call Csm_KeyExchangeCalcSecret */ + return Csm_KeyExchangeCalcSecret(keyId, partnerPublicValuePtr, partnerPublicValueLength); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_KeyExchangeCalcSecretAsr4_04() */ + +/********************************************************************************************************************** + * Csm_KeyGenerateAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyGenerateAsr4_03(uint32 keyId) +{ + /* #10 Call Csm_KeyGenerate */ + return Csm_KeyGenerate(keyId); +} /* Csm_KeyGenerateAsr4_03() */ + +/********************************************************************************************************************** + * Csm_KeyGenerateAsr4_04() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeyGenerateAsr4_04(uint32 keyId) +{ + /* #10 Call Csm_KeyGenerate */ + return Csm_KeyGenerate(keyId); +} /* Csm_KeyGenerateAsr4_04() */ + +/********************************************************************************************************************** + * Csm_KeySetValidAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_KeySetValidAsr4_03(uint32 keyId) +{ + /* #10 Call Csm_KeySetValid */ + return Csm_KeySetValid(keyId); +} /* Csm_KeySetValidAsr4_03() */ + +/********************************************************************************************************************** + * Csm_RandomSeedAsr4_03() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_RandomSeedAsr4_03(uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) seedPtr, + uint32 seedLength) +{ + /* #10 Call Csm_RandomSeed */ + return Csm_RandomSeed(keyId, seedPtr, seedLength); /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_RandomSeedAsr4_03() */ + +/********************************************************************************************************************** + * Csm_SaveContextJobWithVoidPtr() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_SaveContextJobWithVoidPtr(uint32 jobId, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) contextBufferPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) contextBufferLengthPtr) +{ + /* #10 Call Csm_SaveContextJob */ + return Csm_SaveContextJob(jobId, (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))contextBufferPtr, contextBufferLengthPtr); /* PRQA S 0316 */ /* MD_CSM_0316 */ /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_SaveContextJobWithVoidPtr() */ + +/********************************************************************************************************************** + * Csm_RestoreContextJobWithVoidPtr() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +FUNC(Std_ReturnType, CSM_CODE) Csm_RestoreContextJobWithVoidPtr(uint32 jobId, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) contextBufferPtr, + uint32 contextBufferLength) +{ + /* #10 Call Csm_RestoreContextJob */ + return Csm_RestoreContextJob(jobId, (P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR))contextBufferPtr, contextBufferLength); /* PRQA S 0316 */ /* MD_CSM_0316 */ /* SBSW_CSM_API_CALL_FORWARDING_PTR_WRAPPER */ +} /* Csm_RestoreContextJobWithVoidPtr() */ + +# define CSM_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* (CSM_RTE_PORTS == STD_ON) */ + +/********************************************************************************************************************** + * END OF FILE: Csm_Rte.c + *********************************************************************************************************************/ diff --git a/Source/bsw/Csm/Csm_Rte.h b/Source/bsw/Csm/Csm_Rte.h new file mode 100644 index 0000000..ce06a22 --- /dev/null +++ b/Source/bsw/Csm/Csm_Rte.h @@ -0,0 +1,2903 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/* \file Csm_Rte.h + * \brief MICROSAR Crypto Service Manager (CSM) RTE + * + * \details Description of the MICROSAR Crypto Service Manager (CSM) service APIs used only by RTE + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#if !defined (CSM_RTE_H) +# define CSM_RTE_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Csm.h" + + /* Usage check */ +# if !defined (CSM_RTE_SOURCE) +# error "This is a private header and should only be included by Csm_Rte.c" +# endif + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + + /********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + + /********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +# if (CSM_RTE_PORTS == STD_ON) + +# define CSM_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * Csm_HashAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Hash(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the hash shall be computed. + * \param[in] dataLength Contains the number of bytes to be hashed. + * \param[out] resultPtr Contains the pointer to the data where the hash value shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer provided by resultPtr. When the request has finished, the actual length of + * the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_HashAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_HashDataRefAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Hash(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the hash shall be computed. + * \param[in] dataLength Contains the number of bytes to be hashed. + * \param[out] resultPtr Contains the pointer to the data where the hash value shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer provided by resultPtr. When the request has finished, the actual length of + * the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_HashDataRefAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_HashDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Hash(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the hash shall be computed. + * \param[in] dataLength Contains the number of bytes to be hashed. + * \param[out] resultPtr Contains the pointer to the data where the hash value shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer provided by resultPtr. When the request has finished, the actual length of + * the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_HashDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_HashDataRef() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Hash(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the hash shall be computed. + * \param[in] dataLength Contains the number of bytes to be hashed. + * \param[out] resultPtr Contains the pointer to the data where the hash value shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer provided by resultPtr. When the request has finished, the actual length of + * the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_HashDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_MacGenerateAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_MacGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be computed. + * \param[in] dataLength Contains the number of bytes for the MAC generation. + * \param[out] macPtr Contains the pointer to the data where the MAC shall be stored. + * \param[in,out] macLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer provided by macPtr. When the request has finished, the actual length of + * the returned MAC shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerateAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr); + +/********************************************************************************************************************** + * Csm_MacGenerateAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_MacGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be computed. + * \param[in] dataLength Contains the number of bytes for the MAC generation. + * \param[out] macPtr Contains the pointer to the data where the MAC shall be stored. + * \param[in,out] macLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer provided by macPtr. When the request has finished, the actual length of + * the returned MAC shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerateAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr); + +/********************************************************************************************************************** + * Csm_MacGenerateDataRefAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_MacGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be computed. + * \param[in] dataLength Contains the number of bytes for the MAC generation. + * \param[out] macPtr Contains the pointer to the data where the MAC shall be stored. + * \param[in,out] macLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer provided by macPtr. When the request has finished, the actual length of + * the returned MAC shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerateDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr); + +/********************************************************************************************************************** + * Csm_MacGenerateDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_MacGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be computed. + * \param[in] dataLength Contains the number of bytes for the MAC generation. + * \param[out] macPtr Contains the pointer to the data where the MAC shall be stored. + * \param[in,out] macLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer provided by macPtr. When the request has finished, the actual length of + * the returned MAC shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerateDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr); + +/********************************************************************************************************************** + * Csm_MacGenerateDataRef() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_MacGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be computed. + * \param[in] dataLength Contains the number of bytes for the MAC generation. + * \param[out] macPtr Contains the pointer to the data where the MAC shall be stored. + * \param[in,out] macLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer provided by macPtr. When the request has finished, the actual length of + * the returned MAC shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_MacGenerateDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) macPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) macLengthPtr); + +/********************************************************************************************************************** + * Csm_MacVerifyAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_MacVerify(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be verified. + * \param[in] dataLength Contains the number of data bytes for which the MAC shall be verified. + * \param[in] macPtr Holds a pointer to the MAC to be verified. + * \param[in] macLength Contains the MAC length in BITS to be verified. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the MAC + * verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerifyAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_MacVerifyAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_MacVerify(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be verified. + * \param[in] dataLength Contains the number of data bytes for which the MAC shall be verified. + * \param[in] macPtr Holds a pointer to the MAC to be verified. + * \param[in] macLength Contains the MAC length in BITS to be verified. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the MAC + * verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerifyAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_MacVerifyDataRefAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_MacVerify(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be verified. + * \param[in] dataLength Contains the number of data bytes for which the MAC shall be verified. + * \param[in] macPtr Holds a pointer to the MAC to be verified. + * \param[in] macLength Contains the MAC length in BITS to be verified. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the MAC + * verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerifyDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_MacVerifyDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_MacVerify(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be verified. + * \param[in] dataLength Contains the number of data bytes for which the MAC shall be verified. + * \param[in] macPtr Holds a pointer to the MAC to be verified. + * \param[in] macLength Contains the MAC length in BITS to be verified. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the MAC + * verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerifyDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_MacVerifyDataRef() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_MacVerify(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data for which the MAC shall be verified. + * \param[in] dataLength Contains the number of data bytes for which the MAC shall be verified. + * \param[in] macPtr Holds a pointer to the MAC to be verified. + * \param[in] macLength Contains the MAC length in BITS to be verified. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the MAC + * verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_MacVerifyDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) macPtr, + uint32 macLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_EncryptAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Encrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be encrypted. + * \param[in] dataLength Contains the number of bytes to encrypt. + * \param[out] resultPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_EncryptAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_EncryptAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Encrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be encrypted. + * \param[in] dataLength Contains the number of bytes to encrypt. + * \param[out] resultPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_EncryptAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_EncryptDataRefAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Encrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be encrypted. + * \param[in] dataLength Contains the number of bytes to encrypt. + * \param[out] resultPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_EncryptDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_EncryptDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Encrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be encrypted. + * \param[in] dataLength Contains the number of bytes to encrypt. + * \param[out] resultPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_EncryptDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_EncryptDataRef() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Encrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be encrypted. + * \param[in] dataLength Contains the number of bytes to encrypt. + * \param[out] resultPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_EncryptDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_DecryptAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Decrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be decrypted. + * \param[in] dataLength Contains the number of bytes to decrypt. + * \param[out] resultPtr Contains the pointer to the data where the decrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_DecryptAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_DecryptAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Decrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be decrypted. + * \param[in] dataLength Contains the number of bytes to decrypt. + * \param[out] resultPtr Contains the pointer to the data where the decrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_DecryptAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_DecryptDataRefAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Decrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be decrypted. + * \param[in] dataLength Contains the number of bytes to decrypt. + * \param[out] resultPtr Contains the pointer to the data where the decrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_DecryptDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_DecryptDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Decrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be decrypted. + * \param[in] dataLength Contains the number of bytes to decrypt. + * \param[out] resultPtr Contains the pointer to the data where the decrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_DecryptDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_DecryptDataRef() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_Decrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be decrypted. + * \param[in] dataLength Contains the number of bytes to decrypt. + * \param[out] resultPtr Contains the pointer to the data where the decrypted data shall be stored. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the output length information is + * stored in bytes. On calling this function, this parameter shall contain the size + * of the buffer provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_DecryptDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_AEADEncryptAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_AEADEncrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] plaintextPtr Contains the pointer to the data to be encrypted. + * \param[in] plaintextLength Contains the number of bytes to encrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[out] ciphertextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] ciphertextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the ciphertext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by ciphertextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in,out] tagLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the Tag is stored. On calling this function, this parameter shall contain the + * size of the buffer in bytes provided by tagPtr. When the request has + * finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncryptAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr); + +/********************************************************************************************************************** + * Csm_AEADEncryptAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_AEADEncrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] plaintextPtr Contains the pointer to the data to be encrypted. + * \param[in] plaintextLength Contains the number of bytes to encrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[out] ciphertextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] ciphertextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the ciphertext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by ciphertextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in,out] tagLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the Tag is stored. On calling this function, this parameter shall contain the + * size of the buffer in bytes provided by tagPtr. When the request has + * finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncryptAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr); + +/********************************************************************************************************************** + * Csm_AEADEncryptDataRefAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_AEADEncrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] plaintextPtr Contains the pointer to the data to be encrypted. + * \param[in] plaintextLength Contains the number of bytes to encrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[out] ciphertextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] ciphertextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the ciphertext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by ciphertextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in,out] tagLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the Tag is stored. On calling this function, this parameter shall contain the + * size of the buffer in bytes provided by tagPtr. When the request has + * finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncryptDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr); + +/********************************************************************************************************************** + * Csm_AEADEncryptDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_AEADEncrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] plaintextPtr Contains the pointer to the data to be encrypted. + * \param[in] plaintextLength Contains the number of bytes to encrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[out] ciphertextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] ciphertextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the ciphertext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by ciphertextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in,out] tagLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the Tag is stored. On calling this function, this parameter shall contain the + * size of the buffer in bytes provided by tagPtr. When the request has + * finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncryptDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr); + +/********************************************************************************************************************** + * Csm_AEADEncryptDataRef() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_AEADEncrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] plaintextPtr Contains the pointer to the data to be encrypted. + * \param[in] plaintextLength Contains the number of bytes to encrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[out] ciphertextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] ciphertextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the ciphertext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by ciphertextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in,out] tagLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the Tag is stored. On calling this function, this parameter shall contain the + * size of the buffer in bytes provided by tagPtr. When the request has + * finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_AEADEncryptDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + uint32 plaintextLength, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) ciphertextLengthPtr, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) tagPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) tagLengthPtr); + +/********************************************************************************************************************** + * Csm_AEADDecryptAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_AEADDecrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] ciphertextPtr Contains the pointer to the data to be decrypted. + * \param[in] ciphertextLength Contains the number of bytes to decrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[in] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in] tagLength Contains the length in bytes of the Tag to be verified. + * \param[out] plaintextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] plaintextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the plaintext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by plaintextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] verifyPtr Contains the pointer to the result of the verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecryptAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_AEADDecryptAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_AEADDecrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] ciphertextPtr Contains the pointer to the data to be decrypted. + * \param[in] ciphertextLength Contains the number of bytes to decrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[in] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in] tagLength Contains the length in bytes of the Tag to be verified. + * \param[out] plaintextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] plaintextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the plaintext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by plaintextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] verifyPtr Contains the pointer to the result of the verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecryptAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_AEADDecryptDataRefAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_AEADDecrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] ciphertextPtr Contains the pointer to the data to be decrypted. + * \param[in] ciphertextLength Contains the number of bytes to decrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[in] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in] tagLength Contains the length in bytes of the Tag to be verified. + * \param[out] plaintextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] plaintextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the plaintext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by plaintextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] verifyPtr Contains the pointer to the result of the verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecryptDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_AEADDecryptDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_AEADDecrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] ciphertextPtr Contains the pointer to the data to be decrypted. + * \param[in] ciphertextLength Contains the number of bytes to decrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[in] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in] tagLength Contains the length in bytes of the Tag to be verified. + * \param[out] plaintextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] plaintextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the plaintext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by plaintextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] verifyPtr Contains the pointer to the result of the verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecryptDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_AEADDecryptDataRef() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_AEADDecrypt(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] ciphertextPtr Contains the pointer to the data to be decrypted. + * \param[in] ciphertextLength Contains the number of bytes to decrypt. + * \param[in] associatedDataPtr Contains the pointer to the associated data. + * \param[in] associatedDataLength Contains the number of bytes of the associated data. + * \param[in] tagPtr Contains the pointer to the data where the Tag shall be stored. + * \param[in] tagLength Contains the length in bytes of the Tag to be verified. + * \param[out] plaintextPtr Contains the pointer to the data where the encrypted data shall be stored. + * \param[in,out] plaintextLengthPtr Holds a pointer to the memory location in which the output length in bytes of + * the plaintext is stored. On calling this function, this parameter shall + * contain the size of the buffer in bytes provided by plaintextPtr. When the + * request has finished, the actual length of the returned value shall be stored. + * \param[out] verifyPtr Contains the pointer to the result of the verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_AEADDecryptDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) ciphertextPtr, + uint32 ciphertextLength, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) associatedDataPtr, + uint32 associatedDataLength, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) tagPtr, + uint32 tagLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) plaintextPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) plaintextLengthPtr, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_SignatureGenerateAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_SignatureGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be signed. + * \param[in] dataLength Contains the number of bytes to sign. + * \param[out] signaturePtr Contains the pointer to the data where the signature shall be stored. + * \param[in,out] signatureLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer in bytes provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerateAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) signatureLengthPtr); + +/********************************************************************************************************************** + * Csm_SignatureGenerateAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_SignatureGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be signed. + * \param[in] dataLength Contains the number of bytes to sign. + * \param[out] signaturePtr Contains the pointer to the data where the signature shall be stored. + * \param[in,out] signatureLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer in bytes provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerateAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) signatureLengthPtr); + +/********************************************************************************************************************** + * Csm_SignatureGenerateDataRefAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_SignatureGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be signed. + * \param[in] dataLength Contains the number of bytes to sign. + * \param[out] signaturePtr Contains the pointer to the data where the signature shall be stored. + * \param[in,out] signatureLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer in bytes provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerateDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) signatureLengthPtr); + +/********************************************************************************************************************** + * Csm_SignatureGenerateDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_SignatureGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be signed. + * \param[in] dataLength Contains the number of bytes to sign. + * \param[out] signaturePtr Contains the pointer to the data where the signature shall be stored. + * \param[in,out] signatureLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer in bytes provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerateDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) signatureLengthPtr); + +/********************************************************************************************************************** + * Csm_SignatureGenerateDataRef() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_SignatureGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be signed. + * \param[in] dataLength Contains the number of bytes to sign. + * \param[out] signaturePtr Contains the pointer to the data where the signature shall be stored. + * \param[in,out] signatureLengthPtr Holds a pointer to the memory location in which the output length in bytes is + * stored. On calling this function, this parameter shall contain the size of the + * buffer in bytes provided by resultPtr. When the request has finished, the actual + * length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureGenerateDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) signatureLengthPtr); + +/********************************************************************************************************************** + * Csm_SignatureVerifyAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_SignatureVerify(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be verified. + * \param[in] dataLength Contains the number of bytes to be verified. + * \param[in] signaturePtr Holds a pointer to the signature to be verified. + * \param[in] signatureLength Contains the signature length in bytes. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the + * signature verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerifyAsr4_03(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_SignatureVerifyAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_SignatureVerify(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be verified. + * \param[in] dataLength Contains the number of bytes to be verified. + * \param[in] signaturePtr Holds a pointer to the signature to be verified. + * \param[in] signatureLength Contains the signature length in bytes. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the + * signature verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerifyAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_SignatureVerifyDataRefAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_SignatureVerify(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be verified. + * \param[in] dataLength Contains the number of bytes to be verified. + * \param[in] signaturePtr Holds a pointer to the signature to be verified. + * \param[in] signatureLength Contains the signature length in bytes. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the + * signature verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerifyDataRefAsr4_04(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_SignatureVerifyDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_SignatureVerify(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be verified. + * \param[in] dataLength Contains the number of bytes to be verified. + * \param[in] signaturePtr Holds a pointer to the signature to be verified. + * \param[in] signatureLength Contains the signature length in bytes. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the + * signature verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerifyDataRefAsrR19_11(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_SignatureVerifyDataRef() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_SignatureVerify(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Indicates which operation mode(s) to perform. + * \param[in] dataPtr Contains the pointer to the data to be verified. + * \param[in] dataLength Contains the number of bytes to be verified. + * \param[in] signaturePtr Holds a pointer to the signature to be verified. + * \param[in] signatureLength Contains the signature length in bytes. + * \param[out] verifyPtr Holds a pointer to the memory location, which will hold the result of the + * signature verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_SignatureVerifyDataRef(uint32 jobId, + Crypto_OperationModeType mode, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) dataPtr, + uint32 dataLength, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) signaturePtr, + uint32 signatureLength, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_RandomGenerateAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_RandomGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[out] resultPtr Holds a pointer to the memory location which will hold the result of the + * random number generation. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the result length in bytes + * is stored. On calling this function, this parameter shall contain the + * number of random bytes, which shall be stored to the buffer provided by + * resultPtr. When the request has finished, the actual length of the returned + * value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy of random number generator is exhausted + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_RandomGenerateAsr4_03(uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_RandomGenerateDataRefAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_RandomGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[out] resultPtr Holds a pointer to the memory location which will hold the result of the + * random number generation. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the result length in bytes + * is stored. On calling this function, this parameter shall contain the + * number of random bytes, which shall be stored to the buffer provided by + * resultPtr. When the request has finished, the actual length of the returned + * value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy of random number generator is exhausted + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_RandomGenerateDataRefAsr4_03(uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_RandomGenerateDataRefAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_RandomGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[out] resultPtr Holds a pointer to the memory location which will hold the result of the + * random number generation. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the result length in bytes + * is stored. On calling this function, this parameter shall contain the + * number of random bytes, which shall be stored to the buffer provided by + * resultPtr. When the request has finished, the actual length of the returned + * value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy of random number generator is exhausted + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_RandomGenerateDataRefAsrR19_11(uint32 jobId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_RandomGenerateDataRef() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_RandomGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[out] resultPtr Holds a pointer to the memory location which will hold the result of the + * random number generation. + * \param[in,out] resultLengthPtr Holds a pointer to the memory location in which the result length in bytes + * is stored. On calling this function, this parameter shall contain the + * number of random bytes, which shall be stored to the buffer provided by + * resultPtr. When the request has finished, the actual length of the returned + * value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * CRYPTO_E_ENTROPY_EXHAUSTION Request failed, entropy of random number generator is exhausted + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_RandomGenerateDataRef(uint32 jobId, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) resultPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) resultLengthPtr); + +/********************************************************************************************************************** + * Csm_CancelJobAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_CancelJob(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Not used, just for interface compatibility provided + * \return E_OK Request successful - Job was cancelled or was already Idle + * E_NOT_OK Request failed - Job could not be cancelled + * CRYPTO_E_JOB_CANCELED Request pending - Job will be cancelled with next callback notification + * \pre - + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with E_NOT_OK) + * \synchronous TRUE + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJobAsr4_03(uint32 jobId, Crypto_OperationModeType mode); + +/********************************************************************************************************************** + * Csm_CancelJobAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_CancelJob(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] mode Not used, just for interface compatibility provided + * \return E_OK Request successful - Job was cancelled or was already Idle + * E_NOT_OK Request failed - Job could not be cancelled + * CRYPTO_E_JOB_CANCELED Request pending - Job will be cancelled with next callback notification + * \pre - + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with E_NOT_OK) + * \synchronous TRUE + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJobAsr4_04(uint32 jobId, Crypto_OperationModeType mode); + +/********************************************************************************************************************** + * Csm_CancelJobNoOpMode() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_CancelJob(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \return E_OK Request successful - Job was cancelled or was already Idle + * E_NOT_OK Request failed - Job could not be cancelled + * CRYPTO_E_JOB_CANCELED Request pending - Job will be cancelled with next callback notification + * \pre - + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with E_NOT_OK) + * \synchronous TRUE + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJobNoOpMode(uint32 jobId); + +/********************************************************************************************************************** + * Csm_CancelJobNoOpModeAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_CancelJob(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \return E_OK Request successful - Job was cancelled or was already Idle + * E_NOT_OK Request failed - Job could not be cancelled + * CRYPTO_E_JOB_CANCELED Request pending - Job will be cancelled with next callback notification + * \pre - + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with E_NOT_OK) + * \synchronous TRUE + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJobNoOpModeAsr4_03(uint32 jobId); + +/********************************************************************************************************************** + * Csm_CancelJobNoOpModeAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_CancelJob(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \return E_OK Request successful - Job was cancelled or was already Idle + * E_NOT_OK Request failed - Job could not be cancelled + * CRYPTO_E_JOB_CANCELED Request pending - Job will be cancelled with next callback notification + * \pre - + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with E_NOT_OK) + * \synchronous TRUE + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_CancelJobNoOpModeAsr4_04(uint32 jobId); + +/********************************************************************************************************************** + * Csm_JobKeyDeriveAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyDerive44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[in] targetKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_READ_FAIL Request failed, not allowed to extract key element + * CRYPTO_E_KEY_WRITE_FAIL Request failed, not allowed to write key element + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyDeriveAsr4_03(uint32 jobId, uint32 keyId, uint32 targetKeyId); + +/********************************************************************************************************************** + * Csm_JobKeyDeriveAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyDerive44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[in] targetKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_READ_FAIL Request failed, not allowed to extract key element + * CRYPTO_E_KEY_WRITE_FAIL Request failed, not allowed to write key element + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyDeriveAsrR19_11(uint32 jobId, uint32 keyId, uint32 targetKeyId); + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubValAsrR21_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyExchangeCalcPubVal(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length information + * is stored. On calling this function, this parameter shall contain the size of the buffer provided + * by publicValuePtr. When the request has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcPubValAsrR21_11(uint32 jobId, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr); + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubValAsrR20_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyExchangeCalcPubVal44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length information + * is stored. On calling this function, this parameter shall contain the size of the buffer provided + * by publicValuePtr. When the request has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcPubValAsrR20_11(uint32 jobId, + uint32 keyId, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr); + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubValAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyExchangeCalcPubVal44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length information + * is stored. On calling this function, this parameter shall contain the size of the buffer provided + * by publicValuePtr. When the request has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcPubValAsr4_03(uint32 jobId, + uint32 keyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr); + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcPubValAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyExchangeCalcPubVal44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length information + * is stored. On calling this function, this parameter shall contain the size of the buffer provided + * by publicValuePtr. When the request has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcPubValAsrR19_11(uint32 jobId, + uint32 keyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr); + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecretAsrR21_11_A() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyExchangeCalcSecret(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partner's public value. + * \param[in] partnerPublicValueLength Contains the length of the partner's public value in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcSecretAsrR21_11_A(uint32 jobId, + P2CONST(void, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecretAsrR21_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyExchangeCalcSecret(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partner's public value. + * \param[in] partnerPublicValueLength Contains the length of the partner's public value in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcSecretAsrR21_11(uint32 jobId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecretAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyExchangeCalcSecret44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partner's public value. + * \param[in] partnerPublicValueLength Contains the length of the partner's public value in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcSecretAsr4_03(uint32 jobId, + uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * Csm_JobKeyExchangeCalcSecretAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyExchangeCalcSecret44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partner's public value. + * \param[in] partnerPublicValueLength Contains the length of the partner's public value in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyExchangeCalcSecretAsrR19_11(uint32 jobId, + uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * Csm_JobKeyGenerateAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyGenerate44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyGenerateAsr4_03(uint32 jobId, uint32 keyId); + +/********************************************************************************************************************** + * Csm_JobKeyGenerateAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeyGenerate44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeyGenerateAsrR19_11(uint32 jobId, uint32 keyId); + +/********************************************************************************************************************** + * Csm_JobKeySetInvalidAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeySetInvalid44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeySetInvalidAsr4_03(uint32 jobId, uint32 keyId); + +/********************************************************************************************************************** + * Csm_JobKeySetValidAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeySetValid44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeySetValidAsr4_03(uint32 jobId, uint32 keyId); + +/********************************************************************************************************************** + * Csm_JobKeySetValidAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobKeySetValid44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobKeySetValidAsrR19_11(uint32 jobId, uint32 keyId); + +/********************************************************************************************************************** + * Csm_JobRandomSeedAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobRandomSeed44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[in] seedPtr Holds a pointer to the memory location which contains the data to feed the seed. + * \param[in] seedLength Contains the length of the seed in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobRandomSeedAsr4_03(uint32 jobId, + uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) seedPtr, + uint32 seedLength); + +/********************************************************************************************************************** + * Csm_JobRandomSeedAsrR19_11() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_JobRandomSeed44x(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] keyId Not used - keyId already given by corresponding job of passed jobId + * \param[in] seedPtr Holds a pointer to the memory location which contains the data to feed the seed. + * \param[in] seedLength Contains the length of the seed in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_JobRandomSeedAsrR19_11(uint32 jobId, + uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) seedPtr, + uint32 seedLength); + +/********************************************************************************************************************** + * Csm_CertificateParseAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_CertificateParse(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key to be used for the certificate parsing. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_CertificateParseAsr4_03(uint32 keyId); + +/********************************************************************************************************************** + * Csm_CertificateVerifyAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_CertificateVerify(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key which shall be used to validate the certificate. + * \param[in] verifyKeyId Holds the identifier of the key containing the certificate to be verified. + * \param[out] verifyPtr Holds a pointer to the memory location which will contain the result of the certificate + * verification. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_CertificateVerifyAsr4_03(uint32 keyId, + uint32 verifyKeyId, + P2VAR(Crypto_VerifyResultType, AUTOMATIC, CSM_APPL_VAR) verifyPtr); + +/********************************************************************************************************************** + * Csm_KeyCopyAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyCopy(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] targetKeyId Holds the identifier of the key whose key element shall be the + * destination element. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element size does not match size of provided data + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyCopyAsr4_03(uint32 keyId, uint32 targetKeyId); + +/********************************************************************************************************************** + * Csm_KeyCopyAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyCopy(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] targetKeyId Holds the identifier of the key whose key element shall be the + * destination element. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element size does not match size of provided data + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyCopyAsr4_04(uint32 keyId, uint32 targetKeyId); + +/********************************************************************************************************************** + * Csm_KeyDeriveAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyDerive(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_READ_FAIL Request failed, not allowed to extract key element + * CRYPTO_E_KEY_WRITE_FAIL Request failed, not allowed to write key element + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyDeriveAsr4_03(uint32 keyId, uint32 targetKeyId); + +/********************************************************************************************************************** + * Csm_KeyDeriveAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyDerive(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key which is used for key derivation. + * \param[in] targetKeyId Holds the identifier of the key which is used to store the derived key. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_READ_FAIL Request failed, not allowed to extract key element + * CRYPTO_E_KEY_WRITE_FAIL Request failed, not allowed to write key element + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyDeriveAsr4_04(uint32 keyId, uint32 targetKeyId); + +/********************************************************************************************************************** + * Csm_KeyElementCopyAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyElementCopy(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for + * the copy operation. + * \param[in] targetKeyId Holds the identifier of the key whose key element shall be the + * destination element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination + * for the copy operation. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementCopyAsr4_03(uint32 keyId, + uint32 keyElementId, + uint32 targetKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * Csm_KeyElementCopyAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyElementCopy(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for + * the copy operation. + * \param[in] targetKeyId Holds the identifier of the key whose key element shall be the + * destination element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination + * for the copy operation. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementCopyAsr4_04(uint32 keyId, + uint32 keyElementId, + uint32 targetKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * Csm_KeyElementCopyPartialAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyElementCopyPartial(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key whose key element shall be the source + * element. + * \param[in] keyElementId Holds the identifier of the key element which shall be the source for the + * copy operation. + * \param[in] keyElementSourceOffset This is the offset of the source key element indicating the start index + * of the copy operation. + * \param[in] keyElementTargetOffset This is the offset of the destination key element indicating the start index + * of the copy operation. + * \param[in] keyElementCopyLength Specifies the number of bytes that shall be copied. + * \param[in] targetKeyId Holds the identifier of the key whose key element shall be the destination + * element. + * \param[in] targetKeyElementId Holds the identifier of the key element which shall be the destination for + * the copy operation. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element sizes are not compatible + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementCopyPartialAsr4_03(uint32 keyId, + uint32 keyElementId, + uint32 keyElementSourceOffset, + uint32 keyElementTargetOffset, + uint32 keyElementCopyLength, + uint32 targetKeyId, + uint32 targetKeyElementId); + +/********************************************************************************************************************** + * Csm_KeyElementGetAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyElementGet(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key from which a key element shall be + * extracted. + * \param[in] keyElementId Holds the identifier of the key element to be extracted. + * \param[out] keyPtr Holds the pointer to the memory location where the key shall be copied + * to. + * \param[in,out] keyLengthPtr Holds a pointer to the memory location in which the output buffer length + * in bytes is stored. On calling this function, this parameter shall + * contain the buffer length in bytes of the keyPtr. When the request has + * finished, the actual size of the written input bytes shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementGetAsr4_03(uint32 keyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) keyPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) keyLengthPtr); + +/********************************************************************************************************************** + * Csm_KeyElementGetAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyElementGet(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key from which a key element shall be + * extracted. + * \param[in] keyElementId Holds the identifier of the key element to be extracted. + * \param[out] keyPtr Holds the pointer to the memory location where the key shall be copied + * to. + * \param[in,out] keyLengthPtr Holds a pointer to the memory location in which the output buffer length + * in bytes is stored. On calling this function, this parameter shall + * contain the buffer length in bytes of the keyPtr. When the request has + * finished, the actual size of the written input bytes shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_READ_FAIL Request failed because read access was denied + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER The provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementGetAsr4_04(uint32 keyId, + uint32 keyElementId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) keyPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) keyLengthPtr); + +/********************************************************************************************************************** + * Csm_KeyElementSetAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyElementSet(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key for which a new material shall be set. + * \param[in] keyElementId Holds the identifier of the key element to be written. + * \param[in] keyPtr Holds the pointer to the key element bytes to be processed. + * \param[in] keyLength Contains the number of key element bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_WRITE_FAIL Request failed because write access was denied. + * CRYPTO_E_KEY_NOT_AVAILABLE Request failed because the key is not available + * CRYPTO_E_KEY_SIZE_MISMATCH Request failed, key element size does not match size of provided data. + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyElementSetAsr4_03(uint32 keyId, + uint32 keyElementId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) keyPtr, + uint32 keyLength); + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcPubValAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyExchangeCalcPubVal(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER Request failed because the provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcPubValAsr4_03(uint32 keyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr); + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcPubValAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyExchangeCalcPubVal(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[out] publicValuePtr Contains the pointer to the data where the public value shall be stored. + * \param[in,out] publicValueLengthPtr Holds a pointer to the memory location in which the public value length + * information is stored. On calling this function, this parameter shall + * contain the size of the buffer provided by publicValuePtr. When the request + * has finished, the actual length of the returned value shall be stored. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * CRYPTO_E_SMALL_BUFFER Request failed because the provided buffer is too small to store the result + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcPubValAsr4_04(uint32 keyId, + P2VAR(uint8, AUTOMATIC, CSM_APPL_VAR) publicValuePtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) publicValueLengthPtr); + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcSecretAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyExchangeCalcSecret(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partner's + * public value. + * \param[in] partnerPublicValueLength Contains the length of the partner's public value in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcSecretAsr4_03(uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * Csm_KeyExchangeCalcSecretAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyExchangeCalcSecret(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key which shall be used for the key exchange + * protocol. + * \param[in] partnerPublicValuePtr Holds the pointer to the memory location which contains the partner's + * public value. + * \param[in] partnerPublicValueLength Contains the length of the partner's public value in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyExchangeCalcSecretAsr4_04(uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) partnerPublicValuePtr, + uint32 partnerPublicValueLength); + +/********************************************************************************************************************** + * Csm_KeyGenerateAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key for which a new material shall be generated. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyGenerateAsr4_03(uint32 keyId); + +/********************************************************************************************************************** + * Csm_KeyGenerateAsr4_04() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeyGenerate(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key for which a new material shall be generated. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * CRYPTO_E_KEY_EMPTY Request failed because of uninitialized source key element + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeyGenerateAsr4_04(uint32 keyId); + +/********************************************************************************************************************** + * Csm_KeySetValidAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_KeySetValid(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key for which a new material shall be validated. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_KeySetValidAsr4_03(uint32 keyId); + +/********************************************************************************************************************** + * Csm_RandomSeedAsr4_03() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_RandomSeed(). + * \details See original function for behavior, parameter and return value description. + * \param[in] keyId Holds the identifier of the key for which a new seed shall be generated. + * \param[in] seedPtr Holds a pointer to the memory location which contains the data to feed the + * seed. + * \param[in] seedLength Contains the length of the seed in bytes. + * \return E_OK Request successful + * E_NOT_OK Request failed + * CRYPTO_E_BUSY Request failed, Crypto Driver Object is busy + * CRYPTO_E_KEY_NOT_VALID Request failed, the key's state is "invalid" + * \context TASK + * \reentrant TRUE, but not for the same keyId + * \synchronous TRUE + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_RandomSeedAsr4_03(uint32 keyId, + P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR) seedPtr, + uint32 seedLength); + +/********************************************************************************************************************** + * Csm_SaveContextJobWithVoidPtr() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_SaveContextJob(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[out] contextBufferPtr Pointer to the buffer in the application where the context data shall be + * stored to. + * \param[in,out] contextBufferLengthPtr Pointer to the buffer, where the length value is located.As input data it + * provides the maximum length of data available in contextBufferPtr.As + * output data it provides the actual length of data located in context + * BufferPtr(or 0 in case of a failure) + * \return E_OK Context data successfully provided. + * E_NOT_OK Context data could not be provided, values are not valid. + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_SaveContextJobWithVoidPtr(uint32 jobId, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) contextBufferPtr, + P2VAR(uint32, AUTOMATIC, CSM_APPL_VAR) contextBufferLengthPtr); + +/********************************************************************************************************************** + * Csm_RestoreContextJobWithVoidPtr() + *********************************************************************************************************************/ +/*! \brief Wrapper function of Csm_RestoreContextJob(). + * \details See original function for behavior, parameter and return value description. + * \param[in] jobId Holds the identifier of the job using the CSM service. + * \param[in] contextBufferPtr Pointer to the buffer, where the context data are located that + * shall be restored. + * \param[in] contextBufferLength Provides the length of context data that are located in contextBufferPtr. + * \return E_OK Context data successfully restored. + * E_NOT_OK Context data could not be restored. + * CRYPTO_E_BUSY Request failed, service is busy or queue is full + * \context TASK + * \reentrant TRUE, but not for the same jobId (will be rejected with CRYPTO_E_BUSY) + * \synchronous TRUE|FALSE Depends on given job. + * \pre - + * \note Shall only be called by Rte. + * The returned value is defined by the underlying Crypto Driver and may differ from the listed ones. + *********************************************************************************************************************/ +extern FUNC(Std_ReturnType, CSM_CODE) Csm_RestoreContextJobWithVoidPtr(uint32 jobId, + P2VAR(void, AUTOMATIC, CSM_APPL_VAR) contextBufferPtr, + uint32 contextBufferLength); + +# define CSM_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# endif /* (CSM_RTE_PORTS == STD_ON) */ + +#endif /* !defined (CSM_RTE_H) */ +/********************************************************************************************************************** + * END OF FILE: Csm_Rte.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Csm/Csm_Types.h b/Source/bsw/Csm/Csm_Types.h new file mode 100644 index 0000000..5a40736 --- /dev/null +++ b/Source/bsw/Csm/Csm_Types.h @@ -0,0 +1,45 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file Csm_Types.h + * \brief MICROSAR Crypto Service Manager (CSM) + * + * \details This header was used to provide the type declarations needed by other modules. Starting with Csm + * version 7.00.00, these type declarations were moved to Crypto_GeneralTypes.h according to AUTOSAR + * R19-11 and later. This header is kept for backward compatibility. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file (Csm.h). + * + * FILE VERSION + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the VERSION CHECK below. + *********************************************************************************************************************/ + +#if !defined (CSM_TYPES_H) +# define CSM_TYPES_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +# include "Crypto_GeneralTypes.h" + +#endif /* !defined (CSM_TYPES_H) */ + +/********************************************************************************************************************** + * END OF FILE: Csm_Types.h + *********************************************************************************************************************/ diff --git a/Source/bsw/Csm/Make/Csm_cfg.mak b/Source/bsw/Csm/Make/Csm_cfg.mak new file mode 100644 index 0000000..25c76bb --- /dev/null +++ b/Source/bsw/Csm/Make/Csm_cfg.mak @@ -0,0 +1,81 @@ +############################################################################### +# File Name : Csm_cfg.mak +# Description: Configuration makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Csm_rules.mak file. +############################################################################### + +############################################################## +# CAN_CONFIG_PATH: (not used for Vector) +# The Variable CAN_CONFIG_PATH is optional. It allows the +# configuration of the directory, where you can also find the +# generated source files. Generally they should be in the +# directory $(PROJECT_ROOT)\source\networks. +# But if the application should run on several hardware +# targets, then different CAN configurations of different +# directories will be necessary. Therefor the variable +# CAN_CONFIG_PATH should be used. +# +# For example: +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\st10 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# + +#CSM_CONFIG_PATH = + + +############################################################## +# CAN_DRIVER_MODE: (not used for Vector) +# This Variable contains the name of the can driver module. At +# the moment the Standard Software Core Supports the two driver +# can_drv.c (single CAN) and can_drvm.c (multi CAN). Other +# values are not allowed. +# +# For example: +# CAN_DRIVER_MODE = singlechannel/multichannel +# + +#CSM_DRIVER_MODE = singlechannel + + +############################################################### +# REQUIRED +# +# No Other resources are required to write a Configuration +# Makefile. +# +############################################################### + + +############################################################### +# PROVIDE +# +# A Configuration Makefile does not provide resources for other +# basic software bundles or the base_make package +# +############################################################### + + +############################################################### +# REGISTRY +# +# Like the Provide-Section this block is empty. +# +############################################################### + + +############################################################### +# SPECIFIC +# +# All variables in the _cfg makefile are "Specific" variables, +# because they should only be used in the *_check.mak, +# *_defs.mak and *_rules.mak Makefiles of the same basic +# software bundle. +############################################################### diff --git a/Source/bsw/Csm/Make/Csm_check.mak b/Source/bsw/Csm/Make/Csm_check.mak new file mode 100644 index 0000000..c6b4171 --- /dev/null +++ b/Source/bsw/Csm/Make/Csm_check.mak @@ -0,0 +1,79 @@ +############################################################################### +# File Name : Csm_check.mak +# Description: Configuration check makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Csm_rules.mak file. +############################################################################### + +############################################################### +# REGISTRY +# + +#e.g.: PREPARE_CONFIGURATION_INTERFACE += CAN_MODULES +PREPARE_CONFIGURATION_INTERFACE += + +CHECK_VARS_WHICH_ARE_REQUIRED += + +CHECK_VARS_WHICH_ARE_OPTIONAL += + +CHECK_VARS_WHICH_ARE_OBSOLETE += + +CHECK_VARS_WITH_ONE_CC_FILE += +CHECK_VARS_WITH_MORE_CC_FILES += + +CHECK_VARS_WITH_ONE_CPP_FILE += +CHECK_VARS_WITH_MORE_CPP_FILES += + +CHECK_VARS_WITH_ONE_ASM_FILE += +CHECK_VARS_WITH_MORE_ASM_FILES += + +CHECK_VARS_WITH_ONE_LIB_FILE += +CHECK_VARS_WITH_MORE_LIB_FILES += + +CHECK_VARS_WITH_ONE_OBJ_FILE += +CHECK_VARS_WITH_MORE_OBJ_FILES += + +#e.g: CHECK_VARS_WITH_ONE_DIRECTORY += $(DIRECTORIES_TO_CREATE) +# $(DIRECTORIES_TO_CREATE) = C:\demo\drv (this var is defined in _rules.mak) +CHECK_VARS_WITH_ONE_DIRECTORY += +CHECK_VARS_WITH_MORE_DIRECTORIES += + +CHECK_VARS_WITH_ONE_FILE += +CHECK_VARS_WITH_MORE_FILES += + +CHECK_VARS_WITH_MAX_LENGTH_ONE += + +############################################################### +# SPECIFIC +# +#ifneq ($(CAN_DRIVER_MODE),singlechannel) +#ifneq ($(CAN_DRIVER_MODE),multichannel) +#$(error The value of the variable CAN_DRIVER_MODE is not valid. \ +# Please use singlechannel or multichannel) +#endif +#endif + + +############################################################### +# REQUIRED +# +# No other resources are required for a Configuration Check +# Makefile +# +############################################################### + + +############################################################### +# PROVIDE +# +# A configuration Makefile does not provide resources for other +# basic software bundles or the base-make package. +# +############################################################### + diff --git a/Source/bsw/Csm/Make/Csm_defs.mak b/Source/bsw/Csm/Make/Csm_defs.mak new file mode 100644 index 0000000..e3441fe --- /dev/null +++ b/Source/bsw/Csm/Make/Csm_defs.mak @@ -0,0 +1,81 @@ +############################################################################### +# File Name : Csm_defs.mak +# Description: Public makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Csm_rules.mak file. +############################################################################### + +############################################################### +# INTERNAL REQUIRED CONFIGURATION (in can_cfg.mak) +# +# CAN_MODULES (required) (not necessary for Vector) +# CAN_DRIVER_MODE (required) (not necessary for Vector) +# CAN_PROJECT_PATH (optional) +# CAN_BUILD_LIBRARY (required) + + +############################################################### +# REQUIRED (defined in base_make) +# +# PROJECT_ROOT +# SSC_ROOT +############################################################### + + +############################################################### +# SPECIFIC +# Specific variables which were defined here are only for local use in this Makefile +# if for example additional includes are necessary, these vars can be defined and used in the REGISTRY-Part. +# e.g.: $(CAN_CORE_PATH) = $(SSC_ROOT)\Can could be used for CPP_INCLUDE_PATH += $(CAN_CORE_PATH)\CPP_FILES\... +CSM_CORE_PATH = +# e.g.: CAN_OUTPUT_PATH = $(GENDATA_DIR) +CSM_OUTPUT_PATH = $(GENDATA_DIR) + +#CAN_TOOL_PATH = $(PROJECT_ROOT)\core\com\can\gentool + +# it is also possible to generate own configurations with some checks like the following example +# ifneq ( $(CAN_CONFIG_PATH),) +# CAN_PROJECT_PATH = $(CAN_CONFIG_PATH) +# else +# CAN_PROJECT_PATH = $(PROJECT_ROOT)\source\network\can +# endif + + +############################################################### +# REGISTRY +# +# $(SSC_PLUGINS) is a list of the components. Here can is added (not necessary for Vector, whole component-list also exists in Global.makefile.target.make...) +# e.g.: SSC_PLUGINS += can +SSC_PLUGINS += +#e.g.: can_DEPENDENT_PLUGINS = +CSM_DEPENDENT_PLUGINS = + +#----------------------------------------------------------------------------------------- +# MakeSupport usually includes all header-files which were in the same +# directory as the source-files automatically, but to ensure that the +# Asr-Makefiles will also work with other Basic-Make-Packages, +# it is necessary to define all include directories for this Module +# e.g.: CC_INCLUDE_PATH += $(CAN_CORE_PATH) +#------------------------------------------------------------------------------------------ +CC_INCLUDE_PATH += Csm$(BSW_SRC_DIR) +CPP_INCLUDE_PATH += +ASM_INCLUDE_PATH += + +#PREPROCESSOR_DEFINES+= drivermode + +#drivermode_KEY = CAN_MODE +#drivermode_VALUE = $(CAN_DRIVER_MODE) + + +############################################################### +# PROVIDE +# +# A Public Makefile does not provide resources for other basic +# software bundles or the base_make package. +############################################################### diff --git a/Source/bsw/Csm/Make/Csm_rules.mak b/Source/bsw/Csm/Make/Csm_rules.mak new file mode 100644 index 0000000..9672694 --- /dev/null +++ b/Source/bsw/Csm/Make/Csm_rules.mak @@ -0,0 +1,102 @@ +############################################################################### +# File Name : Csm_rules.mak +# Description: Rules makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Version Date Author Description +#------------------------------------------------------------------------------ +# 1.00.00 2012-10-01 visrpp Creation for ASR 4.0.3 +# 1.00.01 2017-08-21 visrpp Updated to new template +# 1.01.00 2019-02-06 vircbl Added support of component-based SIP structure +# 1.02.00 2019-11-25 visenc Added new file +#------------------------------------------------------------------------------ +# TemplateVersion = 1.02 +############################################################################### + + +############################################################### +# REGISTRY +# + +#e.g.: LIBRARIES_TO_BUILD += $(LIB_OUPUT_PATH)\vendorx_canlib1.$(LIB_FILE_SUFFIX) +LIBRARIES_TO_BUILD += Csm +Csm_FILES = Csm$(BSW_SRC_DIR)\Csm.c Csm$(BSW_SRC_DIR)\Csm_Rte.c + +# e.g.: CC_FILES_TO_BUILD += drv\can_drv.c +CC_FILES_TO_BUILD += Csm$(BSW_SRC_DIR)\Csm.c Csm$(BSW_SRC_DIR)\Csm_Rte.c +CPP_FILES_TO_BUILD += +ASM_FILES_TO_BUILD += + +#LIBRARIES_LINK_ONLY += (not yet supported) +#OBJECTS_LINK_ONLY += (not yet supported) + +#------------------------------------------------------------------------------------------------- +#only define new dirs, OBJ, LIB, LOG were created automaticly +#------------------------------------------------------------------------------------------------- +DIRECTORIES_TO_CREATE += + +#DEPEND_GCC_OPTS += (not yet supported) + +# e.g.: GENERATED_SOURCE_FILES += $(GENDATA_DIR)\drv_par.c +GENERATED_SOURCE_FILES += $(GENDATA_DIR)\Csm_*Cfg.c + +#e.g.: COMMON_SOURCE_FILES += $(GENDATA_DIR)\v_par.c +COMMON_SOURCE_FILES += + +#------------------------------------------------------------------------------------------------- +# .dep & .lnk & .bin and..... +# all in err\ & obj\ & lst\ & lib\ & log\ will be deleted by clean-rule automaticly +# so in this clean-rule it is only necessary to define additional files which +# were not delete automaticly. +# e.g.: $()\can_test.c +#------------------------------------------------------------------------------------------------- +MAKE_CLEAN_RULES += +#MAKE_GENERATE_RULES += +#MAKE_COMPILER_RULES += +#MAKE_DEBUG_RULES += +#MAKE_CONFIG_RULES += +#MAKE_ADD_RULES += + + +############################################################### +# REQUIRED (defined in BaseMake (global.Makefile.target.make...)) +# +# SSC_ROOT (required) +# PROJECT_ROOT (required) +# +# LIB_OUTPUT_PATH (optional) +# OBJ_OUTPUT_PATH (optional) +# +# OBJ_FILE_SUFFIX +# LIB_FILE_SUFFIX +# +############################################################### + + +############################################################### +# PROVIDE this Section can be used to define own additional rules +# +# In vendorx_can_cfg.mak: +# Please configure the project file: +#CAN_CONFIG_FILE = $(PROJECT_ROOT)\source\network\can\my_can_config.cfg + +#In vendorx_can_config : +#generate_can_config: + #$(SSC_ROOT)\core\com\can\tools\canconfiggen.exe -o $(CAN_CONFIG_FILE) + + +############################################################### +# SPECIFIC +# +# There are no rules defined for the Specific part of the +# Rules-Makefile. Each author is free to create temporary +# variables or to use other resources of GNU-MAKE +# +############################################################### + + diff --git a/Source/bsw/Det/Det.c b/Source/bsw/Det/Det.c new file mode 100644 index 0000000..1c4b89e --- /dev/null +++ b/Source/bsw/Det/Det.c @@ -0,0 +1,1055 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file Det.c + * \brief Default Error Tracer source file + * + * \details Contains the implementation of static and API functions. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + * + * FILE VERSION + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the VERSION CHECK below. + *********************************************************************************************************************/ + +#define DET_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + + #include "Det.h" + #include "Det_Private_Cfg.h" + +/* use internal target define to handle DualTarget use case where the DET_PROCESSOR_ switch is generated for the real target */ +#if defined (DET_PROCESSOR_CANOEEMU) || defined (VVIRTUALTARGET) +# define DET_TARGET_CANOEEMU +#endif + +#if defined (DET_TARGET_CANOEEMU) +# include /* PRQA S 5124 */ /* MD_DET_5124 */ /* simulation environment, no production code */ +# include "CANoeApi.h" +# if (CANOEAPI_VERSION >= 239) /* COV_DET_CANOE_VTT */ +# include "CANoeEmuProcessor.h" +# endif +# if (_MSC_VER >= 1400) /* COV_DET_CANOE_VTT */ +# include +# include /* PRQA S 5127 */ /* MD_DET_5127 */ /* simulation environment, no production code */ +# endif + /* detect VTT use case */ +# if (CANOEAPI_VERSION >= 200) /* COV_DET_CANOE_VTT */ +# if defined (VVIRTUALTARGET) +# define DET_VTTUSECASE +# endif +# else +# if defined (_MICROSOFT_C_VTT_) /* COV_DET_CANOE_VTT */ +# define DET_VTTUSECASE +# endif +# endif +#endif /* (DET_TARGET_CANOEEMU) */ + +#if (DET_DEBUG_ENABLED == STD_ON) +# include "SchM_Det.h" +#endif + +#if (DET_FORWARD_TO_DEM == STD_ON) +# include "Dem.h" +#endif + +#if (DET_FORWARD_TO_DLT == STD_ON) +# include "Dlt.h" +#endif + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ + +/** + * Version check for source and header file consistency + */ +#if (DET_SW_MAJOR_VERSION != 25) +# error "Source and Header file are inconsistent!" +#endif + +#if (DET_SW_MINOR_VERSION != 0) +# error "Source and Header file are inconsistent!" +#endif + +#if (DET_SW_PATCH_VERSION != 0) +# error "Source and Header file are inconsistent!" +#endif + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + **********************************************************************************************************************/ + + +/********************** compiler abstraction *******************************/ +#if !defined (DET_LOCAL) /* COV_DET_COMPATIBILITY */ +# define DET_LOCAL static /* standard AutoSar 4.x define */ +#endif + +#if !defined (DET_LOCAL_INLINE) /* COV_DET_COMPATIBILITY */ +# if defined (LOCAL_INLINE) /* COV_DET_COMPATIBILITY */ +# define DET_LOCAL_INLINE LOCAL_INLINE +# else +# define DET_LOCAL_INLINE DET_LOCAL +# endif +#endif + +#if (DET_ENABLED == STD_ON) + +/********************************************************************************************************************** + * LOCAL FUNCTION MACROS + **********************************************************************************************************************/ + +/* critical section macros \trace DSGN-Det22791 */ +# define Det_EnterCritical() SchM_Enter_Det_DET_EXCLUSIVE_AREA_0() +# define Det_LeaveCritical() SchM_Exit_Det_DET_EXCLUSIVE_AREA_0() + +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + **********************************************************************************************************************/ + +# define DET_START_SEC_VAR_INIT_UNSPECIFIED +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +DET_LOCAL volatile VAR(boolean, DET_VAR) detModuleInit = FALSE; + +# define DET_STOP_SEC_VAR_INIT_UNSPECIFIED +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define DET_START_SEC_VAR_NOINIT_8BIT +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (DET_REPORT_ERROR_RECURSIONLIMIT > 0) +DET_LOCAL volatile VAR(uint8, DET_VAR) detRecursionCounterReportError; /* recursion limit counter \trace DSGN-Det22792 */ +# endif + +# if (DET_REPORT_RUNTIMEERROR_RECURSIONLIMIT > 0) +DET_LOCAL volatile VAR(uint8, DET_VAR) detRecursionCounterReportRuntimeError; /* recursion limit counter \trace DSGN-Det22792 */ +# endif + +# if (DET_REPORT_TRANSIENTFAULT_RECURSIONLIMIT > 0) +DET_LOCAL volatile VAR(uint8, DET_VAR) detRecursionCounterReportTransientFault; /* recursion limit counter \trace DSGN-Det22792 */ +# endif + +# define DET_STOP_SEC_VAR_NOINIT_8BIT +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +# define DET_START_SEC_VAR_NOINIT_UNSPECIFIED +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (DET_DEBUG_ENABLED == STD_ON) + +/* global variables, should be put in a watch window */ +# if (DET_GLOBALFILTERSIZE > 0) +volatile VAR(DetInfoType, DET_VAR) detGlobalFilter[DET_GLOBALFILTERSIZE]; /* ##### use this variable to configure global filters */ /* PRQA S 1504 */ /* MD_MSR_Rule8.7 */ +# endif +# if (DET_BREAKFILTERSIZE > 0) +volatile VAR(DetInfoType, DET_VAR) detBreakFilter[DET_BREAKFILTERSIZE]; /* ##### use this variable to configure break filters */ /* PRQA S 1504 */ /* MD_MSR_Rule8.7 */ +# endif +# if (DET_DLTFILTERSIZE > 0) +volatile VAR(DetInfoType, DET_VAR) detDltFilter[DET_DLTFILTERSIZE]; /* ##### use this variable to configure dlt filters */ /* PRQA S 1504 */ /* MD_MSR_Rule8.7 */ +# endif +# if (DET_LOGBUFFERSIZE > 0) +volatile VAR(DetInfoType, DET_VAR) detLogBuffer[DET_LOGBUFFERSIZE]; /* ##### use this variable to view log buffer */ /* PRQA S 1504 */ /* MD_MSR_Rule8.7 */ +# endif +volatile VAR(DetStatusType, DET_VAR) detStatus; /* ##### use this variable to configure DET debug operation */ /* PRQA S 1504 */ /* MD_MSR_Rule8.7 */ + +# endif /* DET_DEBUG_ENABLED */ + +# define DET_STOP_SEC_VAR_NOINIT_UNSPECIFIED +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +# define DET_START_SEC_CODE +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (DET_DEBUG_ENABLED == STD_ON) +/*********************************************************************************************************************** + * Det_CheckFilterMatch() + **********************************************************************************************************************/ +/*! \brief Check if a DET error matches filter conditions + * \details A filter match is detected if all structure members of at least one filter and detInfo are identical + * or the non-identical ones are don't care (0xFF). + * \param[in] filter pointer to an array of filters + * \param[in] size number of filters + * \param[in] active flag to indicate if filter is active + * \param[in] detInfo pointer to structure holding DET error for filtering + * \return FALSE: no filter match, TRUE: filter match + * \pre - + * \context TASK|ISR2 + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-Det22783, DSGN-Det22785 + **********************************************************************************************************************/ +# if (DET_GLOBALFILTERSIZE > 0) || (DET_BREAKFILTERSIZE > 0) +DET_LOCAL_INLINE FUNC(boolean, DET_CODE) Det_CheckFilterMatch( volatile P2CONST( DetInfoType, AUTOMATIC, DET_VAR ) filter, uint8 size, boolean active, P2CONST( DetInfoType, AUTOMATIC, DET_VAR ) detInfo ); +# endif + +/*********************************************************************************************************************** + * Det_LogError() + **********************************************************************************************************************/ +/*! \brief Store a DET error in the log buffer + * \details It is further detected if an overrun occurs and if a forced break handler call is required. + * \param[in] active flag to indicate if logging is active + * \param[in] detInfo pointer to structure holding DET error for filtering + * \return FALSE: do not force break handler call, TRUE: force break handler call + * \pre - + * \context TASK|ISR2 + * \reentrant TRUE + * \synchronous TRUE + * \trace DSGN-Det22792, DSGN-Det22784 + **********************************************************************************************************************/ +# if (DET_LOGBUFFERSIZE > 0) +DET_LOCAL_INLINE FUNC(boolean, DET_CODE) Det_LogError( boolean active, P2CONST( DetInfoType, AUTOMATIC, DET_VAR ) detInfo ); +# endif + +# endif /* DET_DEBUG_ENABLED */ + +/*********************************************************************************************************************** + * Det_CanoeOutput() + **********************************************************************************************************************/ +/*! \brief Output DET error information in CANoe + * \details Its behavior depends on the version of the simulation environment. + * \param[in] ModuleId Module ID of calling module + * \param[in] InstanceId The identifier of the index based instance of a module + * \param[in] ApiId ID of API service in which error is detected + * \param[in] ErrorId ID of detected development error + * \pre - + * \context TASK|ISR2 + * \reentrant TRUE + * \synchronous TRUE + **********************************************************************************************************************/ +# if defined (DET_TARGET_CANOEEMU) +DET_LOCAL_INLINE FUNC(void, DET_CODE) Det_CanoeOutput( uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId ); +# endif + +/*********************************************************************************************************************** + * Det_EndlessLoop() + **********************************************************************************************************************/ +/*! \brief Enter endless loop + * \details Used to stop further processing. + * \pre - + * \context TASK|ISR2 + * \reentrant TRUE + * \synchronous TRUE + **********************************************************************************************************************/ +DET_LOCAL FUNC(void, DET_CODE) Det_EndlessLoop( void ); + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +# if (DET_DEBUG_ENABLED == STD_ON) +/*********************************************************************************************************************** + * Det_CheckFilterMatch() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + **********************************************************************************************************************/ +# if (DET_GLOBALFILTERSIZE > 0) || (DET_BREAKFILTERSIZE > 0) +DET_LOCAL_INLINE FUNC(boolean, DET_CODE) Det_CheckFilterMatch( volatile P2CONST( DetInfoType, AUTOMATIC, DET_VAR ) filter, uint8 size, boolean active, P2CONST( DetInfoType, AUTOMATIC, DET_VAR ) detInfo ) +{ + VAR(uint8_least, AUTOMATIC) i; + VAR (boolean, AUTOMATIC) retval = FALSE; /* no filter match */ + /* #10 if filter is active */ + if(active == TRUE) + { + /* #20 linear search over all filters */ + for(i = 0; i < size; i++) + { + /* #30 compare each structure member if it is identical or if filter is set to don't care */ + if( + ((filter[i].mModuleId == detInfo->mModuleId) || (filter[i].mModuleId == DET_DONTCARE_16)) && + ((filter[i].mInstanceId == detInfo->mInstanceId) || (filter[i].mInstanceId == DET_DONTCARE_8)) && + ((filter[i].mApiId == detInfo->mApiId) || (filter[i].mApiId == DET_DONTCARE_8)) && + ((filter[i].mErrorId == detInfo->mErrorId) || (filter[i].mErrorId == DET_DONTCARE_8)) + ) + { + retval = TRUE; + break; + } + } + } + return retval; +} +# endif + +/*********************************************************************************************************************** + * Det_LogError() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + **********************************************************************************************************************/ +# if (DET_LOGBUFFERSIZE > 0) +DET_LOCAL_INLINE FUNC(boolean, DET_CODE) Det_LogError( boolean active, P2CONST( DetInfoType, AUTOMATIC, DET_VAR ) detInfo ) +{ + VAR (boolean, AUTOMATIC) forceBreakHandler = FALSE; /* do not force break handler call */ + + /* #10 if logging is active */ + if(active == TRUE) + { + Det_EnterCritical(); + detStatus.logIndex++; /* PRQA S 3387 */ /* MD_DET_3387 */ + /* #20 if overrun of circular buffer occurs */ + if(detStatus.logIndex >= DET_LOGBUFFERSIZE) + { + detStatus.logIndex = 0; + /* #30 if break on overrun is active set return value to force break handler call */ +# if (DET_BREAKFILTERSIZE > 0) + if(detStatus.breakOnLogOverrun == TRUE) + { + forceBreakHandler = TRUE; + } +# endif + } + /* #40 store DET error in log buffer */ + detLogBuffer[detStatus.logIndex].mModuleId = detInfo->mModuleId; /* SBSW_DET_1 */ + detLogBuffer[detStatus.logIndex].mInstanceId = detInfo->mInstanceId; /* SBSW_DET_1 */ + detLogBuffer[detStatus.logIndex].mApiId = detInfo->mApiId; /* SBSW_DET_1 */ + detLogBuffer[detStatus.logIndex].mErrorId = detInfo->mErrorId; /* SBSW_DET_1 */ + Det_LeaveCritical(); + } + return forceBreakHandler; +} +# endif + +# endif /* DET_DEBUG_ENABLED */ + +/*********************************************************************************************************************** + * Det_CanoeOutput() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + **********************************************************************************************************************/ +# if defined (DET_TARGET_CANOEEMU) +DET_LOCAL_INLINE FUNC(void, DET_CODE) Det_CanoeOutput( uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId ) +{ +# if defined (DET_VTTUSECASE) + /* #10 if VIP is configured forward error to CANoe API */ + (void) CANoeAPI_DetReportError(ModuleId, InstanceId, ApiId, ErrorId); +# else + /* #20 else format error string and output it in the CANoe write window */ + { + char str[255]; /* PRQA S 5013 */ /* MD_DET_5013 */ + +# if (_MSC_VER >= 1400) /* COV_DET_CANOE_VTT */ + time_t timeVal; + struct tm timeS; + + (void) time(&timeVal); /* PRQA S 5127,5139 */ /* MD_DET_5127 */ /* simulation environment, no production code */ /* SBSW_DET_3 */ + (void) localtime_s(&timeS, &timeVal); /* PRQA S 5127,5139 */ /* MD_DET_5127 */ /* simulation environment, no production code */ /* SBSW_DET_3 */ + + (void) strftime(str, sizeof(str), "%H:%M:%S", &timeS); /* PRQA S 5127,5139 */ /* MD_DET_5127 */ /* simulation environment, no production code */ /* SBSW_DET_3 */ + + (void) sprintf_s(str + strlen(str), sizeof(str) - strlen(str), /* PRQA S 0488 */ /* MD_DET_0488 */ /* simulation environment, no production code */ /* SBSW_DET_3 */ /* VCA_DET_1 */ + " DET Error: ModuleId 0x%x, InstanceId 0x%x, ApiId 0x%x, ErrorId 0x%x", ModuleId, InstanceId, ApiId, ErrorId); +# else + (void) sprintf(str, "DET Error: ModuleId 0x%x, InstanceId 0x%x, ApiId 0x%x, ErrorId 0x%x", /* SBSW_DET_3 */ /* VCA_DET_1 */ + ModuleId, InstanceId, ApiId, ErrorId); +# endif + CANoeAPI_WriteString((const char *)str); /* PRQA S 5013 */ /* MD_DET_5013 */ /* SBSW_DET_3 */ + } +# endif +} +# endif + +/*********************************************************************************************************************** + * Det_EndlessLoop() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + **********************************************************************************************************************/ +DET_LOCAL FUNC(void, DET_CODE) Det_EndlessLoop( void ) +{ +# if (DET_DEBUG_ENABLED == STD_ON) +# if ! defined (DET_REGRESSION_TEST) /* COV_DET_TEST_CODE */ + while(detStatus.unlockBreak == FALSE) /* set this variable to TRUE=1 to unlock breakpoint */ +# endif +# else +# if ! defined (DET_REGRESSION_TEST) /* COV_DET_TEST_CODE */ + while(1) +# endif +# endif + { + ; /* ##### typical place for a breakpoint if extended debugging support is enabled */ +# if defined (DET_TARGET_CANOEEMU) +# if (CANOEAPI_VERSION < 200) /* COV_DET_CANOE_VTT */ + break; +# elif (CANOEAPI_VERSION < 239) /* COV_DET_CANOE_VTT */ + CANoeAPI_ConsumeTicks(1000); +# else +# if (DET_DEBUG_ENABLED == STD_ON) + { + sint64 nanoseconds = 100000000LL; /* 100ms */ + CANoeAPI_ConsumeTime(nanoseconds); + } +# else + CANoeEmuProcessor_EndlessLoop(); +# endif +# endif +# endif + } +# if (DET_DEBUG_ENABLED == STD_ON) +# if ! defined (DET_REGRESSION_TEST) /* COV_DET_TEST_CODE */ + detStatus.unlockBreak = FALSE; /* PRQA S 2880 */ /* MD_MSR_Unreachable */ +# else + detStatus.unlockBreak = TRUE; /* PRQA S 2880 */ /* MD_MSR_Unreachable */ +# endif +# endif +} + + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +/********************************************************************************************************************** + * Det_Init() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + **********************************************************************************************************************/ +FUNC(void, DET_CODE) Det_Init( CONSTP2CONST(Det_ConfigPtrType, AUTOMATIC, DET_CONST ) ConfigPtr ) /* PRQA S 1505 */ /* MD_MSR_Rule8.7 */ +{ +# if (DET_DEBUG_ENABLED == STD_ON) +# if (DET_GLOBALFILTERSIZE > 0) || (DET_BREAKFILTERSIZE > 0) || (DET_LOGBUFFERSIZE > 0) + VAR(uint8_least, AUTOMATIC) i; +# endif + detStatus.globalFilterActive = FALSE; + detStatus.logActive = FALSE; + detStatus.logIndex = 0; + detStatus.breakOnLogOverrun = FALSE; + detStatus.breakFilterActive = FALSE; + detStatus.unlockBreak = FALSE; +# if (DET_GLOBALFILTERSIZE > 0) + for(i = 0; i < DET_GLOBALFILTERSIZE; i++) + { + detGlobalFilter[i].mModuleId = 0; /* SBSW_DET_2 */ + detGlobalFilter[i].mInstanceId = 0; /* SBSW_DET_2 */ + detGlobalFilter[i].mApiId = 0; /* SBSW_DET_2 */ + detGlobalFilter[i].mErrorId = 0; /* SBSW_DET_2 */ + } +# endif +# if (DET_BREAKFILTERSIZE > 0) + for(i = 0; i < DET_BREAKFILTERSIZE; i++) + { + detBreakFilter[i].mModuleId = 0; /* SBSW_DET_2 */ + detBreakFilter[i].mInstanceId = 0; /* SBSW_DET_2 */ + detBreakFilter[i].mApiId = 0; /* SBSW_DET_2 */ + detBreakFilter[i].mErrorId = 0; /* SBSW_DET_2 */ + } +# endif +# if (DET_DLTFILTERSIZE > 0) + for(i = 0; i < DET_DLTFILTERSIZE; i++) + { + detDltFilter[i].mModuleId = 0; /* SBSW_DET_2 */ + detDltFilter[i].mInstanceId = 0; /* SBSW_DET_2 */ + detDltFilter[i].mApiId = 0; /* SBSW_DET_2 */ + detDltFilter[i].mErrorId = 0; /* SBSW_DET_2 */ + } +# endif +# if (DET_LOGBUFFERSIZE > 0) + for(i = 0; i < DET_LOGBUFFERSIZE; i++) + { + detLogBuffer[i].mModuleId = 0; /* SBSW_DET_2 */ + detLogBuffer[i].mInstanceId = 0; /* SBSW_DET_2 */ + detLogBuffer[i].mApiId = 0; /* SBSW_DET_2 */ + detLogBuffer[i].mErrorId = 0; /* SBSW_DET_2 */ + } +# endif +# endif + +# if (DET_REPORT_ERROR_RECURSIONLIMIT > 0) + detRecursionCounterReportError = 0; /* reset recursion limit counter */ +# endif + +# if (DET_REPORT_RUNTIMEERROR_RECURSIONLIMIT > 0) + detRecursionCounterReportRuntimeError = 0; /* reset recursion limit counter */ +# endif + +# if (DET_REPORT_TRANSIENTFAULT_RECURSIONLIMIT > 0) + detRecursionCounterReportTransientFault = 0; /* reset recursion limit counter */ +# endif + + DET_DUMMY_STATEMENT_CONST(ConfigPtr); /* is never used */ /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ + + detModuleInit = TRUE; +} + +/*********************************************************************************************************************** + * Det_Start() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + **********************************************************************************************************************/ +FUNC(void, DET_CODE) Det_Start( void ) /* PRQA S 1505 */ /* MD_MSR_Rule8.7 */ +{ +# if (DET_FORWARD_TO_DEM == STD_ON) + VAR(Det_DemForwardingTableIterType, AUTOMATIC) indexDemForward; + /* #10 initialize Dem Event status (if configured) */ + for(indexDemForward=0; indexDemForward 0) && (DET_BREAKFILTERSIZE > 0) + VAR(boolean, AUTOMATIC) forceBreakHandler; +# endif +# if (DET_GLOBALFILTERSIZE > 0) || (DET_BREAKFILTERSIZE > 0) || (DET_LOGBUFFERSIZE > 0) || ((DET_FORWARD_TO_DLT == STD_ON) && (DET_DLTFILTERSIZE > 0)) + VAR(DetInfoType, AUTOMATIC) detInfo; + detInfo.mModuleId = ModuleId; + detInfo.mInstanceId = InstanceId; + detInfo.mApiId = ApiId; + detInfo.mErrorId = ErrorId; +# endif +# endif + +# if defined (DET_TARGET_CANOEEMU) + /* #10 forward DET error to CANoe if configured */ + Det_CanoeOutput(ModuleId, InstanceId, ApiId, ErrorId); +# else +# if (DET_FORWARD_TO_DLT == STD_OFF) && (DET_ERROR_HOOK_ENABLED == STD_OFF ) && ((DET_DEBUG_ENABLED == STD_OFF) || \ + ((DET_DEBUG_ENABLED == STD_ON) && (DET_GLOBALFILTERSIZE==0) && (DET_LOGBUFFERSIZE==0) && (DET_BREAKFILTERSIZE==0))) /* COV_DET_DUMMY_STMT */ + DET_DUMMY_STATEMENT(ModuleId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ + DET_DUMMY_STATEMENT(InstanceId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ + DET_DUMMY_STATEMENT(ApiId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ + DET_DUMMY_STATEMENT(ErrorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ +# endif +# endif + + /* #40 if DET is initialized: */ + if(detModuleInit == TRUE) /* in case of call to uninitialized DET return */ + { + /* #45 increment nesting counter for recursion detection */ +# if (DET_REPORT_ERROR_RECURSIONLIMIT > 0) + Det_EnterCritical(); + detRecursionCounterReportError++; /* PRQA S 3387 */ /* MD_DET_3387 */ + Det_LeaveCritical(); + if(detRecursionCounterReportError > DET_REPORT_ERROR_RECURSIONLIMIT) + { + Det_EndlessLoop(); + } + else +#endif + { + /* #50 call error hooks (if configured) */ +# if (DET_ERROR_HOOK_ENABLED == STD_ON ) + for(index = 0; index < Det_GetSizeOfErrorHookTable(); index++) + { + calloutReturn = Det_GetErrorHookTable(index)(ModuleId, InstanceId, ApiId, ErrorId); /* SBSW_DET_4 */ + } +# endif + +# if (DET_FORWARD_TO_DLT == STD_ON) + /* #60 forward DET error to DLT module (if configured) unless filtered out by a DLT filter */ +# if (DET_DEBUG_ENABLED == STD_ON) && (DET_DLTFILTERSIZE > 0) + if(Det_CheckFilterMatch(detDltFilter, DET_DLTFILTERSIZE, detStatus.dltFilterActive, &detInfo) == FALSE) /* SBSW_DET_6 */ +# endif + { + Dlt_DetForwardErrorTrace(ModuleId, InstanceId, ApiId, ErrorId); + } +# endif + + +# if (DET_ERROR_HOOK_ENABLED == STD_ON ) + /* if last error hook (if configured) returned E_OK: */ + if(calloutReturn == E_OK) +# endif + { + +# if (DET_DEBUG_ENABLED == STD_ON) + /* #70 check for global filter match (if configured), in case of no match continue */ +# if (DET_GLOBALFILTERSIZE > 0) + if(Det_CheckFilterMatch(detGlobalFilter, DET_GLOBALFILTERSIZE, detStatus.globalFilterActive, &detInfo) == FALSE) /* SBSW_DET_6 */ +# endif + { +# if (DET_LOGBUFFERSIZE > 0) +# if (DET_BREAKFILTERSIZE > 0) + /* #80 store DET error in log buffer (if configured) */ + forceBreakHandler = Det_LogError(detStatus.logActive, &detInfo); /* SBSW_DET_6 */ +# else + (void) Det_LogError(detStatus.logActive, &detInfo); /* SBSW_DET_6 */ +# endif +# endif + /* #90 check for break filter match or forced break handler call (if configured), in case of no match continue */ +# if (DET_BREAKFILTERSIZE > 0) + if((Det_CheckFilterMatch(detBreakFilter, DET_BREAKFILTERSIZE, detStatus.breakFilterActive, &detInfo) == FALSE) /* SBSW_DET_6 */ +# if (DET_LOGBUFFERSIZE > 0) + || (forceBreakHandler == TRUE) +# endif + ) +# endif + { + /* #100 enter endless loop - in variant with debug support loop can be left by setting a flag */ + Det_EndlessLoop(); + } + } +# else /* DET_DEBUG_ENABLED */ + /* in variant without debug support it is not possible to leave the endless loop on a real target */ + Det_EndlessLoop(); /*lint !e522 */ +# endif /* DET_DEBUG_ENABLED */ + + } + } + /* #110 decrement nesting counter for recursion detection */ +# if (DET_REPORT_ERROR_RECURSIONLIMIT > 0) + Det_EnterCritical(); + detRecursionCounterReportError--; /* PRQA S 3387 */ /* MD_DET_3387 */ + Det_LeaveCritical(); +#endif + } + + return E_OK; +} /* Det_ReportError */ + + +/*********************************************************************************************************************** + * Det_ReportRuntimeError() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + **********************************************************************************************************************/ +/* PRQA S 6050, 6080 1 */ /* MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, DET_CODE) Det_ReportRuntimeError( uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId ) /* PRQA S 1505 */ /* MD_MSR_Rule8.7 */ /*lint -e{438} */ +{ +# if (DET_RUNTIME_ERROR_CALLOUT_ENABLED == STD_ON) + VAR(Std_ReturnType, AUTOMATIC) calloutReturn = E_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + VAR(uint8_least, AUTOMATIC) index; +# endif +# if (DET_FORWARD_TO_DEM == STD_ON) + VAR(Det_DemForwardingTableIterType, AUTOMATIC) indexDemForward; +# endif +# if (DET_DEBUG_ENABLED == STD_ON) +# if (DET_LOGBUFFERSIZE > 0) || ((DET_FORWARD_TO_DLT == STD_ON) && (DET_DLTFILTERSIZE > 0)) + VAR(DetInfoType, AUTOMATIC) detInfo; + detInfo.mModuleId = ModuleId; + detInfo.mInstanceId = InstanceId; + detInfo.mApiId = ApiId; + detInfo.mErrorId = ErrorId; +# endif +# endif + +# if defined (DET_TARGET_CANOEEMU) + /* #10 forward DET error to CANoe if configured */ + Det_CanoeOutput(ModuleId, InstanceId, ApiId, ErrorId); +# else +# if (DET_FORWARD_TO_DLT == STD_OFF) && (DET_RUNTIME_ERROR_CALLOUT_ENABLED == STD_OFF ) && ((DET_DEBUG_ENABLED == STD_OFF) || \ + ((DET_DEBUG_ENABLED == STD_ON) && (DET_LOGBUFFERSIZE==0) )) /* COV_DET_DUMMY_STMT */ + DET_DUMMY_STATEMENT(ModuleId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ + DET_DUMMY_STATEMENT(InstanceId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ + DET_DUMMY_STATEMENT(ApiId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ + DET_DUMMY_STATEMENT(ErrorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ +# endif +# endif + + /* #40 if DET is initialized: */ + if(detModuleInit == TRUE) /* in case of call to uninitialized DET return */ + { + /* #45 increment nesting counter for recursion detection */ +# if (DET_REPORT_RUNTIMEERROR_RECURSIONLIMIT > 0) + Det_EnterCritical(); + detRecursionCounterReportRuntimeError++; /* PRQA S 3387 */ /* MD_DET_3387 */ + Det_LeaveCritical(); + if(detRecursionCounterReportRuntimeError > DET_REPORT_RUNTIMEERROR_RECURSIONLIMIT) + { + Det_EndlessLoop(); + } + else +# endif + { + /* #50 call runtime error callouts (if configured) */ +# if (DET_RUNTIME_ERROR_CALLOUT_ENABLED == STD_ON) + for(index = 0; index < Det_GetSizeOfRuntimeErrorCalloutTable(); index++) + { + calloutReturn = Det_GetRuntimeErrorCalloutTable(index)(ModuleId, InstanceId, ApiId, ErrorId); /* SBSW_DET_4 */ + } +# endif + +# if (DET_FORWARD_TO_DLT == STD_ON) + /* #60 forward DET error to DLT module (if configured) unless filtered out by a DLT filter */ +# if (DET_DEBUG_ENABLED == STD_ON) && (DET_DLTFILTERSIZE > 0) + if(Det_CheckFilterMatch(detDltFilter, DET_DLTFILTERSIZE, detStatus.dltFilterActive, &detInfo) == FALSE) /* SBSW_DET_6 */ +# endif + { + Dlt_DetForwardErrorTrace(ModuleId, InstanceId, ApiId, ErrorId); + } +# endif + +# if (DET_FORWARD_TO_DEM == STD_ON) + { +# if (DET_OSAPPLICATIONIDOFDEMFORWARDINGTABLE == STD_ON) + VAR(ApplicationType, AUTOMATIC) applicationId = GetApplicationID(); +# endif + /* #62 forward DET error to DEM module (if configured) */ + for(indexDemForward=0; indexDemForward 0) + /* #80 store DET error in log buffer (if configured) */ + (void) Det_LogError(detStatus.logActive, &detInfo); /* SBSW_DET_6 */ +# endif +# endif + } + } + /* #110 decrement nesting counter for recursion detection */ +# if (DET_REPORT_RUNTIMEERROR_RECURSIONLIMIT > 0) + Det_EnterCritical(); + detRecursionCounterReportRuntimeError--; /* PRQA S 3387 */ /* MD_DET_3387 */ + Det_LeaveCritical(); +#endif + } + + return E_OK; +} /* Det_ReportRuntimeError */ + + +/*********************************************************************************************************************** + * Det_ReportTransientFault() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + **********************************************************************************************************************/ +/* PRQA S 6050, 6080 1 */ /* MD_MSR_STCAL, MD_MSR_STMIF */ +FUNC(Std_ReturnType, DET_CODE) Det_ReportTransientFault( uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId ) /* PRQA S 1505 */ /* MD_MSR_Rule8.7 */ /*lint -e{438} */ +{ +# if (DET_TRANSIENT_FAULT_CALLOUT_ENABLED == STD_ON) + VAR(Std_ReturnType, AUTOMATIC) calloutReturn = E_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */ + VAR(uint8_least, AUTOMATIC) index; +# endif +# if (DET_DEBUG_ENABLED == STD_ON) +# if (DET_LOGBUFFERSIZE > 0) || ((DET_FORWARD_TO_DLT == STD_ON) && (DET_DLTFILTERSIZE > 0)) + VAR(DetInfoType, AUTOMATIC) detInfo; + detInfo.mModuleId = ModuleId; + detInfo.mInstanceId = InstanceId; + detInfo.mApiId = ApiId; + detInfo.mErrorId = ErrorId; +# endif +# endif + +# if defined (DET_TARGET_CANOEEMU) + /* #10 forward DET error to CANoe if configured */ + Det_CanoeOutput(ModuleId, InstanceId, ApiId, ErrorId); +# else +# if (DET_FORWARD_TO_DLT == STD_OFF) && (DET_TRANSIENT_FAULT_CALLOUT_ENABLED == STD_OFF ) && ((DET_DEBUG_ENABLED == STD_OFF) || \ + ((DET_DEBUG_ENABLED == STD_ON) && (DET_LOGBUFFERSIZE==0) )) /* COV_DET_DUMMY_STMT */ + DET_DUMMY_STATEMENT(ModuleId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ + DET_DUMMY_STATEMENT(InstanceId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ + DET_DUMMY_STATEMENT(ApiId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ + DET_DUMMY_STATEMENT(ErrorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */ /*lint -e{438} */ +# endif +# endif + + /* #40 if DET is initialized: */ + if(detModuleInit == TRUE) /* in case of call to uninitialized DET return */ + { + /* #45 increment nesting counter for recursion detection */ +# if (DET_REPORT_TRANSIENTFAULT_RECURSIONLIMIT > 0) + Det_EnterCritical(); + detRecursionCounterReportTransientFault++; /* PRQA S 3387 */ /* MD_DET_3387 */ + Det_LeaveCritical(); + if(detRecursionCounterReportTransientFault > DET_REPORT_TRANSIENTFAULT_RECURSIONLIMIT) + { + Det_EndlessLoop(); + } + else +# endif + { + /* call transient fault callouts (if configured) */ +# if (DET_TRANSIENT_FAULT_CALLOUT_ENABLED == STD_ON) + for(index = 0; index < Det_GetSizeOfTransientFaultCalloutTable(); index++) + { + calloutReturn |= Det_GetTransientFaultCalloutTable(index)(ModuleId, InstanceId, ApiId, ErrorId); /* SBSW_DET_4 */ + } +# endif + +# if (DET_FORWARD_TO_DLT == STD_ON) + /* #60 forward DET error to DLT module (if configured) unless filtered out by a DLT filter */ +# if (DET_DEBUG_ENABLED == STD_ON) && (DET_DLTFILTERSIZE > 0) + if(Det_CheckFilterMatch(detDltFilter, DET_DLTFILTERSIZE, detStatus.dltFilterActive, &detInfo) == FALSE) /* SBSW_DET_6 */ +# endif + { + Dlt_DetForwardErrorTrace(ModuleId, InstanceId, ApiId, ErrorId); + } +# endif + +# if (DET_DEBUG_ENABLED == STD_ON) +# if (DET_LOGBUFFERSIZE > 0) + /* #80 store DET error in log buffer (if configured) */ + (void) Det_LogError(detStatus.logActive, &detInfo); /* SBSW_DET_6 */ +# endif +# endif + } + /* #110 decrement nesting counter for recursion detection */ +# if (DET_REPORT_TRANSIENTFAULT_RECURSIONLIMIT > 0) + Det_EnterCritical(); + detRecursionCounterReportTransientFault--; /* PRQA S 3387 */ /* MD_DET_3387 */ + Det_LeaveCritical(); +#endif + } + +# if (DET_TRANSIENT_FAULT_CALLOUT_ENABLED == STD_ON) + /* #120 use return value of last transient fault callout (if configured) */ + return calloutReturn; +# else + return E_OK; +# endif +} /* Det_ReportTransientFault */ + + +# if (DET_VERSION_INFO_API == STD_ON) +/*********************************************************************************************************************** + * Det_GetVersionInfo() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + **********************************************************************************************************************/ +FUNC(void, DET_CODE) Det_GetVersionInfo( P2VAR( Std_VersionInfoType, AUTOMATIC, DET_APPL_DATA ) versioninfo ) /* PRQA S 1505 */ /* MD_MSR_Rule8.7 */ +{ + /* #10 if versioninfo is no NULL pointer */ + if(versioninfo != NULL_PTR) + { + /* #20 fill versions from defines into versioninfo structure */ + versioninfo->vendorID = DET_VENDOR_ID; /* SBSW_DET_7 */ + versioninfo->moduleID = DET_MODULE_ID; /* SBSW_DET_7 */ + versioninfo->sw_major_version = DET_SW_MAJOR_VERSION; /* SBSW_DET_7 */ + versioninfo->sw_minor_version = DET_SW_MINOR_VERSION; /* SBSW_DET_7 */ + versioninfo->sw_patch_version = DET_SW_PATCH_VERSION; /* SBSW_DET_7 */ + } + else + { + (void) Det_ReportError(DET_MODULE_ID, DET_INSTANCE_ID, DET_SID_GETVERSIONINFO, DET_E_PARAM_POINTER); + } +} +# endif + +# define DET_STOP_SEC_CODE +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* DET_ENABLED */ + +/* module specific MISRA deviations: + MD_DET_5013: MISRA2012 rule 4.6 + Reason: Usage of "char" data type is necessary if error messages are output in the CANoe write window because the CANoe API requires this. + Risk: Potentially unknown size and signedness of data type. + Prevention: The affected code part is only active in a PC simulation environment and does not run on an embedded target. Therefore this deviation is not critical. No change planned. + MD_DET_0488: MISRA2012 rule 18.4 + Reason: Pointer arithmetic is only used in the CANoe simulation environment for debug purposes, not included in production code. + Risk: None. + Prevention: No change planned. + MD_DET_5124: MISRA2012 rule 21.6 + Reason: Standard library functionality is only used in the CANoe simulation environment for debug purposes, not included in production code. + Risk: None. + Prevention: No change planned. + MD_DET_5127: MISRA2012 rule 21.10 + Reason: Standard library functionality is only used in the CANoe simulation environment for debug purposes, not included in production code. + Risk: None. + Prevention: No change planned. + MD_DET_3387: MISRA2012 rule 13.3 + Reason: The ++ of -- operator is used on a volatile variable. + Risk: None because the volatile variable access is protected by a critical section. + Prevention: No change planned. +*/ + +/* SBSW_JUSTIFICATION_BEGIN + \ID SBSW_DET_1 + \DESCRIPTION Array Write Access (P6 - Wrong Initialization and Usage of a Pointer due to Wrong Index) + Update of log buffer in Det_LogError. Due to the code structure the calculated array index cannot exceed the array size. + Therefore this is not critical and no out of bounds array access can occur. The index is unconditionally reset to zero if is equal or greater than DET_LOGBUFFERSIZE. + \COUNTERMEASURE \N The code structure already ensures that the index cannot exceed the size of the array. + \ID SBSW_DET_2 + \DESCRIPTION Array Write Access (P6 - Wrong Initialization and Usage of a Pointer due to Wrong Index) + Initialization of global array in Det_Init. Both the array size and the loop is is controlled by generated #defines DET_*SIZE. + Therefore this is not critical and no out of bounds array access can occur. + \COUNTERMEASURE \N The code structure already ensures that the index cannot exceed the size of the array. + \ID SBSW_DET_3 + \DESCRIPTION Function Call + Calls to CANoe API or C stdlib with pointer parameters. + This code is only active in case of the CANoe emulation or vtt environment which is not used production code. + \COUNTERMEASURE \N This code part is not active for embedded production targets. + \ID SBSW_DET_4 + \DESCRIPTION Function Pointer Call + Iteration over generated function pointer tables using identifiers generated by the ComStackLib. + \COUNTERMEASURE \N Qualified use-case CSL01 of ComStackLib assures correct dimension of arrays and consistency of corresponding size definitions. + The validity of the callout function names is covered by SMI-5. + \ID SBSW_DET_6 + \DESCRIPTION Function Call + call of internal functions Det_CheckFilterMatch and Det_LogError (both functions cannot be called by the application or other modules) + There could be a Null pointer dereferencing if these functions are called with invalid pointer parameters. + However, at the three places in Det_ReportError where these functions are called the calls always uses valid pointers. + So there is no need for an additional Null pointer check in these functions. + \COUNTERMEASURE \N The code structure already ensures that the functions are always called with valid pointers. + \ID SBSW_DET_7 + \DESCRIPTION Pointer Write Access (P1 - Wrong Pointer Parameter) + The function Det_GetVersionInfo writes to the object referenced by parameter versioninfo. The structure is provided by application code and passed to the DET. + The fault pattern P9 is already prevented by a NULL pointer check. + \COUNTERMEASURE \N The caller ensures that the pointers passed to the parameter versioninfo is valid. + \ID SBSW_DET_8 + \DESCRIPTION Usage of debug features (generic aspect, not traceable to a specific ReviewHelper finding) + \COUNTERMEASURE \S The DET should not be in production code. + If it is used the extended debug features should be switched off because they are only relevant if a debugger is attached. + All of the above listed array write accesses occur only if extended debug features are enabled. SMI-Det-ExtendedDebugFeatures + \ID SBSW_DET_9 + \DESCRIPTION Argument for completeness of analyzed code (generic aspect, not traceable to a specific ReviewHelper finding) + \COUNTERMEASURE \N If all features of the DET are activated the whole code of the DET is active, there are no mutual exclusive code parts except for the AUTOSAR version which is fixed to 4. + The additional debug code in case of C_COMP_ANSI_CANOE has not been considered because it is a simulation environment only and therefore this code will never run on an ECU. +SBSW_JUSTIFICATION_END */ + +/* VCA_JUSTIFICATION_BEGIN + \ID VCA_DET_1 + \DESCRIPTION Function Call + Calls to CANoe API or C stdlib with pointer parameters. + This code is only active in case of the CANoe emulation or vtt environment which is not used production code. + \COUNTERMEASURE \N This code part is not active for embedded production targets. +VCA_JUSTIFICATION_END */ + +/* START_COVERAGE_JUSTIFICATION +\ID COV_DET_COMPATIBILITY + \ACCEPT TX + \ACCEPT XF + \REASON [COV_MSR_COMPATIBILITY] +\ID COV_DET_CANOE_VTT + \ACCEPT TF xf tf + \ACCEPT TX + \ACCEPT XF + \ACCEPT XX + \REASON Code which is only relevant for the CANoeEmu and VTT simulation environments which are not used by the test suite. +\ID COV_DET_TEST_CODE + \ACCEPT TX + \REASON Code is only deactivated during regression test to prevent endless loop. +\ID COV_DET_DUMMY_STMT + \ACCEPT XF xf xf xf tx xf xf xf + \ACCEPT XF xf xf xf tx xf + \REASON Insert dummy statement only if necessary to avoid compiler warnings. There is no functional impact. +END_COVERAGE_JUSTIFICATION */ diff --git a/Source/bsw/Det/Det.h b/Source/bsw/Det/Det.h new file mode 100644 index 0000000..9eb2e81 --- /dev/null +++ b/Source/bsw/Det/Det.h @@ -0,0 +1,386 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file Det.h + * \brief Header of Default Error Tracer + * + * \details Contains definitions, types, externals and prototype declarations. + * \trace SPEC-2880976, SPEC-2880977 + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 0.01.00 2005-08-18 Om Creation + * 2.00.00 2006-05-18 Om Update for AUTOSAR Release 2.0 + * 3.00.00 2007-08-08 Jk Update for AUTOSAR Release 2.1 + * 3.01.00 2007-09-17 Jk GetVersionInfo API added + * 3.02.00 2007-11-28 HH Extended debug features added + * 4.00.00 2008-01-02 HH Update for AUTOSAR Release 3.0 + * compiler abstraction and memmap added + * 4.01.00 2008-09-12 HH ESCAN00023736: DET entry callout + * ESCAN00029923: DET could be called recursively + * 4.02.00 2008-12-09 HH ESCAN00030591: compile error if extended version check is disabled + * ESCAN00031617: Compiler warning about sprintf on CANoe emulation platform + * 4.03.00 2008-12-09 HH ESCAN00033897: case-sensitive issue: #include "VStdLib.h" instead of "#include "vstdlib.h" in Det.c + * 4.03.01 2009-05-20 HH ESCAN00034249: DET entry callout Appl_DetEntryCallout is only called once + * ESCAN00034566: Compiler warnings because of unused parameters in Det_ReportError + * 4.03.02 2010-07-27 HH ESCAN00039898: Endless loop on CANoe platform + * ESCAN00042300: support time-stamp for write window messages on CANoe platform + * 5.00.00 2011-01-13 HH ESCAN00048023: Update for AUTOSAR Release 4.0 + * 5.01.00 2011-10-27 HH ESCAN00054556: AR3-1698 support CDK MISRA report + * 5.02.00 2012-06-25 HH ESCAN00060956: do not use v_cfg.h for Cfg5 + * 5.03.00 2013-01-18 HH ESCAN00064266: AR4-220: Compiler error: Different errors due to unknown STATIC + * 6.00.00 2013-08-22 HH ESCAN00068394: AR4-292: Reporting of DET and DEM errors via DLT + * 6.00.01 2013-12-17 HH ESCAN00072683: version consistency checking is too strict + * 6.01.00 2014-03-20 HH ESCAN00074316: AR4-647: Adapt DET for VIP + * 7.00.00 2014-12-11 HH ESCAN00080181: FEAT-427: SafeBSW Step I [AR4-728] + * ESCAN00077908: MISRA deviation: MISRA-C:2004 Rule 4060 metric deviation + * ESCAN00079312: change return value from Appl_DetEntryCallout from uint8 to boolean + * ESCAN00077108: ESCAN00077108: Add "consume ticks" for a more realistic behaviour in VTT + * ESCAN00081763: FEAT-1275: SafeBSW Step 2 + * ESCAN00082803: [VTT] Det uses wrong Macro to detect VTT Usecase + * 7.00.01 2015-11-24 HH ESCAN00086457: Compiler warning: file does not end in newline + * 7.01.00 2016-02-22 HH ESCAN00087792: FEAT-1688: SafeBSW Step 4 + * 10.00.00 2016-12-24 HH FEAT-1939: Support AUTOSAR 4.3 + * 11.00.00 2018-08-20 HH STORYC-4674: MISRA-C:2012 Compliance + * 12.00.00 2020-07-16 HH SWAT-37: DET: Improvements + * ESCAN00105736: Compiler error: header file "os.h" not found by case sensitive compiler + * SWAT-1049: Det: AUTOSAR 19-11 Analysis (update to 4.5.0) + * SWAT-1028: Update endless loop handling to new CANoe API + * 13.00.00 2021-04-30 HH SWAT-1098: Usage of _MemMap.h in Det + * 14.00.00 2021-12-07 HH SWAT-1652: DET: use VVIRTUALTARGET instead of _MICROSOFT_C_VTT_ + * 14.00.01 2022-10-13 HH ESCAN00112589: Compiler warning: variable "forceBreakHandler" in function Det_ReportError set but not used + * ESCAN00113283: DualTarget: In case of VTT target no CANoe output is generated and the endless loop may be entered + * main-1 2024-07-22 vishh SWAT-3509 Det Migration to GitLab + * Change history is maintained in the global ChangeHistory.txt file starting with this release. +*********************************************************************************************************************/ + +#ifndef DET_H +# define DET_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +# include "Std_Types.h" +# include "Compiler.h" +# include "Det_Cfg.h" + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/** + * Define vendor and module ID + */ +# define DET_VENDOR_ID (30u) /* HIS Vendor ID for Vector */ +# define DET_MODULE_ID (15u) /* Det Module ID according to BSW Modules */ + +/** + * Define AUTOSAR specification version if not already externally specified (ESCAN00072683) + */ +# if !defined (DET_AR_MAJOR_VERSION) /* COV_DET_COMPATIBILITY */ +# define DET_AR_MAJOR_VERSION (4u) +# define DET_AR_MINOR_VERSION (5u) +# define DET_AR_PATCH_VERSION (0u) +# endif + +/** + * Define AUTOSAR release version if not already externally specified (ESCAN00072683) + */ +# if !defined (DET_AR_RELEASE_MAJOR_VERSION) /* COV_DET_COMPATIBILITY */ +# define DET_AR_RELEASE_MAJOR_VERSION (4u) +# define DET_AR_RELEASE_MINOR_VERSION (5u) +# define DET_AR_RELEASE_PATCH_VERSION (0u) +# define DET_AR_RELEASE_REVISION_VERSION DET_AR_RELEASE_PATCH_VERSION +# endif + +/** + * Define version for header and source file consistency (decimal version of ALM implementation package) + */ +# define DET_SW_MAJOR_VERSION (25u) +# define DET_SW_MINOR_VERSION (0u) +# define DET_SW_PATCH_VERSION (0u) + +/** + * Define error types + */ + +/* Development Errors */ +# define DET_E_PARAM_POINTER (1u) + +/* Runtime Errors - currently not used by the DET */ +# define DET_E_CANNOT_REPORT (1u) +# define DET_E_WRONG_MODULE (2u) +# define DET_E_WRONG_INSTANCE (3u) +# define DET_E_WRONG_API (4u) +# define DET_E_WRONG_ERROR (5u) + +/* Transient Faults - currently not used by the DET */ +# define DET_E_UNAVAILABLE (1u) + +/** + * Define API service IDs + */ +#define DET_SID_INIT (0x00u) +#define DET_SID_START (0x02u) +#define DET_SID_REPORTERROR (0x01u) +#define DET_SID_REPORTRUNTIMEERROR (0x04u) +#define DET_SID_REPORTTRANSIENTFAULT (0x05u) +#define DET_SID_GETVERSIONINFO (0x03u) + +#define DET_INSTANCE_ID (0x00u) + +# if (DET_ENABLED == STD_ON) + +/* don't care patterns for filters */ +#define DET_DONTCARE_8 (0xFFu) +#define DET_DONTCARE_16 (0xFFFFu) + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/*! structure used to configure filters and store log data, using 0xFF for a filter item means don't care */ + +typedef uint8 Det_ConfigPtrType; + +typedef struct +{ + uint16 mModuleId; + uint8 mInstanceId; + uint8 mApiId; + uint8 mErrorId; +} DetInfoType; + +# if (DET_DEBUG_ENABLED == STD_ON) +/*! structure to control the operation of DET debug extension */ +typedef struct +{ + boolean globalFilterActive; /* FALSE: global filters disabled, TRUE: global filters enabled */ + boolean logActive; /* FALSE: logging disabled, TRUE: logging enabled */ + boolean breakOnLogOverrun; /* FALSE: break on log buffer overrun disabled, TRUE: break on log buffer overrun enabled */ + boolean breakFilterActive; /* FALSE: break filters disabled, TRUE: break filters enabled */ + boolean unlockBreak; /* FALSE: break, TRUE: unlock break, can be used to unlock endless loop */ + boolean dltFilterActive; /* FALSE: dlt filters disabled, TRUE: dlt filters enabled */ + uint8 logIndex; /* do not modify: last index in array where data was logged, range: 0..DET_LOGBUFFERSIZE-1 */ +} DetStatusType; +# endif + +/********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + *********************************************************************************************************************/ + +# if (DET_DEBUG_ENABLED == STD_ON) + +# define DET_START_SEC_VAR_NOINIT_UNSPECIFIED +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*! global variables, should be put in a watch window */ +# if (DET_GLOBALFILTERSIZE > 0) +/*! ##### use this variable to configure global filters */ +extern volatile VAR(DetInfoType, DET_VAR) detGlobalFilter[DET_GLOBALFILTERSIZE]; +# endif +# if (DET_BREAKFILTERSIZE > 0) +/*! ##### use this variable to configure break filters */ +extern volatile VAR(DetInfoType, DET_VAR) detBreakFilter[DET_BREAKFILTERSIZE]; +# endif +# if (DET_DLTFILTERSIZE > 0) +/*! ##### use this variable to configure dlt filters */ +extern volatile VAR(DetInfoType, DET_VAR) detDltFilter[DET_DLTFILTERSIZE]; +# endif +# if (DET_LOGBUFFERSIZE > 0) +/*! ##### use this variable to view log buffer (circular buffer) */ +extern volatile VAR(DetInfoType, DET_VAR) detLogBuffer[DET_LOGBUFFERSIZE]; +# endif +/*! ##### use this variable to configure DET debug operation */ +extern volatile VAR(DetStatusType, DET_VAR) detStatus; +# define DET_STOP_SEC_VAR_NOINIT_UNSPECIFIED +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# endif /* DET_DEBUG_ENABLED */ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +# define DET_START_SEC_CODE +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * Det_Init() + **********************************************************************************************************************/ +/*! \brief Initializes the DET + * \details Global function as an interface from EcuM to DET for initialization + * \param[in] ConfigPtr Pointer to configuration (not used) + * \pre - + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + * \note Shall be called during startup by EcuM in a safe context, e.g. before the OS is started. + * \trace SPEC-2880978, SPEC-2880979, SPEC-2880995, SPEC-2880996 + * \trace CREQ-1 + **********************************************************************************************************************/ +FUNC(void, DET_CODE) Det_Init( CONSTP2CONST( Det_ConfigPtrType, AUTOMATIC, DET_CONST ) ConfigPtr ); + +/*********************************************************************************************************************** + * Det_Start() + **********************************************************************************************************************/ +/*! \brief Starts the DET + * \details Global function as an interface from EcuM to DET for start + * \pre - + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + * \note Shall be called during startup by EcuM in a safe context, e.g. before the OS is started. + * \trace SPEC-2880980, SPEC-2880998 + * \trace CREQ-2 + **********************************************************************************************************************/ +FUNC(void, DET_CODE) Det_Start( void ); + +/*********************************************************************************************************************** + * Det_InitMemory() + **********************************************************************************************************************/ +/*! \brief Initializes the DET + * \details Initializes the state variable for the un-init check of the DET. If this function is used it must be called before Det_Init. + * \pre - + * \context TASK + * \reentrant FALSE + * \synchronous TRUE + * \note Shall be called during startup by EcuM in a safe context, e.g. before the OS is started. + * \trace CREQ-1 + **********************************************************************************************************************/ +FUNC(void, DET_CODE) Det_InitMemory( void ); + +/*********************************************************************************************************************** + * Det_ReportError() + **********************************************************************************************************************/ +/*! \brief Development error reporting function + * \details Global function for BSW-Modules to report errors to the DET. + * If extended debug features are disabled the DET enters an endless loop in case of an embedded target + * or issues an error message in the CANoe write window in case of a simulated target. + * \param[in] ModuleId Module ID of calling module + * \param[in] InstanceId The identifier of the index based instance of a module + * \param[in] ApiId ID of API service in which error is detected + * \param[in] ErrorId ID of detected development error + * \return E_OK (always) + * \pre - + * \context TASK|ISR2 + * \reentrant TRUE + * \synchronous TRUE + * \note If filtering is active the default settings of the filter discard error reports of ModuleId 0 (zero). + * \trace SPEC-2880982, SPEC-2880983, SPEC-2880984, SPEC-2880985, SPEC-2880986, SPEC-2880987, SPEC-2880988 + * \trace SPEC-2880989, SPEC-2880991, SPEC-2880997, SPEC-2881003 + * \trace CREQ-4, DSGN-Det22798, DSGN-Det22785, DSGN-Det22786, DSGN-Det22801, DSGN-Det22811 + **********************************************************************************************************************/ +FUNC(Std_ReturnType, DET_CODE) Det_ReportError( uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId ); + +/*********************************************************************************************************************** + * Det_ReportRuntimeError() + **********************************************************************************************************************/ +/*! \brief Runtime error reporting function + * \details Global function for BSW-Modules to report runtime errors to the DET. + * This function returns and issues an error message in the CANoe write window in case of a simulated target. + * \param[in] ModuleId Module ID of calling module + * \param[in] InstanceId The identifier of the index based instance of a module + * \param[in] ApiId ID of API service in which error is detected + * \param[in] ErrorId ID of detected development error + * \return E_OK (always) + * \pre - + * \context TASK|ISR2 + * \reentrant TRUE + * \synchronous TRUE + * \trace SPEC-2880982, SPEC-2880983, SPEC-2880984, SPEC-2880987, SPEC-2880988, SPEC-2880993 + * \trace SPEC-2880999, SPEC-2881004 + * \trace CREQ-120271, DSGN-Det22801, DSGN-Det22784, DSGN-Det22786, DSGN-Det22811 + **********************************************************************************************************************/ +FUNC(Std_ReturnType, DET_CODE) Det_ReportRuntimeError( uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId ); + +/*********************************************************************************************************************** + * Det_ReportTransientFault() + **********************************************************************************************************************/ +/*! \brief Transient fault reporting function + * \details Global function for BSW-Modules to report transient faults to the DET. + * This function returns and issues an error message in the CANoe write window in case of a simulated target. + * \param[in] ModuleId Module ID of calling module + * \param[in] InstanceId The identifier of the index based instance of a module + * \param[in] ApiId ID of API service in which error is detected + * \param[in] ErrorId ID of detected development error + * \return E_OK (always) if no callouts are configured - return value of last callout if callouts are configured + * \pre - + * \context TASK|ISR2 + * \reentrant TRUE + * \synchronous TRUE + * \trace SPEC-2880982, SPEC-2880983, SPEC-2880984, SPEC-2880987, SPEC-2880988, SPEC-2880992 + * \trace SPEC-2881000, SPEC-2881005 + * \trace CREQ-120272, DSGN-Det22801, DSGN-Det22784, DSGN-Det22786, DSGN-Det22811 + **********************************************************************************************************************/ +FUNC(Std_ReturnType, DET_CODE) Det_ReportTransientFault( uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId ); + +# if (DET_VERSION_INFO_API == STD_ON) +/*********************************************************************************************************************** + * Det_GetVersionInfo() + **********************************************************************************************************************/ +/*! \brief Read the DET version information + * \details Global function for BSW-Modules to get the Version of DET + * \param[out] versioninfo Version information of the DET + * \pre - + * \context TASK|ISR2 + * \reentrant TRUE + * \synchronous TRUE + * \config DET_VERSION_INFO_API + * \trace SPEC-2880990, SPEC-2880994, SPEC-2881001 + * \trace CREQ-5 + * \spec + * requires $valid(versioninfo, $range(0,0)); + * \endspec + **********************************************************************************************************************/ +FUNC(void, DET_CODE) Det_GetVersionInfo( P2VAR( Std_VersionInfoType, AUTOMATIC, DET_APPL_DATA ) versioninfo ); +# endif + +# define DET_STOP_SEC_CODE +# include "Det_MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# else /* DET_ENABLED */ + +/* if the Det is disabled provide the API as empty macros */ +# define Det_Init(a) +# define Det_Start() +# define Det_InitMemory() +# define Det_ReportError(a,b,c,d) E_OK +# define Det_ReportRuntimeError(a,b,c,d) E_OK +# define Det_ReportTransientFault(a,b,c,d) E_OK +# define Det_GetVersionInfo(a) + +# endif /* DET_ENABLED */ +#endif /* DET_H */ + +/*! + * \exclusivearea DET_EXCLUSIVE_AREA_0 + * Assures atomic storage of reported errors in the log buffer and consistency of recursion counters. + * \protects detLogBuffer, detStatus.logIndex + * \protects detRecursionCounterReportError, detRecursionCounterReportRuntimeError + * \protects detRecursionCounterReportTransientFault + * \usedin Det_ReportError, Det_ReportRuntimeError, Det_ReportTransientFault + * \exclude Det_ReportError, Det_ReportRuntimeError, Det_ReportTransientFault + * \length SHORT maximal 10 C-statements without loop are used this exclusive area. + * \endexclusivearea + */ + +/********************************************************************************************************************** + * END OF FILE: Det.h + *********************************************************************************************************************/ + diff --git a/Source/bsw/Det/Make/Det_cfg.mak b/Source/bsw/Det/Make/Det_cfg.mak new file mode 100644 index 0000000..5ea4fef --- /dev/null +++ b/Source/bsw/Det/Make/Det_cfg.mak @@ -0,0 +1,75 @@ +############################################################################### +# File Name : Det_cfg.mak +# Description: Configuration makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Det_rules.mak file. +############################################################################### + +############################################################## +# CAN_CONFIG_PATH: (not used for Vector) +# The Variable CAN_CONFIG_PATH is optional. It allows the +# configuration of the directory, where you can also find the +# generated source files. Generally they should be in the +# directory $(PROJECT_ROOT)\source\networks. +# But if the application should run on several hardware +# targets, then different CAN configurations of different +# directories will be necessary. Therefor the variable +# CAN_CONFIG_PATH should be used. +# +# For example: +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\st10 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# + +############################################################## +# CAN_DRIVER_MODE: (not used for Vector) +# This Variable contains the name of the can driver module. At +# the moment the Standard Software Core Supports the two driver +# can_drv.c (single CAN) and can_drvm.c (multi CAN). Other +# values are not allowed. +# +# For example: +# CAN_DRIVER_MODE = singlechannel/multichannel +# + +############################################################### +# REQUIRED +# +# No Other resources are required to write a Configuration +# Makefile. +# +############################################################### + + +############################################################### +# PROVIDE +# +# A Configuration Makefile does not provide resources for other +# basic software bundles or the base_make package +# +############################################################### + + +############################################################### +# REGISTRY +# +# Like the Provide-Section this block is empty. +# +############################################################### + + +############################################################### +# SPECIFIC +# +# All variables in the _cfg makefile are "Specific" variables, +# because they should only be used in the *_check.mak, +# *_defs.mak and *_rules.mak Makefiles of the same basic +# software bundle. +############################################################### diff --git a/Source/bsw/Det/Make/Det_check.mak b/Source/bsw/Det/Make/Det_check.mak new file mode 100644 index 0000000..b0791aa --- /dev/null +++ b/Source/bsw/Det/Make/Det_check.mak @@ -0,0 +1,79 @@ +############################################################################### +# File Name : Det_check.mak +# Description: Configuration check makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Det_rules.mak file. +############################################################################### + +############################################################### +# REGISTRY +# + +#e.g.: PREPARE_CONFIGURATION_INTERFACE += CAN_MODULES +PREPARE_CONFIGURATION_INTERFACE += + +CHECK_VARS_WHICH_ARE_REQUIRED += + +CHECK_VARS_WHICH_ARE_OPTIONAL += + +CHECK_VARS_WHICH_ARE_OBSOLETE += + +CHECK_VARS_WITH_ONE_CC_FILE += +CHECK_VARS_WITH_MORE_CC_FILES += + +CHECK_VARS_WITH_ONE_CPP_FILE += +CHECK_VARS_WITH_MORE_CPP_FILES += + +CHECK_VARS_WITH_ONE_ASM_FILE += +CHECK_VARS_WITH_MORE_ASM_FILES += + +CHECK_VARS_WITH_ONE_LIB_FILE += +CHECK_VARS_WITH_MORE_LIB_FILES += + +CHECK_VARS_WITH_ONE_OBJ_FILE += +CHECK_VARS_WITH_MORE_OBJ_FILES += + +#e.g: CHECK_VARS_WITH_ONE_DIRECTORY += $(DIRECTORIES_TO_CREATE) +# $(DIRECTORIES_TO_CREATE) = C:\demo\drv (this var is defined in _rules.mak) +CHECK_VARS_WITH_ONE_DIRECTORY += +CHECK_VARS_WITH_MORE_DIRECTORIES += + +CHECK_VARS_WITH_ONE_FILE += +CHECK_VARS_WITH_MORE_FILES += + +CHECK_VARS_WITH_MAX_LENGTH_ONE += + +############################################################### +# SPECIFIC +# +#ifneq ($(CAN_DRIVER_MODE),singlechannel) +#ifneq ($(CAN_DRIVER_MODE),multichannel) +#$(error The value of the variable CAN_DRIVER_MODE is not valid. \ +# Please use singlechannel or multichannel) +#endif +#endif + + +############################################################### +# REQUIRED +# +# No other resources are required for a Configuration Check +# Makefile +# +############################################################### + + +############################################################### +# PROVIDE +# +# A configuration Makefile does not provide resources for other +# basic software bundles or the base-make package. +# +############################################################### + diff --git a/Source/bsw/Det/Make/Det_defs.mak b/Source/bsw/Det/Make/Det_defs.mak new file mode 100644 index 0000000..54d6d84 --- /dev/null +++ b/Source/bsw/Det/Make/Det_defs.mak @@ -0,0 +1,80 @@ +############################################################################### +# File Name : Det_defs.mak +# Description: Public makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the Det_rules.mak file. +############################################################################### + +############################################################### +# INTERNAL REQUIRED CONFIGURATION (in can_cfg.mak) +# +# CAN_MODULES (required) (not necessary for Vector) +# CAN_DRIVER_MODE (required) (not necessary for Vector) +# CAN_PROJECT_PATH (optional) +# CAN_BUILD_LIBRARY (required) + + +############################################################### +# REQUIRED (defined in base_make) +# +# PROJECT_ROOT +# SSC_ROOT +############################################################### + + +############################################################### +# SPECIFIC +# Specific variables which were defined here are only for local use in this Makefile +# if for example additional includes are necessary, these vars can be defined and used in the REGISTRY-Part. +# e.g.: $(CAN_CORE_PATH) = $(SSC_ROOT)\Can could be used for CPP_INCLUDE_PATH += $(CAN_CORE_PATH)\CPP_FILES\... +DET_CORE_PATH = +DET_OUTPUT_PATH = $(GENDATA_DIR) + +#CAN_TOOL_PATH = $(PROJECT_ROOT)\core\com\can\gentool + +# it is also possible to generate own configurations with some checks like the following example +# ifneq ( $(CAN_CONFIG_PATH),) +# CAN_PROJECT_PATH = $(CAN_CONFIG_PATH) +# else +# CAN_PROJECT_PATH = $(PROJECT_ROOT)\source\network\can +# endif + + +############################################################### +# REGISTRY +# +# $(SSC_PLUGINS) is a list of the components. Here can is added (not necessary for Vector, whole component-list also exists in Global.makefile.target.make...) +# e.g.: SSC_PLUGINS += can +SSC_PLUGINS += +#e.g.: can_DEPENDENT_PLUGINS = +DET_DEPENDENT_PLUGINS = + +#----------------------------------------------------------------------------------------- +# MakeSupport usually includes all header-files which were in the same +# directory as the source-files automatically, but to ensure that the +# Asr-Makefiles will also work with other Basic-Make-Packages, +# it is necessary to define all include directories for this Module +# e.g.: CC_INCLUDE_PATH += $(CAN_CORE_PATH) +#------------------------------------------------------------------------------------------ +CC_INCLUDE_PATH += Det$(BSW_SRC_DIR) +CPP_INCLUDE_PATH += +ASM_INCLUDE_PATH += + +#PREPROCESSOR_DEFINES+= drivermode + +#drivermode_KEY = CAN_MODE +#drivermode_VALUE = $(CAN_DRIVER_MODE) + + +############################################################### +# PROVIDE +# +# A Public Makefile does not provide resources for other basic +# software bundles or the base_make package. +############################################################### diff --git a/Source/bsw/Det/Make/Det_rules.mak b/Source/bsw/Det/Make/Det_rules.mak new file mode 100644 index 0000000..3d3b54d --- /dev/null +++ b/Source/bsw/Det/Make/Det_rules.mak @@ -0,0 +1,103 @@ +############################################################################### +# File Name : Det_rules.mak +# Description: Rules makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Version Date Author Description +#------------------------------------------------------------------------------ +# 1.00.00 2007-06-13 Aba Initial Version of Template (1.0) +# 1.01.00 2008-02-14 HH Added support of AUTOSAR DET +# 1.02.00 2008-04-30 fbg Changes for ASR library support +# 1.03.00 2017-02-27 HH Added Det_Cfg.c in file list +# 1.04.00 2019-02-06 vircbl Added support of component-based SIP structure +#------------------------------------------------------------------------------ +# TemplateVersion = 1.02 +############################################################################### + + +############################################################### +# REGISTRY +# + +#e.g.: LIBRARIES_TO_BUILD += $(LIB_OUPUT_PATH)\vendorx_canlib1.$(LIB_FILE_SUFFIX) +LIBRARIES_TO_BUILD += Det +Det_FILES = Det$(BSW_SRC_DIR)\Det.c + +# e.g.: CC_FILES_TO_BUILD += drv\can_drv.c +CC_FILES_TO_BUILD += Det$(BSW_SRC_DIR)\Det.c +CPP_FILES_TO_BUILD += +ASM_FILES_TO_BUILD += + +#LIBRARIES_LINK_ONLY += (not yet supported) +#OBJECTS_LINK_ONLY += (not yet supported) + +#------------------------------------------------------------------------------------------------- +#only define new dirs, OBJ, LIB, LOG were created automaticly +#------------------------------------------------------------------------------------------------- +DIRECTORIES_TO_CREATE += + +#DEPEND_GCC_OPTS += (not yet supported) + +# e.g.: GENERATED_SOURCE_FILES += $(GENDATA_DIR)\drv_par.c +GENERATED_SOURCE_FILES += $(GENDATA_DIR)\Det_Cfg.c + +#e.g.: COMMON_SOURCE_FILES += $(GENDATA_DIR)\v_par.c +COMMON_SOURCE_FILES += + +#------------------------------------------------------------------------------------------------- +# .dep & .lnk & .bin and..... +# all in err\ & obj\ & lst\ & lib\ & log\ will be deleted by clean-rule automaticly +# so in this clean-rule it is only necessary to define additional files which +# were not delete automaticly. +# e.g.: $()\can_test.c +#------------------------------------------------------------------------------------------------- +MAKE_CLEAN_RULES += +#MAKE_GENERATE_RULES += +#MAKE_COMPILER_RULES += +#MAKE_DEBUG_RULES += +#MAKE_CONFIG_RULES += +#MAKE_ADD_RULES += + + +############################################################### +# REQUIRED (defined in BaseMake (global.Makefile.target.make...)) +# +# SSC_ROOT (required) +# PROJECT_ROOT (required) +# +# LIB_OUTPUT_PATH (optional) +# OBJ_OUTPUT_PATH (optional) +# +# OBJ_FILE_SUFFIX +# LIB_FILE_SUFFIX +# +############################################################### + + +############################################################### +# PROVIDE this Section can be used to define own additional rules +# +# In vendorx_can_cfg.mak: +# Please configure the project file: +#CAN_CONFIG_FILE = $(PROJECT_ROOT)\source\network\can\my_can_config.cfg + +#In vendorx_can_config : +#generate_can_config: +#$(SSC_ROOT)\core\com\can\tools\canconfiggen.exe -o $(CAN_CONFIG_FILE) + + +############################################################### +# SPECIFIC +# +# There are no rules defined for the Specific part of the +# Rules-Makefile. Each author is free to create temporary +# variables or to use other resources of GNU-MAKE +# +############################################################### + + diff --git a/Source/bsw/Fbl/applvect.h b/Source/bsw/Fbl/applvect.h new file mode 100644 index 0000000..a09e80a --- /dev/null +++ b/Source/bsw/Fbl/applvect.h @@ -0,0 +1,106 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Generic application vector table for platforms with Interrupt Vector Base Register. + * This file is usually compiled and linked with the bootloader and is located OUTSIDE the + * protected area of the FBL. It must be compiled, linked and downloaded with the + * application after changing the magic value to 'APPL' + * and setting the start label to the entry point of the application. + * If the application is set to valid, the bootloader checks the magic flag in the first + * entry of the ApplIntJmpTable and then calls the function specified in the second entry. + * + * This file must be compiled and linked in the bootloader + * and the application to the SAME MEMORY LOCATION! + * + * \note Please note, that this file contains example source code used by the Flash Bootloader. These + * functions may influence the behavior of the bootloader in principle. Therefore, great care must + * be taken to verify the correctness of the implementation. The contents of the originally delivered + * files are only examples resp. implementation proposals. With regard to the fact that these + * functions are meant for demonstration purposes only, Vector Informatik's liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2020 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * AUTHOR IDENTITY + * -------------------------------------------------------------------------------------------------------------------- + * Name Initials Company + * -------------------------------------------------------------------------------------------------------------------- + * Johannes Krimmel KJs Vector Informatik GmbH + * Christian Ralcewicz RCn Vector Informatik GmbH + * -------------------------------------------------------------------------------------------------------------------- + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2017-10-27 KJs Initial version + * 01.00.01 2020-09-18 RCn ESCAN00106567 No changes + **********************************************************************************************************************/ + +#ifndef __APPL_VECT_H__ +#define __APPL_VECT_H__ + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#define FBLVTABAPPL_IVBR_VERSION 0x0100u +#define FBLVTABAPPL_IVBR_RELEASE_VERSION 0x01u + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#define APPLVECT_FROM_BOOT 0x42544C44ul /* 'BTLD', Reserved for Bootloader internal value + * This magic value mustn't be set + * for the application vector table, just + * for the table linked with the Bootloader. + */ + +#define APPLVECT_FROM_APPL 0x4150504Cul /* 'APPL', Set this label only for the + * application vector table linked with the Application! + */ + +/*********************************************************************************************************************** + * EXTERNAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +/* Reset vector pointer definition for the FBL - compiler/hardware specific. + * When using this file for the actual application, FBL_RESET_ENTRY_LABEL may not be defined. + * Please insert the label manually and adapt the defines or include fbl_cfg.h. + */ +#if !defined( FBL_RESET_ENTRY_LABEL ) +# error "Please define FBL_RESET_ENTRY_LABEL to entry label of the startup code." +#else +extern void FBL_RESET_ENTRY_LABEL( void ); +# define RESET_ENTRY_ADDRESS (vuint32)&FBL_RESET_ENTRY_LABEL +#endif /* FBL_ENTRY_LABEL */ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBL_APPLVECT_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_19.1 */ +V_MEMROM0 extern V_MEMROM1 vuint32 V_MEMROM2 ApplIntJmpTable[2]; +#define FBL_APPLVECT_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_19.1 */ + +#endif /* __APPL_VECT_H__ */ + +/*********************************************************************************************************************** + * END OF FILE: APPLVECT.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_applvect.c b/Source/bsw/Fbl/fbl_applvect.c new file mode 100644 index 0000000..3f9a5fa --- /dev/null +++ b/Source/bsw/Fbl/fbl_applvect.c @@ -0,0 +1,101 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Generic application vector table for platforms with Interrupt Vector Base Register. + * This file is usually compiled and linked with the bootloader and is located OUTSIDE the + * protected area of the FBL. It must be compiled, linked and downloaded with the + * application after changing the magic value to 'APPL' + * and setting the start label to the entry point of the application. + * If the application is set to valid, the bootloader checks the magic flag in the first + * entry of the ApplIntJmpTable and then calls the function specified in the second entry. + * + * This file must be compiled and linked in the bootloader + * and the application to the SAME MEMORY LOCATION! + * + * \note Please note, that this file contains example source code used by the Flash Bootloader. These + * functions may influence the behavior of the bootloader in principle. Therefore, great care must + * be taken to verify the correctness of the implementation. The contents of the originally delivered + * files are only examples resp. implementation proposals. With regard to the fact that these + * functions are meant for demonstration purposes only, Vector Informatik's liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2020 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * AUTHOR IDENTITY + * -------------------------------------------------------------------------------------------------------------------- + * Name Initials Company + * -------------------------------------------------------------------------------------------------------------------- + * Johannes Krimmel KJs Vector Informatik GmbH + * Christian Ralcewicz RCn Vector Informatik GmbH + * -------------------------------------------------------------------------------------------------------------------- + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2017-10-27 KJs Initial version + * 01.00.01 2020-09-18 RCn ESCAN00106567 Compiler issue: "fbl_cfg.h" cannot be opened + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_def.h" +#include "applvect.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLVTABAPPL_IVBR_VERSION != 0x0100u ) || \ + ( FBLVTABAPPL_IVBR_RELEASE_VERSION != 0x01u ) +# error "Error in fbl_applvect.c: Source and header file are inconsistent!" +#endif + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBL_APPLVECT_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_19.1 */ +/* PRQA S 305,428 1 */ /* MD_ApplVect_0305, MD_ApplVect_0428*/ +V_MEMROM0 V_MEMROM1 vuint32 V_MEMROM2 ApplIntJmpTable[2] = {APPLVECT_FROM_BOOT, RESET_ENTRY_ADDRESS}; +#define FBL_APPLVECT_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_19.1 */ + +/********************************************************************************************************************** + * MISRA + *********************************************************************************************************************/ + +/* Module specific MISRA deviations: + + MD_ApplVect_0305: + Reason: Cast between a pointer to function and an integral type. + Risk: Target data types are not big enough - data loss occurs. + Prevention: The length of the pointer is known for the used platform and has to be kept in mind by the programmer. + + MD_ApplVect_0428: + Reason: Function identifier is not followed by () but a function call may be intended. + No function call intended. The address of the function shall be used. + Risk: No risk. + Prevention: No prevention required. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: APPLVECT.C + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_assert.h b/Source/bsw/Fbl/fbl_assert.h new file mode 100644 index 0000000..72a86ca --- /dev/null +++ b/Source/bsw/Fbl/fbl_assert.h @@ -0,0 +1,129 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief System specific assertion defines + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 04.00.00 2016-02-26 visach ESCAN00088307 Rework to support FblMain 3.xx + * ESCAN00088433 Moved assertion specific code to fbl_assert.h + * 04.00.01 2016-07-15 visdlm ESCAN00091011 No changes + * 04.01.00 2016-08-18 vistns ESCAN00091531 No changes + * 04.02.00 2016-10-31 viscb ESCAN00092597 No changes + * 04.02.01 2017-05-09 visjhg ESCAN00095090 No changes + * visrie ESCAN00095204 Added assertion defines for DET + * 04.03.00 2017-07-28 viscb ESCAN00095458 No changes + * visach ESCAN00096096 No changes + * 04.04.00 2018-02-26 visdkl ESCAN00098503 No changes + * 04.04.01 2018-07-06 visdkl ESCAN00099860 No changes + * 04.04.01 2018-07-06 visdkl ESCAN00099860 No changes + * 04.05.00 2018-09-13 visrie ESCAN00100731 No changes + * 2018-11-20 visdkl ESCAN00101393 No changes + * 04.06.00 2019-12-03 visjdn FBL-999 No changes + * 05.00.00 2020-03-02 vistbe FBL-949 No changes + * ESCAN00105231 No changes + * 05.01.00 2020-04-29 vistmo FBL-1584 No changes + * 05.02.00 2020-05-08 visrie FBL-1414 No changes + * 05.03.00 2020-07-16 visrie FBL-2021 No changes + * 05.04.00 2024-05-03 visrie FBL-8515 No changes + * ESCAN00117096 No changes + * 05.05.00 2025-10-03 pharring FBL-10242 Add support for logger + * 05.06.00 2025-10-22 mpatil FBL-11533 Logical Block Meta data information is not indexed correctly + * in OTA usecase + **********************************************************************************************************************/ + +#ifndef FBL_ASSERT_H +#define FBL_ASSERT_H + +/*********************************************************************************************************************** + * DEFINITION OF ASSERTION CODES (SYSTEM) + **********************************************************************************************************************/ + +/* Note: System assertions are only allowed in the range from 0x00-0x7F. Others are reserved. */ +#if defined( FBL_ENABLE_ASSERTION ) +/* 0x00-0x1F: General FBL assertions */ +# define kFblSysAssertMissingForcedRCRRP 0x00u + +# define kFblSysAssertInitializationFailed 0x10u + +/* 0x20-0x3F: Internal assertions */ +# define kFblSysAssertServiceReqBeforeResp 0x20u +# define kFblSysAssertServiceMainHandlerInvalid 0x21u +# define kFblSysAssertDet 0x22u + +/* 0x40-0x4F: Generated data assertions */ +# define kFblSysAssertWdBufferOverflow 0x40u + +/* 0x50-0x6F: User parameter assertions */ +# define kFblSysAssertParameterOutOfRange 0x50u +# define kFblAssertIllegalReturnValue 0x51u +# define kFblSysAssertRepeatedCallOnConcludedService 0x60u + +/* 0x70-0x7F: Communication wrapper assertions */ +# define kFblSysAssertStateNotIdle 0x70u +# define kFblSysAssertNoBufferAvailable 0x71u + +/* 0x80-0xFF: OEM specific */ +# include "fbl_assert_oem.h" + +# if defined( __LINE__ ) && defined( __FILE__ ) && defined( FBL_ENABLE_ASSERTION_EXTENDED_INFO ) +# define FBL_DECL_ASSERT_EXTENDED_INFO(n) const vuint8* module, vuint16 line, n +# define FBL_USED_ASSERT_EXTENDED_INFO(n) __FILE__, __LINE__,(n) +# else +# define FBL_DECL_ASSERT_EXTENDED_INFO(n) n /* PRQA S 3410 */ /* MD_FblAssert_3410 */ +# define FBL_USED_ASSERT_EXTENDED_INFO(n) (n) /* PRQA S 3453 */ /* MD_MSR_19.7 */ +# endif /* __LINE__ && __FILE__ && FBL_ENABLE_ASSERTION_EXTENDED_INFO */ +#endif /* FBL_ENABLE_ASSERTION || FBL_ENABLE_LOGGER */ + +/* No statement should be added to below if clauses, in order to prevent errors suggested by Misra rule 14.9 */ +/* PRQA S 3412 4 */ /* MD_FblAssert_Assertion */ +#if defined( FBL_ENABLE_ASSERTION ) +# define assertFbl(p, e) if (!(p)) ApplFblFatalError(FBL_USED_ASSERT_EXTENDED_INFO(e)) /* PRQA S 2214 */ /* MD_FblAssert_Assertion */ +# define assertFblUser(p, e) if (!(p)) ApplFblFatalError(FBL_USED_ASSERT_EXTENDED_INFO(e)) /* PRQA S 2214 */ /* MD_FblAssert_Assertion */ +# define assertFblGen(p, e) if (!(p)) ApplFblFatalError(FBL_USED_ASSERT_EXTENDED_INFO(e)) /* PRQA S 2214 */ /* MD_FblAssert_Assertion */ +# define assertFblInternal(p, e) if (!(p)) ApplFblFatalError(FBL_USED_ASSERT_EXTENDED_INFO(e)) /* PRQA S 2214 */ /* MD_FblAssert_Assertion */ +#else +# define assertFbl(p, e) +# define assertFblUser(p, e) +# define assertFblGen(p, e) +# define assertFblInternal(p, e) +#endif /* FBL_ENABLE_ASSERTION */ + +/* Module specific MISRA deviations: + + MD_FblAssert_Assertion: + Reason: This is an assertion macro used only for debugging in development (FBL_ENABLE_ASSERTION). There should + be no need to extend the amount of statements, so the current usage is accepted. + Risk: Unintended debugging code behavior could result, through adding further statements, + Prevention: A comment is in place to avoid that further statements are added to the if condition. + + MD_FblAssert_3410: + Reason: This macro serves as function parameter type qualifier and cannot have parentheses, because this would + result in an invalid function parameter list. + Risk: Usage at not intended places and unintended code behavior due to the missing parentheses. + Prevention: Reviews must ensure that this macro is only used in function parameter lists. +*/ + +#endif /* FBL_ASSERT_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_ASSERT.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_assert_oem.h b/Source/bsw/Fbl/fbl_assert_oem.h new file mode 100644 index 0000000..8b622ee --- /dev/null +++ b/Source/bsw/Fbl/fbl_assert_oem.h @@ -0,0 +1,78 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief OEM specific assertion defines (Ford) + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2026 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2022-08-15 vistmo FBL-5514 Support Additional OTA functionality + * ESCAN00112435 No changes + * ESCAN00112575 No changes + * 05.01.00 2022-10-04 jschmitding FBL-5917 No changes + * ESCAN00113919 No changes + * 05.01.01 2022-10-17 fmenke ESCAN00112879 No changes + * 05.01.02 2023-01-13 fmenke ESCAN00112890 No changes + * ESCAN00113612 No changes + * 05.02.00 2023-02-09 vistmo ESCAN00112972 No changes + * ESCAN00113292 No changes + * ESCAN00113835 No changes + * ESCAN00113843 No changes + * ESCAN00113764 No changes + * FBL-6438 No changes + * 05.02.01 2023-05-11 fmenke ESCAN00113831 No changes + * 05.03.00 2023-07-24 fmenke FBL-7335 No changes + * 05.03.01 2023-08-31 lhopfhauer ESCAN00115494 No changes + * 05.03.02 2024-07-16 erizk ESCAN00117344 No changes + * 05.03.03 2025-02-06 virchl ESCAN00118587 No changes + * 05.04.00 2025-02-28 jjohnson FBL-10065 No changes + * 05.04.01 2025-06-10 jostravsky ESCAN00120315 No changes + * 05.04.02 2025-07-08 visarcmijo ESCAN00119833 No changes + * 05.05.00 2025-09-01 fmenke FBL-11218 No changes + * ESCAN00120917 No changes + * 05.06.00 2025-10-28 mpatil FBL-11690 No changes + * 05.07.00 2026-01-13 dganesh FBL-12162 No changes + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * DEFINITION OF ASSERTION CODES (OEM) + **********************************************************************************************************************/ + +/* Note: OEM assertions are only allowed in the range from 0x80-0xFF. Others are reserved. */ + +/* 0x80-0x9F: General FBL assertions */ +#define kFblOemAssertInvalidError 0x82u + +/* 0xA0-0xBF: Internal assertions */ +#define kFblOemAssertSessionIndexNotFound 0xA0u +#define kFblOemAssertIllegalParameter 0xA1u +#define kFblOemAssertIllegalExecutionPath 0xA2u +#define kFblOemAssertInvalidSecLvlIdx 0xA3u + +/* 0xC0-0xDF: Generated data assertions */ +#define kFblOemAssertPreHandlerIdxInvalid 0xC0u + +/* 0xE0-0xFF: User parameter assertions */ +#define kFblOemAssertParameterOutOfRange 0xE0u +#define kFblOemAssertIllegalReturnValue 0xE1u + +/*********************************************************************************************************************** + * END OF FILE: FBL_ASSERT_OEM.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_def.h b/Source/bsw/Fbl/fbl_def.h new file mode 100644 index 0000000..926a80f --- /dev/null +++ b/Source/bsw/Fbl/fbl_def.h @@ -0,0 +1,423 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Main definitions for the Flash Boot Loader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 04.00.00 2016-02-26 visach ESCAN00088307 Rework to support FblMain 3.xx + * ESCAN00088433 Moved assertion specific code to fbl_assert.h + * 04.00.01 2016-07-15 visdlm ESCAN00091011 Added programming voltage check defines + * 04.01.00 2016-08-18 vistns ESCAN00091531 Updated support of HMC + * 04.02.00 2016-10-31 viscb ESCAN00092597 Added support for SYMC SLP2 + * 04.02.01 2017-05-09 visjhg ESCAN00095090 Include upper-case Fbl_Cfg.h for DaVinci Configurator use-case + * visrie ESCAN00095204 No changes + * 04.03.00 2017-07-28 viscb ESCAN00095458 Removed unneeded client switches + * visach ESCAN00096096 Added fallback activation of NV-Wrapper and Vector SecMod + * 04.04.00 2018-02-26 visdkl ESCAN00098503 Updated support of Toyota SLP4 + * 04.04.01 2018-07-06 visdkl ESCAN00099860 Compiler error: shift count is too large + * 04.05.00 2018-09-13 visrie ESCAN00100731 Added additional flags for BootManager use-case + * 2018-11-20 visdkl ESCAN00101393 Removed support for Ford SLP6 + * 04.06.00 2019-12-03 visjdn FBL-999 Add define V_ENABLE_USE_DUMMY_STATEMENTS + * 05.00.00 2020-03-02 vistbe FBL-949 Add include for FblBm_Cfg.h + * ESCAN00105231 Compiler error: define syntax + * 05.01.00 2020-04-29 vistmo FBL-1584 Adding OTA startup support + * 05.02.00 2020-05-08 visrie FBL-1414 Adding One-Step-Updater support + * 05.03.00 2020-07-16 visrie FBL-2021 Adding OTA response after reset support + * 05.04.00 2024-05-03 visrie FBL-8515 Add generic defines and cleanup client list + * ESCAN00117096 Compiler error: Bit count of CPU not supported + * 05.05.00 2025-10-03 pharring FBL-10242 No changes + * 05.06.00 2025-10-22 mpatil FBL-11533 No changes + **********************************************************************************************************************/ + +#ifndef FBL_DEF_H +#define FBL_DEF_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +/* Basic configurations */ +#include "v_cfg.h" + +#if defined( VGEN_GENY ) && !defined( VGEN_ENABLE_CANFBL ) +/* This file was obviously not included in FBL, so it's used in user application + check if MAGIC_NUMBER was generated. In this case we have to remove the check for the + following include because FBL generation use different number than application */ +# if defined( MAGIC_NUMBER ) +# undef MAGIC_NUMBER +# endif +#endif + +#include "FblBm_Cfg.h" + +/* Configuration file for flash boot loader */ +#include "Fbl_Cfg.h" +#if defined( VGEN_GENY ) && !defined( VGEN_ENABLE_CANFBL ) +/* The last include redefined MAGIC_NUMBER, which is not relevant for application so + invalidate it */ +# if defined( MAGIC_NUMBER ) +# undef MAGIC_NUMBER +# endif +#endif + +/* Basic type definitions */ +#include "v_def.h" + +#if defined( FBL_ENABLE_SECMOD_VECTOR ) +# include "SecM_cfg.h" +#endif + +/* In application either remove FBL_ENABLE_ASSERTION switch or provide fbl_assert.h */ +# include "fbl_assert.h" + +/* PRQA S 3453 EOF */ /* MD_MSR_19.7 */ +/* PRQA S 3458 EOF */ /* MD_MSR_19.4 */ + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblDef CQComponent : Implementation */ +#define FBLDEF_VERSION 0x0506u +#define FBLDEF_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* Select usage of unified main interface */ +#define FBL_DEF_ENABLE_NON_KB_MAIN + +#ifndef NULL +# define NULL ((void *)0) +#endif + +/* Configuration of default switches */ +/* Activate NV-Wrapper if not explicitly configured */ +# if !defined( FBL_ENABLE_WRAPPER_NV ) && \ + !defined( FBL_DISABLE_WRAPPER_NV ) +# define FBL_ENABLE_WRAPPER_NV +# endif +/* Activate Vector SecMod if not explicitly configured */ +# if !defined( FBL_ENABLE_SECMOD_VECTOR ) && \ + !defined( FBL_DISABLE_SECMOD_VECTOR ) +# define FBL_ENABLE_SECMOD_VECTOR +# endif +/* Disable StayInBoot if not explicitly configured */ +#if !defined( FBL_ENABLE_STAY_IN_BOOT ) && \ + !defined( FBL_DISABLE_STAY_IN_BOOT ) +# define FBL_DISABLE_STAY_IN_BOOT +#endif + +/* Define return code of several functions */ +#define kFblOk 0x00u +#define kFblFailed 0x01u + +/* Defines for programming voltage check */ +#define kFblVoltageTooLow 0x01u +#define kFblVoltageTooHigh 0x02u + +/* Programming request flag */ +#define kProgRequest 0x00u /**< Diagnostic programming request is reported to main */ +#define kProgRequestXcp 0x01u /**< XCP programming request is reported to main */ +#define kProgRequestOta 0x02u /**< OTA programming request is reported to main */ +#define kNoProgRequest 0xFFu /**< No programming request */ + +#define kProgRequestWithResponse 0x02u /**< External programming request with response required */ +#define kProgRequestNoResponse 0x03u /**< No response required to programming request */ + +#define kCheckStayInBootRequest 0x10u /**< Check for stay in boot message */ +#define kInitKeysRequest 0x11u /**< Initialize crypto keys */ +#define kInitMacsRequest 0x12u /**< Initialize MACs */ + +/* Flag indicates that a response is required after programming request (only used by certain SLPs) */ +#define kFblStartWithResponse 0xAAu /**< FBL shall send a response after startup */ +#define kFblStartNoResponse 0x5Fu /**< FBL shall not send a response after startup */ + +/* Application validation */ +# define kApplValid 1u /**< Application is fully programmed */ +# define kApplInvalid 0u /**< Operational software is missing */ + +/* Memory status (flash erased detection) */ +# define kFlashErased 1u /**< Flash memory is in erased state */ +# define kFlashNotErased 0u /**< Flash memory is not in erased state (already written) */ + +/* Define return code of security access functions (only used by certain SLPs) */ +#define kFblSecNewSeedIssued 3u /**< seed */ +#define kFblSecGranted 4u /**< seed - key - status */ +#define kFblSecDeniedLocked 5u /**< status */ +#define kFblSecDeniedIncorrectLevel 6u /**< seed */ +#define kFblSecDeniedInvalidKey 7u + +#if !defined( FBL_REPEAT_CALL_CYCLE ) +/** Set default to 1ms for repeat time of main loop */ +# define FBL_REPEAT_CALL_CYCLE 1u +#endif + +#if defined( FBL_ENABLE_BANKING ) +#else +# define FBL_CALL_TYPE +#endif /* FBL_ENABLE_BANKING */ + +#ifndef V_CALLBACK_NEAR +# define V_CALLBACK_NEAR +#endif +#ifndef V_API_NEAR +# define V_API_NEAR +#endif + + +/* Defines to convert BigEndian bytes into short or long values ********************/ +#if defined( C_CPUTYPE_BIGENDIAN ) +# if defined( C_CPUTYPE_32BIT ) +# define FblBytesToShort(hi,lo) (((vuint16)(hi) << 8u) | ((vuint16)(lo))) +# else +# define FblBytesToShort(hi,lo) (vuint16)*(V_MEMRAM1_FAR vuint16 V_MEMRAM2_FAR *)(&(hi)) +# endif /* C_CPUTYPE_32BIT */ +#endif /* C_CPUTYPE_BIGENDIAN */ +#if defined( C_CPUTYPE_LITTLEENDIAN ) +# define FblBytesToShort(hi,lo) (((vuint16)(hi) << 8u) | ((vuint16)(lo))) +#endif /* C_CPUTYPE_LITTLEENDIAN */ + +#if defined( C_CPUTYPE_BIGENDIAN ) +# if defined( C_CPUTYPE_32BIT ) +# define FblBytesToLong(hiWrd_hiByt,hiWrd_loByt,loWrd_hiByt,loWrd_loByt) \ + (((vuint32)(hiWrd_hiByt) << 24u) | \ + ((vuint32)(hiWrd_loByt) << 16u) | \ + ((vuint32)(loWrd_hiByt) << 8u) | \ + ((vuint32)(loWrd_loByt) ) ) +# else +# define FblBytesToLong(hiWrd_hiByt,hiWrd_loByt,loWrd_hiByt, loWrd_loByt) \ + (vuint32)*(V_MEMRAM1_FAR vuint32 V_MEMRAM2_FAR *)(&(hiWrd_hiByt)) +# endif /* C_CPUTYPE_32BIT */ +#endif /* C_CPUTYPE_BIGENDIAN */ +#if defined( C_CPUTYPE_LITTLEENDIAN ) +# define FblBytesToLong(hiWrd_hiByt,hiWrd_loByt,loWrd_hiByt,loWrd_loByt) \ + (((vuint32)(hiWrd_hiByt) << 24u) | \ + ((vuint32)(hiWrd_loByt) << 16u) | \ + ((vuint32)(loWrd_hiByt) << 8u) | \ + ((vuint32)(loWrd_loByt) ) ) +#endif /* C_CPUTYPE_LITTLEENDIAN */ + +/* FBL bit definitions */ +#define FBL_BIT0 0x01u +#define FBL_BIT1 0x02u +#define FBL_BIT2 0x04u +#define FBL_BIT3 0x08u +#define FBL_BIT4 0x10u +#define FBL_BIT5 0x20u +#define FBL_BIT6 0x40u +#define FBL_BIT7 0x80u + +/* Defines for response after reset */ +#define RESET_RESPONSE_NOT_REQUIRED 0x00u /**< No response required */ +#define RESET_RESPONSE_SDS_REQUIRED 0x01u /**< Response to SessionControl-DefaultSession required */ +#define RESET_RESPONSE_ECURESET_REQUIRED 0x02u /**< Response to EcuReset-HardReset required */ +#define RESET_RESPONSE_KEYOFFON_REQUIRED 0x03u /**< Response to EcuReset-KeyOffOnReset required */ +#define RESET_RESPONSE_OSU_REQUIRED 0x04u /**< Response to One-Step-Updater required */ +#define RESET_RESPONSE_OTA_REQUIRED 0x05u /**< Response to OTA required */ + +/* Macros to harmonize type casts for inverting bits */ +#define FblInvertBits(x,type) ((type)~((type)(x))) /* PRQA S 0277 */ /* MD_FblDef_Invert */ +#define FblInvert8Bit(x) ((vuint8) ((x) ^ ((vuint8 )0xFFu))) +#define FblInvert16Bit(x) ((vuint16)((x) ^ ((vuint16)0xFFFFu))) +#define FblInvert32Bit(x) ((vuint32)((x) ^ ((vuint32)0xFFFFFFFFul))) + +/* Logical Marker (only used by certain SLPs) */ +#define LM_Upload 0x80u +#define LM_Calibration 0x81u +#define LM_Global 0x82u +#define LM_LogZone 0x83u +#define LM_UploadNoCrc 0x84u +#define LM_AppliKey 0x88u + +# define kFblDiagTimeP2 FBL_DIAG_TIME_P2MAX +# define kFblDiagTimeP2Star FBL_DIAG_TIME_P3MAX + +/* Reprogramming request flags */ +#define kEepFblReprogram 0xB5u /**< FBL is started with normal reprogramming request, e.g. programming session */ +#define kEepFblXcpProgram 0x5Bu /**< FBL is started with XCP reprogramming request */ +#define kEepFblOtaReprogram 0x5Cu /**< FBL is started with OTA reprogramming request */ +#define kEepFblActive 0xA4u +#define kEepFblVpm 0xC6u +#define kEepFblLinkControl 0x93u + +/* Flags to indicate if NV functions should read or write data */ +#define kEepWriteData 1u /**< Write data to NV memory */ +#define kEepReadData 2u /**< Read data from NV memory */ + +/* Error code defines for ApplFblErrorNotification */ +#define kFblErrTypeAppl 0x10u +#define kFblErrTypeFlash 0x20u +#define kFblErrTypeEeprom 0x30u +#define kFblErrTypeSec 0x40u +#define kFblErrTypeVectorTPMC 0x50u + +/** Round length up to next multiple of alignment */ +#define FBL_LENGTH_ALIGN_ROUND_UP(length, align) (((((length) - 1u) / (align)) + 1u) * (align)) +/** Round length down to next multiple of alignment */ +#define FBL_LENGTH_ALIGN_ROUND_DOWN(length, align) (((length) / (align)) * (align)) + +/** Helper macro to get number of array entries */ +#define FBL_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +/** Number of validity bytes required for logical block validity information */ +#define FBL_NUMBER_OF_VALIDITY_FLAG_BYTES (FBL_LENGTH_ALIGN_ROUND_UP(FBL_LBT_BLOCK_COUNT, 8u) / 8u) + +#if defined( FBL_USE_DUMMY_STATEMENT ) +# if !defined( V_ENABLE_USE_DUMMY_STATEMENT ) +# define V_ENABLE_USE_DUMMY_STATEMENT +# endif +#endif + +/*********************************************************************************************************************** + * State handling framework + **********************************************************************************************************************/ + +/* State array settings */ +#if defined( C_CPUTYPE_8BIT ) +typedef vuint8 tFblStateBitmap; +# define FBL_STATE_BITS 8u +# define kFblStateMaskNone 0x00u +# define kFblStateMaskAll 0xFFu +# define FblInvertStates(x) FblInvert8Bit(x) /* PRQA S 3453 */ /* MD_MSR_19.7 */ +#elif defined( C_CPUTYPE_16BIT ) +typedef vuint16 tFblStateBitmap; +# define FBL_STATE_BITS 16u +# define kFblStateMaskNone 0x0000u +# define kFblStateMaskAll 0xFFFFu +# define FblInvertStates(x) FblInvert16Bit(x) /* PRQA S 3453 */ /* MD_MSR_19.7 */ +#elif defined( C_CPUTYPE_32BIT ) || \ + defined( C_CPUTYPE_64BIT ) +typedef vuint32 tFblStateBitmap; +# define FBL_STATE_BITS 32u +# define kFblStateMaskNone 0x00000000ul +# define kFblStateMaskAll 0xFFFFFFFFul +# define FblInvertStates(x) FblInvert32Bit(x) /* PRQA S 3453 */ /* MD_MSR_19.7 */ +#else +# error "Bit count of CPU not supported." +#endif + +/* State mask build macros */ +/* PRQA S 3453 10 */ /* MD_MSR_19.7 */ +#define FBL_STATE_MASK(bit) ((tFblStateBitmap)(1ul << ((bit) % FBL_STATE_BITS))) +#define FBL_STATE_MULTIMASK(min, max) ((((kFblStateMaskAll) >> ((min) % FBL_STATE_BITS)) << ((min) % FBL_STATE_BITS)) ^ (((kFblStateMaskAll) >> (((max) + 1u) % FBL_STATE_BITS)) << (((max) + 1u) % FBL_STATE_BITS))) +#define FBL_STATE_MASKLONG(bit) (1ul << (bit)) +#define FBL_STATE_MULTIMASKLONG(min, max) ((((~0ul) >> (min)) << (min)) ^ (((max) < (STATE_BITS - 1u)) ? (((~0ul) >> ((max) + 1u)) << ((max) + 1u)) : 0ul)) +#define FBL_STATE_INDEX(bit) ((bit) / FBL_STATE_BITS) +#define FBL_STATE_SET(arr, bit) ((arr)[FBL_STATE_INDEX(bit)] |= FBL_STATE_MASK(bit)) +#define FBL_STATE_CLR(arr, bit) ((arr)[FBL_STATE_INDEX(bit)] &= FblInvertStates(FBL_STATE_MASK(bit))) +#define FBL_STATE_MULTICLR(arr, min, max) ((arr)[FBL_STATE_INDEX(min)] &= FblInvertStates(FBL_STATE_MULTIMASK((min), (max)))) +#define FBL_STATE_TEST(arr, bit) (((arr)[FBL_STATE_INDEX(bit)] & FBL_STATE_MASK(bit)) == FBL_STATE_MASK(bit)) + +/*********************************************************************************************************************** + * TYPEDEFS (basic types) + **********************************************************************************************************************/ +typedef vuint8 tFblErrorType; +typedef vuint16 tFblErrorCode; + +typedef vuint8 tFblResult; /**< FBL result codes */ +typedef vuint8 tFblProgStatus; /**< Status of reprogramming flag */ +typedef vuint8 tApplStatus; /**< Application valid status */ +typedef vuint8 tMagicFlag; /**< Application valid flag */ +typedef vuint8 tFlashStatus; /**< Flash erased status flag */ + +/* The below bootloader address types always define logical addresses. + * This is important for those platforms which provide a paged physical memory + * address space. For those platforms with linear physical address space, logical + * and physical addresses are identical. + */ +#if defined( C_CPUTYPE_8BIT ) && !defined( FBL_PROCESSOR_BANKED ) +typedef vuint16 FBL_ADDR_TYPE; +typedef vuint16 FBL_MEMSIZE_TYPE; +#else +typedef vuint32 FBL_ADDR_TYPE; +typedef vuint32 FBL_MEMSIZE_TYPE; +#endif + +typedef vuint8 FBL_MEMID_TYPE; + +typedef FBL_ADDR_TYPE tFblAddress; +typedef FBL_MEMSIZE_TYPE tFblLength; + +typedef FBL_ADDR_TYPE tMtabAddress; +typedef FBL_MEMSIZE_TYPE tMtabLength; +typedef FBL_MEMID_TYPE tMtabMemId; + +typedef vuint16 tChecksum; + +/*********************************************************************************************************************** + * TYPEDEFS (function pointers) + **********************************************************************************************************************/ + +/* Function pointer for FBL-exported functions */ +#if defined( FBL_ENABLE_BANKING ) +typedef FBL_CALL_TYPE void (*FBL_CALL_TYPE tExportFct)(void); /* PRQA S 0313 */ /* MD_FblDef_Export */ +#else +typedef MEMORY_FAR void (*tExportFct)(void); /* PRQA S 0313 */ /* MD_FblDef_Export */ +#endif /* FBL_ENABLE_BANKING */ + +typedef FBL_CALL_TYPE vuint8 (* tFblRealtimeFct)(void); + +/** Function pointer to read memory */ +typedef FBL_CALL_TYPE tFblLength (* tReadMemoryFct)(tFblAddress address, V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * buffer, tFblLength length); + +/*********************************************************************************************************************** + * TYPEDEFS (other) + **********************************************************************************************************************/ + +#if defined( FBL_ENABLE_DATA_PROCESSING ) +typedef struct tagProcParam +{ + V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * dataBuffer; + vuint16 dataLength; + V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * dataOutBuffer; + vuint16 dataOutLength; + vuint16 dataOutMaxLength; + vuint8 (* wdTriggerFct)(void); + vuint8 mode; +} tProcParam; +#endif + +#endif /* FBL_DEF_H */ + +/* Module specific MISRA deviations: + + MD_FblDef_Export: + Reason: Verify interface functions are stored as void pointers as actual type is not known at configuration time. + The software that uses these functions has to take care that a cast to the correct function type is being done before usage + Risk: The software that uses this elements does not correctly cast before usage. + Prevention: Review of implementations and testing of the functionality. + + MD_FblDef_Invert: + Reason: Usage of FblInvert.. macros implies usage of ~ operator and appropriate casts. This includes a cast from + negative integer to unsigned value. The integer is only an intermediate type that occurs because of + integer promotion while using ~ operator, though only a bit mask is operated on. + Risk: No risk. + Prevention: No prevention defined. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_DEF.H + **********************************************************************************************************************/ + diff --git a/Source/bsw/Fbl/fbl_diag.c b/Source/bsw/Fbl/fbl_diag.c new file mode 100644 index 0000000..f6fa0a7 --- /dev/null +++ b/Source/bsw/Fbl/fbl_diag.c @@ -0,0 +1,6492 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Diagnostic services supported in boot mode + * Declaration of functions, variables and constants + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2026 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2022-08-15 vistmo FBL-5514 Support Additional OTA functionality + * ESCAN00112435 The verification of the flash driver always fails + * ESCAN00112575 Ford tokens are wrongly rejected + * 05.01.00 2022-10-04 jschmitding FBL-5917 Make FBL SWDL 008 Compliant + * ESCAN00113919 No changes + * 05.01.01 2022-10-17 fmenke ESCAN00112879 Routine Check Application Validity is failing + * 05.01.02 2023-01-13 fmenke ESCAN00112890 DID D071 does not return the last successful token received + * ESCAN00113612 Server message ID check does not work correctly + * 05.02.00 2023-02-09 vistmo ESCAN00112972 Token with reserved bits set in SyncP is accepted + * ESCAN00113292 Wrong NRC for invalid RoutineControlOptionRecord on Set OTA Update + * ESCAN00113835 For token mode 5 reprogrammable keys are not extracted correctly + * ESCAN00113843 Token with "Has Key ID" bit set in SyncP is accepted + * ESCAN00113764 RID 7013 (token download) is always supported + * FBL-6438 No changes + * 05.02.01 2023-05-11 fmenke ESCAN00113831 Application validation fails in case of MAC update failure + * regardless logical block is optional or mandatory + * 05.03.00 2023-07-24 fmenke FBL-7335 Support new app signing handling + * 05.03.01 2023-08-31 lhopfhauer ESCAN00115494 Bootloader does not enter programming session when + * started from application + * 05.03.02 2024-07-16 erizk ESCAN00117344 Compiler error: FblRealTimeSupportVoid undefined, assuming + * extern returning int + * 05.03.03 2025-02-06 virchl ESCAN00118587 No Response for the Routine Control "Check Valid Application" 0x0304 + * 05.04.00 2025-02-28 jjohnson FBL-10065 Support App Signing Specification 2.1.3 + * 05.04.01 2025-06-10 jostravsky ESCAN00120315 Response to programming session request may be wrong + * 05.04.02 2025-07-08 visarcmijo ESCAN00119833 No NRC is returned to an RID 7013 requested without SBL activation + * 05.05.00 2025-09-01 fmenke FBL-11218 Add support for NXP DSP firmware update + * ESCAN00120917 SBL can be downloaded again and be executed without + * signature verification + * 05.06.00 2025-10-28 mpatil FBL-11690 Adding hooks and return values for callouts for Routine 7013 + * 05.07.00 2026-01-13 dganesh FBL-12162 Support Ford SWDL 008.5 + **********************************************************************************************************************/ + +#define FBL_DIAG_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" /* Common include files */ +#include "fbl_diag.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLDIAG_14229_FORD_VERSION != 0x0507u ) || \ + ( FBLDIAG_14229_FORD_RELEASE_VERSION != 0x00u ) +# error "Error in fbl_diag.c: Source and header file are inconsistent!" +#endif + +#if ( FBLDIAG_14229_FORD_VERSION != _FBLDIAG_OEM_VERSION ) || \ + ( FBLDIAG_14229_FORD_RELEASE_VERSION != _FBLDIAG_OEM_RELEASE_VERSION ) +# error "Error in fbl_diag.c: Source and v_ver.h are inconsistent!" +#endif + + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#define FBL_DIAG_IMPL_TYPE_OUTPUT 1 +#define FBL_DIAG_IMPL_TYPE_STATEBITMAP 2 +#define FBL_DIAG_IMPL_TYPE_SERVICEPROPERTY 3 +#define FBL_DIAG_IMPL_TYPE_SERVICELIST 4 +#define FBL_DIAG_IMPL_TYPE_SERVICELIST_HANDLER 5 +#define FBL_DIAG_IMPL_TYPE_SERVICELIST_ENUM 6 + +#define kDiagInitSequenceNum ((vuint8) 0x01u) +#define kDiagSegmentOutOfRange ((vuint8) 0xFFu) +#define kDiagSubparamMask ((vuint8) 0x7Fu) + +/* Transfer types (used with transferType) */ +# define DOWNLOAD_RAM ((vuint8) 0x10u) +# define DOWNLOAD_FLASH ((vuint8) 0x40u) + +/* Allow external definition of RAM state table usage */ +#if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) || \ + defined( FBL_DIAG_DISABLE_RAM_STATETABLES ) +#else +# define FBL_DIAG_ENABLE_RAM_STATETABLES +#endif +#define FBL_DIAG_STATE_ARRAYS +#if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) +# define FBL_DIAG_SERVICE_LIST_HANDLES +#endif + +#define FBL_DIAG_CHECK_LIST_HANDLES + +/* Maximum wait time for ECU reset request */ +#if !defined( kCwMaxWaitTimeEcuResetRequest ) +# define kFblDiagMaxWaitTimeEcuResetRequest kFblDiagTimeP2Star +#else +# define kFblDiagMaxWaitTimeEcuResetRequest (kCwMaxWaitTimeEcuResetRequest / FBL_REPEAT_CALL_CYCLE) +#endif + +/* Macros to access the ecuReset timer value */ +#define TimeoutEcuResetValue() ecuResetTimeout +#define DecTimeoutEcuResetValue() (ecuResetTimeout--) +#define ResetEcuResetTimeout() (ecuResetTimeout = (vuint16)(kFblDiagMaxWaitTimeEcuResetRequest/DIAG_CALL_CYCLE)) +#define StopEcuResetTimeout() (ecuResetTimeout = 0) + +#if defined( FBL_DIAG_ENABLE_SESSION_PARAMETERS ) +/* + * Negative return value for FblDiagGetSessionIndex(). This value has to be greater than 0x7F because the SPRMIB bit + * restricts the value range. + */ +# define kDiagSessionNotFound ((vuint8)0xFFu) +#endif /* FBL_DIAG_ENABLE_SESSION_PARAMETERS */ + +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) +/* Indicator for non-initialized security level index */ +# define kDiagInvalidSecLvlIdx ((vuint8)0xFFu) +#endif /* FBL_ENABLE_SEC_ADDITIONAL_LEVELS */ + +/* Return values for DID 0xD021 - Current Diagnostic Application */ +#define kFblDiagAppPbl 0x01u +#define kFblDiagAppSbl 0x02u +#define kFblDiagAppUnknown 0xFFu + +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +/* Define for customer for getting FESN */ +# if !defined( FblDiagGetFesn ) +# define FblDiagGetFesn() fblCommonData.FordElectronicSerialNumber +# endif + +/* Dynamic offset calculation macro */ +# define FblDiagCalcDynamicSyncPHeaderOffset(offset) ((offset) - FBL_DIAG_TOKEN_FESN_LEN) + +/* Defines for token parameter offset */ +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +# define FBL_DIAG_TOKEN_PARAM_SYNCP_ENC_DATA_OFFSET 0u +# define FBL_DIAG_TOKEN_PARAM_CPU_DEST_OFFSET 1u +# define FBL_DIAG_TOKEN_PARAM_SERVICE_TYPE_OFFSET 2u +# define FBL_DIAG_TOKEN_PARAM_CRYPTOTYPE_OFFSET 6u +# define FBL_DIAG_TOKEN_PARAM_PAYLOAD_SIZE_OFFSET 7u +# define FBL_DIAG_TOKEN_PARAM_FESN_OFFSET 11u +# define FBL_DIAG_TOKEN_PARAM_SERVERMESSAGEID_OFFSET(token) FblDiagIsTokenFesnRequired(token) ? 27u : FblDiagCalcDynamicSyncPHeaderOffset(27u) +# define FBL_DIAG_TOKEN_PARAM_CMD_OFFSET(token) FblDiagIsTokenFesnRequired(token) ? 35u : FblDiagCalcDynamicSyncPHeaderOffset(35u) +# define FBL_DIAG_TOKEN_PARAM_KEY_INDEX_OFFSET(token) FblDiagIsTokenFesnRequired(token) ? 36u : FblDiagCalcDynamicSyncPHeaderOffset(36u) +# define FBL_DIAG_TOKEN_PARAM_NAME_LENGTH_INDEX_OFFSET(token) FblDiagIsTokenFesnRequired(token) ? 37u : FblDiagCalcDynamicSyncPHeaderOffset(37u) +# define FBL_DIAG_TOKEN_PARAM_NAME_INDEX_OFFSET(token) FblDiagIsTokenFesnRequired(token) ? 38u : FblDiagCalcDynamicSyncPHeaderOffset(38u) +# define FBL_DIAG_TOKEN_PARAM_PAYLOAD_FESN_OFFSET(token) FblDiagIsTokenFesnRequired(token) ? 80u : FblDiagCalcDynamicSyncPHeaderOffset(80u) +# define FBL_DIAG_TOKEN_PARAM_DEVKEY_OFFSET(token) FblDiagIsTokenFesnRequired(token) ? 107u : FblDiagCalcDynamicSyncPHeaderOffset(107u) +# define FBL_DIAG_TOKEN_PARAM_PRODKEY_OFFSET(token) FblDiagIsTokenFesnRequired(token) ? 619u : FblDiagCalcDynamicSyncPHeaderOffset(619u) +# define FBL_DIAG_TOKEN_PARAM_TOKENKEY_OFFSET(token) FblDiagIsTokenFesnRequired(token) ? 1131u : FblDiagCalcDynamicSyncPHeaderOffset(1131u) + +/* Generic Defines for token handling */ +# define FBL_DIAG_TOKEN_RESBITS_REQ 0x03u +# define FBL_DIAG_TOKEN_KEYID_REQ 0x04u +# define FBL_DIAG_TOKEN_FESN_REQ 0x08u +# define FBL_DIAG_TOKEN_FESN_SHIFT 0x03u +# define FBL_DIAG_TOKEN_FESN_LEN 8u +# define FBL_DIAG_TOKEN_MSGID_REQ 0x10u +# define FBL_DIAG_TOKEN_MOD5_FESN_LEN 3u +# define FBL_DIAG_TOKEN_CPU_DEST 0u +# define FBL_DIAG_TOKEN_PROTOCOL_VERSION 0x20u +# define FBL_DIAG_TOKEN_PROTOCOL_VERSION_MASK 0xE0u +# define FBL_DIAG_TOKEN_NAME_LENGTH 0x0Bu +# define FBL_DIAG_TOKEN_NAME "APP_SIGN_SW" +# define FBL_DIAG_TOKEN_SERVICE_TYPE 0x110u +# define FBL_DIAG_TOKEN_CRYPTOTYPE 0x0Fu /* Only RSA supported */ +# define FBL_DIAG_TOKEN_PAYLOAD_SIZE_MODE0_4 43u +# define FBL_DIAG_TOKEN_PAYLOAD_SIZE_MODE5 1606u + +# define FBL_DIAG_TOKEN_KEY_INDEX_0 0u /* Used for mode 5 tokens */ +# define FBL_DIAG_TOKEN_KEY_INDEX_1 1u /* Used for mode 0-4 tokens */ +# define FBL_DIAG_TOKEN_KEY_EXP_MAX 256u + +/* Defines Token Handling Commands */ +# define FBL_DIAG_TOKEN_CMD_REVERTPROD 0u +# define FBL_DIAG_TOKEN_CMD_USEDEVPERM 1u +# define FBL_DIAG_TOKEN_CMD_USEDEVTEMP 2u +# define FBL_DIAG_TOKEN_CMD_USEDEVDATE 3u +# define FBL_DIAG_TOKEN_CMD_USEDEVIGNI 4u +# define FBL_DIAG_TOKEN_CMD_PROGKEY 5u + +/* Defines Token Handling Macro */ +# define FblDiagIsTokenProtocolVersionCorrect(token) (((token)[FBL_DIAG_TOKEN_PARAM_SYNCP_ENC_DATA_OFFSET] & FBL_DIAG_TOKEN_PROTOCOL_VERSION_MASK) == FBL_DIAG_TOKEN_PROTOCOL_VERSION) +# define FblDiagIsTokenKeyIDRequired(token) (((token)[FBL_DIAG_TOKEN_PARAM_SYNCP_ENC_DATA_OFFSET] & FBL_DIAG_TOKEN_KEYID_REQ) == FBL_DIAG_TOKEN_KEYID_REQ) +# define FblDiagIsTokenMsgIDRequired(token) (((token)[FBL_DIAG_TOKEN_PARAM_SYNCP_ENC_DATA_OFFSET] & FBL_DIAG_TOKEN_MSGID_REQ) == FBL_DIAG_TOKEN_MSGID_REQ) +# define FblDiagIsTokenFesnRequired(token) (((token)[FBL_DIAG_TOKEN_PARAM_SYNCP_ENC_DATA_OFFSET] & FBL_DIAG_TOKEN_FESN_REQ) == FBL_DIAG_TOKEN_FESN_REQ) +# define FblDiagIsTokenReserverdBitsSet(token) (((token)[FBL_DIAG_TOKEN_PARAM_SYNCP_ENC_DATA_OFFSET] & FBL_DIAG_TOKEN_RESBITS_REQ) != 0u) +# define FblDiagGetTokenCPUDestination(token) ((token)[FBL_DIAG_TOKEN_PARAM_CPU_DEST_OFFSET]) +# define FblDiagGetTokenServiceType(token) (((vuint16)(token)[FBL_DIAG_TOKEN_PARAM_SERVICE_TYPE_OFFSET] << 8u) | \ + (vuint16)(token)[FBL_DIAG_TOKEN_PARAM_SERVICE_TYPE_OFFSET + 1u] ) +# define FblDiagGetTokenCryptoType(token) ((token)[FBL_DIAG_TOKEN_PARAM_CRYPTOTYPE_OFFSET]) +# define FblDiagGetTokenCommandType(token) ((token)[FBL_DIAG_TOKEN_PARAM_CMD_OFFSET(token)]) +# define FblDiagGetTokenPayloadSize(token) (((vuint32)(token)[FBL_DIAG_TOKEN_PARAM_PAYLOAD_SIZE_OFFSET] << 24u) | \ + ((vuint32)(token)[FBL_DIAG_TOKEN_PARAM_PAYLOAD_SIZE_OFFSET + 1u] << 16u) | \ + ((vuint32)(token)[FBL_DIAG_TOKEN_PARAM_PAYLOAD_SIZE_OFFSET + 2u] << 8u) | \ + (vuint32)(token)[FBL_DIAG_TOKEN_PARAM_PAYLOAD_SIZE_OFFSET + 3u]) +# define FblDiagGetTokenTokenNameLength(token) ((vuint8)(token)[FBL_DIAG_TOKEN_PARAM_NAME_LENGTH_INDEX_OFFSET(token)]) +# define FblDiagGetTokenTokenName(token) (&(token)[FBL_DIAG_TOKEN_PARAM_NAME_INDEX_OFFSET(token)]) +# define FblDiagGetTokenFesn(token) (&(token)[FBL_DIAG_TOKEN_PARAM_FESN_OFFSET]) +# define FblDiagGetTokenServerMsgIdPtr(token) (&(token)[FBL_DIAG_TOKEN_PARAM_SERVERMESSAGEID_OFFSET(token)]) +# define FblDiagGetTokenPayloadFesn(token) (&(token)[FBL_DIAG_TOKEN_PARAM_PAYLOAD_FESN_OFFSET(token)]) +# define FblDiagGetTokenKeyIndex(token) ((token)[FBL_DIAG_TOKEN_PARAM_KEY_INDEX_OFFSET(token)]) +/* Define to get the key index from the token */ +# define FblDiagGetTokenDevKeyIndex(token) (&(token)[FBL_DIAG_TOKEN_PARAM_DEVKEY_OFFSET(token)]) +# define FblDiagGetTokenProdKeyIndex(token) (&(token)[FBL_DIAG_TOKEN_PARAM_PRODKEY_OFFSET(token)]) +# define FblDiagGetTokenTokenKeyIndex(token) (&(token)[FBL_DIAG_TOKEN_PARAM_TOKENKEY_OFFSET(token)]) + +# endif /* FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING */ +#endif /* SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC */ + + +/*****************************************************************************/ +/* State handling ************************************************************/ +/*****************************************************************************/ + +#define SPLIT_SHORT(id) ((vuint8)(((id) >> 8u) & 0xFFu)), ((vuint8)((id) & 0xFFu)) + +# define STATE_CHECK_COUNT 2u +# define STATE_ADDCLR_COUNT 3u +#define STATE_COUNT (STATE_CHECK_COUNT + STATE_ADDCLR_COUNT) + +/* State array build macros */ +#define STATE_ARRAYENTRY(mask, idx) ((tStateBitmap)(((mask) >> ((idx) * STATE_BITS)) & kDiagStateMaskAll)) +#if ( STATECHECK_ARRAYSIZE == 1u ) +# define STATE_BUILDARRAYENTRIES(mask) STATE_ARRAYENTRY(mask, 0u) +#endif +#if ( STATECHECK_ARRAYSIZE == 2u ) +# define STATE_BUILDARRAYENTRIES(mask) STATE_ARRAYENTRY(mask, 0u), STATE_ARRAYENTRY(mask, 1u) +#endif +#if ( STATECHECK_ARRAYSIZE == 3u ) +# define STATE_BUILDARRAYENTRIES(mask) STATE_ARRAYENTRY(mask, 0u), STATE_ARRAYENTRY(mask, 1u), STATE_ARRAYENTRY(mask, 2u) +#endif +#if ( STATECHECK_ARRAYSIZE == 4u ) +# define STATE_BUILDARRAYENTRIES(mask) STATE_ARRAYENTRY(mask, 0u), STATE_ARRAYENTRY(mask, 1u), STATE_ARRAYENTRY(mask, 2u), STATE_ARRAYENTRY(mask, 3u) +#endif +#if ( STATECHECK_ARRAYSIZE > 4u ) +# error "Invalid array size for state check!" +#endif + +#define STATE_BUILDARRAY(mask) { STATE_BUILDARRAYENTRIES(mask) } + +/* State masks and access macros */ +#define kDiagStateMaskAllLong STATE_MULTIMASKLONG(0u, ((STATECHECK_ARRAYSIZE * STATE_BITS) - 1u)) + +#define kDiagStateMask(state) STATE_MASKLONG(state) + +#define SetDiagState(state) STATE_SET(fblStates, state) +#define ClrDiagState(state) STATE_CLR(fblStates, state) + +#define kDiagStateNone (0x00uL) + +#define ClrDiagSession() STATE_MULTICLR(fblStates, kDiagStateIdxSessionDefault, kDiagStateIdxSessionProgramming) + +#define kDiagStateSessionDefault kDiagStateMask(kDiagStateIdxSessionDefault) +#define SetDiagDefaultDiagSession() { \ + ClrDiagSession(); \ + SetDiagState(kDiagStateIdxSessionDefault); \ + SetDiagSessionType(kDiagSubDefaultSession); \ + } + +#define kDiagStateSessionProgramming kDiagStateMask(kDiagStateIdxSessionProgramming) +#define SetDiagProgrammingSession() { \ + ClrDiagSession(); \ + SetDiagState(kDiagStateIdxSessionProgramming); \ + SetDiagSessionType(kDiagSubProgrammingSession); \ + } + +#define kDiagStateSessionDefaultProgramming (kDiagStateSessionDefault | kDiagStateSessionProgramming) +#define kDiagStateSessionAll kDiagStateSessionDefaultProgramming + +#define kDiagStateSecurityKey01 kDiagStateMask(kDiagStateIdxSecurityKey01) +#define GetSecurityKeyAllowed() GetDiagState(kDiagStateIdxSecurityKey01) +#define SetSecurityKeyAllowed() SetDiagState(kDiagStateIdxSecurityKey01) +#define ClrSecurityKeyAllowed() ClrDiagState(kDiagStateIdxSecurityKey01) + +#define kDiagStateSecurityKeyAll (kDiagStateSecurityKey01) + +#define kDiagStateSecurityAccess01 kDiagStateMask(kDiagStateIdxSecurityAccess01) +#define GetSecurityAccess01() GetDiagState(kDiagStateIdxSecurityAccess01) +#define SetSecurityAccess01() SetDiagState(kDiagStateIdxSecurityAccess01) +#define ClrSecurityAccess01() ClrDiagState(kDiagStateIdxSecurityAccess01) +#define SetCurrentSecLvl(secLvl) diagCurrentSecLvl = (secLvl) + +#define kDiagStateSecurityAccessAll (kDiagStateSecurityAccess01) + +/* Security access states are used in state machine definition */ +#define kDiagStateSecurityAccessDelay01 kDiagStateNone + +#define kDiagStateSecurityAccessDelayAll (kDiagStateSecurityAccessDelay01) +#if !defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) +# define kServiceCheckListSubFctSecCheck kServiceCheckListSubFctCheck +#endif + +#define kDiagStateFunctionalRequest kDiagStateMask(kDiagStateIdxFunctionalRequest) +#define GetFunctionalRequest() GetDiagState(kDiagStateIdxFunctionalRequest) +#define SetFunctionalRequest() SetDiagState(kDiagStateIdxFunctionalRequest) +#define ClrFunctionalRequest() ClrDiagState(kDiagStateIdxFunctionalRequest) + + +#define kDiagStateServiceInProgress kDiagStateMask(kDiagStateIdxServiceInProgress) +#define SetServiceInProgress() SetDiagState(kDiagStateIdxServiceInProgress) +#define ClrServiceInProgress() ClrDiagState(kDiagStateIdxServiceInProgress) + +#define kDiagStateTpConfirmationFlag kDiagStateMask(kDiagStateIdxTpConfirmationFlag) +#define GetTpConfirmationFlag() GetDiagState(kDiagStateIdxTpConfirmationFlag) +#define SetTpConfirmationFlag() SetDiagState(kDiagStateIdxTpConfirmationFlag) +#define ClrTpConfirmationFlag() ClrDiagState(kDiagStateIdxTpConfirmationFlag) + +#define kDiagStateDiagIndication kDiagStateMask(kDiagStateIdxDiagIndication) +#define GetDiagIndication() GetDiagState(kDiagStateIdxDiagIndication) +#define SetDiagIndication() SetDiagState(kDiagStateIdxDiagIndication) +#define ClrDiagIndication() ClrDiagState(kDiagStateIdxDiagIndication) + +#define kDiagStateSuppressPosRspMsg kDiagStateMask(kDiagStateIdxSuppressPosRspMsg) +#define GetSuppressPosRspMsg() GetDiagState(kDiagStateIdxSuppressPosRspMsg) +#define SetSuppressPosRspMsg() SetDiagState(kDiagStateIdxSuppressPosRspMsg) +#define ClrSuppressPosRspMsg() ClrDiagState(kDiagStateIdxSuppressPosRspMsg) + +#define kDiagStateResponseProcessing kDiagStateMask(kDiagStateIdxResponseProcessing) +#define SetResponseProcessing() SetDiagState(kDiagStateIdxResponseProcessing) +#define ClrResponseProcessing() ClrDiagState(kDiagStateIdxResponseProcessing) + +#define kDiagStateRcrRpInProgress kDiagStateMask(kDiagStateIdxRcrRpInProgress) +#define SetRcrRpInProgress() SetDiagState(kDiagStateIdxRcrRpInProgress) +#define ClrRcrRpInProgress() ClrDiagState(kDiagStateIdxRcrRpInProgress) + +#define kDiagStateWaitForRcrRpConf kDiagStateMask(kDiagStateIdxWaitForRcrRpConf) +#define GetWaitForRcrRpConf() GetDiagState(kDiagStateIdxWaitForRcrRpConf) +#define SetWaitForRcrRpConf() SetDiagState(kDiagStateIdxWaitForRcrRpConf) +#define ClrWaitForRcrRpConf() ClrDiagState(kDiagStateIdxWaitForRcrRpConf) + +#define kDiagStateMemDriverInitialized kDiagStateMask(kDiagStateIdxMemDriverInitialized) +#define SetMemDriverInitialized() SetDiagState(kDiagStateIdxMemDriverInitialized) +#define ClrMemDriverInitialized() ClrDiagState(kDiagStateIdxMemDriverInitialized) + +#define kDiagStateTransferDataAllowed kDiagStateMask(kDiagStateIdxTransferDataAllowed) +#define GetTransferDataAllowed() GetDiagState(kDiagStateIdxTransferDataAllowed) +#define SetTransferDataAllowed() SetDiagState(kDiagStateIdxTransferDataAllowed) +#define ClrTransferDataAllowed() ClrDiagState(kDiagStateIdxTransferDataAllowed) + +#define kDiagStateTransferDataSucceeded kDiagStateMask(kDiagStateIdxTransferDataSucceeded) +#define GetTransferDataSucceeded() GetDiagState(kDiagStateIdxTransferDataSucceeded) +#define SetTransferDataSucceeded() SetDiagState(kDiagStateIdxTransferDataSucceeded) +#define ClrTransferDataSucceeded() ClrDiagState(kDiagStateIdxTransferDataSucceeded) + +#define kDiagStateFirstDownloadReq kDiagStateMask(kDiagStateIdxFirstDownloadReq) +#define GetFirstDownloadReq() GetDiagState(kDiagStateIdxFirstDownloadReq) +#define SetFirstDownloadReq() SetDiagState(kDiagStateIdxFirstDownloadReq) +#define ClrFirstDownloadReq() ClrDiagState(kDiagStateIdxFirstDownloadReq) + +#define kDiagStateEraseMemorySucceeded kDiagStateMask(kDiagStateIdxEraseMemorySucceeded) +#define GetEraseMemorySucceeded() GetDiagState(kDiagStateIdxEraseMemorySucceeded) +#define SetEraseMemorySucceeded() SetDiagState(kDiagStateIdxEraseMemorySucceeded) +#define ClrEraseMemorySucceeded() ClrDiagState(kDiagStateIdxEraseMemorySucceeded) + +#if defined( FBL_DIAG_ENABLE_UPLOAD ) +#define kDiagStateTransferDataUpload kDiagStateMask(kDiagStateIdxTransferDataUpload) +#define GetTransferDataUpload() GetDiagState(kDiagStateIdxTransferDataUpload) +#define SetTransferDataUpload() SetDiagState(kDiagStateIdxTransferDataUpload) +#define ClrTransferDataUpload() ClrDiagState(kDiagStateIdxTransferDataUpload) +#endif /* FBL_DIAG_ENABLE_UPLOAD */ + + +#define kDiagStateResetMsgConfirmed kDiagStateMask(kDiagStateIdxResetMsgConfirmed) +#define GetResetMsgConfirmed() GetDiagState(kDiagStateIdxResetMsgConfirmed) +#define SetResetMsgConfirmed() SetDiagState(kDiagStateIdxResetMsgConfirmed) +#define ClrResetMsgConfirmed() ClrDiagState(kDiagStateIdxResetMsgConfirmed) + +#define kDiagStateEcuResetFctFinished kDiagStateMask(kDiagStateIdxEcuResetFctFinished) +#define GetEcuResetFctFinished() GetDiagState(kDiagStateIdxEcuResetFctFinished) +#define SetEcuResetFctFinished() SetDiagState(kDiagStateIdxEcuResetFctFinished) +#define ClrEcuResetFctFinished() ClrDiagState(kDiagStateIdxEcuResetFctFinished) + +#define kDiagStateWaitEcuReset kDiagStateMask(kDiagStateIdxWaitEcuReset) +#define SetWaitEcuReset() { \ + SetDiagState(kDiagStateIdxWaitEcuReset); \ + ResetEcuResetTimeout(); \ + } +#define ClrWaitEcuReset() { \ + ClrDiagState(kDiagStateWaitEcuReset); \ + ClrDiagState(kDiagStateResetMsgConfirmed); \ + ClrDiagState(kDiagStateEcuResetFctFinished); \ + StopEcuResetTimeout(); \ + } + +#define kDiagStateDiagBufferLocked kDiagStateMask(kDiagStateIdxDiagBufferLocked) +#define SetDiagBufferLocked() SetDiagState(kDiagStateIdxDiagBufferLocked) +#define ClrDiagBufferLocked() ClrDiagState(kDiagStateIdxDiagBufferLocked) + + +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# define kDiagStateDiagDevelopmentKey kDiagStateMask(kDiagStateIdxDiagDevelopmentKey) +# define SetDiagDevelopmentKey() SetDiagState(kDiagStateIdxDiagDevelopmentKey) +# define ClrDiagDevelopmentKey() ClrDiagState(kDiagStateIdxDiagDevelopmentKey) +#endif + +#define kDiagStateProcessingDone kDiagStateMask(kDiagStateIdxProcessingDone) +#define GetProcessingDone() GetDiagState(kDiagStateIdxProcessingDone) +#define SetProcessingDone() SetDiagState(kDiagStateIdxProcessingDone) +#define ClrProcessingDone() ClrDiagState(kDiagStateIdxProcessingDone) + +#define kDiagStateLockedByInit kDiagStateMask(kDiagStateIdxLockedByInit) +#define GetLockedByInit() GetDiagState(kDiagStateIdxLockedByInit) +#define SetLockedByInit() SetDiagState(kDiagStateIdxLockedByInit) +#define ClrLockedByInit() ClrDiagState(kDiagStateIdxLockedByInit) + +#if defined( FBL_DIAG_ENABLE_SESSION_PARAMETERS ) +# define SetDiagSessionType(type) (currentDiagSessionIndex = FblDiagGetSessionIndex(type)) +# define GetDiagSessionType() (kDiagSessionParameters[currentDiagSessionIndex].sessionType) +# define GetDiagSessionTimingP2() (kDiagSessionParameters[currentDiagSessionIndex].p2Timing) +# define GetDiagSessionTimingP2Star() (kDiagSessionParameters[currentDiagSessionIndex].p2StarTiming) +#else +# define SetDiagSessionType(type) (currentDiagSessionType = (type)) +# define GetDiagSessionType() (currentDiagSessionType) +# define GetDiagSessionTimingP2() (kDiagSessionTimingP2) +# define GetDiagSessionTimingP2Star() (kDiagSessionTimingP2Star) +#endif /* FBL_DIAG_ENABLE_SESSION_PARAMETERS */ + + +/* Helper macro to get number of array entries */ +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +/*****************************************************************************/ +/* Definitions for the state machine *****************************************/ +/*****************************************************************************/ + +#define kDiagRqlUnlimited (0xFFFFu) + +#define kDiagNoSubServices (V_MEMROM1 tServiceList V_MEMROM2 V_MEMROM3 *)V_NULL +#define kDiagNoCheckList (tServiceCheckList *)V_NULL + +#define kDiagNoServiceProp (ptServiceProp)V_NULL + +/* Typedefs and structures for internal use **********************************/ + +/* State machine */ +#if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) +typedef V_MEMRAM1 struct tagServiceProp V_MEMRAM2 V_MEMRAM3 * ptServiceProp; +#else +typedef V_MEMROM1 struct tagServiceProp V_MEMROM2 V_MEMROM3 * ptServiceProp; +#endif + +typedef struct tagServiceCheck +{ + vuint8 checkHandlerIdx; + vuint8 NRC; + vuint8 errorHandlerIdx; +} tServiceCheck; + +typedef struct +{ + V_MEMROM1 struct tagServiceCheck V_MEMROM2 V_MEMROM3 * list; + vuint8 count; +} tServiceCheckList; + +typedef struct tagServiceList +{ + ptServiceProp list; + tCwDataLengthType bufPos; + vuint8 idSize; + vuint8 count; +} tServiceList; + +#if defined( FBL_DIAG_STATE_ARRAYS ) +# define FBL_DIAG_STATE_SET 0 +# define FBL_DIAG_STATE_UNSET 1 +# define FBL_DIAG_STATE_ADD 2 +# define FBL_DIAG_STATE_CLR 3 +# define FBL_DIAG_STATE_CLRFAIL 4 + +# define stateSet states[FBL_DIAG_STATE_SET] +# define stateUnset states[FBL_DIAG_STATE_UNSET] +# define stateAdd states[FBL_DIAG_STATE_ADD] +# define stateClr states[FBL_DIAG_STATE_CLR] +# define stateClrFail states[FBL_DIAG_STATE_CLRFAIL] +#endif + +typedef struct tagServiceProp +{ + V_MEMROM1 struct tagServiceList V_MEMROM2 V_MEMROM3 * subServices; + V_MEMROM1 vuint8 V_MEMROM2 V_MEMROM3 * serviceId; +#if defined( FBL_DIAG_CHECK_LIST_HANDLES ) +#else + V_MEMROM1 tServiceCheckList V_MEMROM2 V_MEMROM3 * checks; +#endif + vuint16 minLength; + vuint16 maxLength; +#if defined( FBL_DIAG_STATE_ARRAYS ) && \ + ( STATE_COUNT > 0 ) + tStateBitmap states[STATE_COUNT][STATECHECK_ARRAYSIZE]; +#else + tStateBitmap stateSet[STATECHECK_ARRAYSIZE]; + tStateBitmap stateUnset[STATECHECK_ARRAYSIZE]; + tStateBitmap stateAdd[STATECHECK_ARRAYSIZE]; + tStateBitmap stateClr[STATECHECK_ARRAYSIZE]; + tStateBitmap stateClrFail[STATECHECK_ARRAYSIZE]; +#endif + vuint8 mainHandlerIdx; +#if defined( FBL_DIAG_CHECK_LIST_HANDLES ) + vuint8 checkListIdx; +#endif +} tServiceProp; + +#if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) +typedef struct +{ +# if defined( FBL_DIAG_SERVICE_LIST_HANDLES ) +# else + V_MEMROM1 struct tagServiceList V_MEMROM2 V_MEMROM3 * subServices; +# endif + V_MEMROM1 vuint8 V_MEMROM2 V_MEMROM3 * serviceId; +# if defined( FBL_DIAG_CHECK_LIST_HANDLES ) +# else + V_MEMROM1 tServiceCheckList V_MEMROM2 V_MEMROM3 * checks; +# endif + vuint16 minLength; + vuint16 maxLength; + vuint8 stateUsage; + vuint8 mainHandlerIdx; +# if defined( FBL_DIAG_CHECK_LIST_HANDLES ) + vuint8 checkListIdx; +# endif +# if defined( FBL_DIAG_SERVICE_LIST_HANDLES ) + vuint8 subServicesHandler; +# endif +} tServicePropROM; +#endif + +#define FBL_DIAG_CHECK_HANDLER(name) tFblResult name( const V_MEMRAM1 tServiceProp V_MEMRAM2 V_MEMRAM3 * properties, \ + V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * pbDiagBuffer, \ + tCwDataLengthType length, tCwDataLengthType position, \ + V_MEMRAM1 ptServiceProp V_MEMRAM2 V_MEMRAM3 * result ) +#define FBL_DIAG_ERROR_HANDLER(name) tFblResult name( const V_MEMRAM1 tServiceProp V_MEMRAM2 V_MEMRAM3 *properties, \ + V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * pbDiagBuffer, \ + tCwDataLengthType diagReqDataLen ) +#define FBL_DIAG_MAIN_HANDLER(name) tFblResult name( V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * pbDiagBuffer, \ + tCwDataLengthType diagReqDataLen ) + +typedef FBL_DIAG_CHECK_HANDLER((*tFblDiagCheckHandler)); +typedef FBL_DIAG_ERROR_HANDLER((*tFblDiagErrorHandler)); +typedef FBL_DIAG_MAIN_HANDLER((*tFblDiagMainHandler)); + +/* Check handler */ + +#if defined( FBL_DIAG_ENABLE_SESSION_PARAMETERS ) +typedef struct +{ + vuint8 sessionType; /* Diagnostic Session Type */ + vuint16 p2Timing; /* P2 Timing Value [ms] */ + vuint16 p2StarTiming; /* P2* Timing Value [ms] / 10 */ +} tDiagSessionParameters; +#endif /* FBL_ENABLE_SESSION_PARAMETERS */ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBLDIAG_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* Data buffer for diagnostic data */ +V_MEMRAM0 V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * V_MEMRAM1 V_MEMRAM2 DiagBuffer; +V_MEMRAM0 V_MEMRAM1 vuint8 V_MEMRAM2 diagErrorCode; /* Diagnostic error code */ +V_MEMRAM0 V_MEMRAM1 tCwDataLengthType V_MEMRAM2 DiagDataLength; /* Stores number of received data */ +V_MEMRAM0 V_MEMRAM1_NEAR vuint16 V_MEMRAM2_NEAR P2Timeout; /* P2 timeout value */ +V_MEMRAM0 V_MEMRAM1_NEAR vuint16 V_MEMRAM2_NEAR testerPresentTimeout; /* Timer value for TesterPresent timeout */ +V_MEMRAM0 V_MEMRAM1 vuint8 V_MEMRAM2 diagResponseFlag; /* Flag to enable/suppress diagnostic response */ +V_MEMRAM0 V_MEMRAM1_NEAR vuint8 V_MEMRAM2_NEAR diagServiceCurrent; /* Currently processed diag service ID */ +V_MEMRAM0 V_MEMRAM1_NEAR tStateBitmap V_MEMRAM2_NEAR fblStates[STATE_INDEX(kDiagNumberOfStates - 1u) + 1u]; /* State bitmap array */ +V_MEMRAM0 V_MEMRAM1 vuint8 V_MEMRAM2 diagCurrentSecLvl; /* Current security level */ +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) +V_MEMRAM0 V_MEMRAM1 vuint8 V_MEMRAM2 diagRequestedSecLvlIdx; /* Table index of currently requested security level */ +#endif +#if defined( FBL_ENABLE_SLEEPMODE ) +V_MEMRAM0 V_MEMRAM1 vuint32 V_MEMRAM2 sleepCounter; /* Counter, determines when to sleep */ +#endif + +#if defined( FBL_ENABLE_DEBUG_STATUS ) +/* Variables for error status reporting */ /* PRQA S 1514 6 */ /* MD_FblDiag_1514 */ +V_MEMRAM0 V_MEMRAM1 vuint16 V_MEMRAM2 errStatErrorCode; /* Error status */ +V_MEMRAM0 V_MEMRAM1 vuint16 V_MEMRAM2 errStatFblStates; /* FBL state flag */ +V_MEMRAM0 V_MEMRAM1 vuint8 V_MEMRAM2 errStatLastServiceId; /* Last received service identifier */ +V_MEMRAM0 V_MEMRAM1 vuint8 V_MEMRAM2 errStatFlashDrvVersion[3]; /* Flash driver version information */ +V_MEMRAM0 V_MEMRAM1 vuint16 V_MEMRAM2 errStatFlashDrvErrorCode; /* Flash driver error code */ +V_MEMRAM0 V_MEMRAM1 tBlockDescriptor V_MEMRAM2 errStatDescriptor; /* Error status block descriptor */ +#endif + +#define FBLDIAG_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) + +# define FBLDIAG_START_SEC_CONST +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +V_MEMROM0 V_MEMROM1 tDiagSecAccessParams V_MEMROM2 kDiagSecAccessParams[] = +{ + { kDiagSecLevelFlash, kSecSeedLength, kSecKeyLength } +}; + +# define FBLDIAG_STOP_SEC_CONST +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBL_ENABLE_SEC_ADDITIONAL_LEVELS */ + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +#define FBLDIAG_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* PRQA S 3218 TAG_FblDiag_3218_1 */ /* MD_FblDiag_3218 */ + +/* Temporary data used during download in TransferData */ +V_MEMRAM0 static V_MEMRAM1 tDiagSegmentList V_MEMRAM2 diagSegmentList; /* Complete list of download segments */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 currentSegment; /* Index of currently processed download segment */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 currentBlock; /* Index of currently processed download block */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 lastErasedBlock; +V_MEMRAM0 static V_MEMRAM1 tBlockHeader V_MEMRAM2 blockHeader[FBL_LBT_BLOCK_COUNT]; /* Structure with runtime information about logical blocks */ +V_MEMRAM0 static V_MEMRAM1 tFblDiagAddr V_MEMRAM2 transferAddress; /* Actual transfer address */ +V_MEMRAM0 static V_MEMRAM1 tFblLength V_MEMRAM2 transferRemainder; /* Number of remaining transfer bytes */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 transferType; /* Download into RAM/Flash or upload */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 expectedSequenceCnt; /* Block sequence counter */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 currentSequenceCnt; /* Current Block sequence counter */ +V_MEMRAM0 static V_MEMRAM1_NEAR vuint16 V_MEMRAM2_NEAR ecuResetTimeout; /* Timeout for EcuReset request (CW) */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 dataFormatId; /* Combined encryption and compression method */ +V_MEMRAM0 static V_MEMRAM1 tFblLength V_MEMRAM2 totalProgramLength; /* Total number of programmed bytes */ + +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 diagRequestedSecLvl; /* Currently requested security level (via seed) */ +#endif + +#if defined( FBL_DIAG_ENABLE_SESSION_PARAMETERS ) +/* Internal index of the active diagnostic session (table kDiagSessionParameters) */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 currentDiagSessionIndex; +#else +/* Type of the active diagnostic session according to the SessionControl sub-function parameter */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 currentDiagSessionType; +#endif + +#define FBLDIAG_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLDIAG_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* State check masks */ +V_MEMROM0 static V_MEMROM1 tStateBitmap V_MEMROM2 kDiagStateMaskSessions[STATECHECK_ARRAYSIZE] = STATE_BUILDARRAY(kDiagStateSessionAll); +V_MEMROM0 static V_MEMROM1 tStateBitmap V_MEMROM2 kDiagStateMaskFunctional[STATECHECK_ARRAYSIZE] = STATE_BUILDARRAY(kDiagStateFunctionalRequest); +V_MEMROM0 static V_MEMROM1 tStateBitmap V_MEMROM2 kDiagStateMaskSecurityAccess[STATECHECK_ARRAYSIZE] = STATE_BUILDARRAY(kDiagStateSecurityAccess01); +V_MEMROM0 static V_MEMROM1 tStateBitmap V_MEMROM2 kDiagStateMaskSequenceError[STATECHECK_ARRAYSIZE] = STATE_BUILDARRAY(kDiagStateSecurityKey01 | kDiagStateTransferDataAllowed); + /* PRQA S 2790, 3494 1 */ /* MD_FblDiag_2790_kDiagStateMaskAllLong, MD_FblDiag_ConstValue */ +V_MEMROM0 static V_MEMROM1 tStateBitmap V_MEMROM2 kDiagStateMaskGeneralConditions[STATECHECK_ARRAYSIZE] = STATE_BUILDARRAY(kDiagStateMaskAllLong); +V_MEMROM0 static V_MEMROM1 tStateBitmap V_MEMROM2 kDiagStateMaskReset[STATECHECK_ARRAYSIZE] = STATE_BUILDARRAY(kDiagStateNone); + +#define FBLDIAG_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLDIAG_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* Concatenation of service properties */ +V_MEMRAM0 static V_MEMRAM1_NEAR tServiceProp V_MEMRAM2_NEAR serviceProperties; +/* Result of service execution */ +V_MEMRAM0 static V_MEMRAM1_NEAR tFblResult V_MEMRAM2_NEAR serviceResult; + +#if defined( FBL_DIAG_ENABLE_UPLOAD ) +/* maxNumberOfBlockLength is a 12 bit value that determines the maximum size */ +/* of a block of data that can be transferred */ +V_MEMRAM0 static V_MEMRAM1 vuint16 V_MEMRAM2 maxNumberOfBlockLength; +#endif /* FBL_DIAG_ENABLE_UPLOAD */ + +#define FBLDIAG_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLDIAG_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBL_DIAG_ENABLE_SESSION_PARAMETERS ) +V_MEMROM0 static V_MEMROM1 tDiagSessionParameters V_MEMROM2 kDiagSessionParameters[] = +{ + /* Default Session */ + { kDiagSubDefaultSession, 50, 500 }, + /* Programming Session */ + { kDiagSubProgrammingSession, kDiagSessionTimingP2, kDiagSessionTimingP2Star } +}; + +V_MEMROM0 static V_MEMROM1 vuint8 V_MEMROM2 kDiagNumberOfSessions = sizeof(kDiagSessionParameters) / sizeof(tDiagSessionParameters); +#endif /* FBL_DIAG_ENABLE_SESSION_PARAMETERS */ + +#define FBLDIAG_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +/* SHA256 + CRC16 */ +# define FBL_DIAG_VERIFY_BUFFER_SIZE (SEC_VERIFY_CLASS_DDD_DIGEST_SIZE + SEC_SIZE_CHECKSUM_CRC) +# define FBL_DIAG_CRC_OFFSET SEC_VERIFY_CLASS_DDD_CHECKSUM_OFFSET +#else +/* CRC16 */ +# define FBL_DIAG_VERIFY_BUFFER_SIZE (SEC_VERIFY_CLASS_DDD_DIGEST_SIZE) +# define FBL_DIAG_CRC_OFFSET 0u +#endif + +#define FBLDIAG_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +/* Parameters for pipelined signature calculation */ +V_MEMRAM0 static V_MEMRAM1 SecM_SignatureParamType V_MEMRAM2 pipeVerifyParam; +# if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +V_MEMRAM0 static V_MEMRAM1 SecM_SignatureParamType V_MEMRAM2 pipeVerifyParamCrc; +# endif +/* Used to store hash value and optionally security module context */ /* PRQA S 3678 1 */ /* MD_FblDiag_3678 */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 pipeVerifyBuf[FBL_DIAG_VERIFY_BUFFER_SIZE]; +V_MEMRAM0 static V_MEMRAM1 vuint32 V_MEMRAM2 pipeVerifyLength; +# if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +V_MEMRAM0 static V_MEMRAM1 SecM_CRCParamType V_MEMRAM2 pipeVerifyCrc; +V_MEMRAM0 static V_MEMRAM1 vuint32 V_MEMRAM2 pipeVerifyLengthCrc; +# endif +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +#if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) +V_MEMRAM0 static V_MEMRAM1 SecM_VerifyParamType V_MEMRAM2 verifyParam; +V_MEMRAM0 static V_MEMRAM1 FL_SegmentInfoType V_MEMRAM2 verifySegmentInfo[1]; +#endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT */ + +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +V_MEMRAM0 static V_MEMRAM1 vuint16 V_MEMRAM2 verifyTokenSignLength; +#endif + +/* Output buffer which keeps the verification result from FblMemBlockVerify (RequestTransferExit, CheckProgDep) */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 verifyOutputBuf[FBL_DIAG_VERIFY_BUFFER_SIZE]; + +#define FBLDIAG_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + + +/*********************************************************************************************************************** + * PROTOTYPES + **********************************************************************************************************************/ + +#define FBLDIAG_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +static void FblDiagSegmentInit( void ); +static vuint8 FblDiagSegmentNext( tFblDiagAddr segAddr, tFblLength segLength, vuint8 blockIdx ); +static tCwDataLengthType FblDiagGetMaxTransferDataBlockLength(void); +static void DiagDiscardReception( void ); +static tFblResult FblInitMemoryDriver( void ); +static void FblDeinitMemoryDriver( void ); +static void FblDiagDeinit( void ); + +#define FBLDIAG_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLDIAG_RAMCODE_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +static void DiagResetResponseHandling( void ); +#define FBLDIAG_RAMCODE_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLDIAG_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +static V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * FblDiagMemGetActiveBuffer(void); + +/*-- Service property functions ---------------------------------------------*/ +static void FblDiagSetState (const V_MEMRAM1 tStateBitmap V_MEMRAM2 V_MEMRAM3 * state); +static void FblDiagClrState (const V_MEMRAM1 tStateBitmap V_MEMRAM2 V_MEMRAM3 * state); +static void FblDiagRetainState (V_MEMROM1 tStateBitmap V_MEMROM2 V_MEMROM3 * state); +static void FblDiagInitStateTables ( void ); +static void FblDiagSetProperties(ptServiceProp source, tServiceProp * destination); +static void FblDiagMergeProperties(ptServiceProp source, tServiceProp * merge); +static void FblDiagDispatch ( void ); + +static tFblResult FblDiagSecAccessSeed(V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * pbDiagBuffer, tCwDataLengthType diagReqDataLen, vuint8 secLevel); +static tFblResult FblDiagSecAccessKey(V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * pbDiagBuffer, tCwDataLengthType diagReqDataLen, vuint8 secLevel); + +/*-- Service check functions ------------------------------------------------*/ +static FBL_DIAG_CHECK_HANDLER(FblDiagSearchService); +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSession); +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckLength); +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckFunctional); +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSuppressPosRsp); +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSecurityAccess); +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSequenceError); +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckGeneralConditions); +#if defined( FBL_DIAG_ENABLE_UPLOAD ) +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckTransferMode); +#endif +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) +static FBL_DIAG_CHECK_HANDLER(FblDiagSearchSecService); +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSecLength); +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSecSequenceError); +#endif + +/*-- Diagnostic error handler service functions -----------------------------*/ +#if defined( FBL_ENABLE_USERSERVICE ) +static FBL_DIAG_ERROR_HANDLER(FblDiagErrorHandlerServiceNotFound); +#endif +#if defined( FBL_ENABLE_USERSUBFUNCTION ) +static FBL_DIAG_ERROR_HANDLER(FblDiagErrorHandlerSubFunctionNotFound); +#endif +static FBL_DIAG_ERROR_HANDLER(FblDiagErrorHandlerExecMainHandler); + +/*-- Diagnostic main handler service functions ------------------------------*/ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerDefaultSession); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerProgrammingSession); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerTesterPresent); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerEcuReset); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcEraseMemory); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcCheckProgDep); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcActivateSbl); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcCheckValidApp); +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcTokenDownload); +# endif +#endif +#if defined( FBL_DIAG_ENABLE_UPDATE_SEC_BYTES ) +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcUpdateSecBytes); +#endif +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerSecAccessSeed); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerSecAccessKey); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRequestDownload); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerTransferDataDownload); +#if defined( FBL_DIAG_ENABLE_UPLOAD ) +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRequestUpload); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerTransferDataUpload); +#endif +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRequestTransferExit); +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerReadDataById); +#if defined( FBL_DIAG_ENABLE_WRITE_DATA_BY_IDENTIFIER ) +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerWriteDataById); +#endif +#if defined( FBL_ENABLE_USERROUTINE ) +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRoutineControl); +#endif + +/*-- Ford specific functions --------------------------------------------*/ +static void FblDiagInitDownloadSequence( void ); +static tFblResult FblDiagPrepareDidResponse( V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 *pbDiagBuffer, vuint16 reqDid, tDidDataPtr didData, vuint16 didLen ); +static tFblResult FblDiagCheckState( const V_MEMRAM1 tServiceProp V_MEMRAM2 V_MEMRAM3 *properties, V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 *pbDiagBuffer, tCwDataLengthType length, tCwDataLengthType position, V_MEMROM1 tStateBitmap V_MEMROM2 * stateMask, ptServiceProp * result); +static tFblResult FblDiagSessionTransition( V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * pbDiagBuffer, tCwDataLengthType diagReqDataLen ); +static void FblDiagSessionControlParamInit( V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * pbDiagBuffer, tCwDataLengthType diagReqDataLen ); +#if defined( FBL_DIAG_ENABLE_SESSION_PARAMETERS ) +static vuint8 FblDiagGetSessionIndex( vuint8 diagnosticSessionType ); +#endif +#if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) +static SecM_StatusType FblDiagVerification( V_MEMRAM1 SecM_VerifyParamType V_MEMRAM2 V_MEMRAM3 * verifyPar ); +#endif +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) && ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +static SecM_StatusType FblDiagVerifySignature( V_MEMRAM1 SecM_SignatureParamType V_MEMRAM2 V_MEMRAM3 * pVerifyParam ); +#endif +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +static tTokenHdlResult FblDiagTokenLengthCheck(vuint8 cmdType, vuint16 tokenLength); +static tTokenHdlResult FblDiagTokenKeyProcessing(vuint8 cmdType, V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tokenBufferPtr); +static tTokenHdlResult FblDiagValidateToken( const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tokenBuf ); +static tFblResult FblDiagCheckServerMessageId( const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tokenBuf ); +static tTokenHdlResult FblDiagTokenCallout( vuint8 cmdType, const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tokenBuf, vuint16 tokenLength ); +# endif +#endif + +#define FBLDIAG_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*****************************************************************************/ +/*** State machine configuration *********************************************/ +/*****************************************************************************/ + +/* The handler tables */ +enum +{ + kServiceCheckHandlerSearchService + ,kServiceCheckHandlerCheckSession + ,kServiceCheckHandlerCheckLength + ,kServiceCheckHandlerCheckFunctional + ,kServiceCheckHandlerCheckSuppressPosRsp + ,kServiceCheckHandlerCheckSecurityAccess + ,kServiceCheckHandlerCheckSequenceError + ,kServiceCheckHandlerCheckGeneralConditions +#if defined( FBL_DIAG_ENABLE_UPLOAD ) + ,kServiceCheckHandlerTransferMode +#endif +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) + ,kServiceCheckHandlerSearchSecService + ,kServiceCheckHandlerCheckSecLength + ,kServiceCheckHandlerCheckSecSequenceError +#endif +}; + +#define FBLDIAG_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +V_MEMROM0 static V_MEMROM1 tFblDiagCheckHandler V_MEMROM2 kServiceCheckHandlerFctTable[] = +{ + &FblDiagSearchService + ,&FblDiagCheckSession + ,&FblDiagCheckLength + ,&FblDiagCheckFunctional + ,&FblDiagCheckSuppressPosRsp + ,&FblDiagCheckSecurityAccess + ,&FblDiagCheckSequenceError + ,&FblDiagCheckGeneralConditions +#if defined( FBL_DIAG_ENABLE_UPLOAD ) + ,&FblDiagCheckTransferMode +#endif +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) + ,&FblDiagSearchSecService + ,&FblDiagCheckSecLength + ,&FblDiagCheckSecSequenceError +#endif +}; + +enum +{ + kServiceErrorHandlerExecMainHandler +#if defined( FBL_ENABLE_USERSERVICE ) + ,kServiceErrorHandlerServiceNotFound +#endif +#if defined( FBL_ENABLE_USERSUBFUNCTION ) + ,kServiceErrorHandlerSubFunctionNotFound +#endif + /*----------------------*/ + ,kServiceErrorHandlerNone +}; + +V_MEMROM0 static V_MEMROM1 tFblDiagErrorHandler V_MEMROM2 kServiceErrorHandlerFctTable[] = +{ + &FblDiagErrorHandlerExecMainHandler +#if defined( FBL_ENABLE_USERSERVICE ) + ,&FblDiagErrorHandlerServiceNotFound +#endif +#if defined( FBL_ENABLE_USERSUBFUNCTION ) + ,&FblDiagErrorHandlerSubFunctionNotFound +#endif +}; + +enum +{ + kServiceMainHandlerDefaultSession + ,kServiceMainHandlerProgrammingSession + ,kServiceMainHandlerTesterPresent + ,kServiceMainHandlerEcuReset + ,kServiceMainHandlerRcEraseMemory + ,kServiceMainHandlerRcCheckProgDep + ,kServiceMainHandlerRcActivateSbl + ,kServiceMainHandlerRcCheckValidApp +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) + ,kServiceMainHandlerRcTokenDownload +# endif +#endif +#if defined( FBL_DIAG_ENABLE_UPDATE_SEC_BYTES ) + ,kServiceMainHandlerRcUpdateSecBytes +#endif + ,kServiceMainHandlerSecAccessSeed + ,kServiceMainHandlerSecAccessKey + ,kServiceMainHandlerRequestDownload + ,kServiceMainHandlerTransferDataDownload +#if defined( FBL_DIAG_ENABLE_UPLOAD ) + ,kServiceMainHandlerRequestUpload + ,kServiceMainHandlerTransferDataUpload +#endif + ,kServiceMainHandlerRequestTransferExit + ,kServiceMainHandlerReadDataById +#if defined( FBL_DIAG_ENABLE_WRITE_DATA_BY_IDENTIFIER ) + ,kServiceMainHandlerWriteDataById +#endif +#if defined( FBL_ENABLE_USERROUTINE ) + ,kServiceMainHandlerRoutineControl +#endif + /*----------------------*/ + ,kServiceMainHandlerNone +}; + +V_MEMROM0 static V_MEMROM1 tFblDiagMainHandler V_MEMROM2 kServiceMainHandlerFctTable[] = { + &FblDiagMainHandlerDefaultSession + ,&FblDiagMainHandlerProgrammingSession + ,&FblDiagMainHandlerTesterPresent + ,&FblDiagMainHandlerEcuReset + ,&FblDiagMainHandlerRcEraseMemory + ,&FblDiagMainHandlerRcCheckProgDep + ,&FblDiagMainHandlerRcActivateSbl + ,&FblDiagMainHandlerRcCheckValidApp +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) + ,&FblDiagMainHandlerRcTokenDownload +# endif +#endif +#if defined( FBL_DIAG_ENABLE_UPDATE_SEC_BYTES ) + ,&FblDiagMainHandlerRcUpdateSecBytes +#endif + ,&FblDiagMainHandlerSecAccessSeed + ,&FblDiagMainHandlerSecAccessKey + ,&FblDiagMainHandlerRequestDownload + ,&FblDiagMainHandlerTransferDataDownload +#if defined( FBL_DIAG_ENABLE_UPLOAD ) + ,&FblDiagMainHandlerRequestUpload + ,&FblDiagMainHandlerTransferDataUpload +#endif + ,&FblDiagMainHandlerRequestTransferExit + ,&FblDiagMainHandlerReadDataById +#if defined( FBL_DIAG_ENABLE_WRITE_DATA_BY_IDENTIFIER ) + ,&FblDiagMainHandlerWriteDataById +#endif +#if defined( FBL_ENABLE_USERROUTINE ) + ,&FblDiagMainHandlerRoutineControl +#endif +}; + + + +/*****************************************************************************/ +/* Service checks */ +V_MEMROM0 static V_MEMROM1 tServiceCheck V_MEMROM2 kDiagServiceChecks[] = +{ + { + kServiceCheckHandlerSearchService + ,kDiagNrcServiceNotSupported +# if defined( FBL_ENABLE_USERSERVICE ) + ,kServiceErrorHandlerServiceNotFound +# else + ,kServiceErrorHandlerNone +# endif + } + ,{ + kServiceCheckHandlerCheckFunctional + ,kDiagNrcNoResponse + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSession + ,kDiagNrcServiceNotSupportedInActiveSession + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckLength + ,kDiagNrcIncorrectMessageLengthOrInvalidFormat + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSecurityAccess + ,kDiagNrcSecurityAccessDenied + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSequenceError + ,kDiagNrcRequestSequenceError + ,kServiceErrorHandlerNone + } +}; + +V_MEMROM0 static V_MEMROM1 tServiceCheckList V_MEMROM2 kDiagServiceCheckTable = +{ + kDiagServiceChecks + ,(sizeof(kDiagServiceChecks)/sizeof(kDiagServiceChecks[0])) +}; + +/*****************************************************************************/ + +V_MEMROM0 static V_MEMROM1 tServiceCheck V_MEMROM2 kDiagSubFctChecks[] = +{ + /* No real check, but only needs to be set once here */ + { + kServiceCheckHandlerCheckSuppressPosRsp + ,kDiagNrcNoResponse + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerSearchService + ,kDiagNrcSubFunctionNotSupported +# if defined( FBL_ENABLE_USERSUBFUNCTION ) + ,kServiceErrorHandlerSubFunctionNotFound +# else + ,kServiceErrorHandlerNone +# endif + } + ,{ + kServiceCheckHandlerCheckFunctional + ,kDiagNrcNoResponse + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSession + ,kDiagNrcSubfunctionNotSupportedInActiveSession + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckLength + ,kDiagNrcIncorrectMessageLengthOrInvalidFormat + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSecurityAccess + ,kDiagNrcSecurityAccessDenied + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSequenceError + ,kDiagNrcRequestSequenceError + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckGeneralConditions + ,kDiagNrcConditionsNotCorrect + ,kServiceErrorHandlerNone + } +}; + +V_MEMROM0 static V_MEMROM1 tServiceCheckList V_MEMROM2 kDiagSubFctCheckTable = +{ + kDiagSubFctChecks + ,(sizeof(kDiagSubFctChecks)/sizeof(kDiagSubFctChecks[0])) +}; + +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) +/*****************************************************************************/ +V_MEMROM0 static V_MEMROM1 tServiceCheck V_MEMROM2 kDiagSubFctSecChecks[] = +{ + /* No real check, but only needs to be set once here */ + { + kServiceCheckHandlerCheckSuppressPosRsp + ,kDiagNrcNoResponse + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerSearchSecService + ,kDiagNrcSubFunctionNotSupported +# if defined( FBL_ENABLE_USERSUBFUNCTION ) + ,kServiceErrorHandlerSubFunctionNotFound +# else + ,kServiceErrorHandlerNone +# endif + } + ,{ + kServiceCheckHandlerCheckFunctional + ,kDiagNrcNoResponse + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSession + ,kDiagNrcSubfunctionNotSupportedInActiveSession + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSecLength + ,kDiagNrcIncorrectMessageLengthOrInvalidFormat + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSecSequenceError + ,kDiagNrcRequestSequenceError + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckGeneralConditions + ,kDiagNrcConditionsNotCorrect + ,kServiceErrorHandlerNone + } +}; + +V_MEMROM0 static V_MEMROM1 tServiceCheckList V_MEMROM2 kDiagSubFctSecCheckTable = +{ + kDiagSubFctSecChecks + ,(sizeof(kDiagSubFctSecChecks)/sizeof(kDiagSubFctSecChecks[0])) +}; +#endif /* FBL_ENABLE_SEC_ADDITIONAL_LEVELS */ + +/*****************************************************************************/ + +V_MEMROM0 static V_MEMROM1 tServiceCheck V_MEMROM2 kDiagRcTypeChecks[] = +{ + /* No real check, but only needs to be set once here */ + { + kServiceCheckHandlerCheckSuppressPosRsp + ,kDiagNrcNoResponse + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerSearchService + ,kDiagNrcSubFunctionNotSupported + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckFunctional + ,kDiagNrcNoResponse + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSession + ,kDiagNrcSubfunctionNotSupportedInActiveSession + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckLength + ,kDiagNrcIncorrectMessageLengthOrInvalidFormat + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSecurityAccess + ,kDiagNrcSecurityAccessDenied + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSequenceError + ,kDiagNrcRequestSequenceError + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckGeneralConditions + ,kDiagNrcConditionsNotCorrect + ,kServiceErrorHandlerNone + } +}; + +V_MEMROM0 static V_MEMROM1 tServiceCheckList V_MEMROM2 kDiagRcTypeCheckTable = +{ + kDiagRcTypeChecks + ,(sizeof(kDiagRcTypeChecks)/sizeof(kDiagRcTypeChecks[0])) +}; + +/*****************************************************************************/ + +V_MEMROM0 static V_MEMROM1 tServiceCheck V_MEMROM2 kDiagNonSubFctChecks[] = +{ + { + kServiceCheckHandlerCheckGeneralConditions + ,kDiagNrcConditionsNotCorrect + ,kServiceErrorHandlerNone + } +}; + +V_MEMROM0 static V_MEMROM1 tServiceCheckList V_MEMROM2 kDiagNonSubFctCheckTable = +{ + kDiagNonSubFctChecks + ,(sizeof(kDiagNonSubFctChecks)/sizeof(kDiagNonSubFctChecks[0])) +}; + +/*****************************************************************************/ + +V_MEMROM0 static V_MEMROM1 tServiceCheck V_MEMROM2 kDiagSubRoutineChecks[] = +{ + { + kServiceCheckHandlerSearchService + ,kDiagNrcRequestOutOfRange + ,kServiceErrorHandlerExecMainHandler + } + ,{ + kServiceCheckHandlerCheckFunctional + ,kDiagNrcNoResponse + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSession + ,kDiagNrcRequestOutOfRange + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSecurityAccess + ,kDiagNrcSecurityAccessDenied + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckGeneralConditions + ,kDiagNrcConditionsNotCorrect + ,kServiceErrorHandlerNone + } +}; + +V_MEMROM0 static V_MEMROM1 tServiceCheckList V_MEMROM2 kDiagSubRoutineCheckTable = +{ + kDiagSubRoutineChecks + ,(sizeof(kDiagSubRoutineChecks)/sizeof(kDiagSubRoutineChecks[0])) +}; + +#if defined( FBL_DIAG_ENABLE_UPLOAD ) +/*****************************************************************************/ +/* TransferData checks */ +V_MEMROM0 static V_MEMROM1 tServiceCheck V_MEMROM2 kDiagTransferDataChecks[] = +{ + { + kServiceCheckHandlerTransferMode + ,kDiagErrorNone + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckLength + ,kDiagNrcIncorrectMessageLengthOrInvalidFormat + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckSecurityAccess + ,kDiagNrcSecurityAccessDenied + ,kServiceErrorHandlerNone + } + ,{ + kServiceCheckHandlerCheckGeneralConditions + ,kDiagNrcConditionsNotCorrect + ,kServiceErrorHandlerNone + } + +}; + +V_MEMROM0 static V_MEMROM1 tServiceCheckList V_MEMROM2 kDiagTransferDataCheckTable = +{ + kDiagTransferDataChecks + ,(sizeof(kDiagTransferDataChecks)/sizeof(kDiagTransferDataChecks[0])) +}; +#endif /* FBL_DIAG_ENABLE_UPLOAD */ + +/*****************************************************************************/ + +#if defined( FBL_DIAG_CHECK_LIST_HANDLES ) +/* The check list tables */ +enum +{ + kServiceCheckListServiceCheck + ,kServiceCheckListSubFctCheck +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) + ,kServiceCheckListSubFctSecCheck +#endif + ,kServiceCheckListNonSubFctCheck + ,kServiceCheckListSubRoutineCheck + ,kServiceCheckListRcTypeCheck +#if defined( FBL_DIAG_ENABLE_UPLOAD ) + ,kServiceCheckListTransferDataCheck +#endif + /*----------------------*/ + ,kServiceCheckListNone +}; + +V_MEMROM0 static V_MEMROM1 tServiceCheckList V_MEMROM2 V_MEMROM3 * V_MEMROM1 V_MEMROM2 kServiceCheckListTable[] = +{ + &kDiagServiceCheckTable + ,&kDiagSubFctCheckTable +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) + ,&kDiagSubFctSecCheckTable +#endif + ,&kDiagNonSubFctCheckTable + ,&kDiagSubRoutineCheckTable + ,&kDiagRcTypeCheckTable +#if defined( FBL_DIAG_ENABLE_UPLOAD ) + ,&kDiagTransferDataCheckTable +#endif +}; +#endif + +/* Service handlers **********************************************************/ +/* PRQA S 0342 TAG_FblDiag_0342_1 */ /* MD_MSR_Rule20.10_0342 */ +/* PRQA S 0841 TAG_FblDiag_0841_1 */ +enum +{ +#define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) kDiagService ## name +#define FBL_DIAG_IMPL_TYPE FBL_DIAG_IMPL_TYPE_OUTPUT +#define FBL_DIAG_IMPL_OUTPUT FBL_DIAG_STATE_RESULT, + +#include "fbl_diag.def" /* PRQA S 5087 */ /* MD_FblDiag_5087_DiagDef */ + +#undef FBL_DIAG_STATE_DEF +#undef FBL_DIAG_IMPL_TYPE +#undef FBL_DIAG_IMPL_OUTPUT + + kDiagNumberOfServices +}; + +#if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) +/* State Bitmaps ************************************************************/ +V_MEMROM0 static V_MEMROM1 tStateBitmap V_MEMROM2 kDiagStateBitmaps[] = +{ +#define FBL_DIAG_IMPL_TYPE FBL_DIAG_IMPL_TYPE_STATEBITMAP +#include "fbl_diag.def" /* PRQA S 5087 */ /* MD_FblDiag_5087_DiagDef */ +#undef FBL_DIAG_IMPL_TYPE +}; + +#endif +/* Service IDs ***************************************************************/ + +#if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) +V_MEMRAM0 static V_MEMRAM1 tServiceProp V_MEMRAM2 kDiagServiceProperties[kDiagNumberOfServices]; +#else +V_MEMROM0 static V_MEMROM1 tServiceProp V_MEMROM2 kDiagServiceProperties[kDiagNumberOfServices]; +#endif + +/* Service IDs ***************************************************************/ +#define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) \ + V_MEMROM0 static V_MEMROM1 vuint8 V_MEMROM2 kDiagSrvId_ ## name [] = { id } +#define FBL_DIAG_IMPL_TYPE FBL_DIAG_IMPL_TYPE_OUTPUT +#define FBL_DIAG_IMPL_OUTPUT FBL_DIAG_STATE_RESULT; + +#include "fbl_diag.def" /* PRQA S 5087 */ /* MD_FblDiag_5087_DiagDef */ + +#undef FBL_DIAG_STATE_DEF +#undef FBL_DIAG_IMPL_TYPE +#undef FBL_DIAG_IMPL_OUTPUT + +/* Service Lists *************************************************************/ + +#define FBL_DIAG_IMPL_TYPE FBL_DIAG_IMPL_TYPE_SERVICELIST +#include "fbl_diag.def" /* PRQA S 5087 */ /* MD_FblDiag_5087_DiagDef */ +#undef FBL_DIAG_IMPL_TYPE + +#if defined( FBL_DIAG_SERVICE_LIST_HANDLES ) +enum +{ +#define FBL_DIAG_IMPL_TYPE FBL_DIAG_IMPL_TYPE_SERVICELIST_ENUM +#include "fbl_diag.def" /* PRQA S 5087 */ /* MD_FblDiag_5087_DiagDef */ +#undef FBL_DIAG_IMPL_TYPE + kDiagServiceListHandler_None +}; + +V_MEMROM0 static V_MEMROM1 tServiceList V_MEMROM2 V_MEMROM3 * V_MEMROM1 V_MEMROM2 kDiagSubFctTblHandler[] = +{ +#define FBL_DIAG_IMPL_TYPE FBL_DIAG_IMPL_TYPE_SERVICELIST_HANDLER +#include "fbl_diag.def" /* PRQA S 5087 */ /* MD_FblDiag_5087_DiagDef */ +#undef FBL_DIAG_IMPL_TYPE + kDiagNoSubServices +}; +#endif + +/* Service Properties ********************************************************/ + +#if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) +V_MEMROM0 static V_MEMROM1 tServicePropROM V_MEMROM2 kDiagServicePropertiesROM[] = +#else +V_MEMROM0 static V_MEMROM1 tServiceProp V_MEMROM2 kDiagServiceProperties[] = +#endif +{ +#define FBL_DIAG_IMPL_TYPE FBL_DIAG_IMPL_TYPE_SERVICEPROPERTY +#include "fbl_diag.def" /* PRQA S 5087 */ /* MD_FblDiag_5087_DiagDef */ +#undef FBL_DIAG_IMPL_TYPE +}; +/* PRQA L:TAG_FblDiag_0342_1 */ +/* PRQA L:TAG_FblDiag_0881_1 */ +/* PRQA L:TAG_FblDiag_0841_1 */ +/* PRQA L:TAG_FblDiag_3410_1 */ +/* PRQA L:TAG_FblDiag_3412_1 */ +/* PRQA L:TAG_FblDiag_3431_1 */ +/* PRQA L:TAG_FblDiag_3453_2 */ +/* PRQA L:TAG_FblDiag_3218_1 */ + +#define FBLDIAG_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +#define FBLDIAG_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBL_ENABLE_USERSERVICE ) +/*********************************************************************************************************************** + * FblDiagErrorHandlerServiceNotFound + **********************************************************************************************************************/ +/*! \brief Execute callback for user specific service implementations + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] diagReqDataLen Request length + * \return User service found + **********************************************************************************************************************/ +static FBL_DIAG_ERROR_HANDLER(FblDiagErrorHandlerServiceNotFound) +{ + tFblResult result; +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)properties; +#endif + + ApplDiagUserService(&pbDiagBuffer[kDiagFmtRoutineIdHigh], diagReqDataLen); + + result = kFblFailed; + if (DiagGetError() == kDiagErrorNone) + { + result = kFblOk; + } + + return result; +} +#endif /* FBL_ENABLE_USERSERVICE */ + +#if defined( FBL_ENABLE_USERSUBFUNCTION ) +/*********************************************************************************************************************** + * FblDiagErrorHandlerSubFunctionNotFound + **********************************************************************************************************************/ +/*! \brief Execute callback for user specific subfunction implementations + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] diagReqDataLen Request length + * \return User subfunction found + **********************************************************************************************************************/ +static FBL_DIAG_ERROR_HANDLER(FblDiagErrorHandlerSubFunctionNotFound) +{ + tFblResult result; +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)properties; +#endif + + ApplDiagUserSubFunction(&pbDiagBuffer[kDiagFmtRoutineIdHigh], diagReqDataLen); + + result = kFblFailed; + if (DiagGetError() == kDiagErrorNone) + { + result = kFblOk; + } + + return result; +} +#endif /* FBL_ENABLE_USERSUBFUNCTION */ + +/*********************************************************************************************************************** + * FblDiagErrorHandlerExecMainHandler + **********************************************************************************************************************/ +/*! \brief Execute main handler of parent service + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] diagReqDataLen Request length + * \return Main handler execution result + **********************************************************************************************************************/ +static FBL_DIAG_ERROR_HANDLER(FblDiagErrorHandlerExecMainHandler) +{ + tFblResult result; + + result = kFblFailed; + if (properties->mainHandlerIdx != (vuint8)kServiceMainHandlerNone) + { + result = (kServiceMainHandlerFctTable[properties->mainHandlerIdx])(pbDiagBuffer, diagReqDataLen); + } + + return result; +} + +/*********************************************************************************************************************** + * FblDiagSearchService + **********************************************************************************************************************/ +/*! \brief Search the subservice table using the id at the current request position + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Search successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Search failed + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +static FBL_DIAG_CHECK_HANDLER(FblDiagSearchService) +{ + V_MEMROM1 tServiceList V_MEMROM2 V_MEMROM3 * localSubServices; + ptServiceProp subSrvLst = V_NULL; /* PRQA S 3679 */ /* MD_MSR_Rule8.13 */ + ptServiceProp subService = V_NULL; /* PRQA S 3679 */ /* MD_MSR_Rule8.13 */ + + vuint8 curPos; + vuint8 subSrvIdx; + tFblResult valid; + tFblResult found; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)length; +#endif + + localSubServices = properties->subServices; + subSrvLst = localSubServices->list; + + found = kFblFailed; + for (subSrvIdx = 0; subSrvIdx < localSubServices->count; subSrvIdx++) + { + subService = &subSrvLst[subSrvIdx]; + + valid = kFblOk; + for (curPos = 0; curPos < localSubServices->idSize; curPos++) + { + if (subService->serviceId[curPos] != pbDiagBuffer[position + curPos]) + { + valid = kFblFailed; + /* Code size optimization, single break in loop allowed by MISRA */ + break; + } + } + + if (valid == kFblOk) + { + found = kFblOk; + *result = subService; + /* Code size optimization, single break in loop allowed by MISRA */ + break; + } + } + + return found; +} + +/*********************************************************************************************************************** + * FblDiagCheckState + **********************************************************************************************************************/ +/*! \brief Check if the masked state matches the service requirements + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in] stateMask State mask + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Check successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Check failed + **********************************************************************************************************************/ +/* PRQA S 3673, 6060 1 */ /* MD_MSR_Rule8.13, MD_MSR_STPAR */ +static tFblResult FblDiagCheckState( const V_MEMRAM1 tServiceProp V_MEMRAM2 V_MEMRAM3 *properties, V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 *pbDiagBuffer, tCwDataLengthType length, tCwDataLengthType position, V_MEMROM1 tStateBitmap V_MEMROM2 * stateMask, ptServiceProp * result) +{ + vuint8 idx, valid; + tStateBitmap maskedState; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 4 */ /* MD_MSR_DummyStmt */ + (void)pbDiagBuffer; + (void)length; + (void)position; + (void)result; +#endif + valid = kFblOk; + +#if ( STATECHECK_ARRAYSIZE == 1u ) + idx = 0u; +#else + for (idx = 0u; (idx < STATECHECK_ARRAYSIZE) && (valid == kFblOk); idx++) +#endif + { + /* Separate the state bits which have to be set */ + maskedState = properties->stateSet[idx] & stateMask[idx]; + + /* Check if all of the required "Set" states are set */ + if ((maskedState != kDiagStateMaskNone) && ((maskedState & fblStates[idx]) != maskedState)) + { + /* At least one of the required states is not set */ + valid = kFblFailed; + } + else + { + /* Separate the state bits which must not be set */ + maskedState = properties->stateUnset[idx] & stateMask[idx]; + + /* Check if all of the required "Unset" states are cleared */ + if ((maskedState != kDiagStateMaskNone) && ((maskedState & fblStates[idx]) != kDiagStateMaskNone)) + { + /* At least one of the required states is set */ + valid = kFblFailed; + } + } + } + + /* + Positive check result: + - All of the required "Set" states are set + - All of the required "Unset" states are cleared + */ + return valid; +} + +/*********************************************************************************************************************** + * FblDiagCheckSession + **********************************************************************************************************************/ +/*! \brief Check if the session states match the service requirements + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Check successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Check failed + **********************************************************************************************************************/ +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSession) +{ + return FblDiagCheckState(properties, pbDiagBuffer, length, position, kDiagStateMaskSessions, result); +} + +/*********************************************************************************************************************** + * FblDiagCheckFunctional + **********************************************************************************************************************/ +/*! \brief Check if the functional request state matches the service requirements + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Check successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Check failed + **********************************************************************************************************************/ +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckFunctional) +{ + return FblDiagCheckState(properties, pbDiagBuffer, length, position, kDiagStateMaskFunctional, result); +} + +/*********************************************************************************************************************** + * FblDiagCheckSecurityAccess + **********************************************************************************************************************/ +/*! \brief Check if the security access states match the service requirements + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Check successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Check failed + **********************************************************************************************************************/ +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSecurityAccess) +{ + return FblDiagCheckState(properties, pbDiagBuffer, length, position, kDiagStateMaskSecurityAccess, result); +} + +/*********************************************************************************************************************** + * FblDiagCheckSequenceError + **********************************************************************************************************************/ +/*! \brief Check if the states leading to request sequence errors match the service requirements + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Check successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Check failed + **********************************************************************************************************************/ +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSequenceError) +{ + return FblDiagCheckState(properties, pbDiagBuffer, length, position, kDiagStateMaskSequenceError, result); +} + +/*********************************************************************************************************************** + * FblDiagCheckGeneralConditions + **********************************************************************************************************************/ +/*! \brief Check if all possible session states match the service requirements + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Check successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Check failed + **********************************************************************************************************************/ +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckGeneralConditions) +{ + return FblDiagCheckState(properties, pbDiagBuffer, length, position, kDiagStateMaskGeneralConditions, result); +} + +/*********************************************************************************************************************** + * FblDiagCheckLength + **********************************************************************************************************************/ +/*! \brief Check if the request length matches the service requirements + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Check successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Check failed + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckLength) +{ + vuint8 valid; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 3 */ /* MD_MSR_DummyStmt */ + (void)pbDiagBuffer; + (void)position; + (void)result; +#endif + valid = kFblOk; + + if ((properties->minLength > 0u) && (length < properties->minLength)) + { + valid = kFblFailed; + } + + if (length > properties->maxLength) + { + valid = kFblFailed; + } + + return valid; +} + +/*********************************************************************************************************************** + * FblDiagCheckSuppressPosRsp + **********************************************************************************************************************/ +/*! \brief Evaluate the suppress positive response message bit for subfunction requests + * \details No real check, but should only be executed for services with subfunctions + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Check successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Check failed + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSuppressPosRsp) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 3 */ /* MD_MSR_DummyStmt */ + (void)properties; + (void)length; + (void)result; +#endif + + CheckSuppressPosRspMsgIndication(&pbDiagBuffer[position]); + + return kFblOk; +} + +#if defined( FBL_DIAG_ENABLE_UPLOAD ) +/*********************************************************************************************************************** + * FblDiagCheckTransferMode + **********************************************************************************************************************/ +/*! \brief Evaluate the requested transfer mode. This check is used to switch between download and upload transfers. + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Check successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Check failed + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckTransferMode) +{ + V_MEMROM1 tServiceList V_MEMROM2 * localSubServices; + ptServiceProp subSrvLst = V_NULL; /* PRQA S 3679 */ /* MD_MSR_Rule8.13 */ + ptServiceProp subService = V_NULL; /* PRQA S 3679 */ /* MD_MSR_Rule8.13 */ + vuint8 subSrvIdx; + vuint8 found; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 3 */ /* MD_MSR_DummyStmt */ + (void)pbDiagBuffer; + (void)length; + (void)position; +#endif + + localSubServices = properties->subServices; + subSrvLst = localSubServices->list; + + found = kFblFailed; + for (subSrvIdx = 0; (subSrvIdx < localSubServices->count) && (found != kFblOk); subSrvIdx++) + { + subService = &subSrvLst[subSrvIdx]; + if (STATE_TEST(subService->stateSet, kDiagStateIdxTransferDataUpload) == GetTransferDataUpload()) + { + found = kFblOk; + } + } + + if (found == kFblOk) + { + *result = subService; + } + + return found; +} +#endif /* FBL_DIAG_ENABLE_UPLOAD */ + +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) +/*********************************************************************************************************************** + * FblDiagSearchSecService + **********************************************************************************************************************/ +/*! \brief Search the sub service table using the id at the current request position. Special use case for security access + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Search successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Search failed + **********************************************************************************************************************/ +static FBL_DIAG_CHECK_HANDLER(FblDiagSearchSecService) +{ + V_MEMROM1 tServiceList V_MEMROM2 * localSubServices; + ptServiceProp subSrvLst; /* PRQA S 3679 */ /* MD_MSR_Rule8.13 */ + ptServiceProp subService; /* PRQA S 3679 */ /* MD_MSR_Rule8.13 */ + + vuint8 subSrvIdx; + vuint8 found; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)length; +#endif + + localSubServices = properties->subServices; + subSrvLst = localSubServices->list; + subService = kDiagNoServiceProp; + diagRequestedSecLvlIdx = kDiagInvalidSecLvlIdx; + + found = kFblFailed; + + /* Check if level is supported */ + for (subSrvIdx = 0; subSrvIdx < (sizeof(kDiagSecAccessParams)/sizeof(kDiagSecAccessParams[0])); subSrvIdx++) + { + if (kDiagSecAccessParams[subSrvIdx].secLevel == pbDiagBuffer[position] ) + { + /* Level supported - Seed request */ + subService = &subSrvLst[0]; + found = kFblOk; + break; + } + if (kDiagSecAccessParams[subSrvIdx].secLevel == (pbDiagBuffer[position] - 1u)) + { + /* Level supported - Key request */ + subService = &subSrvLst[1]; + found = kFblOk; + break; + } + } + + if (found == kFblOk) + { + /* Cache index of identified table entry for later usage */ + diagRequestedSecLvlIdx = subSrvIdx; + + *result = subService; + } + + return found; +} + +/*********************************************************************************************************************** + * FblDiagCheckSecLength + **********************************************************************************************************************/ +/*! \brief Check if the request length matches the service requirements + * \details Special version for security access. + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Check successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Check failed + **********************************************************************************************************************/ +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSecLength) +{ + vuint8 valid; + + assertFblInternal(diagRequestedSecLvlIdx != kDiagInvalidSecLvlIdx, kFblOemAssertInvalidSecLvlIdx); + + valid = kFblFailed; + + if (kDiagSecAccessParams[diagRequestedSecLvlIdx].secLevel == pbDiagBuffer[position]) + { + /* Seed request -> use standard check + * This works because pbDiagBuffer is not evaluated any more */ + valid = FblDiagCheckLength(properties, pbDiagBuffer, length, position, result); + } + if (kDiagSecAccessParams[diagRequestedSecLvlIdx].secLevel == (pbDiagBuffer[position] - 1u)) + { + /* Key request */ + if ((kDiagSecAccessParams[diagRequestedSecLvlIdx].keyLength + 1u) == length) + { + valid = kFblOk; + } + } + + return valid; +} + +/*********************************************************************************************************************** + * FblDiagCheckSecSequenceError + **********************************************************************************************************************/ +/*! \brief Check if the states leading to request sequence errors match the service requirements for security access + * \param[in] properties Dispatching properties + * \param[in] pbDiagBuffer Diagnostic buffer + * \param[in] length Request length + * \param[in] position Current request position + * \param[in,out] result Resulting properties + * \return Possible return values: + * - kFblOk: Check successful. If applicable, changed properties are returned via parameter 'result' + * - kFblFailed: Check failed + **********************************************************************************************************************/ +static FBL_DIAG_CHECK_HANDLER(FblDiagCheckSecSequenceError) +{ + vuint8 tmpSecLvl; + tFblResult valid; + + assertFblInternal(diagRequestedSecLvlIdx != kDiagInvalidSecLvlIdx, kFblOemAssertInvalidSecLvlIdx); + + valid = kFblOk; + + if ((pbDiagBuffer[position] & 0x01u) == 0x01u) + { + /* Seed request: sub service equals security level */ + tmpSecLvl = pbDiagBuffer[position]; + if ((kDiagSecLevelNone != GetCurrentSecLvl()) && (tmpSecLvl != GetCurrentSecLvl())) + { + valid = kFblFailed; + } + } + else + { + /* Key request: (sub service - 1) equals security level */ + tmpSecLvl = pbDiagBuffer[position] - 1; + if (diagRequestedSecLvl != tmpSecLvl) + { + valid = kFblFailed; + } + } + + if ((kFblOk == valid ) && (kFblOk == ApplFblGetSecLvlSupport(tmpSecLvl))) + { + valid = FblDiagCheckState(properties, pbDiagBuffer, length, position, kDiagStateMaskSequenceError, result); + } + else + { + valid = kFblFailed; + } + + return valid; +} + +#endif /* FBL_ENABLE_SEC_ADDITIONAL_LEVELS */ + +/*********************************************************************************************************************** + * FblDiagSetState + **********************************************************************************************************************/ +/*! \brief Set states according to mask + * \param[in] state State mask + **********************************************************************************************************************/ +static void FblDiagSetState (const V_MEMRAM1 tStateBitmap V_MEMRAM2 V_MEMRAM3 * state) +{ + vuint8 idx; + +#if ( STATECHECK_ARRAYSIZE == 1u) + idx = 0u; +#else + for (idx = 0u; idx < STATECHECK_ARRAYSIZE; idx++) +#endif + { + fblStates[idx] |= state[idx]; + } +} + +/*********************************************************************************************************************** + * FblDiagClrState + **********************************************************************************************************************/ +/*! \brief Clear states according to mask + * \param[in] state State mask + **********************************************************************************************************************/ +static void FblDiagClrState (const V_MEMRAM1 tStateBitmap V_MEMRAM2 V_MEMRAM3 * state) +{ + vuint8 idx; + +#if ( STATECHECK_ARRAYSIZE == 1u) + idx = 0u; +#else + for (idx = 0u; idx < STATECHECK_ARRAYSIZE; idx++) +#endif + { + fblStates[idx] &= FblInvertBits(state[idx], tStateBitmap); + } +} + +/*********************************************************************************************************************** + * FblDiagRetainState + **********************************************************************************************************************/ +/*! \brief Retain the value of all masked states, clear all others including the internal states + * \param[in] state State mask + **********************************************************************************************************************/ +static void FblDiagRetainState (V_MEMROM1 tStateBitmap V_MEMROM2 V_MEMROM3 * state) +{ + vuint8 idx; + + /* Retain values of masked dispatcher states */ +#if ( STATECHECK_ARRAYSIZE == 1u) + idx = 0u; +#else + for (idx = 0u; idx < STATECHECK_ARRAYSIZE; idx++) +#endif + { + fblStates[idx] &= state[idx]; + } + + /* Clear all additional internal flags */ + for ( ; idx < ARRAY_SIZE(fblStates); idx++) + { + fblStates[idx] = 0; + } +} + +#if defined( FBL_DIAG_ENABLE_SESSION_PARAMETERS ) +/*********************************************************************************************************************** + * FblDiagGetSessionIndex + **********************************************************************************************************************/ +/*! \brief Search the diagnostic session table for the requested session type and return the internal session index + * \param[in] diagnosticSessionType SessionControl parameter + * \return Session index + **********************************************************************************************************************/ +static vuint8 FblDiagGetSessionIndex(vuint8 diagnosticSessionType) +{ + vuint8 sessionIdx; + + for (sessionIdx = 0u; sessionIdx < kDiagNumberOfSessions; sessionIdx++) + { + if (kDiagSessionParameters[sessionIdx].sessionType == diagnosticSessionType) + { + /* Found valid session */ + break; + } + } + + if (sessionIdx == kDiagNumberOfSessions) + { + /* + * Config error: this error can only appear if the dispatcher knows more + * diagnostic session types than the session parameter table. + */ + assertFblInternal(0u, kFblOemAssertSessionIndexNotFound); /* PRQA S 2214 */ /* MD_FblDiag_2214 */ + sessionIdx = kDiagSessionNotFound; + } + + return sessionIdx; +} +#endif /* FBL_DIAG_ENABLE_SESSION_PARAMETERS */ + +#define FBLDIAG_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* Diagnostic standard functions ********************************************/ + +#define FBLDIAG_RAMCODE_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * DiagResetResponseHandling + **********************************************************************************************************************/ +/*! \brief Reset the status for service handling + * \pre Service response shall be finished + **********************************************************************************************************************/ +static void DiagResetResponseHandling( void ) +{ + DiagClrError(); + + /* Restart the tester present timer if not in default session */ + if (!GetDiagDefaultDiagSession()) + { + ResetTesterTimeout(); + } + + /* Buffer is now available */ + ClrDiagBufferLocked(); + + /* Reset flag for functional request after processing */ + ClrFunctionalRequest(); + +} + +/*********************************************************************************************************************** + * DiagExRCRResponsePending + **********************************************************************************************************************/ +/*! \brief Transmit a busy message if timer expires + * (forceSend == kNotForceSendResponsePending) or if kForceSendResponsePending is passed. + * \param[in] forceSend Determines if a message is sent independently from timer state. + **********************************************************************************************************************/ +void DiagExRCRResponsePending( vuint8 forceSend ) +{ + static vuint8 rcrrpDiagBuffer[3]; + + if (GetServiceInProgress()) + { + if (((GetP2Timeout() > 0x00u) && (GetP2Timer() < (GetP2Timeout()))) || (forceSend == kForceSendResponsePending)) + { + /* Prepare and transmit RCRRP buffer */ + rcrrpDiagBuffer[0] = kDiagRidNegativeResponse; + rcrrpDiagBuffer[1] = diagServiceCurrent; + rcrrpDiagBuffer[2] = kDiagNrcRcrResponsePending; + FblCwTransmitRP(rcrrpDiagBuffer); + + /* Restart P2-Timer to P2* */ + SetP2Timer(kFblDiagTimeP2Star); + SetP2Timeout(kFblDiagTimeP2Star); /* PRQA S 3493 */ /* MD_FblDiag_3493 */ + + /* If response pending is transmitted and no response + * is set, a positive response has to be transmitted anyway. */ + ClrSuppressPosRspMsg(); + + /* Prepare parameter for the confirmation function */ + SetRcrRpInProgress(); + } + } +} +#define FBLDIAG_RAMCODE_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLDIAG_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * FblDiagMemGetActiveBuffer + **********************************************************************************************************************/ +/*! \brief Function updates Diagnostic buffer (DiagBuffer) and returns updated pbDiagData to handler + * \return updated pbDiagData buffer used by diagnostic handler functions * + **********************************************************************************************************************/ +static V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * FblDiagMemGetActiveBuffer(void) +{ + DiagBuffer = FblMemGetActiveBuffer(); + return DiagBuffer; +} + +/*********************************************************************************************************************** + * DiagDiscardReception + **********************************************************************************************************************/ +/*! \brief Received diagnostic messages are discarded + **********************************************************************************************************************/ +static void DiagDiscardReception( void ) +{ + SetResponseProcessing(); /* Set flag for running response procedure */ + + FblCwDiscardReception(); + + ClrResponseProcessing(); +} + +/*********************************************************************************************************************** + * DiagResponseProcessor + **********************************************************************************************************************/ +/*! \brief Send diagnostic response message + * \pre List of preconditions: + * - Current SID must be in DiagBuffer[0] + * - diagErrorCode must be initialized + * \param[in] dataLength Data length to be transmitted. + **********************************************************************************************************************/ +void DiagResponseProcessor( tCwDataLengthType dataLength ) +{ + ClrServiceInProgress(); + ClrRcrRpInProgress(); + ClrP2Timer(); + ClrP2Timeout(); + DiagDiscardReception(); + FblErrStatSetSId(diagServiceCurrent); + + if (DiagGetError() != kDiagErrorNone) + { + if (GetFunctionalRequest() + && ((DiagGetError() == kDiagNrcServiceNotSupported) + || (DiagGetError() == kDiagNrcServiceNotSupportedInActiveSession) + || (DiagGetError() == kDiagNrcSubFunctionNotSupported) + || (DiagGetError() == kDiagNrcSubfunctionNotSupportedInActiveSession) + || (DiagGetError() == kDiagNrcRequestOutOfRange) + )) + { + /* + No response for functionally addressed requests if + service or subfunction not supported. + */ + DiagResetResponseHandling(); + FblCwResetRxBlock(); + } + else + { + /* Prepare response message */ + DiagBuffer[kDiagFmtSubparam] = diagServiceCurrent; + DiagBuffer[kDiagFmtServiceId] = kDiagRidNegativeResponse; + DiagBuffer[kDiagFmtNegResponse] = DiagGetError(); + + /* Send response in communication wrapper */ + FblCwTransmit(DiagBuffer, 3, kFblCwTxCallNegResponse ); + } + /* Clear 'pending' error */ + DiagClrError(); + } + else if (diagResponseFlag == kDiagPutResponse) + { + if (!GetSuppressPosRspMsg()) + { + /* Transmit positive response if not suppressed */ + DiagBuffer[kDiagFmtServiceId] = (vuint8)(diagServiceCurrent + 0x40u); + + /* Send response in communication wrapper */ + FblCwTransmit(DiagBuffer, (tCwDataLengthType)(dataLength + 1u), kFblCwTxCallPosResponse); + } + else + { + DiagResetResponseHandling(); + FblCwResetRxBlock(); + ClrSuppressPosRspMsg(); + + /* Check if a reset shall be generated without message transmission */ + if (GetWaitEcuReset()) + { + /* If so, generate the reset immediately */ + SetResetMsgConfirmed(); + } + } + } + else + { + /* Do not send a response, just reset internal state */ + DiagResetResponseHandling(); + FblCwResetRxBlock(); + ClrSuppressPosRspMsg(); + + /* Check if a reset shall be generated without message transmission */ + if (GetWaitEcuReset()) + { + /* If so, generate the reset immediately */ + SetResetMsgConfirmed(); + } + } + + /* Response processing executed */ + SetProcessingDone(); +} + +/*********************************************************************************************************************** + * FblRealTimeSupport + **********************************************************************************************************************/ +/*! \brief Transmit busy messages and triggers the watchdog according to system timer + * \pre P2Timer must be initialized + * \return Return code of FblLookForWatchdog + **********************************************************************************************************************/ +vuint8 FblRealTimeSupport( void ) +{ + vuint8 returnCode; + + returnCode = FblLookForWatchdog(); + + DiagExRCRResponsePending(kNotForceSendResponsePending); + + return returnCode; +} + +/*********************************************************************************************************************** + * FblRealTimeSupportVoid + **********************************************************************************************************************/ +/*! \brief Transmit busy messages and triggers the watchdog according to system timer. + * \pre Diagnosis and communication stack must be initialized, diagnostic request has to be received. + * \return None + **********************************************************************************************************************/ +void FblRealTimeSupportVoid( void ) +{ + FblLookForWatchdogVoid(); + DiagExRCRResponsePending(kNotForceSendResponsePending); +} + +#if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) +/*********************************************************************************************************************** + * FblDiagInitStateTables + **********************************************************************************************************************/ +/*! \brief Expand condensed service property tables from ROM to RAM + **********************************************************************************************************************/ +static void FblDiagInitStateTables ( void ) +{ + vuint8 idx; + vuint16 bitmapIdx; + vuint8 stateIdx; + vuint8 stateArrIdx; + vuint8 stateMask; + static V_MEMROM1 tStateBitmap V_MEMROM2 V_MEMROM3 * sourceState; + static V_MEMRAM1 tStateBitmap V_MEMRAM2 V_MEMRAM3 * targetState; + + bitmapIdx = 0; + + for (idx = 0; idx < (sizeof(kDiagServicePropertiesROM)/sizeof(kDiagServicePropertiesROM[0])); idx++) + { +# if defined( FBL_DIAG_SERVICE_LIST_HANDLES ) + kDiagServiceProperties[idx].subServices = kDiagSubFctTblHandler[kDiagServicePropertiesROM[idx].subServicesHandler]; +# else + kDiagServiceProperties[idx].subServices = kDiagServicePropertiesROM[idx].subServices; +# endif + kDiagServiceProperties[idx].serviceId = kDiagServicePropertiesROM[idx].serviceId; +#if defined( FBL_DIAG_CHECK_LIST_HANDLES ) +#else + kDiagServiceProperties[idx].checks = kDiagServicePropertiesROM[idx].checks; +#endif + kDiagServiceProperties[idx].minLength = kDiagServicePropertiesROM[idx].minLength; + kDiagServiceProperties[idx].maxLength = kDiagServicePropertiesROM[idx].maxLength; + kDiagServiceProperties[idx].mainHandlerIdx = kDiagServicePropertiesROM[idx].mainHandlerIdx; +#if defined( FBL_DIAG_CHECK_LIST_HANDLES ) + kDiagServiceProperties[idx].checkListIdx = kDiagServicePropertiesROM[idx].checkListIdx; +#endif + +#if defined( FBL_DIAG_STATE_ARRAYS ) + stateMask = 0x01; +#endif + + for (stateArrIdx = 0; stateArrIdx < STATE_COUNT; stateArrIdx++) + { +#if defined( FBL_DIAG_STATE_ARRAYS ) + targetState = kDiagServiceProperties[idx].states[stateArrIdx]; +#else + switch (stateArrIdx) + { + case 0: + targetState = kDiagServiceProperties[idx].stateSet; + stateMask = 0x01; + break; + case 1: + targetState = kDiagServiceProperties[idx].stateUnset; + stateMask = 0x02; + break; + case 2: + targetState = kDiagServiceProperties[idx].stateAdd; + stateMask = 0x04; + break; + case 3: + targetState = kDiagServiceProperties[idx].stateClr; + stateMask = 0x08; + break; + case 4: + targetState = kDiagServiceProperties[idx].stateClrFail; + stateMask = 0x10; + break; + } +#endif + + if ((kDiagServicePropertiesROM[idx].stateUsage & stateMask) == stateMask) + { + sourceState = &kDiagStateBitmaps[bitmapIdx]; + bitmapIdx += STATECHECK_ARRAYSIZE; + } + else + { + sourceState = kDiagStateMaskReset; + } + +# if ( STATECHECK_ARRAYSIZE == 1u) + stateIdx = 0; +# else + for (stateIdx = 0; stateIdx < STATECHECK_ARRAYSIZE; stateIdx++) +# endif + { + targetState[stateIdx] = sourceState[stateIdx]; + } + + stateMask <<= 1; + } + } +} +#endif + +/*********************************************************************************************************************** + * FblDiagInitDownloadSequence + **********************************************************************************************************************/ +/*! \brief (Re-)initialize download sequence (initialization and session transition) + **********************************************************************************************************************/ +static void FblDiagInitDownloadSequence( void ) +{ + vuint8 blockIdx; + + /* (Re-)initialize download sequence */ + transferRemainder = 0u; + transferType = DOWNLOAD_RAM; + expectedSequenceCnt = 0u; + lastErasedBlock = kBlockNrInvalid; + + /* Initialize download information structure */ + FblDiagSegmentInit(); + + /* Initialize block information */ + currentBlock = kBlockNrInvalid; + + for (blockIdx = 0u; blockIdx < FBL_LBT_BLOCK_COUNT; blockIdx++) + { + blockHeader[blockIdx].state = kBlockState_Init; + blockHeader[blockIdx].nrOfSegments = 0u; + } + + /* Initialize security module */ + (void)ApplFblSecurityInit(); + SetCurrentSecLvl(kDiagSecLevelNone); +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) + /* Initialize security access variables */ + diagRequestedSecLvl = kDiagSecLevelNone; + diagRequestedSecLvlIdx = kDiagInvalidSecLvlIdx; +#endif +} + +/*********************************************************************************************************************** + * FblDiagInitPowerOn + **********************************************************************************************************************/ +/*! \brief Initialize module variables + **********************************************************************************************************************/ +void FblDiagInitPowerOn( void ) +{ + vuint8 idx; + + for (idx = 0u; idx < (sizeof(fblStates)/sizeof(fblStates[0])); idx++) + { + fblStates[idx] = (tStateBitmap)0x00u; + } + + transferRemainder = 0u; + transferType = DOWNLOAD_RAM; + expectedSequenceCnt = 0u; + memSegment = -1; + diagResponseFlag = kDiagPutResponse; + + + /* Initialize variables of lib Lbt */ + FblLbtInitPowerOn(); + + DiagClrError(); + /* Set diagnostic session (default session) */ + SetDiagDefaultDiagSession(); + + /* Stop tester present timer */ + StopTesterTimeout(); + + /* Clear timer for response pending transmission */ + ClrP2Timer(); + /* Clear P2 timeout to prevent erroneous sending of RCR-RP */ + ClrP2Timeout(); + + ApplFblResetVfp(); + + /* Initialize security module */ + (void)SecM_InitPowerOn(V_NULL); + +#if defined( FBL_ENABLE_DEBUG_STATUS ) + /* Initialize error status */ + ApplFblInitErrStatus(); +#endif +} + +/*********************************************************************************************************************** + * FblDiagInit + **********************************************************************************************************************/ +/*! \brief Initialize module variables + **********************************************************************************************************************/ +/* PRQA S 6050 1 */ /* MD_MSR_STCAL */ +void FblDiagInit( void ) +{ + tCwDataLengthType requestLength = 0u; + + /* Get aligned diag buffer pointer from memory library */ + DiagBuffer = FblMemInitPowerOn(); + +#if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) + FblDiagInitStateTables(); +#endif + + /* Reset service properties */ + FblDiagSetProperties(&kDiagServiceProperties[0], &serviceProperties); + + StopEcuResetTimeout(); + + /* If FBL was started from application, already lock diagnostic buffer here */ + if (FblMainGetStartFromAppl()) + { + + requestLength = kDiagRqlDiagnosticSessionControl + 1u; + } + + /* Release the buffer to be able to respond to request receiv ed by application */ + ClrDiagBufferLocked(); + + if (FblDiagRxGetPhysBuffer(requestLength) == DiagBuffer) + { + SetLockedByInit(); + /* Lock the TP buffer, because service buffer is allocated for pos. response */ + FblCwSetRxBlock(); + } + + /* Initialize communication wrapper */ + FblCwSetTxInit(); + +#if defined( FBL_CW_ENABLE_MULTIPLE_CONNECTIONS ) + FblCwResetResponseAddress(); +#endif /* FBL_CW_ENABLE_MULTIPLE_CONNECTIONS */ + +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +# if defined( FBL_DIAG_MULTIPLE_KEY ) + /* Initialized the correct software signing key */ + (void)FblDiagCopyUsedPersKeyToUsedNotPersKey(); +# endif /* FBL_DIAG_MULTIPLE_KEY */ +# endif /* FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING */ +#endif /* SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC */ + + /* Initialize verification component */ + (void)SecM_InitVerification(V_NULL); + +#if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) + /* Assign segment list array */ + verifyParam.segmentList.segmentInfo = verifySegmentInfo; +#endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT */ + + (void)RamDriver_InitSync(V_NULL); + + + FblDiagInitDownloadSequence(); + +} + +/*********************************************************************************************************************** + * FblDiagGetLastErasedBlock + **********************************************************************************************************************/ +/*! \brief Returns last erased logical block or kBlockNrInvalid if no block has been erased yet. + **********************************************************************************************************************/ +vuint8 FblDiagGetLastErasedBlock( void ) +{ + return lastErasedBlock; +} + +/*********************************************************************************************************************** + * FblDiagSetLastErasedBlock + **********************************************************************************************************************/ +/*! \brief Sets last erased logical block. + * \param[in] blockNr Block number of last erased logical block + **********************************************************************************************************************/ +void FblDiagSetLastErasedBlock( vuint8 blockNr ) +{ + lastErasedBlock = blockNr; +} + +/*********************************************************************************************************************** + * CheckSuppressPosRspMsgIndication + **********************************************************************************************************************/ +/*! \brief This functions checks if a diagnostic response has to be sent and resets the positive response + * message indication bit if necessary + * \param[in,out] subparam Diagnostic subparameter + **********************************************************************************************************************/ +void CheckSuppressPosRspMsgIndication( V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 *subparam ) +{ + if (((*(subparam)) & (kDiagSuppressPosRspMsgIndicationBit)) != 0u) + { + SetSuppressPosRspMsg(); /* Set internal flag for response processor */ + (*(subparam)) &= FblInvertBits(kDiagSuppressPosRspMsgIndicationBit, vuint8); /* Clear indication bit */ + } +} + +/*********************************************************************************************************************** + * FblDiagSegmentInit + **********************************************************************************************************************/ +/*! \brief Initialize the download segment table + **********************************************************************************************************************/ +static void FblDiagSegmentInit( void ) +{ + currentSegment = kDiagSegmentOutOfRange; + diagSegmentList.nrOfSegments = 0u; +} + +/*********************************************************************************************************************** + * FblDiagSegmentNext + **********************************************************************************************************************/ +/*! \brief The parameters of a download section (received by the RequestDownload handler) will be copied into + * the segment table. + * \param[in] segAddr Start address of download segment + * \param[in] segLength Length of download segment + * \param[in] blockIdx Index of the logical block which is the target of the download segment + * \return Index of current list entry + **********************************************************************************************************************/ +static vuint8 FblDiagSegmentNext( tFblDiagAddr segAddr, tFblLength segLength, vuint8 blockIdx ) +{ + vuint8 result; + + /* Compare currently used number of address regions against configured max. value */ + if (diagSegmentList.nrOfSegments < SWM_DATA_MAX_NOAR) + { + currentSegment = diagSegmentList.nrOfSegments; + + /* Store segment address, length and logical block index for later use */ + diagSegmentList.segmentInfo[currentSegment].targetAddress = FblDiagGetMemAddr(segAddr); + diagSegmentList.segmentInfo[currentSegment].length = segLength; + + /* Store reference to this segment in blockHeader */ + blockHeader[blockIdx].segmentIdx[blockHeader[blockIdx].nrOfSegments] = currentSegment; + + /* Increment segment counters */ + diagSegmentList.nrOfSegments++; + blockHeader[blockIdx].nrOfSegments++; + + /* Return index of current list entry */ + result = currentSegment; + } + else + { + /* Segment list full, reject creation of new entry */ + result = kDiagSegmentOutOfRange; + } + + return result; +} + +/*********************************************************************************************************************** + * FblDiagGetMaxTransferDataBlockLength + **********************************************************************************************************************/ +/*! \brief Evaluate maximum TransferData block length for active connection + * \details Length is the minimum of link payload length and configured diagnostic buffer size + * \return TransferData block length applicable for active connection + **********************************************************************************************************************/ +static tCwDataLengthType FblDiagGetMaxTransferDataBlockLength(void) +{ + tCwDataLengthType maxBlockLength; + + /* Get payload limit of active communication link */ + maxBlockLength = FblCwGetPayloadLimit(); + + /* Limit block length to available diagnostic buffer size */ + if (FBL_DIAG_BUFFER_LENGTH < maxBlockLength) + { + maxBlockLength = FBL_DIAG_BUFFER_LENGTH; + } + +#if defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) +#else + /* Align length to maximum memory segment size */ + maxBlockLength = (tCwDataLengthType)(((maxBlockLength - 2u) & FblInvert32Bit(FBL_MAX_SEGMENT_SIZE - 1u)) + 2u); +#endif /* FBL_ENABLE_UNALIGNED_DATA_TRANSFER */ + + return maxBlockLength; +} + +/*********************************************************************************************************************** + * FblDiagPostInit + **********************************************************************************************************************/ +/*! \brief This function is called from FblInit() + * \details The diagnostic buffer is prepared to be able to handle the diagnostic request. + **********************************************************************************************************************/ +void FblDiagPostInit( void ) +{ + + if (GetLockedByInit()) + { + if (kFblOk == FblCwPrepareResponseAddress()) + { + /* Clear state if programming session request "simulation" could be done */ + ClrLockedByInit(); + /* Prepare diag buffer */ + diagServiceCurrent = kDiagSidDiagnosticSessionControl; + DiagBuffer[kDiagFmtServiceId] = kDiagSidDiagnosticSessionControl; + DiagBuffer[kDiagFmtSubparam] = kDiagSubProgrammingSession; + /* Omit response for programming request */ + DiagBuffer[kDiagFmtSubparam] |= 0x80u; + DiagDataLength = kDiagRqlDiagnosticSessionControl; + + + /* Simulate data indication */ + FblDiagRxStartIndication(); + FblDiagRxIndication(DiagBuffer, DiagDataLength + 1u); + } + else + { + /* Do the same as if a functional tester present with SPRMB was received in order to unlock/free + * the diagnostic buffer for new requests */ + DiagResetResponseHandling(); + FblCwResetRxBlock(); + } + } +} + + + +/*********************************************************************************************************************** + * FblDiagSessionTransition + **********************************************************************************************************************/ +/*! \brief Common tasks which shall be executed during session transition + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return kFblOk: Session transition completed successfully + * kFblFailed: Session transition failed + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +static tFblResult FblDiagSessionTransition(V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 *pbDiagBuffer, tCwDataLengthType diagReqDataLen) +{ + tFblResult result = kFblOk; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */ + (void)pbDiagBuffer; + (void)diagReqDataLen; +#endif + + /* Reset internal states */ + ClrSecurityKeyAllowed(); + ClrTransferDataAllowed(); + ClrTransferDataSucceeded(); + + FblDiagInitDownloadSequence(); + + + return result; +} + +/*********************************************************************************************************************** + * FblDiagSessionControlParamInit + **********************************************************************************************************************/ +/*! \brief General initialization of response parameter and download preparation. + * \pre All other conditions for a successful session transition have been fulfilled. + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + **********************************************************************************************************************/ +static void FblDiagSessionControlParamInit(V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 *pbDiagBuffer, tCwDataLengthType diagReqDataLen) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; +#endif + + /* + * Save the requested session type and adapt the P2 timing (if required). + * Note: the SPRMIB has been cleared by CheckSuppressPosRspMsgIndication() + * before and doesn't have to be considered here. + */ + SetDiagSessionType(pbDiagBuffer[kDiagFmtSubparam]); + + /* Diagnostic session timing */ + pbDiagBuffer[kDiagFmtSubparam + 1u] = (vuint8)(GetDiagSessionTimingP2() >> 8u); + pbDiagBuffer[kDiagFmtSubparam + 2u] = (vuint8) GetDiagSessionTimingP2(); + pbDiagBuffer[kDiagFmtSubparam + 3u] = (vuint8)(GetDiagSessionTimingP2Star() >> 8u); + pbDiagBuffer[kDiagFmtSubparam + 4u] = (vuint8) GetDiagSessionTimingP2Star(); +} + +/* Diagnostic service handlers *********************************************/ + +/*********************************************************************************************************************** + * FblDiagMainHandlerDefaultSession + **********************************************************************************************************************/ +/*! \brief Switch to default session, issue reset if necessary + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerDefaultSession) +{ + /* Switch to default session by issuing a reset */ + + /* Initialize parameters for SessionControl response */ + FblDiagSessionControlParamInit(pbDiagBuffer, diagReqDataLen); + + /* The response will be sent by FblDiagEcuReset */ + FblDiagEcuReset(kDiagResetPutResponse, RESET_RESPONSE_SDS_REQUIRED); + + /* Shutdown is performed in main loop */ + + return kFblOk; +} + +/*********************************************************************************************************************** + * FblDiagMainHandlerProgrammingSession + **********************************************************************************************************************/ +/*! \brief Switch to programming session + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerProgrammingSession) +{ + tFblResult result; + V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * localPbDiagBuffer; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)pbDiagBuffer; +#endif + + /* ESCAN00067433: Stop background operations of FblLib_Mem */ + DiagBuffer = FblMemInit(); + localPbDiagBuffer = DiagBuffer; + + /* Deinitialize loaded memory driver(s) */ + FblDeinitMemoryDriver(); + + /* Initialize parameters for SessionControl response */ + FblDiagSessionControlParamInit(localPbDiagBuffer, diagReqDataLen); + + /* + * ESCAN00042572: switch session immediately to ensure correct S3 timer + * handling in DiagResponseProcessor()/FblDiagTpConfirmation(). + */ + SetDiagProgrammingSession(); + + /* Send response */ + DiagProcessingDone(kDiagRslDiagnosticSessionControl); + + /* Execute common (post) session transition tasks */ + result = FblDiagSessionTransition(localPbDiagBuffer, diagReqDataLen); + + + return result; +} + +/*********************************************************************************************************************** + * FblDiagMainHandlerTesterPresent + **********************************************************************************************************************/ +/*! \brief TesterPresent service handling + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerTesterPresent) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */ + (void)pbDiagBuffer; + (void)diagReqDataLen; +#endif + + /* Simply transmit a positive response message */ + DiagProcessingDone(kDiagRslTesterPresent); + + return kFblOk; +} + +/*********************************************************************************************************************** + * FblDiagMainHandlerEcuReset + **********************************************************************************************************************/ +/*! \brief Issue reset + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerEcuReset) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */ + (void)pbDiagBuffer; + (void)diagReqDataLen; +#endif + + FblDiagEcuReset(kDiagResetPutResponse, RESET_RESPONSE_ECURESET_REQUIRED); + + /* Shutdown is performed in main loop */ + return kFblOk; +} + +#if defined( FBL_ENABLE_USERROUTINE ) +/*********************************************************************************************************************** + * FblDiagMainHandlerRoutineControl + **********************************************************************************************************************/ +/*! \brief RoutineControl - No (predefined) routine found + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRoutineControl) +{ + tFblResult result; + + result = kFblOk; + + /* + * Call user function to process user specific routine(s). Pass pointer to + * diag buffer which points after the SID. + */ + ApplDiagRoutineControl(&(pbDiagBuffer[kDiagFmtSubparam]), diagReqDataLen); + + if (DiagGetError() == kDiagErrorNone) + { + /* No NRC returned, send the response */ + DiagProcessingDone(DiagDataLength); + } + else + { + result = kFblFailed; + } + + return result; +} +#endif /* FBL_ENABLE_USERROUTINE */ + +/*********************************************************************************************************************** + * FblDiagMainHandlerRcActivateSbl + **********************************************************************************************************************/ +/*! \brief RoutineControl - Activate Secondary Bootloader subroutine + * \pre SBL has been downloaded + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 6050 1 */ /* MD_MSR_STCAL */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcActivateSbl) +{ + tFblResult result; + tBlockDescriptor blockDescriptor; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; +#endif + + /* Send a RCRRP to avoid a timeout during SBL verification and activation */ + DiagExRCRResponsePending(kForceSendResponsePending); + + result = FblLbtGetBlockDescriptorByNr(FBL_LBT_SBL_BLOCK_NUMBER, &blockDescriptor); + + if (kFblOk == result) + { + /* Perform SBL block verification */ + result = ApplFblValidateBlock(blockDescriptor); + } + + if (kFblOk == result) + { + /* Set SBL block state to 'verified' */ + blockHeader[FBL_MTAB_SBL_BLOCK_NUMBER].state = kBlockState_Verified; + result = FblInitMemoryDriver(); + } + + if (result == kFblOk) + { + /* All following download requests are directed to non-volatile memory */ + transferType = DOWNLOAD_FLASH; + /* Activation of SBL (and other memory drivers) succeeded, prepare positive response */ + pbDiagBuffer[kDiagFmtSubRoutineInfo] = (vuint8)((kDiagSubRoutineType1_Sync << 4u) | kDiagSubRoutineStatusCompleted); + } + else + { + /* ESCAN00066098: Activation of SBL failed, send negative response */ + DiagNRCConditionsNotCorrect(); + } + + /* Send response */ + DiagProcessingDone(kDiagRslRcActivateSbl); + + return result; +} + + +/*********************************************************************************************************************** + * FblDiagMainHandlerRcCheckValidApp + **********************************************************************************************************************/ +/*! \brief RoutineControl - Check Valid Application subroutine + * \pre Application software has been downloaded + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 6010, 6030, 6050, 6080 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcCheckValidApp) +{ + tFblResult result; + tFblLbtBlockFilter blockFilter; + tBlockDescriptor iterBlock; + tDiagSegmentList localSegmentList; + FL_SegmentListType localSegmentListSB; + FL_SegmentInfoType segListPerBlock[SWM_DATA_MAX_NOAR]; + vuint8 idxSeg; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; +#endif + + /* Initialize return value */ + result = kFblOk; + /* Initialize localSegmentList */ + localSegmentList.nrOfSegments = 0u; + for(idxSeg = 0u; idxSeg < SWM_DATA_MAX_NOAR; idxSeg++) + { + localSegmentList.segmentInfo[idxSeg].targetAddress = 0u; + localSegmentList.segmentInfo[idxSeg].length = 0u; + } + + /* Check if any data was downloaded besides the SBL */ + if ((kBlockNrInvalid != currentBlock) && (FBL_MTAB_SBL_BLOCK_NUMBER != currentBlock)) + { + /* Send RCRRP message to avoid a P2 timeout during validation */ + DiagExRCRResponsePending(kForceSendResponsePending); + + /* Iterate over logical blocks to determine the validity of the downloaded software/data */ + FblLbtBlockFilterInit(&blockFilter); + FblLbtBlockFilterSetBlockType(&blockFilter, kBlockTypeApplication); + iterBlock = FblLbtBlockFirst(&blockFilter); + while (FblLbtBlockDone() == FALSE) + { + { + /* Check validity of logical block by calling ApplFblValidateBlock() */ + if (ApplFblValidateBlock(iterBlock) == kFblOk) + { + { + if (blockHeader[iterBlock.blockNr].state == kBlockState_Erased) + { + /* Get the segment list */ + (void)FblDiagGetSegmentList(iterBlock.blockNr, &localSegmentList); + + for(idxSeg = 0u; idxSeg < localSegmentList.nrOfSegments; idxSeg++) + { + segListPerBlock[idxSeg].transferredAddress = localSegmentList.segmentInfo[idxSeg].targetAddress; + segListPerBlock[idxSeg].targetAddress = localSegmentList.segmentInfo[idxSeg].targetAddress; + segListPerBlock[idxSeg].length = localSegmentList.segmentInfo[idxSeg].length; + } + + localSegmentListSB.nrOfSegments = localSegmentList.nrOfSegments; /* PRQA S 2983 */ /* MD_FblDiag_2983_2985_RedundantAssignment */ + localSegmentListSB.segmentInfo = segListPerBlock; /* PRQA S 2983 */ /* MD_FblDiag_2983_2985_RedundantAssignment */ + + /* Update MAC for Secure Boot */ + if (ApplFblUpdateBlockMac(&iterBlock, &localSegmentListSB) == kFblOk) /* PRQA S 2741 */ /* MD_FblDiag_2741 */ + { + /* Set block state to 'verified' */ + blockHeader[iterBlock.blockNr].state = kBlockState_Verified; + } + else + { + /* Check logical block assignment */ + if (iterBlock.mandatoryType == TRUE) /* PRQA S 2880 */ /* MD_FblDiag_2880_UnreachableCode */ + { + /* MAC calculation on mandatory Block failed, set overall verification result to 'failed' */ + result = kFblFailed; + } + } + } + else + { + /* Set block state to 'verified' */ + blockHeader[iterBlock.blockNr].state = kBlockState_Verified; + } + } + } + else + { + /* Check logical block assignment */ + if (iterBlock.mandatoryType == TRUE) + { + /* Mandatory Block not valid, set overall verification result to 'failed' */ + result = kFblFailed; + } + } + } + /* Prepare next cycle */ + iterBlock = FblLbtBlockNext(); + } + + if (kFblOk == result) + { + /* + * All mandatory logical blocks are valid. Let the user do the overall validity check (e.g. compatibility check, + * multi-processor configurations). The result has to be persisted inside the user function and can be + * evaluated during startup in ApplFblIsValidApp(). + */ + result = ApplFblValidateApp(); + } + + /* + * There are three valid return states of the validation function: + * + * result | DiagGetError() | state + * ------------|-----------------|--------------------------------------- + * kFblOk | kDiagErrorNone | download valid, pattern written + * kFblFailed | kDiagErrorNone | download invalid, pattern not written + * kFblFailed | !kDiagErrorNone | download valid, pattern write error + */ + + /* Catch invalid combinations of return value and NRC state */ + assertFblUser(((result == kFblOk) && (DiagGetError() == kDiagErrorNone)) || + ((result != kFblOk) && (DiagGetError() == kDiagErrorNone)) || + ((result != kFblOk) && (DiagGetError() != kDiagErrorNone)), + kFblOemAssertIllegalReturnValue); + + } + + /* Proceed only if no NRC has been set in the user functions */ + if (DiagGetError() == kDiagErrorNone) + { + /* Check if all necessary files are present/compatible for the application to be considered valid */ + if (ApplFblIsValidApp() != kApplValid) + { + pbDiagBuffer[kDiagFmtSubRoutineCheckValidAppStatus] = kDiagSubRoutineApplInvalid; + /* Send positive response */ + DiagProcessingDone(kDiagRslRcCheckValidApp); + } + else + { + { + pbDiagBuffer[kDiagFmtSubRoutineCheckValidAppStatus] = kDiagSubRoutineApplValid; + /* Routine is complete */ + pbDiagBuffer[kDiagFmtSubRoutineInfo] = (vuint8)((kDiagSubRoutineType1_Sync << 4u) | kDiagSubRoutineStatusCompleted); + + /* Send positive response */ + DiagProcessingDone(kDiagRslRcCheckValidApp); + } + } + } + else + { + /* Assure correct return value */ + result = kFblFailed; + } + + + + return result; +} + +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +/*********************************************************************************************************************** + * FblDiagTokenLengthCheck + **********************************************************************************************************************/ +/*! \brief Check whether that the token length is consistent with the received command + * \param[in] cmdType The Token mode from TokenCommandType + * \param[in] tokenLength The token length + * \return Possible return values: + * - tTokenHdlResult: result of the validation operation + **********************************************************************************************************************/ +/* PRQA S 6010, 6030 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC */ +static tTokenHdlResult FblDiagTokenLengthCheck(vuint8 cmdType, vuint16 tokenLength) +{ + tTokenHdlResult resultTkn = kTokenHdlrOk; + + /* Check that the token length is consistent with the received command */ + if (cmdType == FBL_DIAG_TOKEN_CMD_REVERTPROD) + { + /* Mode 0 tokens are supported with and without signature */ + if ((tokenLength != FBL_DIAG_TOKEN_MIN_SIZE) && + (tokenLength != (FBL_DIAG_TOKEN_MIN_SIZE + SEC_SIZE_SIG_RSA2048))) + { + DiagNRCIncorrectMessageLengthOrInvalidFormat(); + resultTkn = kTokenHdlrInternalFailed; + } + } + else if (cmdType == FBL_DIAG_TOKEN_CMD_PROGKEY) + { + /* Mode 5 tokens */ + if (tokenLength != FBL_DIAG_TOKEN_MAX_SIZE) + { + DiagNRCIncorrectMessageLengthOrInvalidFormat(); + resultTkn = kTokenHdlrInternalFailed; + } + } + else + { + /* Mode 1-4 tokens always require a signature */ + if (tokenLength != (FBL_DIAG_TOKEN_MIN_SIZE + SEC_SIZE_SIG_RSA2048)) + { + DiagNRCIncorrectMessageLengthOrInvalidFormat(); + resultTkn = kTokenHdlrInternalFailed; + } + } + + return resultTkn; +} + +/*********************************************************************************************************************** + * FblDiagTokenKeyProcessing + **********************************************************************************************************************/ + /*! \brief Function is used to perform key switching or key programming based on the received cmdType + * \param[in] cmdType The Token mode from TokenCommandType + * \param[in] tokenBufferPtr Pointer to the token + * \return Possible return values: + * - tTokenHdlResult: result of the validation operation + **********************************************************************************************************************/ + /* PRQA S 3673, 6010, 6030, 6080 1 */ /* MD_MSR_Rule8.13, MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STMIF */ +static tTokenHdlResult FblDiagTokenKeyProcessing(vuint8 cmdType, V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tokenBufferPtr) +{ + tTokenHdlResult resultTkn = kTokenHdlrOk; + + switch (cmdType) + { +#if defined( FBL_DIAG_MULTIPLE_KEY ) + /* Multiple Key Use Case */ + case FBL_DIAG_TOKEN_CMD_REVERTPROD: + { + /* Revert back to production key */ + if (FblDiagCopyProductionKeyToUsedPersKey() != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagCopyUsedPersKeyToUsedNotPersKey() != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else + { + /* MISRA */ + } + break; + } + case FBL_DIAG_TOKEN_CMD_USEDEVPERM: + { + /* Use development key until further request */ + if (FblDiagCopyDevelopmentKeyToUsedNotPersKey() != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagCopyDevelopmentKeyToUsedPersKey() != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else + { + /* MISRA */ + } + break; + } + case FBL_DIAG_TOKEN_CMD_USEDEVTEMP: + { + /* Use development key until next reset or Cmd 0 */ + if (FblDiagCopyDevelopmentKeyToUsedNotPersKey() != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + break; + } + case FBL_DIAG_TOKEN_CMD_PROGKEY: + { + vuint8 pubKeyBuffer[FBL_DIAG_KEY_MOD_LENGTH + FBL_DIAG_KEY_EXP_LENGTH]; + + /* Program the new keys contained in the token. */ + if (ApplFblTokenParseKey(FblDiagGetTokenDevKeyIndex(tokenBufferPtr), pubKeyBuffer) != kTokenHdlrOk) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagSetDevelopmentModKey(pubKeyBuffer, FBL_DIAG_KEY_MOD_LENGTH) != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagSetDevelopmentExpKey(&pubKeyBuffer[FBL_DIAG_KEY_MOD_LENGTH], FBL_DIAG_KEY_EXP_LENGTH) != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (ApplFblTokenParseKey(FblDiagGetTokenTokenKeyIndex(tokenBufferPtr), pubKeyBuffer) != kTokenHdlrOk) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagSetTokenModKey(pubKeyBuffer, FBL_DIAG_KEY_MOD_LENGTH) != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagSetTokenExpKey(&pubKeyBuffer[FBL_DIAG_KEY_MOD_LENGTH], FBL_DIAG_KEY_EXP_LENGTH) != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (ApplFblTokenParseKey(FblDiagGetTokenProdKeyIndex(tokenBufferPtr), pubKeyBuffer) != kTokenHdlrOk) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagSetProductionModKey(pubKeyBuffer, FBL_DIAG_KEY_MOD_LENGTH) != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagSetProductionExpKey(&pubKeyBuffer[FBL_DIAG_KEY_MOD_LENGTH], FBL_DIAG_KEY_EXP_LENGTH) != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagSetUsedPersModKey(pubKeyBuffer, FBL_DIAG_KEY_MOD_LENGTH) != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagSetUsedPersExpKey(&pubKeyBuffer[FBL_DIAG_KEY_MOD_LENGTH], FBL_DIAG_KEY_EXP_LENGTH) != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagSetUsedNotPersModKey(pubKeyBuffer, FBL_DIAG_KEY_MOD_LENGTH) != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else if (FblDiagSetUsedNotPersExpKey(&pubKeyBuffer[FBL_DIAG_KEY_MOD_LENGTH], FBL_DIAG_KEY_EXP_LENGTH) != SECM_OK) + { + resultTkn = kTokenHdlrInternalFailed; + } + else + { + /* MISRA */ + } + break; + } + default: + { + resultTkn = kTokenHdlrInternalFailed; + break; + } +#else /* FBL_DIAG_MULTIPLE_KEY */ + /* Single Key Use Case */ + case FBL_DIAG_TOKEN_CMD_REVERTPROD: + { + /* Revert back to production key */ + ClrDiagDevelopmentKey(); + break; + } + case FBL_DIAG_TOKEN_CMD_USEDEVPERM: + { + /* Use development key permanently (Not possible to revert to production key) */ + SetDiagDevelopmentKey(); + if (ApplFblWriteVerificationKey(V_NULL) != kFblOk) + { + resultTkn = kTokenHdlrKeyChangeFailed; + /* Revert back to production key, in case of failure */ + ClrDiagDevelopmentKey(); + } + break; + } + case FBL_DIAG_TOKEN_CMD_USEDEVTEMP: + { + /* Use development key until next reset or Cmd 0 */ + SetDiagDevelopmentKey(); + break; + } + case FBL_DIAG_TOKEN_CMD_PROGKEY: + { + vuint8 isDevKeyActive = 0u; + vuint8 pubKeyBuffer[FBL_DIAG_KEY_MOD_LENGTH + FBL_DIAG_KEY_EXP_LENGTH]; + + /* Program the production key contained in the token (Not possible to revert to development key) */ + if (GetDiagDevelopmentKey()) + { + isDevKeyActive = 1u; + } + + ClrDiagDevelopmentKey(); + + if (ApplFblTokenParseKey(FblDiagGetTokenProdKeyIndex(tokenBufferPtr), pubKeyBuffer) == kTokenHdlrOk) + { + /* The Production Key modulo contains sequentially also the exponent */ + if (ApplFblWriteVerificationKey(pubKeyBuffer) != kFblOk) + { + resultTkn = kTokenHdlrKeyChangeFailed; + if (isDevKeyActive == 1u) + { + SetDiagDevelopmentKey(); + } + } + } + else + { + resultTkn = kTokenHdlrInternalFailed; + } + break; + } + default: + { + resultTkn = kTokenHdlrInternalFailed; + break; + } +#endif /* FBL_DIAG_MULTIPLE_KEY */ + } + + return resultTkn; +} +/*********************************************************************************************************************** + * FblDiagMainHandlerRcTokenDownload + **********************************************************************************************************************/ +/*! \brief RoutineControl - Download a Token from the tester into internal RAM + * \pre Diagnostic module shall be initialized + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 6010, 6030, 6080 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STMIF */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcTokenDownload) +{ + SecM_SignatureParamType verifyToken; + SecM_AsymKeyType keyChangeKey; + vuint8 *tokenBufferPtr; + tTokenHdlResult resultTkn = kTokenHdlrOk;; + tFblResult result; + vuint8 cmdType; + vuint16 tokenLength; + + /* Check programming mode - if the SBL is not present and activated, send NRC and do not process token further */ + if (!GetMemDriverInitialized()) + { + DiagNRCRequestSequenceError(); + } + else + { + tokenLength = diagReqDataLen - 3u; + tokenBufferPtr = &pbDiagBuffer[kDiagFmtRoutineIdDataRecord]; + /* Token shall be verified with respective key */ + verifyTokenSignLength = tokenLength - SEC_SIZE_SIG_RSA2048; + /* Extract command */ + cmdType = FblDiagGetTokenCommandType(tokenBufferPtr); + + /* Check that the token length is consistent with the received command */ + resultTkn = FblDiagTokenLengthCheck(cmdType, tokenLength); + + /* Signature verification shall not be done for revert to production command */ + if ((cmdType != FBL_DIAG_TOKEN_CMD_REVERTPROD) && (resultTkn == kTokenHdlrOk)) + { + /* Here the Token signature will be verified */ + /* This verification shall be in common between MKU and SKU */ + /* Forcing the usage of an internal workspace */ + verifyToken.currentHash.sigResultBuffer = (SecM_ResultBufferType)SEC_DEFAULT_WORKSPACE; /* PRQA S 0306 */ /* MD_FblDiag_0306 */ + verifyToken.currentHash.length = SEC_DEFAULT_WORKSPACE_SIZE; + verifyToken.currentDataLength = V_NULL; + verifyToken.sigSourceBuffer = tokenBufferPtr; + verifyToken.sigByteCount = verifyTokenSignLength; + verifyToken.wdTriggerFct = &FblRealTimeSupportVoid; + + if (FblDiagGetTokenKeyIndex(tokenBufferPtr) == FBL_DIAG_TOKEN_KEY_INDEX_0) + { + resultTkn = ApplFblGetTokenVerificationKey(&keyChangeKey); + verifyToken.key = (SecM_VerifyKeyType)&keyChangeKey; /* PRQA S 0314 */ /* MD_FblDiag_0314_KeyPtr */ + } + else + { + /* For mode 1-4 use default internally configured key */ + verifyToken.key = V_NULL; + } + } + + if ((cmdType != FBL_DIAG_TOKEN_CMD_REVERTPROD) && (resultTkn == kTokenHdlrOk)) + { + verifyToken.sigState = SEC_HASH_INIT; + resultTkn = kTokenHdlrSignatureFailed; + + if (FblDiagVerifyTokenSignature(&verifyToken) == SECM_VER_OK) + { + verifyToken.sigState = SEC_HASH_COMPUTE; + if (FblDiagVerifyTokenSignature(&verifyToken) == SECM_VER_OK) + { + verifyToken.sigState = SEC_HASH_FINALIZE; + if (FblDiagVerifyTokenSignature(&verifyToken) == SECM_VER_OK) + { + verifyToken.sigState = SEC_SIG_VERIFY; + verifyToken.sigSourceBuffer = &tokenBufferPtr[verifyTokenSignLength]; + verifyToken.sigByteCount = SEC_SIZE_SIG_RSA2048; + if (FblDiagVerifyTokenSignature(&verifyToken) == SECM_VER_OK) + { + resultTkn = kTokenHdlrOk; + } + } + } + } + } + + /* Do token validation */ + if (resultTkn == kTokenHdlrOk) + { + resultTkn = ApplFblPreValidateToken(tokenBufferPtr); + + if(resultTkn == kTokenHdlrOk) + { + resultTkn = FblDiagValidateToken(tokenBufferPtr); + } + } + + /* Do token copy into NVM after validation successfull */ + if (resultTkn == kTokenHdlrOk) + { + /* Token shall be stored into the NVM */ + if (ApplFblWriteToken(tokenBufferPtr, tokenLength) != kFblOk) + { + resultTkn = kTokenHdlrInternalFailed; + } + } + + /* For mode 3 and 4 perform only Token validation, other modes perform key switch or key reprogramming */ + if ((cmdType != FBL_DIAG_TOKEN_CMD_USEDEVDATE) && (cmdType != FBL_DIAG_TOKEN_CMD_USEDEVIGNI) && (resultTkn == kTokenHdlrOk)) + { + resultTkn = FblDiagTokenKeyProcessing(cmdType, tokenBufferPtr); + } + + /* Call callouts for every mode */ + if (resultTkn == kTokenHdlrOk) + { + resultTkn = FblDiagTokenCallout(cmdType, tokenBufferPtr, tokenLength); + } + } + + if (DiagGetError() == kDiagErrorNone) + { + /* Send positive response */ + pbDiagBuffer[kDiagFmtSubRoutineInfo] = (vuint8)resultTkn; + DiagProcessingDone(kDiagRslRcTokenDownload); + result = kFblOk; + } + else + { + result = kFblFailed; + } + + return result; +} +# endif /* FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING */ +#endif /* SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC */ + +#if defined( FBL_DIAG_ENABLE_UPDATE_SEC_BYTES ) +/*********************************************************************************************************************** + * FblDiagMainHandlerRcUpdateSecBytes + **********************************************************************************************************************/ +/*! \brief RoutineControl - Update Security Bytes subroutine (0x0305) + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcUpdateSecBytes) +{ + tFblResult result = kFblOk; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; +#endif + + /* Check programming mode - is the SBL present and activated? */ + if (!GetMemDriverInitialized()) + { + DiagNRCConditionsNotCorrect(); + } + else + { + /* Check if write request is targeted at the correct security level */ + if (pbDiagBuffer[kDiagFmtSubRoutineUpdateSecBytesLevel] != kDiagSecLevelFlash) + { + /* Invalid security level */ + DiagNRCRequestOutOfRange(); + } + else + { + /* Write security bytes to non-volatile memory */ + result = ApplFblWriteSecurityBytes(&pbDiagBuffer[kDiagFmtSubRoutineUpdateSecBytesValue], kSecSecretKeyLength); + } + } + + /* Send response immediately if no NRC has been set */ + if (DiagGetError() == kDiagErrorNone) + { + /* No NRC has been set, prepare positive response */ + pbDiagBuffer[kDiagFmtSubRoutineIdPar] = (vuint8)((kDiagSubRoutineType1_Sync << 4) | kDiagSubRoutineStatusCompleted ); + + /* Send positive response */ + DiagProcessingDone(kDiagRslRcUpdateSecBytes); + } + else + { + /* NRC has been set, set correct return value */ + result = kFblFailed; + } + + return result; +} +#endif /* FBL_DIAG_ENABLE_UPDATE_SEC_BYTES */ + +/*********************************************************************************************************************** + * FblDiagMainHandlerRcEraseMemory + **********************************************************************************************************************/ +/*! \brief RoutineControl - EraseMemory subroutine + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 6010, 6030, 6050 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcEraseMemory) +{ + tFblResult result = kFblOk; + tBlockDescriptor eraseBlockDescriptor = {0}; + tFblMemBlockInfo blockInfo = {0}; + tFblAddress eraseAddress = 0u; + tFblLength eraseLength = 0u; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; +#endif + + /* Initialize return value */ + { + ClrEraseMemorySucceeded(); + + /* Extract erase region information from the diag buffer */ + eraseAddress = (tFblAddress)FblMemGetInteger(kDiagRqlRcEraseMemoryAddress, &pbDiagBuffer[kDiagFmtSubRoutineEraseMemoryAddress]); + eraseLength = (tFblLength)FblMemGetInteger(kDiagRqlRcEraseMemoryLength, &pbDiagBuffer[kDiagFmtSubRoutineEraseMemorySize]); + + /* Check if the memory driver has been downloaded and initialized */ + if (!GetMemDriverInitialized()) + { + /* Routine not supported in PBL */ + DiagNRCConditionsNotCorrect(); + result = kFblFailed; + } + } + + if (result == kFblOk) + { + /* Retrieve index of logical block (blockNr is kBlockNrInvalid in case of failure) */ + result = FblLbtGetBlockDescriptorByAddressLength(eraseAddress, eraseLength, &eraseBlockDescriptor); + if ((result != kFblOk) + /* Check exact match of requested erase area with logical block */ + || (eraseBlockDescriptor.blockStartAddress != eraseAddress) + || (eraseBlockDescriptor.blockLength != eraseLength) + ) + { + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } + } + + if (result == kFblOk) + { + /* Check type of requested block */ + if (eraseBlockDescriptor.blockNr == FBL_MTAB_SBL_BLOCK_NUMBER) + { + /* Reject all erase requests which are directed to the SBL block */ + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } + } + + if (result == kFblOk) + { +#if defined( FBL_ENABLE_FLASH_ERASED_DETECTION ) + if (ApplFblGetBlockErased(eraseBlockDescriptor) == kFlashErased) + { + result = kFblOk; + } + else +#endif /* FBL_ENABLE_FLASH_ERASED_DETECTION */ + { + /* Avoid P2 timeout during invalidation */ + DiagExRCRResponsePending(kForceSendResponsePending); + + /* Invalidate application before erase procedure */ + result = ApplFblInvalidateBlock(eraseBlockDescriptor); + + /* Catch invalid combinations of return value and NRC state */ + assertFblUser(((result == kFblOk) && (DiagGetError() == kDiagErrorNone)) || + ((result != kFblOk) && (DiagGetError() != kDiagErrorNone)), + kFblOemAssertIllegalReturnValue); + + /* Proceed only if all entry conditions and block invalidation succeeded */ + if (result == kFblOk) + { + /* Start erase procedure */ + blockInfo.targetAddress = eraseBlockDescriptor.blockStartAddress; + blockInfo.targetLength = eraseBlockDescriptor.blockLength; + blockInfo.logicalAddress = eraseBlockDescriptor.blockStartAddress; + blockInfo.logicalLength = eraseBlockDescriptor.blockLength; + /* Additional members are not used for erase indication */ + + result = FblMemRemapStatus(FblMemBlockEraseIndication(&blockInfo)); + } + + if (result == kFblOk) + { +#if defined( FBL_ENABLE_FLASH_ERASED_DETECTION ) + (void)ApplFblSetBlockErased(eraseBlockDescriptor); +#endif + } + } + } + + if (result == kFblOk) + { + /* Remember erased state */ + SetEraseMemorySucceeded(); + lastErasedBlock = eraseBlockDescriptor.blockNr; + blockHeader[eraseBlockDescriptor.blockNr].state = kBlockState_Erased; + } + + /* Send response immediately if no NRC has been set */ + if (DiagGetError() == kDiagErrorNone) + { + /* No NRC has been set, prepare positive response */ + if (result == kFblOk) + { + pbDiagBuffer[kDiagFmtSubRoutineIdPar] = (vuint8)((kDiagSubRoutineType1_Sync << 4) | kDiagSubRoutineStatusCompleted ); + /* Send positive response */ + DiagProcessingDone(kDiagRslRcEraseMemory); + } + else + { + /* ESCAN00066098: Erase procedure failed, send negative response */ + DiagNRCGeneralProgrammingFailure(); + } + } + else + { + /* NRC has been set, set correct return value */ + result = kFblFailed; + } + + return result; +} + +/*********************************************************************************************************************** + * FblDiagMainHandlerRcCheckProgDep + **********************************************************************************************************************/ +/*! \brief RoutineControl - CheckProgrammingDependencies subroutine + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRcCheckProgDep) +{ + tFblAddress checkStartAddress; + tFblLength checkLength; + tFblResult result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; +#endif + + /* Extract check address range */ + checkStartAddress = FblMemGetInteger(kDiagRqlRcCheckProgDepMemoryAddress, &pbDiagBuffer[kDiagFmtSubRoutineCheckMemoryAddress]); + checkLength = FblMemGetInteger(kDiagRqlRcCheckProgDepMemorySize, &pbDiagBuffer[kDiagFmtSubRoutineCheckMemorySize]); + + if (checkLength < kDiagCheckProgDepAdressMinLength) + { + /* Address length is under the minimal length */ + result = kFblFailed; + } + else if (FblMemSegmentNrGet(checkStartAddress) < 0) + { + /* Address start is not located in the Flash Block Table */ + result = kFblFailed; + } + else if (FblMemSegmentNrGet(checkStartAddress + checkLength - 1u) < 0) + { + /* Address end is not located in the Flash Block Table */ + result = kFblFailed; + } + else + { + result = kFblOk; + } + + /* Ensure that a valid address */ + if (result != kFblOk) + { + /* Requested download region does not meet requirements; abort service handling */ + DiagNRCRequestOutOfRange(); + } + else + { + /* Setup segment information */ + verifySegmentInfo[0].targetAddress = checkStartAddress; + verifySegmentInfo[0].transferredAddress = checkStartAddress; + verifySegmentInfo[0].length = checkLength; + verifyParam.segmentList.nrOfSegments = 1; + + /* Trigger checksum calculation */ + verifyParam.blockStartAddress = checkStartAddress; + verifyParam.blockLength = checkLength; + /* No actual verification data included in request */ + verifyParam.verificationData = verifyOutputBuf; + verifyParam.wdTriggerFct = &FblRealTimeSupportVoid; + /* Routine is restricted to ROM access */ + verifyParam.readMemory = (FL_ReadMemoryFctType)&FblReadProm; + + /* Call HIS verification interface to calculate CRC */ + if (SECM_VER_OK == FblDiagVerification(&verifyParam)) + { + /* RoutineInfo */ + pbDiagBuffer[kDiagFmtSubRoutineInfo] = (vuint8)((kDiagSubRoutineType1_Sync << 4) | kDiagSubRoutineStatusCompleted); + + /* CRC value is stored in last two byte of buffer */ /* PRQA S 0314 1 */ /* MD_FblDiag_0314_MemCpy */ + (void)MEMCPY(&pbDiagBuffer[kDiagFmtSubRoutineCrcHigh], &verifyOutputBuf[FBL_DIAG_CRC_OFFSET], SEC_SIZE_CHECKSUM_CRC); + + /* Send positive response */ + DiagProcessingDone(kDiagRslRcCheckProgDep); + } + else + { + /* ESCAN00066098: Verification failed (most likely memory read error), send negative response */ + DiagNRCGeneralReject(); + result = kFblFailed; + } + } + + return result; +} + + +/*********************************************************************************************************************** + * FblDiagSecAccessSeed + **********************************************************************************************************************/ +/*! \brief Process security seed request + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \param[in] secLevel Requested security level + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +static tFblResult FblDiagSecAccessSeed(V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * pbDiagBuffer, tCwDataLengthType diagReqDataLen, vuint8 secLevel ) +{ + vuint8 returnCode; + vuint8 i; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; + (void)secLevel; +# if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) +# else + (void)pbDiagBuffer; /* PRQA S 3112 */ /* MD_MSR_DummyStmt */ +# endif +#endif + +#if ( SYSSERVICE_SECMODHIS_VERSION >= 0x0300u ) + /* Cancel all SecM jobs if security access is performed anew, for example if the download is restarted */ + SecM_CancelAllJobs(); +#endif + + /* Get currently unlocked level */ + if (GetCurrentSecLvl() != kDiagSecLevelNone) + { + /* ECU is already unlocked, send zero seed */ + for (i = 0; i < GetRequestedSeedLength(); i++) + { + pbDiagBuffer[kDiagFmtSeedKeyStart + i] = 0x00u; + } + + /* Security access already granted. Don't allow a key to be submitted. */ + ClrSecurityKeyAllowed(); + returnCode = kFblFailed; + } + else + { + /* Generate seed by application function */ + if (ApplFblSecuritySeed() == kFblOk) + { + /* Accept security key next */ + returnCode = kFblOk; +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) + /* Remember security level */ + diagRequestedSecLvl = pbDiagBuffer[kDiagFmtSubparam]; +#endif + } + else + { + /* Error occurred during seed computation */ + FblErrStatSetError(FBL_ERR_SEED_GENERATION_FAILED); + DiagNRCConditionsNotCorrect(); + returnCode = kFblFailed; + } + } + +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) + if (returnCode != kFblOk) + { + /* Invalidate requested security level */ + diagRequestedSecLvlIdx = kDiagInvalidSecLvlIdx; + } +#endif + + /* Set response length used by fbl_diag: (SID +) sub parameter + seed length */ + DiagProcessingDone(1u + GetRequestedSeedLength()); + + return returnCode; +} + +/*********************************************************************************************************************** + * FblDiagSecAccessKey + **********************************************************************************************************************/ +/*! \brief Process security key request + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \param[in] secLevel Requested security level + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +static tFblResult FblDiagSecAccessKey(V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * pbDiagBuffer, tCwDataLengthType diagReqDataLen, vuint8 secLevel) +{ + vuint8 returnCode; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; + (void)secLevel; +#endif + + /* + * Clearing the SecurityKeyAllowed state cannot be done automatically + * (by the dispatcher) because errors other than key comparison (e.g. + * length check) should not reset the state. + */ + ClrSecurityKeyAllowed(); + + /* Check security access key in application function */ + returnCode = ApplFblSecurityKey(); + + if (returnCode != kFblOk) + { + /* Set NRC */ + DiagNRCInvalidKey(); + } + else + { + SetCurrentSecLvl((vuint8)(pbDiagBuffer[kDiagFmtSubparam] - 1u)); + DiagProcessingDone(kDiagRslSecurityAccessKey); + } + + return returnCode; +} + +/*********************************************************************************************************************** + * FblDiagMainHandlerSecAccessSeed + **********************************************************************************************************************/ +/*! \brief SecurityAccess - Seed handling for security level "Flash" + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerSecAccessSeed) +{ + return FblDiagSecAccessSeed(pbDiagBuffer, diagReqDataLen, kDiagSecLevelFlash); +} + +/*********************************************************************************************************************** + * FblDiagMainHandlerSecAccessKey + **********************************************************************************************************************/ +/*! \brief SecurityAccess - Key handling for security level "Flash Programming" + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerSecAccessKey) +{ + return FblDiagSecAccessKey(pbDiagBuffer, diagReqDataLen, kDiagSecLevelFlash); +} + +/*********************************************************************************************************************** + * FblDiagMainHandlerRequestDownload + **********************************************************************************************************************/ +/*! \brief RequestDownload service handling + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 2889, 6010, 6030, 6050, 6080 1 */ /* MD_FblDiag_2889, MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRequestDownload) +{ + vuint8 lengthFormat = 0u; + vuint8 addrFormat = 0u; + tFblLbtBlockNr requestedDownloadBlock = 0u; + tBlockDescriptor logicalBlockDescriptor = {0}; + tFblLength transferLength = 0u; + tFblMemSegmentInfo segInfo; + tFblMemBlockInfo blockInfo; + tFblResult result = kFblOk; + tCwDataLengthType maxBlockLength; + V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * localPbDiagBuffer = V_NULL; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) +# if defined( FBL_DIAG_ENABLE_FIXED_TRANSFER_ALFI ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; +# endif +#endif + +/* Initialize return value */ + { + localPbDiagBuffer = pbDiagBuffer; + + /* Get encryption and compression method */ + dataFormatId = localPbDiagBuffer[kDiagFmtSubparam]; + +#if defined( FBL_DIAG_ENABLE_FIXED_TRANSFER_ALFI ) + if (localPbDiagBuffer[kDiagFmtFormatOffset] != ((vuint8)(kDiagSubMaxLengthFormat << 4u) | kDiagSubMaxAddrFormat)) + { + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } + + lengthFormat = kDiagSubMaxLengthFormat; + addrFormat = kDiagSubMaxAddrFormat; +#else + /* Get address- and length format */ + lengthFormat = (vuint8)((localPbDiagBuffer[kDiagFmtFormatOffset] & kDiagFmtLengthMask) >> 4u); + addrFormat = (vuint8)(localPbDiagBuffer[kDiagFmtFormatOffset] & kDiagFmtAddrMask); + + if ((lengthFormat < kDiagSubMinLengthFormat) + || (lengthFormat > kDiagSubMaxLengthFormat) + || (addrFormat < kDiagSubMinAddrFormat) + || (addrFormat > kDiagSubMaxAddrFormat)) + { + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } + + if (result == kFblOk) + { + if (diagReqDataLen != (kDiagRqlRequestDownload + lengthFormat + addrFormat)) + { + DiagNRCIncorrectMessageLengthOrInvalidFormat(); + result = kFblFailed; + } + } +#endif /* FBL_DIAG_ENABLE_FIXED_TRANSFER_ALFI */ + } + + if (result == kFblOk) + { +#if defined( FBL_ENABLE_DATA_PROCESSING ) +# if defined( FBL_ENABLE_ENCRYPTION_MODE ) +# else + /* No encrypted data supported */ + if (FblDiagGetEncryptionMode(dataFormatId) != kDiagSubNoEncryption) + { + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } +# endif /* FBL_ENABLE_ENCRYPTION_MODE */ +# if defined( FBL_ENABLE_COMPRESSION_MODE ) +# else + /* No compressed data supported */ + if (FblDiagGetCompressionMode(dataFormatId) != kDiagSubNoCompression) + { + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } +# endif /* FBL_ENABLE_COMPRESSION_MODE */ +#else + if (dataFormatId != kDiagSubNoDataProcessing) + { + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } +#endif /* FBL_ENABLE_DATA_PROCESSING */ + } + + if (result == kFblOk) + { + /* Init expected sequence counter for TransferData */ + expectedSequenceCnt = kDiagInitSequenceNum; + /* Init current sequence counter for TransferData */ + currentSequenceCnt = kDiagInitSequenceNum; + + /* Extract address and length from request */ + transferAddress = (tFblAddress)FblMemGetInteger(addrFormat, &localPbDiagBuffer[kDiagFmtAddrOffset]); + transferRemainder = (tFblLength)FblMemGetInteger(lengthFormat, &localPbDiagBuffer[kDiagFmtAddrOffset + addrFormat]); + + /* Check if length is equal to zero */ + if (transferRemainder == 0u) + { + /* Length zero is unaccepted */ + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } + } + + if (result == kFblOk) + { +#if defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) + /* + * If the requested download contains compressed or encrypted data, the requested download length refers to the + * size of the transfer data (i.e. the length of the processed (decrypted/decompressed) data may differ from the + * requested download length). + */ + if (dataFormatId != kDiagSubNoDataProcessing) + { + /* + * Check the start address only. Flash boundary check not possible here because the resulting length of the + * processed data is not known. Additional check performed in programming routine. + */ + transferLength = 1u; + } + else +#endif /* FBL_ENABLE_PROCESSED_DATA_LENGTH */ + { + transferLength = transferRemainder; + } + + /* Retrieve block descriptor of requested logical block */ + result = FblLbtGetBlockDescriptorByAddressLength(transferAddress, transferLength, &logicalBlockDescriptor); + + /* Ensure that a valid block is set */ + if (result != kFblOk) + { + /* Requested download region is outside of the configured logical blocks; abort service handling */ + DiagNRCRequestOutOfRange(); + } + } + + if (result == kFblOk) + { + requestedDownloadBlock = logicalBlockDescriptor.blockNr; + + if (transferType == DOWNLOAD_FLASH) + { + /* Check state flags */ + if (!GetMemDriverInitialized()) + { + DiagNRCConditionsNotCorrect(); + result = kFblFailed; + } + } + else /* transferType == DOWNLOAD_RAM */ + { + assertFbl(!GetMemDriverInitialized(), kFblOemAssertIllegalExecutionPath); + + /* Check type of requested block */ + if (requestedDownloadBlock != FBL_MTAB_SBL_BLOCK_NUMBER) + { + /* Still in PBL: reject all downloads which are not directed to the SBL block */ + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } + + if (result == kFblOk) + { + /* Restrict execution sequence and perform auto-erase */ + if (blockHeader[requestedDownloadBlock].state == kBlockState_Init) + { + /* "Erase" flash code array (remove spurious code in buffer, support writing of presence pattern) */ + /* Note: since the block state is reset in SessionControl, this will also clean up the flashcode buffer */ + assertFbl(FLASH_SIZE == logicalBlockDescriptor.blockLength, kFblSysAssertParameterOutOfRange); + if (kFblMemStatus_Ok == FblMemEraseRegion(logicalBlockDescriptor.blockStartAddress, logicalBlockDescriptor.blockLength)) + { + blockHeader[requestedDownloadBlock].state = kBlockState_Erased; + } + } + } + } + } + + if (result == kFblOk) + { + /* Check if the respective logical block has been erased */ + if (blockHeader[requestedDownloadBlock].state != kBlockState_Erased) + { + /* Requested download region has not been erased; abort service handling */ + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } + } + + if (result == kFblOk) + { + (void)ApplFblAdjustLbtBlockData(&logicalBlockDescriptor); + + /* Check if requested download block overwrites presence pattern (or exceeds logical block) */ + if ((transferAddress + transferLength) > (logicalBlockDescriptor.blockStartAddress + logicalBlockDescriptor.blockLength)) + { + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } + } + + if (result == kFblOk) + { + /* Copy data and address of segment to initialize diagSegmentList */ + if (FblDiagSegmentNext(transferAddress, transferRemainder, requestedDownloadBlock) == kDiagSegmentOutOfRange) + { + FblErrStatSetError(FBL_ERR_TOO_MANY_SEGMENTS_IN_MODULE); + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } + } + + if (result == kFblOk) + { + /*** Download request has been accepted ***/ + + /* Initialize block data used by FblLib_Mem */ + blockInfo.targetAddress = logicalBlockDescriptor.blockStartAddress; + blockInfo.targetLength = logicalBlockDescriptor.blockLength; + blockInfo.logicalAddress = blockInfo.targetAddress; + blockInfo.logicalLength = blockInfo.targetLength; + blockInfo.verifyRoutineInput.function = V_NULL; + blockInfo.verifyRoutineInput.param = V_NULL; + blockInfo.segmentList = &verifyParam.segmentList; + blockInfo.maxSegments = 1u; /* Only a single segment per block */ +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Check if a customer function is configured for this logical block */ + if (SecM_Default != logicalBlockDescriptor.verifyOutput) + { + /* Switch to output verification (customer function will be set in FblDiagVerification() */ + blockInfo.verifyRoutineOutput.function = &FblDiagVerification; + blockInfo.verifyRoutineOutput.param = &verifyParam; + blockInfo.verifyRoutinePipe.function = V_NULL; + blockInfo.verifyRoutinePipe.param = V_NULL; + } + else + { + /* Initialize the calculation (CCC: SHA256, DDD: CRC16) */ + pipeVerifyParam.currentHash.sigResultBuffer = (vuint32)pipeVerifyBuf; /* PRQA S 0306 */ /* MD_FblDiag_0306 */ + pipeVerifyParam.currentHash.length = sizeof(pipeVerifyBuf); + pipeVerifyParam.currentDataLength = &pipeVerifyLength; +# if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) + /* Initialize the calculation (CCC: CRC16) */ + pipeVerifyParamCrc.currentHash.sigResultBuffer = (vuint32)&pipeVerifyCrc; /* PRQA S 0306 */ /* MD_FblDiag_0306 */ + pipeVerifyParamCrc.currentHash.length = sizeof(pipeVerifyCrc); + pipeVerifyParamCrc.currentDataLength = &pipeVerifyLengthCrc; + blockInfo.verifyRoutinePipe.function = &FblDiagVerifySignature; +# else + blockInfo.verifyRoutinePipe.function = &SecM_VerifyClassDDD; +# endif /* SEC_ENABLE_SECURITY_CLASS_CCC */ + blockInfo.verifyRoutinePipe.param = &pipeVerifyParam; + blockInfo.verifyRoutineOutput.function = V_NULL; + blockInfo.verifyRoutineOutput.param = V_NULL; + } +#else + blockInfo.verifyRoutineOutput.function = &FblDiagVerification; + blockInfo.verifyRoutineOutput.param = &verifyParam; + blockInfo.verifyRoutinePipe.function = V_NULL; + blockInfo.verifyRoutinePipe.param = V_NULL; +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + blockInfo.readFct = &FblReadProm; /* FblWrapperRam required! */ + + /* Indicate the start of a new download block */ + result = FblMemRemapStatus(FblMemBlockStartIndication(&blockInfo)); + (void)FblDiagMemGetActiveBuffer(); + if (result != kDiagErrorNone) + { + DiagSetError(result); + result = kFblFailed; + } + } + + if (result == kFblOk) + { + /* Initialize segment data */ + segInfo.targetAddress = transferAddress; + segInfo.targetLength = transferRemainder; + segInfo.logicalAddress = segInfo.targetAddress; + segInfo.logicalLength = segInfo.targetLength; + segInfo.type = kFblMemType_ROM; /* FblWrapperRam required! */ + segInfo.dataFormat = dataFormatId; + + /* Indicate start of new segment */ + result = FblMemRemapStatus(FblMemSegmentStartIndication(&segInfo)); + localPbDiagBuffer = FblDiagMemGetActiveBuffer(); + + if (result != kDiagErrorNone) + { + DiagSetError(result); + result = kFblFailed; + } + } + + if (result == kFblOk) + { + /* Download of segment accepted: set logical block as "active" */ + currentBlock = requestedDownloadBlock; + +#if defined( FBL_ENABLE_FLASH_ERASED_DETECTION ) + (void)ApplFblClrBlockErased(logicalBlockDescriptor); +#endif + + /* Evaluate maximum block length for TransferData requests */ + maxBlockLength = FblDiagGetMaxTransferDataBlockLength(); + + /* Length format dependent on maximum block length */ + /* PRQA S 2880, 2992, 2996 TAG_FblDiag_ConstValue_1 */ /* MD_FblDiag_ConstValue */ + if (maxBlockLength > 0xFFFFFFuL) + { + lengthFormat = 4u; + } + else if (maxBlockLength > 0xFFFFu) + { + lengthFormat = 3u; + } + else + { + /* Use at least two length bytes */ + lengthFormat = 2u; + } + /* PRQA L:TAG_FblDiag_ConstValue_1 */ + + /* Set length format and maximum block length */ + localPbDiagBuffer[kDiagFmtSubparam] = lengthFormat << 4u; + FblMemSetInteger(lengthFormat, maxBlockLength, &localPbDiagBuffer[kDiagFmtMaxBlockLengthHigh]); + + DiagProcessingDone(kDiagRslRequestDownload + lengthFormat); + + } + else + { + /* In case this was the RD for the SBL, and OTA is enable, revert the current partition in case of failure */ + } + + return result; +} + +/*********************************************************************************************************************** + * FblDiagMainHandlerTransferDataDownload + **********************************************************************************************************************/ +/*! \brief TransferData service handling + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 2889, 3673 1 */ /* MD_FblDiag_2889, MD_MSR_Rule8.13 */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerTransferDataDownload) +{ + tFblResult result; + + /* Check if the requested sequence number is expected */ + if (pbDiagBuffer[kDiagFmtSubparam] != expectedSequenceCnt ) + { + /* Check if sequence number corresponds to a retry */ + if (pbDiagBuffer[kDiagFmtSubparam] == currentSequenceCnt) + { + /* Handle the retries here */ + + /* Repetition of last transferData request */ + /* Simply send a positive response without loading data to memory */ + DiagProcessingDone(kDiagRslTransferData); + + return kFblOk; + } + else /* Sequence number is not for a retry */ + { + /* Send a WrongSequenceError */ + DiagNRCWrongBlockSequenceCounter(); + return kFblFailed; + } + } + + result = FblMemRemapStatus(FblMemDataIndication(DiagBuffer, kDiagFmtDataOffset, (tFblLength)diagReqDataLen - 1u)); + (void)FblDiagMemGetActiveBuffer(); + if (result != kDiagErrorNone) + { + DiagSetError(result); + ClrTransferDataAllowed(); + return kFblFailed; + } + + transferRemainder -= ((tFblLength)diagReqDataLen - 1u); + + if (transferRemainder == 0u) + { + /* Finalize writing the data */ + result = FblMemRemapStatus(FblMemSegmentEndIndication(&totalProgramLength)); + (void)FblDiagMemGetActiveBuffer(); + + if (result != kDiagErrorNone) + { + DiagSetError(result); + return kFblFailed; + } + + result = FblMemRemapStatus(FblMemBlockEndIndication()); + if (result != kDiagErrorNone) + { + DiagSetError(result); + return kFblFailed; + } + + } + + /* Memorize current counter */ + currentSequenceCnt = expectedSequenceCnt; + + /* Sequence counter value of next transferData request */ + expectedSequenceCnt++; + + DiagProcessingDone(kDiagRslTransferData); + return kFblOk; +} + +#if defined( FBL_DIAG_ENABLE_UPLOAD ) +/*********************************************************************************************************************** + * FblDiagMainHandlerRequestUpload + **********************************************************************************************************************/ +/*! \brief RequestUpload service handling + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 2889 1 */ /* MD_FblDiag_2889 */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRequestUpload) +{ + vuint8 lengthFormat, addrFormat; + vuint8 requestedUploadBlock; + tFblResult result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) +# if defined( FBL_DIAG_ENABLE_FIXED_TRANSFER_ALFI ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; +# endif +#endif + + +#if defined( FBL_DIAG_ENABLE_FIXED_TRANSFER_ALFI ) + if (pbDiagBuffer[kDiagFmtFormatOffset] != ((vuint8)(kDiagSubMaxLengthFormat << 4) | kDiagSubMaxAddrFormat)) + { + DiagNRCRequestOutOfRange(); + return kFblFailed; + } + + lengthFormat = kDiagSubMaxLengthFormat; + addrFormat = kDiagSubMaxAddrFormat; +#else + /* Get address- and length format */ + lengthFormat = (vuint8)((pbDiagBuffer[kDiagFmtFormatOffset] & kDiagFmtLengthMask) >> 4); + addrFormat = pbDiagBuffer[kDiagFmtFormatOffset] & kDiagFmtAddrMask; + + if ((lengthFormat < kDiagSubMinLengthFormat) || (lengthFormat > kDiagSubMaxLengthFormat) || (addrFormat < kDiagSubMinAddrFormat) || (addrFormat > kDiagSubMaxAddrFormat)) + { + DiagNRCRequestOutOfRange(); + return kFblFailed; + } + + if (diagReqDataLen != (kDiagRqlRequestDownload + lengthFormat + addrFormat)) + { + DiagNRCIncorrectMessageLengthOrInvalidFormat(); + return kFblFailed; + } +#endif /* FBL_DIAG_ENABLE_FIXED_TRANSFER_ALFI */ + + /* Get encryption and compression method */ + dataFormatId = pbDiagBuffer[kDiagFmtSubparam]; + + /* No encrypted or compressed data supported */ + if (dataFormatId != kDiagSubNoDataProcessing) + { + DiagNRCRequestOutOfRange(); + return kFblFailed; + } + + /* Extract address and length from request */ + transferAddress = (tFblAddress)FblMemGetInteger(addrFormat, &pbDiagBuffer[kDiagFmtAddrOffset]); + transferRemainder = (tFblLength)FblMemGetInteger(lengthFormat, &pbDiagBuffer[kDiagFmtAddrOffset + addrFormat]); + + /* Check if length is equal to zero */ + if (transferRemainder == 0u) + { + /* Length zero is unaccepted */ + DiagNRCRequestOutOfRange(); + return kFblFailed; + } + + /* Retrieve index of logical block (result is kBlockNrInvalid in case of failure) */ + result = FblLbtGetBlockNrByAddressLength(transferAddress, transferRemainder, &requestedUploadBlock); + + /* Ensure that a valid block number is set */ + if (result != kFblOk) + { + /* Requested download region is outside of the configured logical blocks; abort service handling */ + DiagNRCRequestOutOfRange(); + return kFblFailed; + } + + /* Save data and address of segment for CRC calculation in TransferExit */ + if (FblDiagSegmentNext(transferAddress, transferRemainder, requestedUploadBlock) == kDiagSegmentOutOfRange) + { + FblErrStatSetError(FBL_ERR_TOO_MANY_SEGMENTS_IN_MODULE); + DiagNRCRequestOutOfRange(); + return kFblFailed; + } + + /* Check programming mode - is the SBL present and activated? */ + if (!GetMemDriverInitialized()) + { + DiagNRCConditionsNotCorrect(); + return kFblFailed; + } + + /* Init expected sequence counter for TransferData */ + expectedSequenceCnt = kDiagInitSequenceNum; + /* Init current sequence counter for TransferData */ + currentSequenceCnt = kDiagInitSequenceNum; + + /* Use whole diag buffer size as block length for TransferDataUpload */ + maxNumberOfBlockLength = (vuint16)FBL_DIAG_BUFFER_LENGTH; + + /* Number of bytes reserved for maximum block length */ + pbDiagBuffer[kDiagFmtSubparam] = kDiagMaxNumberOfBlockLengthLength << 4u; + + /* Report block length which will be used in TransferDataUpload */ + pbDiagBuffer[kDiagFmtMaxBlockLengthHigh] = (vuint8)((maxNumberOfBlockLength >> 8) & 0xFFu); + pbDiagBuffer[kDiagFmtMaxBlockLengthLow] = (vuint8)(maxNumberOfBlockLength & 0xFFu); + + DiagProcessingDone(kDiagRslRequestUpload + kDiagMaxNumberOfBlockLengthLength); + + return kFblOk; +} + +/*********************************************************************************************************************** + * FblDiagMainHandlerTransferDataUpload + **********************************************************************************************************************/ +/*! \brief TransferData service handling + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 2889 1 */ /* MD_FblDiag_2889 */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerTransferDataUpload) +{ + /* The transfer data length is static to account for potential retries */ + static tCwDataLengthType transferDataUpLength; + /* Temporary buffer used to backup data from the diag buffer that is */ + /* overwritten by a retry upload request */ + static vuint8 tmpUploadBuffer[kDiagFmtTransferDataUploadRetryBackupSize]; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; +#endif + + /* Check if the requested sequence number is expected */ + if (DiagBuffer[kDiagFmtSequenceCnt] != expectedSequenceCnt ) + { + /* Check if sequence number corresponds to a retry */ + if (DiagBuffer[kDiagFmtSequenceCnt] == currentSequenceCnt) + { + vuintx i; + + /* + * Repetition of last TransferData request: retrieve the saved data + * from temporary buffer. + */ + for (i = 0u; i < kDiagFmtTransferDataUploadRetryBackupSize; i++) + { + pbDiagBuffer[kDiagFmtDataOffset + i] = tmpUploadBuffer[i]; + } + + /* Re-upload the data that is still in the buffer */ + DiagProcessingDone(transferDataUpLength + 1u); + return kFblOk; + } + else /* Sequence number is not for a retry */ + { + /* Send a WrongSequenceError */ + DiagNRCWrongBlockSequenceCounter(); + return kFblFailed; + } + } + else /* Sequence number is equal to the one expected */ + { + /* Check if anymore data is expected */ + if (transferRemainder == 0u) + { + /* Send NRC TransferDataSuspended and abort, no more data expected! */ + DiagNRCTransferDataSuspended(); + ClrTransferDataAllowed(); + return kFblFailed; + } + } + + /* Memorize current counter */ + currentSequenceCnt = expectedSequenceCnt; + + /* Sequence counter value of next TransferData request */ + expectedSequenceCnt++; + + /* + * Check if the requested length exceeds the diag buffer size. + * kDiagFmtDataOffset accounts for service ID and block sequence counter. + */ + if (transferRemainder > ((tFblLength)maxNumberOfBlockLength - kDiagFmtDataOffset)) + { + transferDataUpLength = ((tCwDataLengthType)maxNumberOfBlockLength - kDiagFmtDataOffset); + } + else + { + transferDataUpLength = (tCwDataLengthType)transferRemainder; + } + + transferRemainder -= transferDataUpLength; + + /* + * Address being passed is either within flash boundaries or within some + * other type of memory supported by the application. + */ + if (FblReadProm(transferAddress, &pbDiagBuffer[kDiagFmtDataOffset], transferDataUpLength) != transferDataUpLength) + { + /* Tried accessing non supported memory location */ + DiagNRCConditionsNotCorrect(); + return kFblFailed; + } + else /* Success */ + { + vuintx i; + + transferAddress += transferDataUpLength; + + /* + * Backup the DATA bytes in the diag buffer which might be overwritten + * by the single frame reception with a retry upload request. + */ + for (i = 0u; i < kDiagFmtTransferDataUploadRetryBackupSize; i++) + { + tmpUploadBuffer[i] = pbDiagBuffer[kDiagFmtDataOffset + i]; + } + } + + DiagProcessingDone(transferDataUpLength + 1u); + + return kFblOk; +} +#endif /* FBL_DIAG_ENABLE_UPLOAD */ + +/*********************************************************************************************************************** + * FblDiagMainHandlerRequestTransferExit + **********************************************************************************************************************/ +/*! \brief RequestTransferExit service handling + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 3673, 2889, 6010, 6030, 6050 1 */ /* MD_MSR_Rule8.13, MD_FblDiag_2889, MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerRequestTransferExit) +{ + tFblResult result; + tFblMemVerifyStatus verifyResult; + tFblMemBlockVerifyData verifyData = {0}; +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + tExportFct exportFct; +#endif + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)diagReqDataLen; +# if defined( FBL_DIAG_ENABLE_UPLOAD ) +# else + (void)pbDiagBuffer; /* PRQA S 3112 */ /* MD_MSR_DummyStmt */ +# endif /* FBL_DIAG_ENABLE_UPLOAD */ +#endif + + assertFblInternal(currentSegment != kDiagSegmentOutOfRange, kFblOemAssertIllegalParameter); + assertFblInternal(currentBlock != kBlockNrInvalid, kFblOemAssertIllegalParameter); + +#if defined( FBL_DIAG_ENABLE_UPLOAD ) + if (GetTransferDataUpload()) + { + /* This service is allowed after all bytes of the segment are transferred */ + if (transferRemainder != 0u) + { + DiagNRCRequestSequenceError(); + return kFblFailed; + } + } +#endif + + /* Send an initial response pending message */ + DiagExRCRResponsePending(kForceSendResponsePending); + + /* Calculate CRC16-CITT value of the given memory area */ +#if defined( FBL_DIAG_ENABLE_UPLOAD ) + if (GetTransferDataUpload()) + { + result = kFblOk; + + /* Setup segment information */ + verifySegmentInfo[0].targetAddress = diagSegmentList.segmentInfo[currentSegment].targetAddress; + verifySegmentInfo[0].transferredAddress = diagSegmentList.segmentInfo[currentSegment].targetAddress; + verifySegmentInfo[0].length = diagSegmentList.segmentInfo[currentSegment].length; + verifyParam.segmentList.nrOfSegments = 1u; + + /* Trigger checksum calculation */ + verifyParam.blockStartAddress = diagSegmentList.segmentInfo[currentSegment].targetAddress; + verifyParam.blockLength = diagSegmentList.segmentInfo[currentSegment].length; + /* No actual verification data included in request; result of CRC calculation will be stored here */ + verifyParam.verificationData = verifyOutputBuf; + verifyParam.wdTriggerFct = &FblRealTimeSupportVoid; + /* Upload is restricted to ROM content */ + verifyParam.readMemory = (FL_ReadMemoryFctType)&FblReadProm; + + if (SECM_VER_OK != FblDiagVerification(&verifyParam)) + { + /* An error occurred during checksum calculation */ + return kFblFailed; + } + + /* Restore the segmentInfo entry for download purposes */ + diagSegmentList.nrOfSegments--; + } + else +#endif /* FBL_DIAG_ENABLE_UPLOAD */ + { +#if defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) + /* Update segment information with actually programmed length */ + diagSegmentList.segmentInfo[currentSegment].length = totalProgramLength; +#endif /* FBL_ENABLE_PROCESSED_DATA_LENGTH */ + + verifyData.verifyDataInput.length = 0u; + verifyData.verifyDataInput.data = V_NULL; +#if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) && !defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Output and pipelined verification use the same data as they are used exclusively */ + /* No actual verification data included in request */ + verifyData.verifyDataOutput.length = FBL_DIAG_VERIFY_BUFFER_SIZE; + verifyData.verifyDataOutput.data = verifyOutputBuf; + verifyData.verifyDataPipe.length = 0u; + verifyData.verifyDataPipe.data = V_NULL; +#else /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + /* Check if customer verification function is configured for this block */ + result = FblLbtGetBlockVerifyOutputFuncByNr(currentBlock, &exportFct); + if (result == kFblOk) + { + if (SecM_Default == exportFct) + { + verifyData.verifyDataOutput.length = 0u; + verifyData.verifyDataOutput.data = V_NULL; + verifyData.verifyDataPipe.length = FBL_DIAG_VERIFY_BUFFER_SIZE; + verifyData.verifyDataPipe.data = verifyOutputBuf; + } + else + { + /* Customer verification function: switch to output verification */ + verifyData.verifyDataOutput.length = FBL_DIAG_VERIFY_BUFFER_SIZE; + verifyData.verifyDataOutput.data = verifyOutputBuf; + verifyData.verifyDataPipe.length = 0u; + verifyData.verifyDataPipe.data = V_NULL; + } + } + else + { + /* Should never happen */ + DiagNRCRequestOutOfRange(); + return kFblFailed; + } +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + + /* Handle LibMem state flags and perform state checks */ + result = FblMemRemapStatus(FblMemBlockVerify(&verifyData, &verifyResult)); + if (result == kDiagErrorNone) + { + /* Store segment checksum for later verification in routine CheckValidApp */ /* PRQA S 0314 1 */ /* MD_FblDiag_0314_MemCpy */ + (void)MEMCPY(diagSegmentList.segmentInfo[currentSegment].checksum, verifyOutputBuf, SEC_VERIFY_CLASS_DDD_DIGEST_SIZE); + } + else + { + DiagSetError(result); + return kFblFailed; + } + } + + if (DiagGetError() == kDiagErrorNone) + { + /* No NRC returned, send the response */ + + /* CRC value is stored in last two byte of buffer */ /* PRQA S 0314 1 */ /* MD_FblDiag_0314_MemCpy */ + (void)MEMCPY(&pbDiagBuffer[kDiagFmtRoutineIdHigh], &verifyOutputBuf[FBL_DIAG_CRC_OFFSET], SEC_SIZE_CHECKSUM_CRC); + + { + DiagProcessingDone(kDiagRslRequestTransferExit); + } + } + else + { + result = kFblFailed; + } + + return result; +} + +/*********************************************************************************************************************** + * FblDiagPrepareDidResponse + **********************************************************************************************************************/ +/*! \brief ReadDataByIdentifier service handling + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] reqDid Requested DID + * \param[in] didData Pointer to DID data + * \param[in] didLength Data length of the DID + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +static tFblResult FblDiagPrepareDidResponse ( vuint8 *pbDiagBuffer, vuint16 reqDid, tDidDataPtr didData, vuint16 didLen ) +{ + vuint16 dataIdx; + tFblResult result = kFblOk; + + /* Check if data fits into diag buffer */ + if ((DiagDataLength + didLen) < FBL_DIAG_BUFFER_LENGTH) + { + /* Write DID to the diag buffer */ + pbDiagBuffer[0] = (vuint8)(reqDid >> 8u); + pbDiagBuffer[1] = (vuint8)(reqDid & 0xFFu); + + if (didData != kDiagComplexDidData) + { + /* Extract the requested information from DID table */ + for (dataIdx = 0u; dataIdx < (didLen - kDiagFmtDataIdSize); dataIdx++) + { + pbDiagBuffer[kDiagFmtDataIdSize + dataIdx] = didData[dataIdx]; + } + } + else + { + /* User callback provides the requested information */ + result = ApplFblReadDataByIdentifier(pbDiagBuffer, didLen - kDiagFmtDataIdSize); + } + } + else + { + /* Requested data doesn't fit into diag buffer */ + DiagNRCResponseTooLong(); + result = kFblFailed; + } + + return result; +} + +/*********************************************************************************************************************** + * FblDiagMainHandlerReadDataById + **********************************************************************************************************************/ +/*! \brief ReadDataByIdentifier service handling + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +/* PRQA S 2889, 6010, 6030, 6080 1 */ /* MD_FblDiag_2889, MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STMIF */ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerReadDataById) +{ + tFblResult result = kFblFailed; + + /* Check if the length is an odd value. */ + if ((diagReqDataLen % 2u) == 1u) + { + DiagNRCIncorrectMessageLengthOrInvalidFormat(); + } + else + { + vuint16 reqDid[FBL_MAX_DID_COUNT]; + vuint16 didLen = 0u; + vuint8 numberOfDids, didIdx, tableIdx; + /* Get pointer to upper byte of first DID */ + V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * localPbDiagBuffer = &pbDiagBuffer[1u]; + /* Reset response length */ + DiagDataLength = 0u; + + /* Extract DIDs from diag buffer, do while in order to always initialize reqDid */ + numberOfDids = 0u; + do + { + reqDid[numberOfDids] = (vuint16)FblMemGetInteger(2u, &localPbDiagBuffer[numberOfDids * 2u]); + numberOfDids++; + } while (numberOfDids < (diagReqDataLen / 2u)); + + /* Process requested DIDs */ + for (didIdx = 0u; (didIdx < numberOfDids) && (DiagGetError() == kDiagErrorNone); didIdx++) + { + /* Handle watchdog but omit transmission of RCRRP (REQPROD 74147) */ + (void)FblLookForWatchdog(); + + result = kFblFailed; + switch (reqDid[didIdx]) + { + /* Active Diagnostic Session */ + case kDiagDataIdActiveDiagnosticSession: + { + /* Bootloader supports programming session only */ + vuint8 diagSessionType = GetDiagSessionType(); + didLen = kDiagFmtDataIdSize + kDiagFmtDataIdActiveDiagnosticSessionSize; + result = FblDiagPrepareDidResponse(localPbDiagBuffer, reqDid[didIdx], (tDidDataPtr)&diagSessionType, didLen); + break; + } + /* Software Download Specification Version */ + case kDiagDataIdSwdlVersion: + { + /* SWDL issue kDiagSwdlVersion */ + vuint8 swdlVersion = kDiagSwdlVersion; + didLen = kDiagFmtDataIdSize + kDiagFmtDataIdSwdlVersionSize; + result = FblDiagPrepareDidResponse(localPbDiagBuffer, reqDid[didIdx], (tDidDataPtr)&swdlVersion, didLen); + break; + } + #if defined( FBL_DIAG_ENABLE_DID_CURRENT_DIAG_APP ) + /* DID 0xD021: Current Diagnostic Application */ + case kDiagDataIdBootloaderCurrentDiagnosticApp: + { + vuint8 currentDiagnosticApp = kFblDiagAppUnknown; + didLen = kDiagFmtDataIdSize + kDiagFmtDataIdBootloaderCurrentDiagAppSize; + if (GetMemDriverInitialized()) + { + currentDiagnosticApp = kFblDiagAppSbl; + } + else + { + currentDiagnosticApp = kFblDiagAppPbl; + } + result = FblDiagPrepareDidResponse(localPbDiagBuffer, reqDid[didIdx], (tDidDataPtr)¤tDiagnosticApp, didLen); + break; + } + #endif + /* User handles the other DIDs */ + default: + { + /* Search table of supported DIDs */ + for (tableIdx = 0; tableIdx < kNrOfDids; tableIdx++) + { + if (fblDidTable[tableIdx].did == reqDid[didIdx]) + { + /* Calculate overall data length for range check and pointer handling */ + didLen = kDiagFmtDataIdSize + fblDidTable[tableIdx].size; + result = FblDiagPrepareDidResponse(localPbDiagBuffer, reqDid[didIdx], fblDidTable[tableIdx].ptr, didLen); + break; + } + } + break; + } + } + + if (result == kFblOk) + { + /* Adjust response length and pointer to diag buffer */ + DiagDataLength += didLen; + localPbDiagBuffer = &localPbDiagBuffer[didLen]; + } + } + + if (DiagGetError() == kDiagErrorNone) + { + /* Check if at least one DID has been found */ + if (DiagDataLength == 0u) + { + DiagNRCRequestOutOfRange(); + result = kFblFailed; + } + else + { + /* No NRC returned, send the response */ + DiagProcessingDone(DiagDataLength); + } + } + else + { + result = kFblFailed; + } + } + + return result; +} + +#if defined( FBL_DIAG_ENABLE_WRITE_DATA_BY_IDENTIFIER ) +/*********************************************************************************************************************** + * FblDiagMainHandlerWriteDataById + **********************************************************************************************************************/ +/*! \brief WriteDataByIdentifier service handling + * \param[in] pbDiagBuffer Pointer to the data in the pbDiagBuffer (without SID) + * \param[in] diagReqDataLen Length of data (without SID) + * \return Possible return values: + * - kFblOk: Service processed successfully (goto next state) + * - kFblFailed: Service processing failed. + **********************************************************************************************************************/ +static FBL_DIAG_MAIN_HANDLER(FblDiagMainHandlerWriteDataById) +{ + tFblResult result; + + + /* Pass pointer to diag buffer which points after the SID. */ + result = ApplFblWriteDataByIdentifier(&(pbDiagBuffer[kDiagFmtDataIdHigh]), diagReqDataLen); + + /* Catch invalid combinations of return value and NRC state */ + assertFblUser(((result == kFblOk) && (DiagGetError() == kDiagErrorNone)) || + ((result != kFblOk) && (DiagGetError() != kDiagErrorNone)), + kFblOemAssertIllegalReturnValue); + + if (DiagGetError() == kDiagErrorNone) + { + /* No NRC returned, send the response */ + DiagProcessingDone(kDiagRslWriteDataByIdentifier); + } + else + { + result = kFblFailed; + } + + return result; +} +#endif + +/* Diagnostic service functions *********************************************/ + +/*********************************************************************************************************************** + * FblDiagEcuReset + **********************************************************************************************************************/ +/*! \brief Initiate ECU reset + * \param[in] resetOptions OR combination of: + * - kDiagResetNoResponse (timeout of TesterPresent) + * - kDiagResetPutResponse (service EcuReset received) + * - kDiagResetStayInBoot (do not reset active boot mode) + * \param[in] responseFlag Value written to reset response flag + **********************************************************************************************************************/ +void FblDiagEcuReset(vuint8 resetOptions, vuint8 responseFlag) +{ +#if defined( FBL_ENABLE_ECURESET_DELAY ) + vuint8 tmpFuncReq = GetFunctionalRequest(); +#endif + + /* Disable tester present timeout monitoring */ + StopTesterTimeout(); + + /* ESCAN00067433: Stop background operations of FblLib_Mem */ + FblMemDeinit(); + + /* Check if a response is required */ + if (GetResetOptionPutResponse(resetOptions) && (!GetSuppressPosRspMsg())) + { + /* Request for reset/FBL-shutdown */ + SetWaitEcuReset(); + + /* Check if response address has been stored successfully */ + if (kFblOk == FblCwSaveResponseAddress()) /* PRQA S 2741 */ /* MD_FblDiag_ConstValue */ + { + /* Transmit response if required */ + switch (responseFlag) + { + case RESET_RESPONSE_SDS_REQUIRED: + { + DiagProcessingDone(kDiagRslDiagnosticSessionControl); + break; + } + case RESET_RESPONSE_ECURESET_REQUIRED: + { + DiagProcessingDone(kDiagRslEcuReset); + break; + } + default: + { + /* Invalid combination of reset option and response flag */ + assertFblInternal(0u, kFblOemAssertParameterOutOfRange); + break; + } + } + } + else + { /* PRQA S 2880 1 */ /* MD_FblDiag_ConstValue */ + DiagNRCGeneralReject(); + } + SetEcuResetFctFinished(); + } + else + { + /* Do not transmit response message */ + DiagSetNoResponse(); + DiagProcessingDone(0u); + FblDiagDeinit(); + } + +#if defined( FBL_ENABLE_ECURESET_DELAY ) + /* Functionally addressed request: wait for a pre-defined time for + * responses from the sub nodes */ + if (tmpFuncReq != 0) + { + vuint16 i = FBL_ECURESET_DELAY_TIME; + + + while (i != 0) + { + /* Watchdog function calls FblCw polling tasks */ + if ((FblLookForWatchdog() & FBL_TM_TRIGGERED) == FBL_TM_TRIGGERED) + { + i--; + } + } + } +#endif /* FBL_ENABLE_ECURESET_DELAY */ + +} + +/*********************************************************************************************************************** + * FblDiagSetProperties + **********************************************************************************************************************/ +/*! \brief Copy service properties from source to target + * \param[in] source Source service properties + * \param[out] target Target service properties + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +static void FblDiagSetProperties(ptServiceProp source, tServiceProp * destination) +{ + vuint8 idx; + vuint8 stateIdx; + + destination->serviceId = source->serviceId; + destination->minLength = source->minLength; + destination->maxLength = source->maxLength; + destination->mainHandlerIdx = source->mainHandlerIdx; + destination->subServices = source->subServices; + +#if defined( FBL_DIAG_STATE_ARRAYS ) + for (stateIdx = 0u; stateIdx < STATE_COUNT; stateIdx++) + { +#if ( STATECHECK_ARRAYSIZE == 1u) + idx = 0; +#else + for (idx = 0u; idx < STATECHECK_ARRAYSIZE; idx++) +#endif + { + destination->states[stateIdx][idx] = source->states[stateIdx][idx]; + } + } +#else +#if ( STATECHECK_ARRAYSIZE == 1u) + idx = 0u; +#else + for (idx = 0u; idx < STATECHECK_ARRAYSIZE; idx++) +#endif + { + destination->stateSet[idx] = source->stateSet[idx]; + destination->stateUnset[idx] = source->stateUnset[idx]; + destination->stateAdd[idx] = source->stateAdd[idx]; + destination->stateClr[idx] = source->stateClr[idx]; + destination->stateClrFail[idx] = source->stateClrFail[idx]; + } +#endif +} + +/*********************************************************************************************************************** + * FblDiagMergeProperties + **********************************************************************************************************************/ +/*! \brief Merge existing contents of target service properties with the one from source. + * \details Service ID, subservices and handlers will be overwritten if present. Length will be updated if values + * are more restrictive. Resulting states are the OR concatenation of the inputs. + * \param[in] source Source service properties + * \param[out] merge Input service properties, merged with source + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +static void FblDiagMergeProperties(ptServiceProp source, tServiceProp * merge) +{ + vuint8 idx; +#if defined( FBL_DIAG_STATE_ARRAYS ) + vuint8 stateIdx; +#endif + + /* PRQA S 2916 TAG_FblDiag_2916_1 */ /* MD_FblDiag_2916 */ + merge->serviceId = source->serviceId; + if (source->minLength > merge->minLength) + { + merge->minLength = source->minLength; + } + if (source->maxLength < merge->maxLength) + { + merge->maxLength = source->maxLength; + } + if (source->mainHandlerIdx != (vuint8)kServiceMainHandlerNone) + { + merge->mainHandlerIdx = source->mainHandlerIdx; + } + merge->subServices = source->subServices; + /* PRQA L: TAG_FblDiag_2916_1 */ + +#if defined( FBL_DIAG_STATE_ARRAYS ) + for (stateIdx = 0u; stateIdx < STATE_COUNT; stateIdx++) + { +# if ( STATECHECK_ARRAYSIZE == 1u) + idx = 0u; +# else + for (idx = 0u; idx < STATECHECK_ARRAYSIZE; idx++) +# endif + { + merge->states[stateIdx][idx] |= source->states[stateIdx][idx]; + } + } +#else +# if ( STATECHECK_ARRAYSIZE == 1u) + idx = 0u; +# else + for (idx = 0u; idx < STATECHECK_ARRAYSIZE; idx++) +# endif + { + merge->stateSet[idx] |= source->stateSet[idx]; + merge->stateUnset[idx] |= source->stateUnset[idx]; + merge->stateAdd[idx] |= source->stateAdd[idx]; + merge->stateClr[idx] |= source->stateClr[idx]; + merge->stateClrFail[idx] |= source->stateClrFail[idx]; + } +#endif +} + +/*********************************************************************************************************************** + * FblDiagDispatch + **********************************************************************************************************************/ +/*! \brief Dispatch the current request in the diagnostic buffer + **********************************************************************************************************************/ +/* PRQA S 6010, 6030 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC */ +static void FblDiagDispatch ( void ) +{ + /* Variables to traverse the service tables */ + ptServiceProp prevProp; /* PRQA S 3679 */ /* MD_MSR_Rule8.13 */ + ptServiceProp currProp; + V_MEMROM1 tServiceList V_MEMROM2 V_MEMROM3 * localSubServices; + V_MEMROM1 tServiceCheckList V_MEMROM2 V_MEMROM3 * checkList; + V_MEMROM1 tServiceCheck V_MEMROM2 V_MEMROM3 * checkFct; + + vuint8 chkFctIdx; + tCwDataLengthType bufferPos; + + tFblResult done; + + /* Set service table entry point */ + FblDiagSetProperties(&kDiagServiceProperties[0], &serviceProperties); + + /* Init traversal variables */ + currProp = (ptServiceProp)&kDiagServiceProperties[0]; + prevProp = currProp; + + localSubServices = currProp->subServices; +#if defined( FBL_DIAG_CHECK_LIST_HANDLES ) + checkList = kServiceCheckListTable[currProp->checkListIdx]; +#else + checkList = currProp->checks; +#endif + bufferPos = localSubServices->bufPos; + + checkFct = (V_MEMROM1 tServiceCheck V_MEMROM2 V_MEMROM3 *)0; + + done = kFblFailed; + + /* Run until service was found or error occurred */ + while (done != kFblOk) + { + /* Assume operation finished */ + done = kFblOk; + + /* Run over all check functions of current service */ + for (chkFctIdx = 0; chkFctIdx < checkList->count; chkFctIdx++) + { + /* Execute check function */ + checkFct = &(checkList->list)[chkFctIdx]; + + if ((kServiceCheckHandlerFctTable[checkFct->checkHandlerIdx])(&serviceProperties, DiagBuffer, DiagDataLength, bufferPos, &currProp) == kFblOk) + { + /* Current service has potentially changed */ + if (currProp != prevProp) + { + /* Merge new properties with existing one */ + FblDiagMergeProperties(currProp, &serviceProperties); + prevProp = currProp; + + /* Not finished yet */ + done = kFblFailed; + } + } + else + { + /* Invalidate service */ + currProp = kDiagNoServiceProp; + break; + } + } + + /* Service property has changed */ + if (done != kFblOk) + { + /* Assume operation finished */ + done = kFblOk; + + /* Valid service found */ + if (currProp != kDiagNoServiceProp) + { + /* Get new check functions */ +#if defined( FBL_DIAG_CHECK_LIST_HANDLES ) + if (currProp->checkListIdx != (vuint8)kServiceCheckListNone) + { + checkList = kServiceCheckListTable[currProp->checkListIdx]; +#else + checkList = currProp->checks; + if (checkList != (void *)0) + { +#endif + /* Initialize check function */ + checkFct = (V_MEMROM1 tServiceCheck V_MEMROM2 V_MEMROM3 *)0; + + /* Not finished yet, new check functions present */ + done = kFblFailed; + } + + /* Get subservices of current service */ + localSubServices = currProp->subServices; + if (localSubServices != (void *)0) + { + /* Move to next buffer position */ + bufferPos = localSubServices->bufPos; + } + } + } + } + + /* Assume dispatching failed */ + serviceResult = kFblFailed; + + /* No valid subservice found */ + if (currProp == kDiagNoServiceProp) + { + /* Failed check function is known */ + if (checkFct != (void *)0) + { + /* Execute error handler */ + if (checkFct->errorHandlerIdx != (vuint8)kServiceErrorHandlerNone) + { + /* Result of error handler changes execution state */ + serviceResult = (kServiceErrorHandlerFctTable[checkFct->errorHandlerIdx])(&serviceProperties, DiagBuffer, DiagDataLength); + } + + /* Error handler wasn't successful and NRC was not set directly */ + if ((serviceResult != kFblOk) && (DiagGetError() == kDiagErrorNone)) + { + /* Set NRC according to check function configuration */ + if (checkFct->NRC == kDiagNrcNoResponse) + { + /* Quiet failure */ + DiagSetNoResponse(); + DiagProcessingDone(0); + } + else + { + /* Set NRC */ + DiagSetError(checkFct->NRC); + } + } + } + else + { + /* + Operation failed but check function is unknown + Set generic NRC + */ + DiagNRCGeneralReject(); + } + } + else + { + /* Execute main handler */ + if (serviceProperties.mainHandlerIdx != (vuint8)kServiceMainHandlerNone) + { + serviceResult = (kServiceMainHandlerFctTable[serviceProperties.mainHandlerIdx])(DiagBuffer, DiagDataLength); + } + } + + /* Set and clear state flags according to execution result */ + if (serviceResult == kFblOk) + { + FblDiagClrState(serviceProperties.stateClr); + FblDiagSetState(serviceProperties.stateAdd); + } + else + { + FblDiagClrState(serviceProperties.stateClrFail); + } +} + +/*********************************************************************************************************************** + * FblDiagTimerTask + **********************************************************************************************************************/ +/*! \brief This function handles the surveillance of the tester present timer. When a timeout occurs, a reset + * is executed. + * \pre FblDiagInit has to be executed + **********************************************************************************************************************/ +void FblDiagTimerTask( void ) +{ + /* Tester present timing */ + if (TimeoutTesterValue() != 0u) + { + DecTimeoutTesterValue(); + if (TimeoutTesterValue() == 0u) + { + /* + * Tester present timer expired: + * Exit bootloader via reset, but force no response!! + */ + FblDiagEcuReset(kDiagResetNoResponse, RESET_RESPONSE_NOT_REQUIRED); + } + } + + /* ECU reset is pending */ + if (TimeoutEcuResetValue() != 0u) + { + DecTimeoutEcuResetValue(); + if (TimeoutEcuResetValue() == 0u) + { + /* ECU reset timer expired */ + /* Exit bootloader via Reset, but force no response!! */ + FblDiagEcuReset(kDiagResetNoResponse, RESET_RESPONSE_NOT_REQUIRED); + } + } + +} + +/*********************************************************************************************************************** + * FblDiagStateTask + **********************************************************************************************************************/ +/*! \brief Handle diagnostic indications. + * \pre FblDiagInit has to be executed + **********************************************************************************************************************/ +void FblDiagStateTask( void ) +{ + + /* Diagnostic request pending */ + if (GetDiagIndication()) + { + /* Setup state flags */ + ClrDiagIndication(); + ClrSuppressPosRspMsg(); + ClrProcessingDone(); + DiagClrError(); + + /* Indicate an ongoing service processing */ + SetServiceInProgress(); + + /* Dispatch request */ + FblDiagDispatch(); + + /* Call response processor in case of NRC */ + if (DiagGetError() != kDiagErrorNone) + { + DiagResponseProcessor(0); + } + + /* Reset internal state in case no response was sent */ + if ((!GetProcessingDone()) && (!GetWaitForRcrRpConf())) + { + DiagSetNoResponse(); + DiagResponseProcessor(0); + } + } + + /* Check for reset request */ + /* The following preconditions have to be fulfilled: + * Reset message confirmed + * Pre-reset function (e.g. flag written to NV-memory) has finished + */ + if (GetWaitEcuReset() && GetResetMsgConfirmed() && GetEcuResetFctFinished()) + { + { + FblDiagDeinit(); + } + } + + /* ESCAN00061727: Resume suspended LibMem operation */ + FblMemResumeIndication(); +} + +/*********************************************************************************************************************** + * FblDiagDeinit + **********************************************************************************************************************/ +/*! \brief Function prepares for FBL shutdown on diagnostic service request. + **********************************************************************************************************************/ +static void FblDiagDeinit(void) +{ + /* Deinitialize verification component */ + (void)SecM_DeinitVerification(V_NULL); + + /* Deinitialize loaded memory driver(s) */ + FblDeinitMemoryDriver(); + + /* Reset internal FBL states */ + FblDiagRetainState(kDiagStateMaskReset); + + /* Clear negative response indicator */ + DiagClrError(); + + /* Request shutdown from communication wrapper */ + FblCwShutdownRequest(kFblCwResetEcuRegularCase); +} + +/*********************************************************************************************************************** + * FblInitMemoryDriver + **********************************************************************************************************************/ +/*! \brief Initializes the flash driver for usage + * \pre Flash driver must be verified + * \return kFblOk = initialization successful, kFblFailed = otherwise + **********************************************************************************************************************/ +static tFblResult FblInitMemoryDriver( void ) +{ + tFblResult result = kFblFailed; + IO_ErrorType memErrorCode; + + if (!GetMemDriverInitialized()) + { + /* Initialize flash driver version */ + FblErrStatSetFlashDrvVersion(); + + /* Turn on programming voltage (if necessary) */ + ApplFblSetVfp(); + + /* ApplFbl[Set|Reset]Vfp() are not allowed to set a NRC */ + assertFblUser((DiagGetError() == kDiagErrorNone), kFblOemAssertIllegalReturnValue); + + /* Check version and initialize flash driver */ + FblCwSetOfflineMode(); + memErrorCode = MemDriver_InitSync(V_NULL); + FblCwSetOnlineMode(); + + /* + * ESCAN00041016: Require all memory drivers to be correctly initialized + * at this point (i.e. non-downloadable drivers, too). + */ + if (memErrorCode == IO_E_OK) + { + /* Set Flash driver initialization flag */ + SetMemDriverInitialized(); + result = kFblOk; + } + else + { + /* Flash driver initialization failure */ + FblErrStatSetError(FBL_ERR_FLASHCODE_INIT_FAILED); + FblErrStatSetFlashDrvError(memErrorCode); + + /* Reset programming voltage */ + ApplFblResetVfp(); + + /* ApplFbl[Set|Reset]Vfp() are not allowed to set a NRC */ + assertFblUser((DiagGetError() == kDiagErrorNone), kFblOemAssertIllegalReturnValue); + } + } + else + { + /* Flash driver already initialized */ + result = kFblOk; + } + + return result; +} + +/*********************************************************************************************************************** + * FblDeinitMemoryDriver + **********************************************************************************************************************/ +/*! \brief Deinitialize memory driver if present + **********************************************************************************************************************/ +static void FblDeinitMemoryDriver( void ) +{ + if (GetDiagProgrammingSession()) + { + if (GetMemDriverInitialized()) + { + /* Deinitialize memory driver flash */ + ClrMemDriverInitialized(); + + /* Remove memory driver from RAM-buffer */ + FblCwSetOfflineMode(); + { + (void)MemDriver_DeinitSync(V_NULL); + } + FblCwSetOnlineMode(); + } + + /* Turn off programming voltage */ + ApplFblResetVfp(); + } +} + +/* Ford specific functions **********************************************/ +#if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) +/*********************************************************************************************************************** + * FblDiagVerification - Ford specific + **********************************************************************************************************************/ +/*! \brief This function calls the HIS verification interface to calculate the CRC16 value over the requested + * address region in non-volatile memory. + * \pre Address region check has been performed (FblDiagAddressRegionCheck) + * \param[in] verifyParam Parameter structure for verification + * \return Result of operation + **********************************************************************************************************************/ +static SecM_StatusType FblDiagVerification(V_MEMRAM1 SecM_VerifyParamType V_MEMRAM2 V_MEMRAM3 * verifyPar) +{ + tBlockDescriptor blockDescriptor; + tFblMemVerifyFctOutput verifyFct; + + /* Set default verification function */ + verifyFct = &SecM_VerificationClassDDD; + + /* + * Note: general address region check is expected to be performed before this + * function is called (e.g. in FblDiagMainHandlerRequestDownload/Upload, FblDiagMainHandlerRcCheckProgDep). + */ + if (FblLbtGetBlockDescriptorByAddressLength(verifyPar->blockStartAddress, verifyPar->blockLength, &blockDescriptor) == kFblOk) + { + if (SecM_Default != blockDescriptor.verifyOutput) + { + /* Logical block no. has been determined successfully: assign block specific verification function */ + verifyFct = (tFblMemVerifyFctOutput)blockDescriptor.verifyOutput; /* PRQA S 0313 */ /* MD_FblDiag_0313_VerifyFctOutput */ + } + } + + /* Perform verification */ + return verifyFct(verifyPar); +} +#endif + +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) && ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +/*********************************************************************************************************************** + * FblDiagVerifySignature + **********************************************************************************************************************/ +/*! \brief This function calls the HIS verification interface to calculate the CRC16 value over the requested + * address region in non-volatile memory (pipelined mode). + * \pre Address region check has been performed (FblDiagAddressRegionCheck) + * \param[in] pVerifyParam Parameter structure for verification + * \return Result of operation + **********************************************************************************************************************/ +static SecM_StatusType FblDiagVerifySignature( V_MEMRAM1 SecM_SignatureParamType V_MEMRAM2 V_MEMRAM3 * pVerifyParam ) +{ + SecM_StatusType result; + SecM_LengthType byteCount; + + result = SECM_VER_ERROR; + + pipeVerifyParamCrc.sigState = pVerifyParam->sigState; + pipeVerifyParamCrc.sigSourceBuffer = pVerifyParam->sigSourceBuffer; + pipeVerifyParamCrc.sigByteCount = pVerifyParam->sigByteCount; + pipeVerifyParamCrc.wdTriggerFct = pVerifyParam->wdTriggerFct; + + switch (pVerifyParam->sigState) + { + case SEC_HASH_INIT: + case SEC_HASH_COMPUTE: + case SEC_HASH_FINALIZE: + { + result = SecM_VerifyClassDDD(pVerifyParam); + (void)SecM_VerifyChecksumCrc(&pipeVerifyParamCrc); + + break; + } + case SEC_SIG_VERIFY: + { + result = SecM_VerifyClassDDD(pVerifyParam); + + byteCount = pVerifyParam->sigByteCount; + pipeVerifyParamCrc.sigSourceBuffer = &pVerifyParam->sigSourceBuffer[byteCount]; + pipeVerifyParamCrc.sigByteCount -= byteCount; + + (void)SecM_VerifyChecksumCrc(&pipeVerifyParamCrc); + + pVerifyParam->sigByteCount += pipeVerifyParamCrc.sigByteCount; + + break; + } + default: + { + /* Nothing to do */ + break; + } + } + + return result; +} +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED && ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) */ + + +#if defined( FBL_ENABLE_STAY_IN_BOOT ) +/*********************************************************************************************************************** + * FblDiagCheckStartMsg - Ford Specific + **********************************************************************************************************************/ +/*! \brief Check if the OEM specific start message has been received + * \pre Start message reception has to be verified by ComWrapper + * \param[in] pData Pointer to received data + * \param[in] length Length of received data + * \return Possible return values: + * - kFblOk: OEM specific start message has been identified + * - kFblFailed: Received message doesn't equal the OEM specific start message + **********************************************************************************************************************/ +vuint8 FblDiagCheckStartMsg(const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 *pData, vuintx length) +{ + vuint8 result; + + /* Initialize variables */ + result = kFblFailed; + + /* Check if received data is long enough */ + if (length >= (kDiagRqlDiagnosticSessionControl + 2u)) + { + /* Check complete message contents for Stay-In-Boot */ + /* For Ford, this is: 0x02 0x10 0x02 (DiagnosticSessionControl/ProgrammingSession) */ + if ( ( pData[0] == (kDiagRqlDiagnosticSessionControl + 1u)) /* Add the service ID */ + && ( pData[kDiagFmtServiceId + 1u] == kDiagSidDiagnosticSessionControl) + && ((pData[kDiagFmtSubparam + 1u] & 0x7Fu) == kDiagSubProgrammingSession)) /* Suppressed bit may be true or false */ + { + /* Start message received */ + result = kFblOk; + } + } + + return result; +} +#endif /* FBL_ENABLE_STAY_IN_BOOT */ + +/*********************************************************************************************************************** + * FblDiagGetSegmentList + **********************************************************************************************************************/ +/*! \brief Returns a list of download segments which have been programmed into a certain logical block + * \param[in] blockIdx Index of the logical block for which the associated download segments shall be returned + * \param[out] blockSegList Pointer to local segment list which shall keep the respective download segments + * \return Number of download segment which are associated with the requested logical block + **********************************************************************************************************************/ +vuint8 FblDiagGetSegmentList(vuint8 blockIdx, V_MEMRAM1 tDiagSegmentList V_MEMRAM2 V_MEMRAM3 * blockSegList) +{ + vuint8 listIdx; + + blockSegList->nrOfSegments = 0u; + + for (listIdx = 0u; listIdx < blockHeader[blockIdx].nrOfSegments; listIdx++) + { + blockSegList->segmentInfo[blockSegList->nrOfSegments] = diagSegmentList.segmentInfo[blockHeader[blockIdx].segmentIdx[listIdx]]; + blockSegList->nrOfSegments++; + } + + return blockSegList->nrOfSegments; +} + +#define FBLDIAG_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* Communication wrapper callback functions **********************************/ +#define FBLDIAG_RAMCODE_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * FblDiagTxErrorIndication + **********************************************************************************************************************/ +/*! \brief Indicates that an error has occurred during transmission. + * \details According to ISO-14229, now the S3 timer must be restarted. + * \pre TP must been initialized + * \param[in] cwMsgType Message type of indication (defined in CW layer): + * - kFblCwMsgTypeRcrRp: Request correctly received/response pending message + * - kFblCwMsgTypeNormal: Normal request message + **********************************************************************************************************************/ +void FblDiagTxErrorIndication( vuint8 cwMsgType ) +{ + /* Do not reset states for RCR-RP confirmation */ + if (cwMsgType != kFblCwMsgTypeRcrRp) + { + DiagResetResponseHandling(); + } +} + +/*********************************************************************************************************************** + * FblDiagRxStartIndication + **********************************************************************************************************************/ +/*! \brief Data reception call-back function to start diagnostic service processing. + * \details Valid TesterPresent requests will simply start the S3 timer and will not be processed. + * \pre TP reception successful + **********************************************************************************************************************/ +void FblDiagRxStartIndication( void ) +{ + /* Halts the S3 timer while receiving a diagnostic message */ + StopTesterTimeout(); +} + +/*********************************************************************************************************************** + * FblDiagRxErrorIndication + **********************************************************************************************************************/ +/*! \brief Indicates that an error has occurred during reception. + * \details According to ISO-14229, now the S3 timer must be restarted. + * \pre TP must been initialized + **********************************************************************************************************************/ +void FblDiagRxErrorIndication( void ) +{ + DiagResetResponseHandling(); +} + +/*********************************************************************************************************************** + * FblDiagRxIndication + **********************************************************************************************************************/ +/*! \brief Data reception call-back function to start diagnostic service processing. + * \details Valid TesterPresent requests will simply start the S3 timer and will not be processed. + * \pre TP reception successful + * \param[in] pbDiagBuffer Pointer to diagnostic buffer + * \param[in] rxDataLength Number of bytes to be received + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +void FblDiagRxIndication( V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * pbDiagBuffer, tCwDataLengthType rxDataLength ) +{ + /* Check for functionally addressed valid TesterPresent message with SuppressPosRsp */ + if ((kDiagSidTesterPresent == pbDiagBuffer[kDiagFmtServiceId]) + && (kDiagSuppressPosRspMsgIndicationBit == pbDiagBuffer[kDiagFmtSubparam]) + && (kDiagRqlTesterPresent == (rxDataLength - 1u)) + && GetFunctionalRequest() + ) + { + /* Bypass logic for this TesterPresent message */ + DiagResetResponseHandling(); /* Reset tester timeout */ + FblCwResetRxBlock(); + } + else + { + /* Start regular service processing */ + DiagClrError(); + diagResponseFlag = kDiagPutResponse; + diagServiceCurrent = pbDiagBuffer[kDiagFmtServiceId]; + + SetP2Timer(kFblDiagTimeP2); /* Reset P2 timer (initial timing) */ + SetP2Timeout(kFblDiagTimeP2); /* PRQA S 3493 */ /* MD_FblDiag_3493 */ + DiagDataLength = rxDataLength - 1u; + SetDiagIndication(); + +#if defined( FBL_MEM_ENABLE_PIPELINING ) + if (FblMemTaskIsPending()) + { + FblMemRxNotification(); + } +#endif + } + + /* Initialize security seed */ + (void)ApplFblSecuritySeedInit(); + +#if defined( FBL_ENABLE_SLEEPMODE ) + /* Request received - reload sleep counter */ + FblSleepCounterReload(); +#endif +} + +/*********************************************************************************************************************** + * FblDiagTxConfirmation + **********************************************************************************************************************/ +/*! \brief TP transmission call-back function. + * \pre TP transmission successful + * \param[in] cwMsgType Message type of indication (defined in CW layer): + * - kFblCwMsgTypeRcrRp: Request correctly received/response pending message + * - kFblCwMsgTypeNormal: Normal request message + **********************************************************************************************************************/ +void FblDiagTxConfirmation( vuint8 cwMsgType ) +{ + /* Do not reset states for RCR-RP confirmation */ + if (cwMsgType != kFblCwMsgTypeRcrRp) + { + DiagResetResponseHandling(); + } + + /* Diag wants to reset FBL after sending an RCR-RP */ + if (GetWaitEcuReset()) + { + SetResetMsgConfirmed(); + } +} + +/*********************************************************************************************************************** + * FblDiagRxGetPhysBuffer + **********************************************************************************************************************/ +/*! \brief Diagnostic buffer management function for physical requests. + * \param[in] rxDataLength Number of bytes to be received + * \return Possible return values: + * - Pointer to diagnostic buffer + * - V_NULL in case no buffer is available + **********************************************************************************************************************/ +vuint8* FblDiagRxGetPhysBuffer( tCwDataLengthType rxDataLength ) +{ + vuint8* result; + + /* Check request length and if buffer is free */ + if ((rxDataLength > 0u ) + && (FBL_DIAG_BUFFER_LENGTH >= rxDataLength) + && (!GetDiagBufferLocked())) + { + /* Initialize state variables */ + ClrFunctionalRequest(); + + /* Lock buffer */ + SetDiagBufferLocked(); + + /* Return diagnostic buffer */ + result = DiagBuffer; + } + else + { + /* Illegal buffer request, return null pointer */ + result = V_NULL; + } + + return result; +} + +/*********************************************************************************************************************** + * FblDiagRxGetFuncBuffer + **********************************************************************************************************************/ +/*! \brief Diagnostic buffer management function for functional requests. + * \param[in] rxDataLength Number of bytes to be received + * \return Possible return values: + * - Pointer to diagnostic buffer + * - V_NULL in case no buffer is available + **********************************************************************************************************************/ +vuint8* FblDiagRxGetFuncBuffer( tCwDataLengthType rxDataLength ) +{ + /* Process functional request like physical request */ + vuint8* diagnosticBuffer = FblDiagRxGetPhysBuffer(rxDataLength); + + /* Set functional request indication */ + if (V_NULL != diagnosticBuffer) + { + SetFunctionalRequest(); + } + + return diagnosticBuffer; +} +#define FBLDIAG_RAMCODE_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLDIAG_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * FblDiagMemPreWrite + **********************************************************************************************************************/ +/*! \brief Function performs actions before FblLib_Mem calls the memory driver write function. + * \return Possible return values: + * - kFblOk: Pre-write operations are successful + * - kFblFailed: Pre-write operations failed + **********************************************************************************************************************/ +tFblResult FblDiagMemPreWrite( void ) +{ + FblCwSetOfflineMode(); + + return kFblOk; + +} + +/*********************************************************************************************************************** + * FblDiagMemPostWrite + **********************************************************************************************************************/ +/*! \brief Checks if message is the platform message or not + * \return Possible return values: + * - kFblOk: Post-write operations are successful + * - kFblFailed: Post-write operations failed + **********************************************************************************************************************/ +tFblResult FblDiagMemPostWrite( void ) +{ + FblCwSetOnlineMode(); + + return kFblOk; +} + +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +/*********************************************************************************************************************** + * FblDiagValidateToken + **********************************************************************************************************************/ +/*! \brief Validate the token against main validity rules + * \return Possible return values: + * - tTokenHdlResult: result of the validation operation + **********************************************************************************************************************/ +/* PRQA S 6010, 6030 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC */ +static tTokenHdlResult FblDiagValidateToken( const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tokenBuf ) +{ + tTokenHdlResult result; + vuintx idx; + vuint8 const *fesnPtr = FblDiagGetFesn(); + + result = kTokenHdlrInternalFailed; + + /* Check if Server Message ID is required and valid */ + if (FblDiagIsTokenMsgIDRequired(tokenBuf)) + { + if (FblDiagCheckServerMessageId(tokenBuf) == kFblOk) + { + result = kTokenHdlrOk; + } + } + + /* Is KeyID present? */ + if ( (result == kTokenHdlrOk) && + (FblDiagIsTokenKeyIDRequired(tokenBuf)) ) + { + /* KeyID must not be present */ + result = kTokenHdlrInternalFailed; + } + + /* Are reserved bits set? */ + if ( (result == kTokenHdlrOk) && + (FblDiagIsTokenReserverdBitsSet(tokenBuf)) ) + { + /* Reserved bits must not be set */ + result = kTokenHdlrInternalFailed; + } + + /* Is FESN present? */ + if ( (result == kTokenHdlrOk) && + FblDiagIsTokenFesnRequired(tokenBuf) && + (FblDiagGetTokenCommandType(tokenBuf) != FBL_DIAG_TOKEN_CMD_PROGKEY) ) + { + /* Check if FESN match */ + for (idx = 0u; idx < FBL_DIAG_TOKEN_FESN_LEN; idx++) + { + if (FblDiagGetTokenFesn(tokenBuf)[idx] != fesnPtr[idx]) + { + result = kTokenHdlrFesnFailed; + } + } + } + + /* For Mode 5 check the first three characters of the FESN */ + if ( (result == kTokenHdlrOk) && + (FblDiagGetTokenCommandType(tokenBuf) == FBL_DIAG_TOKEN_CMD_PROGKEY) ) + { + if (FblDiagIsTokenFesnRequired(tokenBuf)) + { + /* FESN required bit must not be set for mode 5 token */ + result = kTokenHdlrFesnFailed; + } + else + { + /* Check if the first 3 character of the FESN match */ + for (idx = 0u; idx < FBL_DIAG_TOKEN_MOD5_FESN_LEN; idx++) + { + if (FblDiagGetTokenPayloadFesn(tokenBuf)[idx] != fesnPtr[idx]) + { + result = kTokenHdlrFesnFailed; + } + } + } + } + + /* Check if CPU destination match */ + if ((result == kTokenHdlrOk) + && (FblDiagGetTokenCPUDestination(tokenBuf) != FBL_DIAG_TOKEN_CPU_DEST)) + { + result = kTokenHdlrInternalFailed; + } + + /* Check if service type match */ + if ((result == kTokenHdlrOk) + && (FblDiagGetTokenServiceType(tokenBuf) != FBL_DIAG_TOKEN_SERVICE_TYPE)) + { + result = kTokenHdlrInternalFailed; + } + + /* Check if crypto type match */ + if ((result == kTokenHdlrOk) + && (FblDiagGetTokenCryptoType(tokenBuf) != FBL_DIAG_TOKEN_CRYPTOTYPE)) + { + result = kTokenHdlrInternalFailed; + } + + /* Check if payload size match */ + if (result == kTokenHdlrOk) + { + if (FblDiagGetTokenCommandType(tokenBuf) == FBL_DIAG_TOKEN_CMD_PROGKEY) + { + if (FblDiagGetTokenPayloadSize(tokenBuf) != FBL_DIAG_TOKEN_PAYLOAD_SIZE_MODE5) + { + result = kTokenHdlrInternalFailed; + } + } + else + { + if (FblDiagGetTokenPayloadSize(tokenBuf) != FBL_DIAG_TOKEN_PAYLOAD_SIZE_MODE0_4) + { + result = kTokenHdlrInternalFailed; + } + } + } + + /* Check if correct key index match the token public key */ + if (result == kTokenHdlrOk) + { + if (FblDiagGetTokenCommandType(tokenBuf) == FBL_DIAG_TOKEN_CMD_PROGKEY) + { + if (FblDiagGetTokenKeyIndex(tokenBuf) != FBL_DIAG_TOKEN_KEY_INDEX_0) + { + result = kTokenHdlrInternalFailed; + } + } + else + { + if (FblDiagGetTokenKeyIndex(tokenBuf) != FBL_DIAG_TOKEN_KEY_INDEX_1) + { + result = kTokenHdlrInternalFailed; + } + } + } + + /* Check protocol version */ + if ( (result == kTokenHdlrOk) && + (!FblDiagIsTokenProtocolVersionCorrect(tokenBuf))) + { + result = kTokenHdlrProtocolFailed; + } + + /* Check token name length */ + if ( (result == kTokenHdlrOk) && + (FblDiagGetTokenTokenNameLength(tokenBuf) != FBL_DIAG_TOKEN_NAME_LENGTH) ) + { + result = kTokenHdlrInternalFailed; + } + + /* Check token name */ + if (result == kTokenHdlrOk) + { + vuint8 const tokenName[(FBL_DIAG_TOKEN_NAME_LENGTH + 1u)] = FBL_DIAG_TOKEN_NAME; + + for (idx = 0u; idx < FBL_DIAG_TOKEN_NAME_LENGTH; idx++) + { + if (FblDiagGetTokenTokenName(tokenBuf)[idx] != tokenName[idx]) + { + result = kTokenHdlrInternalFailed; + } + } + } + + return result; +} + +/*********************************************************************************************************************** + * FblDiagCheckServerMessageId + **********************************************************************************************************************/ +/*! \brief Check if Server Message ID is valid + * \return Possible return values: + * - kFblOk: Server Message ID is valid + * - kFblFailed: Server Message ID is not valid + **********************************************************************************************************************/ +/* PRQA S 6010, 6030 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC */ +static tFblResult FblDiagCheckServerMessageId( const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tokenBuf ) +{ + tFblResult result = kFblOk; + tFblResult srvMsgIdCompareFinished = kFblFailed; + vuint8 lastServerMessageId[8] = {0}; + vuint8 srvMsgIdFlag; + vuintx idx; + + /* Check if Server Message ID was stored before */ + if (ApplFblReadSrvMsgIDFlag(&srvMsgIdFlag) == kFblOk) + { + if (srvMsgIdFlag == (vuint8)FBL_DIAG_SRVMSGID_STORED) + { + /* Read last Server Message ID from NV Memory */ + result = ApplFblReadLastServerMsgId(lastServerMessageId); + } + else + { + /* Initialize last Server Message ID */ + result = ApplFblWriteLastServerMsgId(lastServerMessageId); + + if (result == kFblOk) + { + /* Set Server Message ID Flag so next time it will be read from NV Memory */ + srvMsgIdFlag = (vuint8)FBL_DIAG_SRVMSGID_STORED; + result = ApplFblWriteSrvMsgIDFlag(&srvMsgIdFlag); + } + } + } + else + { + result = kFblFailed; + } + + if (result == kFblOk) + { + /* Read current Server Message ID from token buffer and compare with last Server Message ID */ + const vuint8 *currentServerMessageId = FblDiagGetTokenServerMsgIdPtr(tokenBuf); + result = kFblFailed; + + /* Check each byte, starting from MSB (index 0 due to network byte order) */ + for (idx = 0u; idx < 8u; idx++) + { + if (currentServerMessageId[idx] > lastServerMessageId[idx]) + { + /* Received server message ID is higher than last server message ID */ + result = kFblOk; + srvMsgIdCompareFinished = kFblOk; + } + else if (currentServerMessageId[idx] < lastServerMessageId[idx]) + { + /* Received server message ID is lower than last server message ID. Break loop so result + * cannot be ok if a byte with lower significance has a higher value in the current server + * message ID */ + srvMsgIdCompareFinished = kFblOk; + } + else + { + /* Values are the same, continue with check */ + } + + if (srvMsgIdCompareFinished == kFblOk) + { + break; + } + } + + if (result == kFblOk) + { + result = ApplFblWriteLastServerMsgId(currentServerMessageId); + } + } + + return result; +} + +/*********************************************************************************************************************** + * FblDiagTokenCallout + **********************************************************************************************************************/ +/*! \brief Calls for each Token mode the related Callout + * \param[in] cmdType The Token mode from TokenCommandType + * \return Possible return values: + * - tTokenHdlResult: result of the callout function + **********************************************************************************************************************/ +static tTokenHdlResult FblDiagTokenCallout( vuint8 cmdType, const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tokenBuf, vuint16 tokenLength ) +{ + tTokenHdlResult result; + + switch (cmdType) + { + case FBL_DIAG_TOKEN_CMD_REVERTPROD: + { + result = ApplFblTokenRevertKey(tokenBuf, tokenLength); + break; + } + case FBL_DIAG_TOKEN_CMD_USEDEVPERM: + { + result = ApplFblTokenUseDevPermKey(tokenBuf, tokenLength); + break; + } + case FBL_DIAG_TOKEN_CMD_USEDEVTEMP: + { + result = ApplFblTokenUseDevTempKey(tokenBuf, tokenLength); + break; + } + case FBL_DIAG_TOKEN_CMD_USEDEVDATE: + { + result = ApplFblTokenUseDevDateKey(tokenBuf, tokenLength); + break; + } + case FBL_DIAG_TOKEN_CMD_USEDEVIGNI: + { + result = ApplFblTokenUseDevIgniKey(tokenBuf, tokenLength); + break; + } + case FBL_DIAG_TOKEN_CMD_PROGKEY: + { + result = ApplFblTokenProgKey(tokenBuf, tokenLength); + break; + } + default: + { + result = kTokenHdlrInternalFailed; + break; + } + } + + return result; +} +# endif /* FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING */ +#endif /* SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC */ + + +#define FBLDIAG_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_FblDiag_0306: + Reason: Address conversion between integer values and pointers is required to allow for hardware independent + configuration and address range checks. + Risk: The size of integer required to hold the result of a pointer cast is implementation-defined. + Prevention: The size of the respective integer data type which holds the address value is adapted on a hardware + specific basis. The correctness of the respective implementation is verified by runtime tests. + + MD_FblDiag_0313_VerifyFctOutput: + Reason: Signature/checksum verification functions are stored as void pointers as actual type is not known at + configuration time. + Risk: Function signature not compatible with expected type. + Prevention: Integrator has to take care the configured functions match with the expected signature. + + MD_FblDiag_0314_MemCpy: + Reason: The copy function have a void pointer as a function parameter. + Risk: No risk, because the underlying vuint8 pointer type is known. + Prevention: No prevention necessary. + + MD_FblDiag_0314_KeyPtr: + Reason: The verification parameter structure has a void pointer member for the key to support different + key types for different use cases + Risk: No risk, because the underlying key pointer type is known. + Prevention: No prevention necessary. + + MD_FblDiag_0883: + Reason: This file has to be included multiple times explicitly, due to creation of multiple structures via fbl_diag.def. + Risk: No identifiable risk because defines are undefined in fbl_diag.imp + Prevention: No prevention required. + + MD_FblDiag_1514: + Reason: The variable is used by other modules and can't be declared static. + Risk: Name conflicts. + Prevention: Compile and link of the different variants in the component and integration test. + + MD_FblDiag_2214: + Reason: Assertion macros have to be disabled in production code and are used only for development. + Risk: Assertion code may be enabled in production code unintentionally. If a assertion condition is unexpectedly + false, the code is active. A problem may occur if the Macro is additionally changed from single statement + to multiple statement. + Prevention: Macro is not allowed to be changed without review. Development code is automatically disabled via + configuration of project state "Production". + + MD_FblDiag_2741: + Reason: Some if conditions seems to be static only on certain compiling conditions. + Risk: A condition is always false or true independently from the compiling configuration. + Prevention: Code inspection and test of the different variants in the component test. + + MD_FblDiag_2790_kDiagStateMaskAllLong: + Reason: Create a mask where all bits are set. Generic implementation shifts therefore too many bytes. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblDiag_2880_UnreachableCode: + Reason: A code section can be executed only based on some static compile time configurations. + Risk: A code section is never executed independently from the compiling configuration. + Prevention: Code inspection and test of the different variants in the component test. + + MD_FblDiag_2889: + Reason: Multiple return paths are used to reduce code complexity, increase readability and reducing nesting level. + Risk: Some operations intended to conclude the function (e.g. states cleaning) can be unintentionally jumped. + Prevention: Code inspection and runtime tests. + + MD_FblDiag_2916: + Reason: Assignment to pointer is done within a function to make code more readable. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblDiag_2983_2985_RedundantAssignment: + Reason: Assignments are redundant only on certain configurations + Risk: Some code part can be really redundant in all possible configurations. + Prevention: Code review. + + MD_FblDiag_3218: + Reason: The local data of this module is kept at a central location for a better overview and maintenance. + Risk: Scope is larger than required (whole file instead of one function). Some other function could access + the variable. + Prevention: Restrict the functionality in this module to the intended purpose. Don't add functions which shall not + be able to access the local data. + + MD_FblDiag_3415: + Reason: Side effect (conditional execution) is intended. + Risk: Unintended side effects. + Prevention: Code is checked for unintended side effects by code inspection. + + MD_FblDiag_3493: + Reason: Depending on the configuration the value is not always true. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblDiag_3678: + Reason: The buffer is actually modified and can therefore not be a const buffer. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblDiag_5087_DiagDef: + Reason: Multiple includes of fbl_diag.def are required for building the configuration tables of the diagnostic layer. + Risk: Resulting code is difficult to understand and maintain. + Prevention: All changes to the affected code parts have to be reviewed by the module responsible. On a mid term + view, the respective implementation will be replaced by generated code. + + MD_FblDiag_ConstValue: + Reason: Value is constant depending on configuration aspects or platform specific implementation. This leads to + constant control expressions, unreachable code or redundant operations. + Risk: Wrong or missing functionality. + Prevention: Code inspection and test of the different variants in the component test. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_DIAG.C + **********************************************************************************************************************/ + diff --git a/Source/bsw/Fbl/fbl_diag.def b/Source/bsw/Fbl/fbl_diag.def new file mode 100644 index 0000000..222454f --- /dev/null +++ b/Source/bsw/Fbl/fbl_diag.def @@ -0,0 +1,251 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Diagnostic services supported in boot mode + * Definition of services and subfunctions for state machine + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2026 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2022-08-15 vistmo FBL-5514 Support Additional OTA functionality + * ESCAN00112435 No changes + * ESCAN00112575 No changes + * 05.01.00 2022-10-04 jschmitding FBL-5917 Make FBL SWDL 008 Compliant + * ESCAN00113919 RoutineControl Routines are protected by security access even + * though it's not required + * 05.01.01 2022-10-17 fmenke ESCAN00112879 No changes + * 05.01.02 2023-01-13 fmenke ESCAN00112890 No changes + * ESCAN00113612 No changes + * 05.02.00 2023-02-09 vistmo ESCAN00112972 No changes + * ESCAN00113292 No changes + * ESCAN00113835 No changes + * ESCAN00113843 No changes + * ESCAN00113764 RID 7013 (token download) is always supported + * FBL-6438 No changes + * 05.02.01 2023-05-11 fmenke ESCAN00113831 No changes + * 05.03.00 2023-07-24 fmenke FBL-7335 No changes + * 05.03.01 2023-08-31 lhopfhauer ESCAN00115494 No changes + * 05.03.02 2024-07-16 erizk ESCAN00117344 No changes + * 05.03.03 2025-02-06 virchl ESCAN00118587 No changes + * 05.04.00 2025-02-28 jjohnson FBL-10065 No changes + * 05.04.01 2025-06-10 jostravsky ESCAN00120315 No changes + * 05.04.02 2025-07-08 visarcmijo ESCAN00119833 No changes + * 05.05.00 2025-09-01 fmenke FBL-11218 No changes + * ESCAN00120917 No changes + * 05.06.00 2025-10-28 mpatil FBL-11690 No changes + * 05.07.00 2026-01-13 dganesh FBL-12162 No changes + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ +#if ( FBLDIAG_14229_FORD_VERSION != 0x0507u ) || \ + ( FBLDIAG_14229_FORD_RELEASE_VERSION != 0x00u ) +# error "Error in fbl_diag.def: State machine definition and source are inconsistent!" +#endif + +#ifndef FBL_DIAG_DEF +#define FBL_DIAG_DEF + +/* PRQA S 0883 EOF */ /* MD_FblDiag_0883 */ + +/* Some preprocessors don't like undefined (but unused) macro parameters */ +#if !defined( FBL_DIAG_DISABLE_DUMMY_MACRO_PARAMETERS ) +# define Root 0u +# define DiagnosticSessionControl 0u +# define EcuReset 0u +# define SecurityAccess 0u +# define TesterPresent 0u +# define ReadDataByIdentifier 0u +# define ReadDataById 0u +# define WriteDataByIdentifier 0u +# define WriteDataById 0u +# define RoutineControl 0u +# define RequestDownload 0u +# define RequestUpload 0u +# define TransferData 0u +# define RequestTransferExit 0u +# define DefaultSession 0u +# define ProgrammingSession 0u +# define HardReset 0u +# define RequestSeed 0u +# define SendKey 0u +# define SecAccessSeed 0u +# define SecAccessKey 0u +# define ZeroSubFunction 0u +# define StartRoutine 0u +# define EraseMemory 0u +# define RcEraseMemory 0u +# define CheckProgDep 0u +# define RcCheckProgDep 0u +# define ActivateSbl 0u +# define RcActivateSbl 0u +# define CheckValidApp 0u +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# define TokenDownload 0u +#endif +# define RcCheckValidApp 0u +# if defined( FBL_DIAG_ENABLE_UPDATE_SEC_BYTES ) +# define UpdateSecBytes 0u +# define RcUpdateSecBytes 0u +# endif +# if defined( FBL_DIAG_ENABLE_UPLOAD ) +# define TransferDataDownload 0u +# define TransferDataUpload 0u +# endif +# define ServiceCheck 0u +# define SubFctCheck 0u +# define TransferDataCheck 0u +# define SubRoutineCheck 0u +# define NonSubFctCheck 0u +# define RcTypeCheck 0u +#endif +#endif /* FBL_DIAG_DEF */ + +/* Increase compatibility with certain preprocessors */ +#if defined( None ) +#else +# define None 0xFFu +#endif + +/* LEVEL 0 Name Parent First Child Last Child Buffer Position ID Main Handler Index Checks Set Unset Add Clear Clear Fail Minimum Request Length Maximum Request Length */ +/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( Root , None , DiagnosticSessionControl , RequestTransferExit , kDiagFmtServiceId , 0x00 , None , ServiceCheck , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , 0u , kDiagRqlUnlimited ) +#include "fbl_diag.imp" + +/* LEVEL 1 Name Parent First Child Last Child Buffer Position ID Main Handler Index Checks Set Unset Add Clear Clear Fail Minimum Request Length Maximum Request Length */ +/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( DiagnosticSessionControl , Root , DefaultSession , ProgrammingSession , kDiagFmtSubparam , kDiagSidDiagnosticSessionControl , None , SubFctCheck , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateFirstDownloadReq) , (kDiagStateSecurityKeyAll | kDiagStateSecurityAccessAll) , (kDiagStateNone) , kDiagRqlSubfunctionService , kDiagRqlUnlimited ) +#include "fbl_diag.imp" + +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( EcuReset , Root , HardReset , HardReset , kDiagFmtSubparam , kDiagSidEcuReset , None , SubFctCheck , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlSubfunctionService , kDiagRqlUnlimited ) +#include "fbl_diag.imp" + +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( SecurityAccess , Root , RequestSeed , SendKey , kDiagFmtSubparam , kDiagSidSecurityAccess , None , SubFctSecCheck , (kDiagStateNone) , (kDiagStateSessionDefault) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateSecurityKeyAll) , kDiagRqlSubfunctionService , kDiagRqlUnlimited ) +#include "fbl_diag.imp" + +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( TesterPresent , Root , ZeroSubFunction , ZeroSubFunction , kDiagFmtSubparam , kDiagSidTesterPresent , None , SubFctCheck , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlSubfunctionService , kDiagRqlUnlimited ) +#include "fbl_diag.imp" + +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( ReadDataByIdentifier , Root , None , None , kDiagFmtDataIdHigh , kDiagSidReadDataByIdentifier , ReadDataById , NonSubFctCheck , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlMinReadDataByIdentifier , kDiagRqlMaxReadDataByIdentifier ) +#include "fbl_diag.imp" + +#if defined( FBL_DIAG_ENABLE_WRITE_DATA_BY_IDENTIFIER ) +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( WriteDataByIdentifier , Root , None , None , kDiagFmtDataIdHigh , kDiagSidWriteDataByIdentifier , WriteDataById , NonSubFctCheck , (kDiagStateSessionProgramming | kDiagStateSecurityAccess01) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlWriteDataByIdentifier , kDiagRqlUnlimited ) +# include "fbl_diag.imp" +#endif /* FBL_DIAG_ENABLE_WRITE_DATA_BY_IDENTIFIER */ + +#if defined( FBL_ENABLE_USERROUTINE ) +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( RoutineControl , Root , ActivateSbl , CheckProgDep , kDiagFmtSubRoutineIdHigh, kDiagSidRoutineControl , RoutineControl , SubRoutineCheck , (kDiagStateSessionProgramming) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlRoutineControl , kDiagRqlUnlimited ) +#else +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( RoutineControl , Root , ActivateSbl , CheckProgDep , kDiagFmtSubRoutineIdHigh, kDiagSidRoutineControl , None , SubRoutineCheck , (kDiagStateSessionProgramming) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlRoutineControl , kDiagRqlUnlimited ) +#endif /* FBL_ENABLE_USERROUTINE */ +#include "fbl_diag.imp" + +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( RequestDownload , Root , None , None , kDiagFmtSubparam , kDiagSidRequestDownload , RequestDownload , NonSubFctCheck , (kDiagStateSessionProgramming | kDiagStateSecurityAccess01) , (kDiagStateNone) , (kDiagStateTransferDataAllowed) , (kDiagStateFirstDownloadReq | kDiagStateTransferDataSucceeded) , (kDiagStateTransferDataAllowed | kDiagStateTransferDataSucceeded) , kDiagRqlRequestDownload + kDiagSubMinLengthFormat + kDiagSubMinAddrFormat, kDiagRqlRequestDownload + kDiagSubMaxLengthFormat + kDiagSubMaxAddrFormat ) +#include "fbl_diag.imp" + +#if defined( FBL_DIAG_ENABLE_UPLOAD ) +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( RequestUpload , Root , None , None , kDiagFmtSubparam , kDiagSidRequestUpload , RequestUpload , NonSubFctCheck , (kDiagStateSessionProgramming | kDiagStateSecurityAccess01) , (kDiagStateTransferDataAllowed) , (kDiagStateTransferDataAllowed | kDiagStateTransferDataUpload), (kDiagStateTransferDataSucceeded) , (kDiagStateTransferDataAllowed | kDiagStateTransferDataSucceeded | kDiagStateTransferDataUpload), kDiagRqlRequestUpload + kDiagSubMinLengthFormat + kDiagSubMinAddrFormat , kDiagRqlRequestUpload + kDiagSubMaxLengthFormat + kDiagSubMaxAddrFormat ) +# include "fbl_diag.imp" + +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( TransferData , Root , TransferDataDownload , TransferDataUpload , kDiagFmtSequenceCnt , kDiagSidTransferData , None , TransferDataCheck, (kDiagStateSessionProgramming | kDiagStateTransferDataAllowed) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateTransferDataSucceeded) , (kDiagStateTransferDataAllowed | kDiagStateTransferDataSucceeded | kDiagStateTransferDataUpload), kDiagRqlTransferDataUpload , kDiagRqlUnlimited ) +# include "fbl_diag.imp" + +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( RequestTransferExit , Root , None , None , kDiagFmtSubparam , kDiagSidRequestTransferExit , RequestTransferExit , NonSubFctCheck , (kDiagStateSessionProgramming | kDiagStateTransferDataAllowed) , (kDiagStateNone) , (kDiagStateTransferDataSucceeded) , (kDiagStateTransferDataAllowed | kDiagStateTransferDataSucceeded | kDiagStateTransferDataUpload), (kDiagStateTransferDataAllowed | kDiagStateTransferDataSucceeded | kDiagStateTransferDataUpload), kDiagRqlRequestTransferExit , kDiagRqlRequestTransferExit ) +# include "fbl_diag.imp" +#else +# if defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( TransferData , Root , None , None , kDiagFmtSubparam , kDiagSidTransferData , TransferDataDownload, NonSubFctCheck , (kDiagStateSessionProgramming | kDiagStateTransferDataAllowed) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateTransferDataSucceeded) , (kDiagStateTransferDataAllowed | kDiagStateTransferDataSucceeded) , kDiagRqlTransferDataDownload , (FBL_DIAG_BUFFER_LENGTH - 1u) ) +# else +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( TransferData , Root , None , None , kDiagFmtSubparam , kDiagSidTransferData , TransferDataDownload, NonSubFctCheck , (kDiagStateSessionProgramming | kDiagStateTransferDataAllowed) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateTransferDataSucceeded) , (kDiagStateTransferDataAllowed | kDiagStateTransferDataSucceeded) , kDiagRqlTransferDataDownload , ((kDiagRqlTransferDataDownload - 1u) + ((FBL_DIAG_BUFFER_LENGTH - 2u) & (~(FBL_MAX_SEGMENT_SIZE - 1u))))) +# endif /* FBL_ENABLE_UNALIGNED_DATA_TRANSFER */ +# include "fbl_diag.imp" + +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( RequestTransferExit , Root , None , None , None , kDiagSidRequestTransferExit , RequestTransferExit , NonSubFctCheck , (kDiagStateSessionProgramming | kDiagStateTransferDataAllowed) , (kDiagStateNone) , (kDiagStateTransferDataSucceeded) , (kDiagStateTransferDataAllowed | kDiagStateTransferDataSucceeded) , (kDiagStateTransferDataAllowed | kDiagStateTransferDataSucceeded) , kDiagRqlRequestTransferExit , kDiagRqlRequestTransferExit ) +# include "fbl_diag.imp" +#endif /* FBL_DIAG_ENABLE_UPLOAD */ + +/* LEVEL 2 Name Parent First Child Last Child Buffer Position ID Main Handler Index Checks Set Unset Add Clear Clear Fail Minimum Request Length Maximum Request Length */ +/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( DefaultSession , DiagnosticSessionControl, None , None , None , kDiagSubDefaultSession , DefaultSession , None , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlDiagnosticSessionControl , kDiagRqlDiagnosticSessionControl ) +#include "fbl_diag.imp" + +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( ProgrammingSession , DiagnosticSessionControl, None , None , None , kDiagSubProgrammingSession , ProgrammingSession , None , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlDiagnosticSessionControl , kDiagRqlDiagnosticSessionControl ) +#include "fbl_diag.imp" + +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( HardReset , EcuReset , None , None , None , kDiagSubHardReset , EcuReset , None , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlEcuReset , kDiagRqlEcuReset ) +#include "fbl_diag.imp" + +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( RequestSeed , SecurityAccess , None , None , None , kDiagSubRequestSeed , SecAccessSeed , None , (kDiagStateNone) , (kDiagStateSecurityAccessDelay01), (kDiagStateSecurityKey01) , (kDiagStateSecurityKeyAll) , (kDiagStateNone) , kDiagRqlSecurityAccessSeed , kDiagRqlSecurityAccessSeed ) +#include "fbl_diag.imp" + +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( SendKey , SecurityAccess , None , None , None , kDiagSubSendKey , SecAccessKey , None , (kDiagStateSecurityKey01) , (kDiagStateSecurityAccessDelay01), (kDiagStateSecurityAccess01) , (kDiagStateSecurityKeyAll | kDiagStateSecurityAccessAll) , (kDiagStateNone) , kDiagRqlSecurityAccessKey , kDiagRqlSecurityAccessKey ) +#include "fbl_diag.imp" + +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( ZeroSubFunction , TesterPresent , None , None , None , kDiagSubZeroSubFunction , TesterPresent , None , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlTesterPresent , kDiagRqlTesterPresent ) +#include "fbl_diag.imp" + +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( ActivateSbl , RoutineControl , StartRoutine , StartRoutine , kDiagFmtSubparam , SPLIT_SHORT(kDiagRoutineIdActivateSbl) , RcActivateSbl , RcTypeCheck , (kDiagStateSecurityAccess01) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlRcActivateSbl , kDiagRqlRcActivateSbl ) +#include "fbl_diag.imp" + + +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( CheckValidApp , RoutineControl , StartRoutine , StartRoutine , kDiagFmtSubparam , SPLIT_SHORT(kDiagRoutineIdCheckValidApp), RcCheckValidApp , RcTypeCheck , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateFirstDownloadReq) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlRcCheckValidApp , kDiagRqlRcCheckValidApp ) +#include "fbl_diag.imp" + +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( TokenDownload , RoutineControl , StartRoutine , StartRoutine , kDiagFmtSubparam , SPLIT_SHORT(kDiagRoutineIdTokenDownload), RcTokenDownload , RcTypeCheck , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlRcTokenDownloadMin , kDiagRqlRcTokenDownloadMax ) +# include "fbl_diag.imp" +# endif +#endif + + +#if defined( FBL_DIAG_ENABLE_UPDATE_SEC_BYTES ) +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( UpdateSecBytes , RoutineControl , StartRoutine , StartRoutine , kDiagFmtSubparam , SPLIT_SHORT(kDiagRoutineIdUpdateSecBytes), RcUpdateSecBytes , RcTypeCheck , (kDiagStateSecurityAccess01) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlRcUpdateSecBytes , kDiagRqlRcUpdateSecBytes ) +# include "fbl_diag.imp" +#endif /* FBL_DIAG_ENABLE_UPDATE_SEC_BYTES */ + +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( EraseMemory , RoutineControl , StartRoutine , StartRoutine , kDiagFmtSubparam , SPLIT_SHORT(kDiagRoutineIdEraseMemory) , RcEraseMemory , RcTypeCheck , (kDiagStateSecurityAccess01) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateFirstDownloadReq) , (kDiagStateNone) , kDiagRqlRcEraseMemory , kDiagRqlRcEraseMemory ) +#include "fbl_diag.imp" +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( CheckProgDep , RoutineControl , StartRoutine , StartRoutine , kDiagFmtSubparam , SPLIT_SHORT(kDiagRoutineIdCheckProgDep) , RcCheckProgDep , RcTypeCheck , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlRcCheckProgDep , kDiagRqlRcCheckProgDep ) +#include "fbl_diag.imp" + +/* LEVEL 3 Name Parent First Child Last Child Buffer Position ID Main Handler Index Checks Set Unset Add Clear Clear Fail Minimum Request Length Maximum Request Length */ +/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ +#define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( StartRoutine , None , None , None , None , kDiagSubStartRoutine , None , None , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlRoutineControl , kDiagRqlUnlimited ) +#include "fbl_diag.imp" + + +#if defined( FBL_DIAG_ENABLE_UPLOAD ) +# if defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( TransferDataDownload , TransferData , None , None , None , kDiagSidTransferData , TransferDataDownload, None , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlTransferDataDownload , (FBL_DIAG_BUFFER_LENGTH - 1u) ) +# else +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( TransferDataDownload , TransferData , None , None , None , kDiagSidTransferData , TransferDataDownload, None , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlTransferDataDownload , ((kDiagRqlTransferDataDownload - 1u) + ((FBL_DIAG_BUFFER_LENGTH - 2u) & (~(FBL_MAX_SEGMENT_SIZE - 1u))))) +# endif /* FBL_ENABLE_UNALIGNED_DATA_TRANSFER */ +# include "fbl_diag.imp" + +# define FBL_DIAG_STATE_RESULT FBL_DIAG_STATE_DEF( TransferDataUpload , TransferData , None , None , None , kDiagSidTransferData , TransferDataUpload , None , (kDiagStateTransferDataUpload) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , (kDiagStateNone) , kDiagRqlTransferDataUpload , kDiagRqlTransferDataUpload ) +# include "fbl_diag.imp" +#endif /* FBL_DIAG_ENABLE_UPLOAD */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_DIAG.DEF + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_diag.h b/Source/bsw/Fbl/fbl_diag.h new file mode 100644 index 0000000..63588a5 --- /dev/null +++ b/Source/bsw/Fbl/fbl_diag.h @@ -0,0 +1,1046 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Diagnostic services supported in boot mode + * Declaration of functions, variables and constants + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2026 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2022-08-15 vistmo FBL-5514 Support Additional OTA functionality + * ESCAN00112435 No changes + * ESCAN00112575 No changes + * 05.01.00 2022-10-04 jschmitding FBL-5917 Make FBL SWDL 008 Compliant + * ESCAN00113919 No changes + * 05.01.01 2022-10-17 fmenke ESCAN00112879 No changes + * 05.01.02 2023-01-13 fmenke ESCAN00112890 No changes + * ESCAN00113612 No changes + * 05.02.00 2023-02-09 vistmo ESCAN00112972 No changes + * ESCAN00113292 No changes + * ESCAN00113835 No changes + * ESCAN00113843 No changes + * ESCAN00113764 RID 7013 (token download) is always supported + * FBL-6438 No changes + * 05.02.01 2023-05-11 fmenke ESCAN00113831 No changes + * 05.03.00 2023-07-24 fmenke FBL-7335 No changes + * 05.03.01 2023-08-31 lhopfhauer ESCAN00115494 Bootloader does not enter programming session when + * started from application + * 05.03.02 2024-07-16 erizk ESCAN00117344 Compiler error: FblRealTimeSupportVoid undefined, assuming + * extern returning int + * 05.03.03 2025-02-06 virchl ESCAN00118587 No changes + * 05.04.00 2025-02-28 jjohnson FBL-10065 Support App Signing Specification 2.1.3 + * 05.04.01 2025-06-10 jostravsky ESCAN00120315 No changes + * 05.04.02 2025-07-08 visarcmijo ESCAN00119833 No changes + * 05.05.00 2025-09-01 fmenke FBL-11218 Add support for NXP DSP firmware update + * ESCAN00120917 No changes + * 05.06.00 2025-10-28 mpatil FBL-11690 No changes + * 05.07.00 2026-01-13 dganesh FBL-12162 No changes + **********************************************************************************************************************/ + +#ifndef FBL_DIAG_H +#define FBL_DIAG_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblDiag_14229_Ford CQComponent : Implementation */ +#define FBLDIAG_14229_FORD_VERSION 0x0507u +#define FBLDIAG_14229_FORD_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#ifndef kDiagCallCycle +# define kDiagCallCycle TpCallCycle /* Same call cycle as TP */ +#endif + +#define kDiagPutResponse ((vuint8) 0x01u) + +/* -- Defines of diag services -- */ +#define kDiagSidDiagnosticSessionControl ((vuint8) 0x10u) +#define kDiagSidEcuReset ((vuint8) 0x11u) +#define kDiagSidReadDataByIdentifier ((vuint8) 0x22u) +#define kDiagSidSecurityAccess ((vuint8) 0x27u) +#define kDiagSidWriteDataByIdentifier ((vuint8) 0x2Eu) +#define kDiagSidRoutineControl ((vuint8) 0x31u) +#define kDiagSidRequestDownload ((vuint8) 0x34u) +#define kDiagSidRequestUpload ((vuint8) 0x35u) +#define kDiagSidTransferData ((vuint8) 0x36u) +#define kDiagSidRequestTransferExit ((vuint8) 0x37u) +#define kDiagSidTesterPresent ((vuint8) 0x3Eu) + +/* -- Defines for address and length format identifier -- */ +/* Not more than 4 byte addresses and lengths can be handled */ +#if defined( FBL_DIAG_ENABLE_FIXED_TRANSFER_ALFI ) +#define kDiagSubMinLengthFormat ((vuint8) 0x04u) +#else +#define kDiagSubMinLengthFormat ((vuint8) 0x01u) +#endif +#define kDiagSubMaxLengthFormat ((vuint8) 0x04u) +/* Includes memory identifier */ +#if defined( FBL_DIAG_ENABLE_FIXED_TRANSFER_ALFI ) +#define kDiagSubMinAddrFormat ((vuint8) 0x04u) +#else +#define kDiagSubMinAddrFormat ((vuint8) 0x02u) +#endif +#define kDiagSubMaxAddrFormat ((vuint8) 0x04u) +#define kDiagSubMemType ((vuint8) 0x00u) +#define kDiagSubFlashDrvMemType ((vuint8) 0x02u) + +#define kDiagSubNoEncryption ((vuint8) 0x00u) +#define kDiagSubNoCompression ((vuint8) 0x00u) +#define kDiagSubNoDataProcessing ((vuint8) ((kDiagSubNoCompression << 4u) | kDiagSubNoEncryption)) +#define kDiagSubDefaultCompression ((vuint8) 0x01u) + +/* -- Defines of diag subservices -- */ +#define kDiagSuppressPosRspMsgIndicationBit ((vuint8) 0x80u) + +/* DiagnosticSessionControl */ +#define kDiagSubDefaultSession ((vuint8) 0x01u) +#define kDiagSubProgrammingSession ((vuint8) 0x02u) + +/* ECUReset */ +#define kDiagSubHardReset ((vuint8) 0x01u) + +/* TesterPresent */ +#define kDiagSubZeroSubFunction ((vuint8) 0x00u) + +/* RoutineControl request, routineControlType */ +#define kDiagSubStartRoutine ((vuint8) 0x01u) +#define kDiagSubStopRoutine ((vuint8) 0x02u) +#define kDiagSubRequestRoutineResults ((vuint8) 0x03u) + +/* RoutineControl response, RoutineType (Ford specific) */ +#define kDiagSubRoutineType1_Sync ((vuint8) 0x01u) +#define kDiagSubRoutineType2_AsyncFiniteNoStop ((vuint8) 0x02u) +#define kDiagSubRoutineType3_AsyncFiniteOrStop ((vuint8) 0x03u) + +/* RoutineControl response, RoutineStatus (Ford specific) */ +#define kDiagSubRoutineStatusCompleted ((vuint8) 0x00u) +#define kDiagSubRoutineStatusAborted ((vuint8) 0x01u) +#define kDiagSubRoutineStatusActive ((vuint8) 0x02u) +#define kDiagSubRoutineApplInvalid ((vuint8) 0x01u) +#define kDiagSubRoutineApplValid ((vuint8) 0x02u) + +/* RoutineControl, RoutineIdentifier */ +#define kDiagRoutineIdEraseMemory ((vuint16) 0xFF00u) +#define kDiagRoutineIdCheckProgDep ((vuint16) 0xFF01u) +#define kDiagRoutineIdActivateSbl ((vuint16) 0x0301u) +#define kDiagRoutineIdCheckValidApp ((vuint16) 0x0304u) +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +# define kDiagRoutineIdTokenDownload ((vuint16) 0x7013u) +# endif +#endif +#define kDiagRoutineIdUpdateSecBytes ((vuint16) 0x0305u) + +/* -- Response Identifier -- */ +/* Negative response SID */ +#define kDiagRidNegativeResponse ((vuint8) 0x7Fu) + +/* Data identifier for ReadDataByIdentifier service */ +#if !defined( kDiagDataIdActiveDiagnosticSession ) +# define kDiagDataIdActiveDiagnosticSession ((vuint16) 0xD100u) +#endif +#define kDiagDataIdSwdlVersion ((vuint16) 0xF162u) +#if defined( FBL_DIAG_ENABLE_DID_CURRENT_DIAG_APP ) +# if !defined( kDiagDataIdBootloaderCurrentDiagnosticApp ) +# define kDiagDataIdBootloaderCurrentDiagnosticApp ((vuint16) 0xD021u) +# endif +#endif +#if !defined( kDiagSwdlVersion ) +# define kDiagSwdlVersion ((vuint8) 0x08u) +#endif + +/* -- Negative Response Codes -- */ +#define kDiagErrorNone ((vuint8) 0x00u) +#define kDiagNrcGeneralReject ((vuint8) 0x10u) +#define kDiagNrcServiceNotSupported ((vuint8) 0x11u) +#define kDiagNrcSubFunctionNotSupported ((vuint8) 0x12u) +#define kDiagNrcIncorrectMessageLengthOrInvalidFormat ((vuint8) 0x13u) +#define kDiagNrcResponseTooLong ((vuint8) 0x14u) +#define kDiagNrcBusyRepeatRequest ((vuint8) 0x21u) +#define kDiagNrcConditionsNotCorrect ((vuint8) 0x22u) +#define kDiagNrcRequestSequenceError ((vuint8) 0x24u) +#define kDiagNrcRequestOutOfRange ((vuint8) 0x31u) +#define kDiagNrcSecurityAccessDenied ((vuint8) 0x33u) +#define kDiagNrcInvalidKey ((vuint8) 0x35u) +#define kDiagNrcExceedNumberOfAttempts ((vuint8) 0x36u) +#define kDiagNrcRequiredTimeDelayNotExpired ((vuint8) 0x37u) +#define kDiagNrcUploadDownloadNotAccepted ((vuint8) 0x70u) +#define kDiagNrcTransferDataSuspended ((vuint8) 0x71u) +#define kDiagNrcGeneralProgrammingFailure ((vuint8) 0x72u) +#define kDiagNrcWrongBlockSequenceCounter ((vuint8) 0x73u) +#define kDiagNrcRcrResponsePending ((vuint8) 0x78u) +#define kDiagNrcSubfunctionNotSupportedInActiveSession ((vuint8) 0x7Eu) +#define kDiagNrcServiceNotSupportedInActiveSession ((vuint8) 0x7Fu) +#define kDiagNrcNoResponse ((vuint8) 0xFFu) + +/* Length (number of bytes) of the maxNumberOfBlockLength parameter in the RequestDownload/-Upload response */ +#define kDiagMaxNumberOfBlockLengthLength ((vuint8) 0x02u) + +/* Maximum supported DID requests */ +#if !defined( FBL_MAX_DID_COUNT ) +# define FBL_MAX_DID_COUNT 5u +#endif + +/* -- Macros for diag exceptions -- */ +#define DiagSetError(errorNo) (diagErrorCode = (errorNo)) +#define DiagClrError() (diagErrorCode = kDiagErrorNone) +#define DiagGetError() (diagErrorCode) +#define DiagNRCGeneralReject() DiagSetError(kDiagNrcGeneralReject) +#define DiagNRCServiceNotSupported() DiagSetError(kDiagNrcServiceNotSupported) +#define DiagNRCSubFunctionNotSupported() DiagSetError(kDiagNrcSubFunctionNotSupported) +#define DiagNRCIncorrectMessageLengthOrInvalidFormat() DiagSetError(kDiagNrcIncorrectMessageLengthOrInvalidFormat) +#define DiagNRCResponseTooLong() DiagSetError(kDiagNrcResponseTooLong) +#define DiagNRCBusyRepeatRequest() DiagSetError(kDiagNrcBusyRepeatRequest) +#define DiagNRCConditionsNotCorrect() DiagSetError(kDiagNrcConditionsNotCorrect) +#define DiagNRCRequestSequenceError() DiagSetError(kDiagNrcRequestSequenceError) +#define DiagNRCRequestOutOfRange() DiagSetError(kDiagNrcRequestOutOfRange) +#define DiagNRCSecurityAccessDenied() DiagSetError(kDiagNrcSecurityAccessDenied) +#define DiagNRCInvalidKey() DiagSetError(kDiagNrcInvalidKey) +#define DiagNRCExceedNumberOfAttempts() DiagSetError(kDiagNrcExceedNumberOfAttempts) +#define DiagNRCRequiredTimeDelayNotExpired() DiagSetError(kDiagNrcRequiredTimeDelayNotExpired) +#define DiagNRCUploadDownloadNotAccepted() DiagSetError(kDiagNrcUploadDownloadNotAccepted) +#define DiagNRCTransferDataSuspended() DiagSetError(kDiagNrcTransferDataSuspended) +#define DiagNRCGeneralProgrammingFailure() DiagSetError(kDiagNrcGeneralProgrammingFailure) +#define DiagNRCWrongBlockSequenceCounter() DiagSetError(kDiagNrcWrongBlockSequenceCounter) +#define DiagNRCRcrResponsePending() DiagSetError(kDiagNrcRcrResponsePending) +#define DiagNRCSubfunctionNotSupportedInActiveSession() DiagSetError(kDiagNrcSubfunctionNotSupportedInActiveSession) +#define DiagNRCServiceNotSupportedInActiveSession() DiagSetError(kDiagNrcServiceNotSupportedInActiveSession) + +/* Defines for length of service request parameters */ +#define kDiagRqlDiagnosticSessionControlParameter ((tCwDataLengthType) 0x00u) +#define kDiagRqlSecurityAccessSeedParameter ((tCwDataLengthType) 0x00u) +#define kDiagRqlSecurityAccessKeyParameter (kSecKeyLength) +#define kDiagRqlRcActivateSblMemoryAddress ((tCwDataLengthType) 0x04u) +#define kDiagRqlRcEraseMemoryMemoryId ((tCwDataLengthType) 0x00u) +#define kDiagRqlRcEraseMemoryAddress ((tCwDataLengthType) 0x04u) +#define kDiagRqlRcEraseMemoryLength ((tCwDataLengthType) 0x04u) +#define kDiagRqlRcCheckProgDepMemoryAddress ((tCwDataLengthType) 0x04u) +#define kDiagRqlRcCheckProgDepMemorySize ((tCwDataLengthType) 0x04u) +#define kDiagRqlRcUpdateSecBytesSecLevel ((tCwDataLengthType) 0x01u) +#define kDiagRqlRcUpdateSecBytesSecBytes ((tCwDataLengthType) 0x01u) + +/* Defines for length of service requests (excluding service ID) */ +#define kDiagRqlSubfunctionService ((tCwDataLengthType) 0x01u) +#define kDiagRqlDiagnosticSessionControl ((tCwDataLengthType) (0x01u+kDiagRqlDiagnosticSessionControlParameter)) +#define kDiagRqlEcuReset ((tCwDataLengthType) 0x01u) +#define kDiagRqlSecurityAccessSeed ((tCwDataLengthType) (0x01u+kDiagRqlSecurityAccessSeedParameter)) +#define kDiagRqlSecurityAccessKey ((tCwDataLengthType) (0x01u+kDiagRqlSecurityAccessKeyParameter)) +#define kDiagRqlMinReadDataByIdentifier ((tCwDataLengthType) 0x02u) +#define kDiagRqlMaxReadDataByIdentifier ((tCwDataLengthType) ((FBL_MAX_DID_COUNT) * 2u)) +#define kDiagRqlWriteDataByIdentifier ((tCwDataLengthType) 0x03u) /* DID + at least one additional data byte */ +#define kDiagRqlRoutineControl ((tCwDataLengthType) 0x03u) +#define kDiagRqlRcEraseMemory ((tCwDataLengthType) (kDiagRqlRoutineControl+kDiagRqlRcEraseMemoryMemoryId+kDiagRqlRcEraseMemoryAddress+kDiagRqlRcEraseMemoryLength)) +#define kDiagRqlRcCheckProgDep ((tCwDataLengthType) (kDiagRqlRoutineControl+kDiagRqlRcCheckProgDepMemoryAddress+kDiagRqlRcCheckProgDepMemorySize)) +#define kDiagRqlRcActivateSbl ((tCwDataLengthType) (kDiagRqlRoutineControl+kDiagRqlRcActivateSblMemoryAddress)) +#define kDiagRqlRcCheckValidApp ((tCwDataLengthType) (kDiagRqlRoutineControl)) +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +# define kDiagRqlRcTokenDownloadMin ((tCwDataLengthType) (kDiagRqlRoutineControl + FBL_DIAG_TOKEN_MIN_SIZE)) +# define kDiagRqlRcTokenDownloadMax ((tCwDataLengthType) (kDiagRqlRoutineControl + FBL_DIAG_TOKEN_MAX_SIZE)) +# endif +#endif +#define kDiagRqlRcUpdateSecBytes ((tCwDataLengthType) (kDiagRqlRoutineControl+kDiagRqlRcUpdateSecBytesSecLevel+kSecSecretKeyLength)) +#define kDiagRqlRequestDownload ((tCwDataLengthType) 0x02u) +#define kDiagRqlRequestUpload ((tCwDataLengthType) 0x02u) +#define kDiagRqlTransferDataDownload ((tCwDataLengthType) 0x02u) /* + Download data, at least one data byte mandatory */ +#define kDiagRqlTransferDataUpload ((tCwDataLengthType) 0x01u) /* Block sequence counter only, data in response message */ +#define kDiagRqlRequestTransferExit ((tCwDataLengthType) 0x00u) +#define kDiagRqlTesterPresent ((tCwDataLengthType) 0x01u) + +/* Defines for length of service response parameters */ +#define kDiagRslEcuResetParameter ((tCwDataLengthType) 0x00u) +#define kDiagRslDiagnosticSessionControlParameter ((tCwDataLengthType) 0x04u) +#define kDiagRslSecurityAccessSeedParameter (kSecSeedLength) +#define kDiagRslSecurityAccessKeyParameter ((tCwDataLengthType) 0x00u) +#define kDiagRslRcEraseMemoryParameter ((tCwDataLengthType) 0x01u) +#define kDiagRslRcCheckProgDepParameter ((tCwDataLengthType) 0x03u) +#define kDiagRslRcActivateSblParameter ((tCwDataLengthType) 0x01u) +#define kDiagRslRcCheckValidAppParameter ((tCwDataLengthType) 0x02u) +#if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +# define kDiagRslRcTokenDownloadParameter ((tCwDataLengthType) 0x01u) +#endif +#define kDiagRslRcUpdateSecBytesParameter ((tCwDataLengthType) 0x01u) +#define kDiagRslTransferDataParameter ((tCwDataLengthType) 0x00u) +#define kDiagRslRequestTransferExitParameter ((tCwDataLengthType) (kSecCrcLength)) + +/* Defines for length of service responses (excluding service ID) */ +#define kDiagRslDiagnosticSessionControl ((tCwDataLengthType) (0x01u+kDiagRslDiagnosticSessionControlParameter)) +#define kDiagRslEcuReset ((tCwDataLengthType) (0x01u+kDiagRslEcuResetParameter)) +#define kDiagRslSecurityAccessSeed ((tCwDataLengthType) (0x01u+kDiagRslSecurityAccessSeedParameter)) +#define kDiagRslSecurityAccessKey ((tCwDataLengthType) (0x01u+kDiagRslSecurityAccessKeyParameter)) +#define kDiagRslReadDataByIdentifier ((tCwDataLengthType) 0x02u) +#define kDiagRslWriteDataByIdentifier ((tCwDataLengthType) 0x02u) +#define kDiagRslRcEraseMemory ((tCwDataLengthType) (0x03u+kDiagRslRcEraseMemoryParameter)) +#define kDiagRslRcCheckProgDep ((tCwDataLengthType) (0x03u+kDiagRslRcCheckProgDepParameter)) +#define kDiagRslRcActivateSbl ((tCwDataLengthType) (0x03u+kDiagRslRcActivateSblParameter)) +#define kDiagRslRcCheckValidApp ((tCwDataLengthType) (0x03u+kDiagRslRcCheckValidAppParameter)) +#if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +# define kDiagRslRcTokenDownload ((tCwDataLengthType) (0x03u+kDiagRslRcTokenDownloadParameter)) +#endif +#define kDiagRslRcUpdateSecBytes ((tCwDataLengthType) (0x03u+kDiagRslRcUpdateSecBytesParameter)) +#define kDiagRslRequestDownload ((tCwDataLengthType) 0x01u) /* + maxNumberOfBlockLength */ +#define kDiagRslRequestUpload ((tCwDataLengthType) 0x01u) /* + maxNumberOfBlockLength */ +#define kDiagRslTransferData ((tCwDataLengthType) (0x01u+kDiagRslTransferDataParameter)) +#define kDiagRslRequestTransferExit ((tCwDataLengthType) (0x00u+kDiagRslRequestTransferExitParameter)) +#define kDiagRslTesterPresent ((tCwDataLengthType) 0x01u) + +/* Diagnostic service format definitions */ +#define kDiagFmtSequenceCnt ((tCwDataLengthType) (kDiagFmtServiceId+0x01u)) /* Position of sequence counter */ +#define kDiagFmtDataOffset ((tCwDataLengthType) (kDiagFmtSequenceCnt+0x01u)) /* Offset to download data in TransferData frame */ +#define kDiagFmtSeedKeyStart ((tCwDataLengthType) (kDiagFmtSubparam+0x01u)) /* Start index of seed/key value */ +#define kDiagFmtAddrOffset ((tCwDataLengthType) 0x03u) +#define kDiagFmtFormatOffset ((tCwDataLengthType) 0x02u) +#define kDiagFmtServiceId ((tCwDataLengthType) 0x00u) +#define kDiagFmtSubparam ((tCwDataLengthType) (kDiagFmtServiceId+0x01u)) +#define kDiagFmtRoutineIdHigh ((tCwDataLengthType) (kDiagFmtServiceId+0x01u)) +#define kDiagFmtRoutineIdLow ((tCwDataLengthType) (kDiagFmtRoutineIdHigh+0x01u)) +#define kDiagFmtRoutineIdPar ((tCwDataLengthType) (kDiagFmtRoutineIdLow+0x01u)) +#define kDiagFmtRoutineIdDataRecord ((tCwDataLengthType) (kDiagFmtRoutineIdPar+0x01u)) +#define kDiagFmtSubRoutineIdHigh ((tCwDataLengthType) (kDiagFmtSubparam+0x01u)) +#define kDiagFmtSubRoutineIdLow ((tCwDataLengthType) (kDiagFmtSubRoutineIdHigh+0x01u)) +#define kDiagFmtSubRoutineIdPar ((tCwDataLengthType) (kDiagFmtSubRoutineIdLow+0x01u)) +#define kDiagFmtSubRoutineIdDataRecord ((tCwDataLengthType) (kDiagFmtSubRoutineIdPar+0x01u)) +#define kDiagFmtSubRoutineEraseMemoryAddress ((tCwDataLengthType) (kDiagFmtSubRoutineIdPar)) +#define kDiagFmtSubRoutineEraseMemorySize ((tCwDataLengthType) (kDiagFmtSubRoutineEraseMemoryAddress+kDiagRqlRcEraseMemoryAddress)) +#define kDiagFmtSubRoutineCheckMemoryAddress ((tCwDataLengthType) (kDiagFmtSubRoutineIdPar)) +#define kDiagFmtSubRoutineCheckMemorySize ((tCwDataLengthType) (kDiagFmtSubRoutineCheckMemoryAddress+kDiagRqlRcCheckProgDepMemoryAddress)) +#define kDiagFmtSubRoutineInfo ((tCwDataLengthType) (kDiagFmtSubRoutineIdPar)) +#define kDiagFmtSubRoutineCheckValidAppStatus ((tCwDataLengthType) (kDiagFmtSubRoutineInfo+0x01u)) +#define kDiagFmtSubRoutineCrcHigh ((tCwDataLengthType) (kDiagFmtSubRoutineInfo+0x01u)) +#define kDiagFmtSubRoutineCrcLow ((tCwDataLengthType) (kDiagFmtSubRoutineCrcHigh+0x01u)) +#define kDiagFmtSubRoutineUpdateSecBytesLevel ((tCwDataLengthType) (kDiagFmtSubRoutineIdPar)) +#define kDiagFmtSubRoutineUpdateSecBytesValue ((tCwDataLengthType) (kDiagFmtSubRoutineUpdateSecBytesLevel+kDiagRqlRcUpdateSecBytesSecLevel)) +#define kDiagFmtNegResponse ((tCwDataLengthType) (kDiagFmtSubparam+0x01u)) /* Position of negative response code */ +#define kDiagFmtLengthMask ((vuint8) 0xF0u) +#define kDiagFmtAddrMask ((vuint8) 0x0Fu) +#define kDiagFmtEncryptionMask ((vuint8) 0x0Fu) +#define kDiagFmtCompressionMask ((vuint8) 0xF0u) +#define kDiagFmtMaxBlockLengthHigh ((vuint8) (kDiagFmtSubparam+0x01u)) +#define kDiagFmtMaxBlockLengthLow ((vuint8) (kDiagFmtMaxBlockLengthHigh+0x01u)) +#define kDiagFmtDataIdHigh ((vuint8) (kDiagFmtSubparam)) +#define kDiagFmtDataIdLow ((vuint8) (kDiagFmtDataIdHigh+0x01u)) +#define kDiagFmtDataIdDataRecord ((vuint8) (kDiagFmtDataIdLow+0x01u)) +#define kDiagFmtDataIdActiveDiagnosticSessionSize ((vuint8) 0x01u) +#define kDiagFmtDataIdSwdlVersionSize ((vuint8) 0x01u) +#if defined( FBL_DIAG_ENABLE_DID_CURRENT_DIAG_APP ) +# define kDiagFmtDataIdBootloaderCurrentDiagAppSize ((vuint8) 0x01u) +#endif +#define kDiagFmtDataIdSize ((vuint8) 0x02u) +#define kDiagFmtTransferDataUploadRetryBackupSize ((vuint8) 0x05u) + +/* Diagnostic session timing */ +#define kDiagSessionTimingP2 ((vuint16) (kFblDiagTimeP2 * FBL_REPEAT_CALL_CYCLE)) +#define kDiagSessionTimingP2Star ((vuint16) ((vuint32)(kFblDiagTimeP2Star * FBL_REPEAT_CALL_CYCLE) / 10u)) + +/* Macros for P2 timeout */ +#define GetP2Timeout() (P2Timeout) +#define SetP2Timeout(val) (P2Timeout = (((val) > 0x01u) ? ((val) / 0x02u) : 0x01u)) +#define ClrP2Timeout() (P2Timeout = 0x00u) + +/* State machine states */ +#if defined( FBL_DIAG_ENABLE_ENUMS_IDX ) +enum +{ + kDiagStateIdxSessionDefault + ,kDiagStateIdxSessionProgramming + ,kDiagStateIdxSecurityKey01 + ,kDiagStateIdxSecurityAccess01 + ,kDiagStateIdxFunctionalRequest + ,kDiagStateIdxTransferDataAllowed + ,kDiagStateIdxTransferDataSucceeded +#if defined( FBL_DIAG_ENABLE_UPLOAD ) + ,kDiagStateIdxTransferDataUpload +#endif + ,kDiagStateIdxFirstDownloadReq + ,kDiagStateIdxSuppressPosRspMsg + /* States below are not relevant for service dispatching */ + ,kDiagStateIdxServiceInProgress + ,kDiagStateIdxTpConfirmationFlag + ,kDiagStateIdxDiagIndication + ,kDiagStateIdxResponseProcessing + ,kDiagStateIdxRcrRpInProgress + ,kDiagStateIdxMemDriverInitialized + ,kDiagStateIdxEraseMemorySucceeded + ,kDiagStateIdxWaitForRcrRpConf + ,kDiagStateIdxWaitEcuReset + ,kDiagStateIdxResetMsgConfirmed + ,kDiagStateIdxEcuResetFctFinished + ,kDiagStateIdxDiagBufferLocked +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) + ,kDiagStateIdxDiagDevelopmentKey +#endif + ,kDiagStateIdxProcessingDone + ,kDiagStateIdxLockedByInit + /*----------------------*/ + , kDiagNumberOfStates +}; +#else +# define kDiagStateIdxSessionDefault (0u) +# define kDiagStateIdxSessionProgramming (kDiagStateIdxSessionDefault + 1u) +# define kDiagStateIdxSecurityKey01 (kDiagStateIdxSessionProgramming + 1u) +# define kDiagStateIdxSecurityAccess01 (kDiagStateIdxSecurityKey01 + 1u) +# define kDiagStateIdxFunctionalRequest (kDiagStateIdxSecurityAccess01 + 1u) +# define kDiagStateIdxTransferDataAllowed (kDiagStateIdxFunctionalRequest + 1u) +# define kDiagStateIdxTransferDataSucceeded (kDiagStateIdxTransferDataAllowed + 1u) +# if defined( FBL_DIAG_ENABLE_UPLOAD ) +# define kDiagStateIdxTransferDataUpload (kDiagStateIdxTransferDataSucceeded + 1u) +# define kDiagStateIdxFirstDownloadReq (kDiagStateIdxTransferDataUpload + 1u) +# else +# define kDiagStateIdxFirstDownloadReq (kDiagStateIdxTransferDataSucceeded + 1u) +# endif /* FBL_DIAG_ENABLE_UPLOAD */ +# define kDiagStateIdxSuppressPosRspMsg (kDiagStateIdxFirstDownloadReq + 1u) +/*----------------------*/ +# define kDiagNumberOfDispatchStates (kDiagStateIdxSuppressPosRspMsg + 1u) +/*----------------------*/ +/* States below are not relevant for service dispatching */ +# define kDiagStateIdxServiceInProgress (kDiagStateIdxSuppressPosRspMsg + 1u) +# define kDiagStateIdxTpConfirmationFlag (kDiagStateIdxServiceInProgress + 1u) +# define kDiagStateIdxDiagIndication (kDiagStateIdxTpConfirmationFlag + 1u) +# define kDiagStateIdxResponseProcessing (kDiagStateIdxDiagIndication + 1u) +# define kDiagStateIdxRcrRpInProgress (kDiagStateIdxResponseProcessing + 1u) +# define kDiagStateIdxMemDriverInitialized (kDiagStateIdxRcrRpInProgress + 1u) +# define kDiagStateIdxEraseMemorySucceeded (kDiagStateIdxMemDriverInitialized + 1u) +# define kDiagStateIdxWaitForRcrRpConf (kDiagStateIdxEraseMemorySucceeded + 1u) +# define kDiagStateIdxWaitEcuReset (kDiagStateIdxWaitForRcrRpConf + 1u) +# define kDiagStateIdxResetMsgConfirmed (kDiagStateIdxWaitEcuReset + 1u) +# define kDiagStateIdxEcuResetFctFinished (kDiagStateIdxResetMsgConfirmed + 1u) +# define kDiagStateIdxDiagBufferLocked (kDiagStateIdxEcuResetFctFinished + 1u) +# define kDiagStateIdxDiagDevelopmentKey (kDiagStateIdxDiagBufferLocked + 1u) +# define kDiagStateIdxProcessingDone (kDiagStateIdxDiagDevelopmentKey + 1u) +# define kDiagStateIdxLockedByInit (kDiagStateIdxProcessingDone + 1u) +# define kDiagStateDisableFlashDriverDeinit (kDiagStateIdxLockedByInit + 1u) +# define kDiagStateEcuResetReasonSwupUpdate (kDiagStateDisableFlashDriverDeinit + 1u) +/*----------------------*/ +# define kDiagNumberOfStates (kDiagStateEcuResetReasonSwupUpdate + 1u) +/*----------------------*/ +#endif + +/* State array settings */ +#define STATE_BITS FBL_STATE_BITS + +#if ( STATE_BITS == 32u ) +typedef vuint32 tStateBitmap; + +#define kDiagStateMaskNone (tStateBitmap)(0x00000000uL) +#define kDiagStateMaskAll (tStateBitmap)(0xFFFFFFFFuL) +#endif + +#if ( STATE_BITS == 16u ) +typedef vuint16 tStateBitmap; + +#define kDiagStateMaskNone (tStateBitmap)(0x0000uL) +#define kDiagStateMaskAll (tStateBitmap)(0xFFFFuL) +#endif + +#if ( STATE_BITS == 8u ) +typedef vuint8 tStateBitmap; + +#define kDiagStateMaskNone (tStateBitmap)(0x00uL) +#define kDiagStateMaskAll (tStateBitmap)(0xFFuL) +#endif + +#if defined( FBL_DIAG_ENABLE_ENUMS_IDX ) +/* + Size of service state array + This has to be set manually, + because the state enum constants + can not be evaluated at preprocess time +*/ +# if ( STATE_BITS == 32u ) +# define STATECHECK_ARRAYSIZE (0x01u) +# endif + +# if ( STATE_BITS == 16u ) +# define STATECHECK_ARRAYSIZE (0x01u) +# endif + +# if ( STATE_BITS == 8u ) +# define STATECHECK_ARRAYSIZE (0x02u) +# endif +#else +# define STATECHECK_ARRAYSIZE (((kDiagNumberOfDispatchStates - 1u) / STATE_BITS) + 1u) +#endif + +#if !defined( STATECHECK_ARRAYSIZE ) +# error "Invalid STATE_BITS value" +#endif + +/* State mask build macros */ +#define STATE_MASK(bit) ((tStateBitmap)(1uL << ((bit) % STATE_BITS))) +#define STATE_MULTIMASK(min, max) ((((kDiagStateMaskAll) >> ((min) % STATE_BITS)) << ((min) % STATE_BITS)) ^ (((kDiagStateMaskAll) >> (((max) + 1u) % STATE_BITS)) << (((max) + 1u) % STATE_BITS))) +#define STATE_MASKLONG(bit) (1uL << (bit)) +#define STATE_MULTIMASKLONG(min, max) ((((~0uL) >> (min)) << (min)) ^ (((max) < (STATE_BITS - 1u)) ? (((~0uL) >> ((max) + 1u)) << ((max) + 1u)) : 0uL)) +#define STATE_INDEX(bit) ((bit) / STATE_BITS) +#define STATE_SET(arr, bit) ((arr)[STATE_INDEX(bit)] |= STATE_MASK(bit)) +#define STATE_CLR(arr, bit) ((arr)[STATE_INDEX(bit)] &= FblInvertBits(STATE_MASK(bit), tStateBitmap)) +#define STATE_MULTICLR(arr, min, max) ((arr)[STATE_INDEX(min)] &= FblInvertBits(STATE_MULTIMASK((min), (max)), tStateBitmap)) +#define STATE_TEST(arr, bit) (((arr)[STATE_INDEX(bit)] & STATE_MASK(bit)) == STATE_MASK(bit)) + +/* State access macros */ +#define GetDiagState(state) STATE_TEST(fblStates, (state)) + +#define GetDiagDefaultDiagSession() GetDiagState(kDiagStateIdxSessionDefault) +#define GetDiagProgrammingSession() GetDiagState(kDiagStateIdxSessionProgramming) +#define GetResponseProcessing() GetDiagState(kDiagStateIdxResponseProcessing) +#define GetRcrRpInProgress() GetDiagState(kDiagStateIdxRcrRpInProgress) +#define GetMemDriverInitialized() GetDiagState(kDiagStateIdxMemDriverInitialized) +#define GetServiceInProgress() GetDiagState(kDiagStateIdxServiceInProgress) +#define GetWaitEcuReset() GetDiagState(kDiagStateIdxWaitEcuReset) +#define GetDiagBufferLocked() GetDiagState(kDiagStateIdxDiagBufferLocked) +/* Flash driver restore handling */ +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# define GetDiagDevelopmentKey() GetDiagState(kDiagStateIdxDiagDevelopmentKey) +#endif +#define GetCurrentSecLvl() diagCurrentSecLvl + +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +/* Macros and defines for token handling */ +# define FBL_DIAG_TOKEN_MIN_SIZE 80u /* Used for mode 0 token without signature */ +# define FBL_DIAG_TOKEN_MAX_SIZE 1891u /* Used for mode 5 token */ +/* Compatibility define */ +# define FBL_DIAG_TOKEN_SIZE FBL_DIAG_TOKEN_MAX_SIZE + +/* Defines for enabling Ford key handling */ +# if defined (FBL_DIAG_SINGLE_KEY) +# define FBL_DIAG_ENABLE_PRODKEY_UPDATE +# define FBL_DIAG_ENABLE_DEVKEY_UPDATE +# define FBL_DIAG_ENABLE_DEVKEY +# endif +# endif /* FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING */ +#endif /* SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC */ + + +/* Compatibility defines */ +#define FblDiagGetDefaultSession() GetDiagDefaultSession() +#define FblDiagGetProgrammingSession() GetDiagProgrammingSession() +#define FblDiagGetExtendedSession() GetDiagExtendedSession() +#define FblDiagGetBufferLocked() GetDiagBufferLocked() +#define FblDiagGetRcrRpInProgress() GetRcrRpInProgress() +#define FblDiagGetMemDriverInitialized() GetMemDriverInitialized() + +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) +# define GetRequestedSeedLength() kDiagSecAccessParams[diagRequestedSecLvlIdx].seedLength +# define GetRequestedKeyLength() kDiagSecAccessParams[diagRequestedSecLvlIdx].keyLength +#else +# define GetRequestedSeedLength() kSecSeedLength +# define GetRequestedKeyLength() kSecKeyLength +#endif + + +#if defined( FBL_ENABLE_DEBUG_STATUS ) +/* Error codes for error status reporting */ +# define FBL_ERR_NONE ((vuint8) 0x00u) + +# define FBL_ERR_FLASH_ERASE_ERROR ((vuint8) 0x10u) +# define FBL_ERR_FLASH_PROG_ERROR ((vuint8) 0x11u) +# define FBL_ERR_FLASH_PROG_CONDITIONS ((vuint8) 0x12u) + +# define FBL_ERR_APPL_OVERLAPPING ((vuint8) 0x20u) +# define FBL_ERR_APPL_NOT_ALIGNED ((vuint8) 0x21u) +# define FBL_ERR_TOO_MANY_SEGMENTS_IN_MODULE ((vuint8) 0x22u) +# define FBL_ERR_NO_MEMORY_REGION_FOUND ((vuint8) 0x23u) +# define FBL_ERR_SEED_GENERATION_FAILED ((vuint8) 0x24u) +# define FBL_ERR_GAP_FILL ((vuint8) 0x25u) +# define FBL_ERR_VERIFICATION ((vuint8) 0x26u) + +# define FBL_ERR_FLASHCODE_INIT_FAILED ((vuint8) 0x30u) +# define FBL_ERR_FLASHCODE_EXCEEDS_MEMORY ((vuint8) 0x31u) +# define FBL_ERR_FLASHCODE_NOT_ACCEPTED ((vuint8) 0x32u) + +# define FBL_ERR_LBT_MISSING_INVALID_FORMAT ((vuint8) 0x40u) +# define FBL_ERR_LBT_ADDR_MISMATCH ((vuint8) 0x41u) +# define FBL_ERR_LBT_BLOCK_INDEX_EXCEEDED ((vuint8) 0x42u) +# define FBL_ERR_LBT_NOT_REPROGRAMMABLE ((vuint8) 0x43u) +# define FBL_ERR_LBT_BLOCK_INDEX_ILLEGAL ((vuint8) 0x44u) + +# define FBL_ERR_DATA_OVERFLOW ((vuint8) 0x50u) + +/* Macros for error status reporting */ +# define FblErrStatSetSId(id) (errStatLastServiceId = (id)) +# define FblErrStatSetState(state) (errStatFblStates = (state)) +# define FblErrStatSetFlashDrvError(error) (errStatFlashDrvErrorCode = (error)) +# define FblErrStatSetFlashDrvVersion() {\ + errStatFlashDrvVersion[0] = flashCode[0];\ + errStatFlashDrvVersion[1] = flashCode[1];\ + errStatFlashDrvVersion[2] = flashCode[3];\ + } +# define FblErrStatSetError(error) (errStatErrorCode = (error)) +# define FblErrStatSetBlockNr(blockNumber) (errStatDescriptor.blockNr = (blockNumber)) +# define FblErrStatSetAddress(address) (errStatDescriptor.blockStartAddress = (address)) +#else +# define FblErrStatSetSId(id) +# define FblErrStatSetState(state) +# define FblErrStatSetFlashDrvError(error) +# define FblErrStatSetFlashDrvVersion() +# define FblErrStatSetError(error) +# define FblErrStatSetBlockNr(blockNr) +# define FblErrStatSetAddress(address) +#endif + +#define DIAG_CALL_CYCLE kDiagCallCycle + +#if !defined( TESTER_PRESENT_TIMEOUT ) +#define TESTER_PRESENT_TIMEOUT ((vuint32) 5000u) +#endif + +#if !defined( TESTER_PRESENT_TIMEOUT_LONG ) +#define TESTER_PRESENT_TIMEOUT_LONG ((vuint32) 30000u) +#endif + +#define TimeoutTesterValue() testerPresentTimeout +#define DecTimeoutTesterValue() (testerPresentTimeout--) +#define ResetTesterTimeout() (testerPresentTimeout = (vuint16)(TESTER_PRESENT_TIMEOUT/DIAG_CALL_CYCLE)) +#define InitTesterTimeoutLong() (testerPresentTimeout = (vuint16)(TESTER_PRESENT_TIMEOUT_LONG/DIAG_CALL_CYCLE)) +#define StopTesterTimeout() (testerPresentTimeout = 0) + +/* Parameter to the function FblDiagEcuReset() */ +#define kDiagResetNoResponse ((vuint8) 0x00u) +#define kDiagResetPutResponse ((vuint8) 0x01u) +#define kDiagResetStayInBoot ((vuint8) 0x02u) + +/* Macros for access of reset options */ +#define GetResetOptionPutResponse(var) (((var) & kDiagResetPutResponse) == kDiagResetPutResponse) +#define GetResetOptionStayInBoot(var) (((var) & kDiagResetStayInBoot) == kDiagResetStayInBoot) + +/* Parameters for busy response handling function */ +#define kNotForceSendResponsePending ((vuint8) 0x00u) +#define kForceSendResponsePending ((vuint8) 0x01u) + +#define DiagProcessingDone(len) DiagResponseProcessor(len) +#define DiagSetNoResponse() (diagResponseFlag = 0) + +/* Error state function, removed if not defined */ +#if !defined( FblErrStatSetAddress ) +# define FblErrStatSetAddress(address) +#endif +#if !defined( FblErrStatSetError ) +# define FblErrStatSetError(errNo) +#endif +#if !defined( FblErrStatSetSId ) +# define FblErrStatSetSId(SId) +#endif + +/* Security levels */ +#define kDiagSecLevelNone ((vuint8) 0x00u) +#define kDiagSecLevelFlash ((vuint8) 0x01u) + +/* Macros for security access */ +#define kDiagNrOfSecurityLevels (0x01u) + +#if !defined( kDiagSubSecTypeMask ) +# define kDiagSubSecTypeMask ((vuint8) 0x7Fu) +#endif + +#if !defined( kDiagSubRequestSeed ) +# define kDiagSubRequestSeed ((vuint8) 0x01u) +#endif + +#if !defined( kDiagSubSendKey ) +# define kDiagSubSendKey ((vuint8) 0x02u) +#endif + +/* Map length defines used by fbl_diag to SecModHis */ +#if !defined( kSecSeedLength ) +# define kSecSeedLength (SEC_SEED_LENGTH) +#endif + +#if !defined( kSecKeyLength ) +# define kSecKeyLength (SEC_KEY_LENGTH) +#endif + +#if !defined( kSecSecretKeyLength ) +# define kSecSecretKeyLength (SEC_SECRET_KEY_LENGTH) +#endif + +#if !defined( kSecCrcLength ) +# define kSecCrcLength (SEC_SIZE_CHECKSUM_CRC) +#endif + +/* Access macros for user diagnostic call-backs */ +#define DiagPutResponseSId(a) (DiagBuffer[0] = (a)) +#define DiagGetRequestSId() (DiagBuffer[0]) + +/* Read memory function for flash driver validation */ +#define FblReadRam FblReadBlock + +/* Internal segment size as used by the diagnostic layer */ +#if !defined( FBL_DIAG_SEGMENT_SIZE ) +# define FBL_DIAG_SEGMENT_SIZE (FBL_MAX_SEGMENT_SIZE) +#endif + +/* Special values for indices into logical block table */ +#define kBlockNrInvalid 0xFFu + +/* Access macros for combined memory identifier/address type */ +#define FblDiagGetMemId(var) +#define FblDiagGetMemAddr(var) ((var)) + +#define FblDiagSetMemId(var, value) +#define FblDiagSetMemAddr(var, value) ((var) = (value)) + +#define FblDiagAddMemAddr(var, value) ((var) += (value)) + +#if defined( FBL_ENABLE_DATA_PROCESSING ) +/* Extract encryption/compression mode from the data format identifier */ +#define FblDiagGetEncryptionMode(dfi) ((vuint8)((dfi) & kDiagFmtEncryptionMask)) +#define FblDiagGetCompressionMode(dfi) ((vuint8)(((dfi) & kDiagFmtCompressionMask) >> 4)) +#endif /* FBL_ENABLE_DATA_PROCESSING */ + +#if defined( FBL_ENABLE_SLEEPMODE ) +/* Sleep mode handling */ +# define kFblSleepDelayTime ((vuint32)(FBL_SLEEP_TIME / FBL_REPEAT_CALL_CYCLE)) +# define FblSleepCounterClear() (sleepCounter = 0x00u) +# define FblSleepCounterReload() (sleepCounter = kFblSleepDelayTime) +# define FblDecSleepCounter() (sleepCounter--) +# define FblGetSleepCounter() ((vuint32) sleepCounter) +#endif +/* PRQA L:TAG_FblDiag_3453_2 */ + +/* Minimum length of address parameter to Check Programming Dependencies */ +#define kDiagCheckProgDepAdressMinLength 0x80u + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +/* Security access levels */ +typedef struct tagSecurityLevel +{ + vuint8 accessType; + vuint8 stateIdxKey; + vuint8 stateIdxAccess; +} tSecurityLevel; + +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) +typedef struct tagDiagSecAccessParams +{ + vuint8 secLevel; /** Security Level = sub function parameter of seed request */ + vuint16 seedLength; /** Size of seed parameter */ + vuint16 keyLength; /** Size of key parameter */ +} tDiagSecAccessParams; +#endif /* FBL_ENABLE_SEC_ADDITIONAL_LEVELS */ + +/* Combined data type for memory identifier and address */ +typedef tFblAddress tFblDiagAddr; + +/* Logical block state definition */ +typedef enum +{ + kBlockState_Init, + kBlockState_Erased, + kBlockState_Verified +} tBlockState; + +/* Header with runtime information about logical block */ +typedef struct +{ + tBlockState state; + vuint8 nrOfSegments; + vuint8 segmentIdx[SWM_DATA_MAX_NOAR]; +} tBlockHeader; + +/** Structure for address and length information of segments */ +typedef struct +{ + tFblAddress targetAddress; + tFblLength length; + vuint8 checksum[SEC_VERIFY_CLASS_DDD_VERIFY_SIZE]; +} tDiagSegmentInfo; + +/** Segment data structure */ +typedef struct +{ + vuint8 nrOfSegments; + tDiagSegmentInfo segmentInfo[SWM_DATA_MAX_NOAR]; +} tDiagSegmentList; + + + +#if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# if defined( FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING ) +/* Return values for token handling */ +typedef enum +{ + kTokenHdlrOk = 0, + kTokenHdlrProtocolFailed = 1, + kTokenHdlrSyncPKeyValFailed = 2, + kTokenHdlrFesnFailed = 3, + kTokenHdlrTimeTokenFailed = 4, +# if defined (FBL_DIAG_SINGLE_KEY) + kTokenHdlrKeyChangeFailed = 5, +# endif + kTokenHdlrSignatureFailed = 6, + kTokenHdlrTokenApplPassed = 7, + kTokenHdlrTokenSignFailed = 8, + kTokenHdlrInternalFailed = 9 +} tTokenHdlResult; + +typedef enum +{ + FBL_DIAG_SRVMSGID_NOTSTORED = 0, + FBL_DIAG_SRVMSGID_STORED = 1 +} tFblDiagSrvMsgIdStoreStatus; + +# endif /* FBL_ENABLE_TOKEN_DOWNLOAD_HANDLING */ +#endif /* SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC */ + +/*********************************************************************************************************************** + * PROTOTYPES + **********************************************************************************************************************/ + +#define FBLDIAG_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +void FblDiagTimerTask( void ); +void FblDiagStateTask( void ); +vuint8 FblRealTimeSupport( void ); +void FblRealTimeSupportVoid( void ); + +void FblDiagPostInit( void ); +void FblDiagEcuReset(vuint8 resetOptions, vuint8 responseFlag); +void FblDiagInitPowerOn( void ); +void FblDiagInit( void ); +vuint8 FblDiagGetLastErasedBlock( void ); +void FblDiagSetLastErasedBlock( vuint8 blockNr ); + +void DiagResponseProcessor( tCwDataLengthType dataLength ); + +#define FBLDIAG_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLDIAG_RAMCODE_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +void DiagExRCRResponsePending( vuint8 forceSend ); + +void FblDiagTxErrorIndication( vuint8 cwMsgType ); +void FblDiagRxIndication( V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * pbDiagBuffer, tCwDataLengthType rxDataLength ); +void FblDiagTxConfirmation( vuint8 cwMsgType ); +vuint8* FblDiagRxGetPhysBuffer( tCwDataLengthType rxDataLength ); +vuint8* FblDiagRxGetFuncBuffer( tCwDataLengthType rxDataLength ); +void FblDiagRxStartIndication( void ); +void FblDiagRxErrorIndication( void ); +#define FBLDIAG_RAMCODE_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLDIAG_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +vuint8 FblDiagCheckStartMsg(const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 *pData, vuintx length); +vuint8 FblDiagGetSegmentList(vuint8 blockIdx, V_MEMRAM1 tDiagSegmentList V_MEMRAM2 V_MEMRAM3 * blockSegList); + +/* Response suppression (exported for user service/routine functions) */ +void CheckSuppressPosRspMsgIndication( V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 *subparam ); + +tFblResult FblDiagMemPreWrite( void ); +tFblResult FblDiagMemPostWrite( void ); + + +#define FBLDIAG_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBLDIAG_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* -- 14229 based -- */ +V_MEMRAM0 extern V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * V_MEMRAM1 V_MEMRAM2 DiagBuffer; +V_MEMRAM0 extern V_MEMRAM1 vuint8 V_MEMRAM2 diagErrorCode; +V_MEMRAM0 extern V_MEMRAM1 tCwDataLengthType V_MEMRAM2 DiagDataLength; +V_MEMRAM0 extern V_MEMRAM1_NEAR vuint16 V_MEMRAM2_NEAR P2Timeout; +V_MEMRAM0 extern V_MEMRAM1_NEAR vuint16 V_MEMRAM2_NEAR testerPresentTimeout; +V_MEMRAM0 extern V_MEMRAM1 vuint8 V_MEMRAM2 diagResponseFlag; +V_MEMRAM0 extern V_MEMRAM1_NEAR vuint8 V_MEMRAM2_NEAR diagServiceCurrent; +V_MEMRAM0 extern V_MEMRAM1_NEAR tStateBitmap V_MEMRAM2_NEAR fblStates[STATE_INDEX(kDiagNumberOfStates - 1u) + 1u]; +V_MEMRAM0 extern V_MEMRAM1 vuint8 V_MEMRAM2 diagCurrentSecLvl; + +#define FBLDIAG_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBL_ENABLE_SEC_ADDITIONAL_LEVELS ) +#define FBLDIAG_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +V_MEMROM0 extern V_MEMROM1 tDiagSecAccessParams V_MEMROM2 kDiagSecAccessParams[]; + +#define FBLDIAG_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLDIAG_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +V_MEMRAM0 extern V_MEMRAM1 vuint8 V_MEMRAM2 diagRequestedSecLvlIdx; + +#define FBLDIAG_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif + +#define FBLDIAG_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + + +#if defined( FBL_ENABLE_DEBUG_STATUS ) +/* Variables for error status reporting */ +V_MEMRAM0 extern V_MEMRAM1 vuint16 V_MEMRAM2 errStatErrorCode; +V_MEMRAM0 extern V_MEMRAM1 vuint16 V_MEMRAM2 errStatFblStates; +V_MEMRAM0 extern V_MEMRAM1 vuint8 V_MEMRAM2 errStatLastServiceId; +V_MEMRAM0 extern V_MEMRAM1 vuint8 V_MEMRAM2 errStatFlashDrvVersion[3]; +V_MEMRAM0 extern V_MEMRAM1 vuint16 V_MEMRAM2 errStatFlashDrvErrorCode; +V_MEMRAM0 extern V_MEMRAM1 tBlockDescriptor V_MEMRAM2 errStatDescriptor; +#endif + +#if defined( FBL_ENABLE_SLEEPMODE ) +V_MEMRAM0 extern V_MEMRAM1 vuint32 V_MEMRAM2 sleepCounter; +#endif + +#define FBLDIAG_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * CONFIGURATION CHECKS + **********************************************************************************************************************/ + +#if ( kFblOk != 0x00 ) +# error "Error in fbl_def.h: use kFblOk as 0x00" +#endif + +#if !( defined( FBL_ENABLE_SYSTEM_CHECK ) || defined( FBL_DISABLE_SYSTEM_CHECK ) ) +# error "Error in fbl_cfg.h: Usage of system check not defined" +#endif + +#if !( defined( FBL_ENABLE_APPL_TASK ) || defined( FBL_DISABLE_APPL_TASK ) ) +# error "Error in fbl_cfg.h: Usage of application task function not defined" +#endif + +#if !( defined( FBL_ENABLE_USERSUBFUNCTION ) || defined( FBL_DISABLE_USERSUBFUNCTION ) ) +# error "Error in fbl_cfg.h: Usage of diag user-subfunction call not defined" +#endif + +#if !( defined( FBL_ENABLE_ENCRYPTION_MODE ) || defined( FBL_DISABLE_ENCRYPTION_MODE ) ) +# error "Error in fbl_cfg.h: Usage of decryption interface not defined" +#endif + +#if !( defined( FBL_WATCHDOG_ON ) || defined( FBL_WATCHDOG_OFF ) ) +# error "Error in fbl_cfg.h: Usage of watchdog support not defined" +#endif + +#if defined( FBL_WATCHDOG_ON ) && !defined( FBL_WATCHDOG_TIME ) +# error "Error in fbl_cfg.h: Watchdog trigger period not defined" +#endif + +#if !( defined( FBL_ENABLE_FBL_START ) || defined( FBL_DISABLE_FBL_START ) ) +# error "Error in fbl_cfg.h: Usage of FblStart function not defined" +#endif + +#if !defined( SWM_DATA_MAX_NOAR ) +# error "Error in fbl_cfg.h: Number of supported download segments (SWM_DATA_MAX_NOAR) not defined" +#endif + +#if !defined( FBL_HEADER_ADDRESS ) +# error "Error in fbl_cfg.h: Start address of bootblock header not defined" +#endif + +#if !defined( FBL_DIAG_BUFFER_LENGTH ) +# error "Error in fbl_cfg.h: FBL_DIAG_BUFFER_LENGTH not defined" +#endif + +#if ( FBL_DIAG_BUFFER_LENGTH < (FBL_DIAG_SEGMENT_SIZE+0x01u) ) +# error "Error in fbl_cfg.h: DiagBuffer size too small - modify FBL_DIAG_BUFFER_LENGTH" +#endif + +# if ( FBL_DIAG_BUFFER_LENGTH > 4095u ) +# error "Error in fbl_cfg.h: DiagBuffer size larger than supported by TP" +# endif +# if ( FBL_DIAG_BUFFER_LENGTH != kFblTpBufferSize ) +# error "Error in fbl_cfg.h: Inconsistent configuration of diag buffer size (see ftp_cfg.h)" +# endif + +#if !defined( FBL_DIAG_TIME_P3MAX ) +# error "Error in fbl_cfg.h: P2Star time not defined" +#endif + +#if !defined( FLASH_SIZE ) +# error "Error in fbl_cfg.h: Size of flash code buffer not defined" +#endif + +#if !defined( FBL_MAX_SEGMENT_SIZE ) +# error "Error in fbl_mio.h: Maximum device segment size not defined" +#endif + +#if defined( FBL_ENABLE_DATA_PROCESSING ) ||\ + defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) +# if defined( FBL_ENABLE_COMPRESSION_MODE ) && !defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) +/* Ford specific: tester/download tool transmits always the compressed data length */ +# error "Error in fbl_cfg.h: Support for compressed data length not activated" +# endif +#endif +#if defined( FBL_ENABLE_COMPRESSION_MODE ) && !defined( FBL_ENABLE_DATA_PROCESSING ) +# error "Error in fbl_cfg.h: Compression/Encryption Mode requires the data processing interface" +#endif + + +#if defined( FBL_ENABLE_PRESENCE_PATTERN ) && !defined( FBL_ENABLE_USE_LOGICAL_BLOCKS ) +# error "Error in fbl_cfg.h: Presence pattern implementation requires the usage of logical blocks" +#endif + +#if !defined( FBL_ENABLE_SEED_KEY_MODULE ) && ( FBL_PROJECT_STATE != FBL_INTEGRATION ) +# error "Error in fbl_cfg.h: Usage of seed/key module is mandatory for production ECUs" +#endif + +#if ((FBL_MAX_DID_COUNT < 1) || (FBL_MAX_DID_COUNT > 255)) +# error "Error in fbl_cfg.h: Unsupported value for maximum amount of read DIDs" +#endif + + +#if (SEC_SECURITY_CLASS != SEC_CLASS_CCC) && (SEC_SECURITY_CLASS != SEC_CLASS_DDD) +# error "Error in SecM_cfg.h: Unsupported security class selected" +#endif + +#if !defined( FBL_MTAB_SBL_BLOCK_NUMBER ) +# error "Error in fbl_mtab.h: Logical block for SBL not defined or wrong name (required: SBL)" +#endif + +/* Warn if legacy configuration switches are used */ +#if defined( FBL_ENABLE_DIAG_SESSION_PARAMETERS ) || \ + defined( FBL_ENABLE_FIXED_TRANSFER_ALFI ) || \ + defined( FBL_ENABLE_UPLOAD ) || \ + defined( FBL_ENABLE_WRITE_DATA_BY_IDENTIFIER ) +# error "Error in fbl_cfg.h: Legacy configuration switches detected. Please update GenTool/PreConfig!" +#endif + +#endif /* FBL_DIAG_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_DIAG.H + **********************************************************************************************************************/ + diff --git a/Source/bsw/Fbl/fbl_diag.imp b/Source/bsw/Fbl/fbl_diag.imp new file mode 100644 index 0000000..ef8e88f --- /dev/null +++ b/Source/bsw/Fbl/fbl_diag.imp @@ -0,0 +1,355 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Diagnostic services supported in boot mode + * Data structure creation for state machine + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2026 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2022-08-15 vistmo FBL-5514 Support Additional OTA functionality + * ESCAN00112435 No changes + * ESCAN00112575 No changes + * 05.01.00 2022-10-04 jschmitding FBL-5917 No changes + * ESCAN00113919 No changes + * 05.01.01 2022-10-17 fmenke ESCAN00112879 No changes + * 05.01.02 2023-01-13 fmenke ESCAN00112890 No changes + * ESCAN00113612 No changes + * 05.02.00 2023-02-09 vistmo ESCAN00112972 No changes + * ESCAN00113292 No changes + * ESCAN00113835 No changes + * ESCAN00113843 No changes + * ESCAN00113764 No changes + * FBL-6438 No changes + * 05.02.01 2023-05-11 fmenke ESCAN00113831 No changes + * 05.03.00 2023-07-24 fmenke FBL-7335 No changes + * 05.03.01 2023-08-31 lhopfhauer ESCAN00115494 No changes + * 05.03.02 2024-07-16 erizk ESCAN00117344 No changes + * 05.03.03 2025-02-06 virchl ESCAN00118587 No changes + * 05.04.00 2025-02-28 jjohnson FBL-10065 No changes + * 05.04.01 2025-06-10 jostravsky ESCAN00120315 No changes + * 05.04.02 2025-07-08 visarcmijo ESCAN00119833 No changes + * 05.05.00 2025-09-01 fmenke FBL-11218 No changes + * ESCAN00120917 No changes + * 05.06.00 2025-10-28 mpatil FBL-11690 No changes + * 05.07.00 2026-01-13 dganesh FBL-12162 No changes + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLDIAG_14229_FORD_VERSION != 0x0507u ) || \ + ( FBLDIAG_14229_FORD_RELEASE_VERSION != 0x00u ) +# error "Error in fbl_diag.imp: State machine implementation and source are inconsistent!" +#endif + +/* PRQA S 0342 EOF */ /* MD_MSR_Rule20.10_0342 */ +/* PRQA S 0883 EOF */ /* MD_FblDiag_0883 */ + +/* --------------------------------------------------------------------------- */ +/* Implementation type: Output */ +/* --------------------------------------------------------------------------- */ +/* Output according to FBL_DIAG_STATE_DEF and FBL_DIAG_IMPL_OUTPUT */ +/* , e.g. FBL_DIAG_STATE_DEF = kDiagService ## name, */ +/* FBL_DIAG_IMPL_OUTPUT = FBL_DIAG_STATE_RESULT, */ +/* --------------------------------------------------------------------------- */ +#if ( FBL_DIAG_IMPL_TYPE == FBL_DIAG_IMPL_TYPE_OUTPUT ) +FBL_DIAG_IMPL_OUTPUT +#endif + +/* --------------------------------------------------------------------------- */ +/* Implementation type: State bitmap */ +/* --------------------------------------------------------------------------- */ +/* Generate state bitmap entries */ +/* --------------------------------------------------------------------------- */ +#if ( FBL_DIAG_IMPL_TYPE == FBL_DIAG_IMPL_TYPE_STATEBITMAP ) +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) set +# if (FBL_DIAG_STATE_RESULT != kDiagStateNone) + STATE_BUILDARRAYENTRIES(FBL_DIAG_STATE_RESULT), +# endif +# undef FBL_DIAG_STATE_DEF + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) unset +# if (FBL_DIAG_STATE_RESULT != kDiagStateNone) + STATE_BUILDARRAYENTRIES(FBL_DIAG_STATE_RESULT), +# endif +# undef FBL_DIAG_STATE_DEF + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) add +# if (FBL_DIAG_STATE_RESULT != kDiagStateNone) + STATE_BUILDARRAYENTRIES(FBL_DIAG_STATE_RESULT), +# endif +# undef FBL_DIAG_STATE_DEF + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) clear +# if (FBL_DIAG_STATE_RESULT != kDiagStateNone) + STATE_BUILDARRAYENTRIES(FBL_DIAG_STATE_RESULT), +# endif +# undef FBL_DIAG_STATE_DEF + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) clearFail +# if (FBL_DIAG_STATE_RESULT != kDiagStateNone) + STATE_BUILDARRAYENTRIES(FBL_DIAG_STATE_RESULT), +# endif +# undef FBL_DIAG_STATE_DEF +#endif + +/* --------------------------------------------------------------------------- */ +/* Implementation type: Service property */ +/* --------------------------------------------------------------------------- */ +/* Generate the service properties, including service IDs, references to child */ +/* node lists and handler functions */ +/* --------------------------------------------------------------------------- */ +#if ( FBL_DIAG_IMPL_TYPE == FBL_DIAG_IMPL_TYPE_SERVICEPROPERTY ) +# if defined( None ) +# undef None +# endif +# define None 0xFFFFFFFFu + +# if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) set +# if (FBL_DIAG_STATE_RESULT != kDiagStateNone) +# define USAGE_MASK_SET 0x01u +# else +# define USAGE_MASK_SET 0x00u +# endif +# undef FBL_DIAG_STATE_DEF + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) unset +# if (FBL_DIAG_STATE_RESULT != kDiagStateNone) +# define USAGE_MASK_UNSET 0x02u +# else +# define USAGE_MASK_UNSET 0x00u +# endif +# undef FBL_DIAG_STATE_DEF + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) add +# if (FBL_DIAG_STATE_RESULT != kDiagStateNone) +# define USAGE_MASK_ADD 0x04u +# else +# define USAGE_MASK_ADD 0x00u +# endif +# undef FBL_DIAG_STATE_DEF + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) clear +# if (FBL_DIAG_STATE_RESULT != kDiagStateNone) +# define USAGE_MASK_CLEAR 0x08u +# else +# define USAGE_MASK_CLEAR 0x00u +# endif +# undef FBL_DIAG_STATE_DEF + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) clearFail +# if (FBL_DIAG_STATE_RESULT != kDiagStateNone) +# define USAGE_MASK_CLEARFAIL 0x10u +# else +# define USAGE_MASK_CLEARFAIL 0x00u +# endif +# undef FBL_DIAG_STATE_DEF +# endif + + { + +# if defined( FBL_DIAG_SERVICE_LIST_HANDLES ) +# else +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) firstChild +# if (FBL_DIAG_STATE_RESULT != None) +# undef FBL_DIAG_STATE_DEF +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) &kDiagSubFctTbl_ ## name + + FBL_DIAG_STATE_RESULT, +# else + kDiagNoSubServices, +# endif +# undef FBL_DIAG_STATE_DEF +# endif + +# if defined( FBL_DIAG_STATE_ARRAYS ) +# if !defined( STATE_PREFIX ) +# define STATE_PREFIX { +# endif +# if !defined( STATE_POSTFIX ) +# define STATE_POSTFIX } +# endif +# else +# if !defined( STATE_PREFIX ) +# define STATE_PREFIX +# endif +# if !defined( STATE_POSTFIX ) +# define STATE_POSTFIX +# endif +# endif + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) checks +# if defined( FBL_DIAG_CHECK_LIST_HANDLES ) +# define FBL_DIAG_STATE_DEF_CHECKIDX(checks) ,checks +# define FBL_DIAG_STATE_DEF_CHECKS(checks) +# else +# if (FBL_DIAG_STATE_RESULT != None) +# define FBL_DIAG_STATE_DEF_CHECKIDX(checks) +# define FBL_DIAG_STATE_DEF_CHECKS(checks) ,&checks +# else +# define FBL_DIAG_STATE_DEF_CHECKIDX(checks) +# define FBL_DIAG_STATE_DEF_CHECKS(checks) ,kDiagNoCheckList +# endif +# endif +# undef FBL_DIAG_STATE_DEF + +# if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) \ + kDiagSrvId_ ## name \ + FBL_DIAG_STATE_DEF_CHECKS( kDiag ## checks ## Table ) \ + ,rqlMin \ + ,rqlMax \ + ,(USAGE_MASK_SET | USAGE_MASK_UNSET | USAGE_MASK_ADD | USAGE_MASK_CLEAR | USAGE_MASK_CLEARFAIL) \ + ,kServiceMainHandler ## handler \ + FBL_DIAG_STATE_DEF_CHECKIDX( kServiceCheckList ## checks ) +# else +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) \ + kDiagSrvId_ ## name \ + FBL_DIAG_STATE_DEF_CHECKS( kDiag ## checks ## Table ) \ + ,rqlMin \ + ,rqlMax \ + ,STATE_PREFIX \ + STATE_BUILDARRAY(set) \ + ,STATE_BUILDARRAY(unset) \ + ,STATE_BUILDARRAY(add) \ + ,STATE_BUILDARRAY(clear) \ + ,STATE_BUILDARRAY(clearFail) \ + STATE_POSTFIX \ + ,kServiceMainHandler ## handler \ + FBL_DIAG_STATE_DEF_CHECKIDX( kServiceCheckList ## checks ) +# endif + +FBL_DIAG_STATE_RESULT + +# undef FBL_DIAG_STATE_DEF_CHECKIDX +# undef FBL_DIAG_STATE_DEF_CHECKS +# undef FBL_DIAG_STATE_DEF + +# if defined( FBL_DIAG_SERVICE_LIST_HANDLES ) +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) firstChild +# if (FBL_DIAG_STATE_RESULT != None) +# undef FBL_DIAG_STATE_DEF +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) kDiagServiceListHandler_ ## name + + ,FBL_DIAG_STATE_RESULT +# else + ,kDiagServiceListHandler_None +# endif +# undef FBL_DIAG_STATE_DEF +# endif + }, + +# if defined( FBL_DIAG_ENABLE_RAM_STATETABLES ) +# undef USAGE_MASK_SET +# undef USAGE_MASK_UNSET +# undef USAGE_MASK_ADD +# undef USAGE_MASK_CLEAR +# undef USAGE_MASK_CLEARFAIL +# endif +# undef None +#endif + +/* --------------------------------------------------------------------------- */ +/* Implementation type: Service list */ +/* --------------------------------------------------------------------------- */ +/* Generate list of all services, referencing the service properties */ +/* --------------------------------------------------------------------------- */ +#if ( FBL_DIAG_IMPL_TYPE == FBL_DIAG_IMPL_TYPE_SERVICELIST ) +# if defined( None ) +# undef None +# endif +# define None 0xFFFFFFFFu + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) firstChild +# if (FBL_DIAG_STATE_RESULT != None) +# undef FBL_DIAG_STATE_DEF +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) \ + V_MEMROM0 static V_MEMROM1 tServiceList V_MEMROM2 kDiagSubFctTbl_ ## name = \ + { \ + &kDiagServiceProperties[kDiagService ## firstChild] \ + ,(bufPos) \ + ,(sizeof(kDiagSrvId_ ## firstChild)/sizeof(kDiagSrvId_ ## firstChild [0])) \ + ,((kDiagService ## lastChild - kDiagService ## firstChild) + 1) \ + } + +FBL_DIAG_STATE_RESULT; +# endif + +# undef None +# undef FBL_DIAG_STATE_DEF +#endif + +/* --------------------------------------------------------------------------- */ +/* Implementation type: Service list handler */ +/* --------------------------------------------------------------------------- */ +/* Generate list of child node references */ +/* --------------------------------------------------------------------------- */ +#if ( FBL_DIAG_IMPL_TYPE == FBL_DIAG_IMPL_TYPE_SERVICELIST_HANDLER ) +# if defined( None ) +# undef None +# endif +# define None 0xFFFFFFFFu + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) firstChild +# if (FBL_DIAG_STATE_RESULT != None) +# undef FBL_DIAG_STATE_DEF +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) &kDiagSubFctTbl_ ## name + +FBL_DIAG_STATE_RESULT, +# endif + +# undef None +# undef FBL_DIAG_STATE_DEF +#endif + +/* --------------------------------------------------------------------------- */ +/* Implementation type: Service list enumeration */ +/* --------------------------------------------------------------------------- */ +/* Generate list of handles to access service list handlers */ +/* --------------------------------------------------------------------------- */ +#if ( FBL_DIAG_IMPL_TYPE == FBL_DIAG_IMPL_TYPE_SERVICELIST_ENUM ) +# if defined( None ) +# undef None +# endif +# define None 0xFFFFFFFFu + +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) firstChild +# if (FBL_DIAG_STATE_RESULT != None) +# undef FBL_DIAG_STATE_DEF +# define FBL_DIAG_STATE_DEF(name, parent, firstChild, lastChild, bufPos, id, handler, checks, set, unset, add, clear, clearFail, rqlMin, rqlMax) kDiagServiceListHandler_ ## name + +FBL_DIAG_STATE_RESULT, +# endif + +# undef None +# undef FBL_DIAG_STATE_DEF +#endif + +/* --------------------------------------------------------------------------- */ +/* Reset result define */ +/* --------------------------------------------------------------------------- */ +#undef FBL_DIAG_STATE_RESULT + +/*********************************************************************************************************************** + * END OF FILE: FBL_DIAG.IMP + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_flio.c b/Source/bsw/Fbl/fbl_flio.c new file mode 100644 index 0000000..e0126f6 --- /dev/null +++ b/Source/bsw/Fbl/fbl_flio.c @@ -0,0 +1,362 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Flash Driver wrapper functions using an Autosar Fls driver + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2022 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2018-08-15 vistbe - Initial version + * 01.01.00 2020-08-12 visrie FBL-1953 Add support for downloadable driver + * 01.02.00 2022-01-21 visjdn FBL-4535 Support secondary/tertiary use-case + * Added/adapted MemMap sections + **********************************************************************************************************************/ + +#define FBL_FLIO_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" +#include "fbl_flio.h" +#include "fbl_flio_cfg.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if (FBLWRAPPERFLASH_ASRFLSHIS_VERSION != 0x0102u) || \ + (FBLWRAPPERFLASH_ASRFLSHIS_RELEASE_VERSION != 0x00u) +# error "Error in fbl_flio.c: Source and header file are inconsistent!" +#endif + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +/** Flash driver state handling */ +typedef enum +{ + kFlashInitState_Uninit = 0u, /**< Flash driver has not be initialized yet */ + kFlashInitState_ReadDriver, /**< Read-only flash driver is active/initialized */ + kFlashInitState_FullDriver /**< Full flash driver (read, write and erase) is active/initialized */ +} tFlashInitState; + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBLFLIO_FLASHCODE_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +V_MEMRAM0 V_MEMRAM1 vuint8 V_MEMRAM2 flashCode[FLASH_SIZE]; +#define FBLFLIO_FLASHCODE_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +#define FBLFLIO_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/** Current initialization state of the flash driver */ +V_MEMRAM0 static V_MEMRAM1 tFlashInitState V_MEMRAM2 initState; +#define FBLFLIO_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLFLIO_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +static IO_ErrorType FlashDriver_PollFls( void ); + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FlashDriver_PollFls + **********************************************************************************************************************/ +/*! \brief Executes operation and polls the status + * \details Calls the Fls main function and polls the status of the flash operation + * \pre Flash driver/Fls is initialized, operation has been started + * \return IO_E_OK in case of success, otherwise IO_E_NOT_OK + **********************************************************************************************************************/ +static IO_ErrorType FlashDriver_PollFls( void ) +{ + IO_ErrorType returnValue; + tFlashUint32 i; + + returnValue = IO_E_NOT_OK; + i = 0u; + + while (FBL_FLASHFLS_GETSTATUS() == MEMIF_BUSY) + { + /* Poll the watchdog frequently */ /* PRQA S 2991, 2995 1 */ /* MD_FblWrapperFlash_2991_2995 */ + if ((i & (FBL_FLASHFLS_WD_POLLING_INTERVAL - 1u)) == 0x00u) + { + FblLookForWatchdogVoid(); + } + i++; + FBL_FLASHFLS_MAINFUNCTION(); + } + + if (FBL_FLASHFLS_GETJOBRESULT() == MEMIF_JOB_OK) + { + returnValue = IO_E_OK; + } + + return returnValue; +} + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FlashDriver_InitPowerOnSync + **********************************************************************************************************************/ +/*! \brief Initialize modules variables and read-only driver + * \return The return code shows the success of the initialization + **********************************************************************************************************************/ +IO_ErrorType FlashDriver_InitPowerOnSync(void) +{ + IO_ErrorType returnValue; + + initState = kFlashInitState_Uninit; + returnValue = IO_E_NOT_OK; + + FBL_FLASHFLS_INITMEMORY(); + FBL_FLASHFLS_INIT(); + + if (FBL_FLASHFLS_GETJOBRESULT() == MEMIF_JOB_OK) + { + initState = kFlashInitState_ReadDriver; + returnValue = IO_E_OK; + } + + return returnValue; +} + +/*********************************************************************************************************************** + * FlashDriver_InitSync + **********************************************************************************************************************/ +/*! \brief Initializes the flash driver + * \details Initializes the Fls module + * \pre None + * \param[in] *address Unused parameter to implement HIS interface + * \return IO_E_OK in case of success, otherwise IO_E_NOT_OK + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +IO_ErrorType FlashDriver_InitSync( void* address ) +{ + IO_ErrorType returnValue; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)address; +#endif + + /* Verify if flashcode signature is correct */ /* PRQA S 0488 3 */ /* MD_FblWrapperFlash_0488 */ + if ( (FLASH_DRIVER_MCUTYPE(flashCode) != FLASH_DRIVER_VERSION_MCUTYPE) + || (FLASH_DRIVER_MASKTYPE(flashCode) != FLASH_DRIVER_VERSION_MASKTYPE) + || (FLASH_DRIVER_INTERFACE(flashCode) != FLASH_DRIVER_VERSION_INTERFACE) + ) + { + /* Flash driver signature mismatch, wrong flash driver */ + returnValue = IO_E_NOT_OK; + } + else + { + initState = kFlashInitState_FullDriver; + returnValue = IO_E_OK; + } + + return returnValue; +} + +/*********************************************************************************************************************** + * FlashDriver_DeinitSync + **********************************************************************************************************************/ +/*! \brief Deinitializes the flash driver + * \details No functionality, just to satisfy interface + * \pre None + * \param[in] *address Unused parameter to implement HIS interface + * \return Always IO_E_OK + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +IO_ErrorType FlashDriver_DeinitSync( void* address ) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 1 */ /* MD_MSR_DummyStmt */ + (void)address; +#endif + + return IO_E_OK; +} + +/*********************************************************************************************************************** + * FlashDriver_RWriteSync + **********************************************************************************************************************/ +/*! \brief Writes data to flash memory + * \details This function programs flash memory by calling the Fls write routine + * \pre Flash driver/Fls is initialized, memory to be programmed is erased + * \param[in] writeBuffer Pointer to input data buffer. + * \param[in] writeLength Data length + * \param[in] writeAddress Write target address + * \return IO_E_OK in case of success, otherwise IO_E_NOT_OK + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +IO_ErrorType FlashDriver_RWriteSync( IO_MemPtrType writeBuffer, IO_SizeType writeLength, IO_PositionType writeAddress ) +{ + IO_ErrorType returnValue; + + /* Verify if flashcode signature is correct */ /* PRQA S 0488 3 */ /* MD_FblWrapperFlash_0488 */ + if ( (FLASH_DRIVER_MCUTYPE(flashCode) != FLASH_DRIVER_VERSION_MCUTYPE) + || (FLASH_DRIVER_MASKTYPE(flashCode) != FLASH_DRIVER_VERSION_MASKTYPE) + || (FLASH_DRIVER_INTERFACE(flashCode) != FLASH_DRIVER_VERSION_INTERFACE) + ) + { + /* Flash driver signature mismatch, wrong flash driver */ + returnValue = IO_E_NOT_OK; + } + else + { + if (initState != kFlashInitState_FullDriver) + { + /* Driver was not initialized yet */ + returnValue = IO_E_NOT_OK; + } + else + { + if (FBL_FLASHFLS_WRITE(writeAddress, writeBuffer, writeLength) == E_OK) + { + returnValue = FlashDriver_PollFls(); + } + else + { + returnValue = IO_E_NOT_OK; + } + } + } + + return returnValue; +} + +/*********************************************************************************************************************** + * FlashDriver_REraseSync + **********************************************************************************************************************/ +/*! \brief Erases area in flash memory + * \details This function erases one or more logical sectors + * \pre Flash driver/Fls is initialized + * \param[in] eraseLength Length of memory to be erased. The length has to be aligned to the length + * of one or more flash sectors + * \param[in] eraseAddress Start address of erase area. The start address has to be the start + * address of a logical flash sector + * \return IO_E_OK in case of success, otherwise IO_E_NOT_OK + **********************************************************************************************************************/ +IO_ErrorType FlashDriver_REraseSync( IO_SizeType eraseLength, IO_PositionType eraseAddress ) +{ + IO_ErrorType returnValue; + + /* Verify if flashcode signature is correct */ /* PRQA S 0488 3 */ /* MD_FblWrapperFlash_0488 */ + if ( (FLASH_DRIVER_MCUTYPE(flashCode) != FLASH_DRIVER_VERSION_MCUTYPE) + || (FLASH_DRIVER_MASKTYPE(flashCode) != FLASH_DRIVER_VERSION_MASKTYPE) + || (FLASH_DRIVER_INTERFACE(flashCode) != FLASH_DRIVER_VERSION_INTERFACE) + ) + { + /* Flash driver signature mismatch, wrong flash driver */ + returnValue = IO_E_NOT_OK; + } + else + { + if (initState != kFlashInitState_FullDriver) + { + /* Driver was not initialized yet */ + returnValue = IO_E_NOT_OK; + } + else + { + if (FBL_FLASHFLS_ERASE(eraseAddress, eraseLength) == E_OK) + { + returnValue = FlashDriver_PollFls(); + } + else + { + /* Erase request failed */ + returnValue = IO_E_NOT_OK; + } + } + } + + return returnValue; +} + +/*********************************************************************************************************************** + * FlashDriver_RReadSync + **********************************************************************************************************************/ +/*! \brief Reads data from flash memory + * \details This function reads data from flash memory by calling the Fls Read function + * \pre Flash driver/Fls is initialized + * \param[out] readBuffer Pointer to read target buffer. The buffer size must be at least readLength Bytes + * \param[in] readLength Size of data to be read + * \param[in] readAddress Start address of data to be read + * \return IO_E_OK in case of success, otherwise IO_E_NOT_OK + **********************************************************************************************************************/ +IO_ErrorType FlashDriver_RReadSync( IO_MemPtrType readBuffer, IO_SizeType readLength, IO_PositionType readAddress ) +{ + IO_ErrorType returnValue; + + returnValue = IO_E_NOT_OK; + + if (initState != kFlashInitState_Uninit) + { + if (FBL_FLASHFLS_READ(readAddress, readBuffer, readLength) == E_OK) + { + returnValue = FlashDriver_PollFls(); + } + } + + return returnValue; +} + +#define FBLFLIO_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* module specific MISRA deviations: + + MD_FblWrapperFlash_0488 + Reason: Performing pointer arithmetic to get version information of flash driver from flash code buffer. + Risk: If "unsigned char" doesn't have a size of 1 Byte, the comparison will lead to wrong results. + Prevention: Check if "unsigned char" has a size of 1 Byte on used platform. + + MD_FblWrapperFlash_2991_2995: + Reason: The value of the if-controlling expression depends on the configuration. + Risk: No risk. + Prevention: No prevention necessary. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_FLIO.C + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_flio.h b/Source/bsw/Fbl/fbl_flio.h new file mode 100644 index 0000000..e64f8be --- /dev/null +++ b/Source/bsw/Fbl/fbl_flio.h @@ -0,0 +1,90 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Flash Driver wrapper functions using an Autosar FLS driver + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2022 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2018-08-15 vistbe - Initial version + * 01.01.00 2020-08-12 visrie FBL-1953 Add support for downloadable driver + * 01.02.00 2022-01-21 visjdn FBL-4535 Support secondary/tertiary use-case + * Added/adapted MemMap sections + **********************************************************************************************************************/ + +#ifndef FBLWRAPPERFLASH_ASRFLSHIS_H +#define FBLWRAPPERFLASH_ASRFLSHIS_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblWrapperFlash_AsrFlsHis CQComponent : Implementation */ +#define FBLWRAPPERFLASH_ASRFLSHIS_VERSION 0x0102u +#define FBLWRAPPERFLASH_ASRFLSHIS_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#if defined( FLASH_SIZE ) +#else +# define FLASH_SIZE 4u +#endif + +/** Determines I/O mode of driver (blocking/non-blocking) */ +#define IO_DRIVERMODUS SYNCRON +/** Type of the memory device */ +#define IO_DEVICETYPE RANDOM + +#define FlashDriver_GetVersionOfDriver() ((IO_U32)(FLASH_DRIVER_VERSION_MAJOR << 16u) |\ + (IO_U32)(FLASH_DRIVER_VERSION_MINOR << 8u) |\ + FLASH_DRIVER_VERSION_PATCH ) + +/*********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLFLIO_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +IO_ErrorType FlashDriver_InitPowerOnSync( void ); +IO_ErrorType FlashDriver_InitSync( void * address ); +IO_ErrorType FlashDriver_DeinitSync( void * address ); +IO_ErrorType FlashDriver_RWriteSync( IO_MemPtrType writeBuffer, IO_SizeType writeLength, IO_PositionType writeAddress ); +IO_ErrorType FlashDriver_REraseSync( IO_SizeType eraseLength, IO_PositionType eraseAddress ); +IO_ErrorType FlashDriver_RReadSync( IO_MemPtrType readBuffer, IO_SizeType readLength, IO_PositionType readAddress ); +#define FBLFLIO_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + **********************************************************************************************************************/ + +#define FBLFLIO_FLASHCODE_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +V_MEMRAM0 extern V_MEMRAM1 vuint8 V_MEMRAM2 flashCode[FLASH_SIZE]; +#define FBLFLIO_FLASHCODE_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* FBLWRAPPERFLASH_ASRFLSHIS_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_FLIO.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_fsm.c b/Source/bsw/Fbl/fbl_fsm.c new file mode 100644 index 0000000..4bd4fe7 --- /dev/null +++ b/Source/bsw/Fbl/fbl_fsm.c @@ -0,0 +1,419 @@ +/********************************************************************************************************************** + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Event-driven hierarchical finite state machine implementation + * + * ------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2023 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/*********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2012-10-30 visjhg - First implementation + * 01.00.01 2012-12-10 visjhg - No changes + * 01.01.00 2013-12-11 visjhg ESCAN00071901 Renamed package to FblLib_Fsm + * visase - Performed MISRA checks + * 01.01.01 2019-01-24 visrie ESCAN00101864 No changes + * 01.02.00 2023-12-15 vistbe FBL-7986 Perform MISRA analysis + * Added/adapted MemMap sections + *********************************************************************************************************************/ + +#define FBL_FSM_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +#include "fbl_fsm_inc.h" + +/********************************************************************************************************************** + * VERSION + *********************************************************************************************************************/ + +/* --- Version check --- */ +#if ( FBLLIB_FSM_VERSION != 0x0102u ) || \ + ( FBLLIB_FSM_RELEASE_VERSION != 0x00u ) +# error "Error in FBL_FSM.C: Source and header file are inconsistent!" +#endif + +#if ( FBLLIB_FSM_VERSION != _FBLLIB_FSM_VERSION ) || \ + ( FBLLIB_FSM_RELEASE_VERSION != _FBLLIB_FSM_RELEASE_VERSION ) +# error "Error in FBL_FSM.C: Source and v_ver.h are inconsistent!" +#endif + +/********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/** Type to select whether super-states should be iterated in case no matching event handler was found */ +typedef enum +{ + kFsmIterateHierarchy_Disabled, /**< Do not iterate super-states */ + kFsmIterateHierarchy_Enabled /**< Iterate super-states until matching event handler was found */ +} tFsmIterateHierarchy; + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ +#define FBLFSM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +static void FblFsmHandleEvent( tFblFsmContextPtr const pFsmContext, tFblFsmEvent event, tFsmIterateHierarchy iterate); +static vuint8 FblFsmGetStateHierachy( const V_MEMRAM1 tFblFsmContext V_MEMRAM2 V_MEMRAM3 * const pFsmContext, tFblFsmState state, + V_MEMRAM1 tFblFsmState V_MEMRAM2 V_MEMRAM3 * hierarchy ); +#define FBLFSM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +#if defined( FBL_FSM_ENABLE_DEBUGGING ) +#define FBLFSM_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/** Global state machine instance counter */ +static tFblFsmInstance g_Instance; +#define FBLFSM_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ +#define FBLFSM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/********************************************************************************************************************** + * FblFsmGetStateHierachy + *********************************************************************************************************************/ +/*! \brief Provides the state hierarchy starting with the given state + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] state The current state + * \param[out] hierarchy The returned state hierarchy + *********************************************************************************************************************/ +static vuint8 FblFsmGetStateHierachy( const V_MEMRAM1 tFblFsmContext V_MEMRAM2 V_MEMRAM3 * const pFsmContext, + tFblFsmState state, + V_MEMRAM1 tFblFsmState V_MEMRAM2 V_MEMRAM3 * hierarchy ) +{ + vuint8 index = 0u; + tFblFsmState localState = state; + + while (FBL_FSM_DEFAULT_STATE != localState) + { + /* Check for hierarchy depth and stateCount to prevent buffer overrun(s) */ + if ( (index >= FBL_FSM_MAX_HIERARCHY_DEPTH) + || (localState >= pFsmContext->stateCount)) + { + FBL_FSM_DEBUG_ERROR_PRINT(pFsmContext->instance); + + index = 0u; + localState = FBL_FSM_DEFAULT_STATE; + } + else + { + hierarchy[index] = localState; + index++; + + localState = pFsmContext->stateDefinitions[localState].superState; + } + } + + return index; +} + +/********************************************************************************************************************** + * FblFsmHandleEvent + *********************************************************************************************************************/ +/*! \brief Handles the given event + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event The event to be handled + * \param[out] iterate Indicates whether state hierarchy iteration is allowed + *********************************************************************************************************************/ +static void FblFsmHandleEvent( tFblFsmContextPtr const pFsmContext, tFblFsmEvent event, tFsmIterateHierarchy iterate ) +{ + vuint16 index; + vuint16 hierarchy = 0u; + tFblFsmState state = pFsmContext->state; + tFblFsmGuard guard; + V_MEMROM1 tFblFsmStateDefinition V_MEMROM2 V_MEMROM3 * stateDef; + V_MEMROM1 tFblFsmEventEntry V_MEMROM2 V_MEMROM3 * triggers; + + FBL_FSM_DEBUG_PRINT2(pFsmContext->instance, event, state); + + while ( (FBL_FSM_DEFAULT_STATE != state) + && (state < pFsmContext->stateCount)) + { + stateDef = &pFsmContext->stateDefinitions[state]; + triggers = stateDef->triggers; + + /* Search for matching event handler */ + for (index = 0u; index < stateDef->triggerCount; index++) + { + if ( (triggers[index].trigger == event) + || (triggers[index].trigger == (tFblFsmEvent)kFblFsmDefaultEvent_Any) ) + { + /* Handler matching event found, now execute handler */ + guard = triggers[index].handler(pFsmContext, event); + + FBL_FSM_DEBUG_PRINT3(pFsmContext->instance, guard); + + if (kFblFsmGuard_False != guard) + { + if (kFblFsmGuard_True == guard) + { + /* Pending state may be "none" */ + pFsmContext->pendingState = triggers[index].nextState; + } + else /* kFblFsmGuard_Overwrite */ + { + /* Do not set pendingState, this is (has to be) done by the event handler */ + } + + /* Stop searching for event handlers as event was handled */ + state = FBL_FSM_DEFAULT_STATE; + break; + } + else /* kFblFsmGuard_False */ + { + /* State shall not be left, continue to search for other matching event handlers */ + } + } + } + + /* Check if event has been already handled */ + if (FBL_FSM_DEFAULT_STATE != state) + { + /* No matching event handler returning kFblFsmGuard_True could be found for current state, + * continue search in (encapsulating) super state, if possible */ + if (kFsmIterateHierarchy_Enabled == iterate) + { + hierarchy++; + + if (hierarchy < FBL_FSM_MAX_HIERARCHY_DEPTH) + { + state = stateDef->superState; + } + else + { + /* Abort search to avoid (potential) infinite loop */ + FBL_FSM_DEBUG_ERROR_PRINT(pFsmContext->instance); + + state = FBL_FSM_DEFAULT_STATE; + } + } + else + { + /* State traversing not allowed, abort search at this point */ + state = FBL_FSM_DEFAULT_STATE; + } + } + } + +#if defined( FBL_FSM_ENABLE_DEBUGGING ) + if ( (state >= pFsmContext->stateCount) + && (FBL_FSM_DEFAULT_STATE != state) ) + { + FBL_FSM_DEBUG_ERROR_PRINT(pFsmContext->instance); + } +#endif /* FBL_FSM_ENABLE_DEBUGGING */ +} + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +/********************************************************************************************************************** + * FblFsmInitPowerOn + *********************************************************************************************************************/ +/*! \brief Module initialization + *********************************************************************************************************************/ +void FblFsmInitPowerOn( void ) +{ +#if defined( FBL_FSM_ENABLE_DEBUGGING ) + g_Instance = 0u; +#endif +} + +/********************************************************************************************************************** + * FblFsmInit + *********************************************************************************************************************/ +/*! \brief State machine initialization + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] initialState The initial state of the state machine + *********************************************************************************************************************/ +void FblFsmInit( tFblFsmContextPtr const pFsmContext, tFblFsmState initialState ) +{ +#if defined( FBL_FSM_ENABLE_DEBUGGING ) + pFsmContext->instance = g_Instance; + g_Instance++; +#endif + + /* Start with internal default state */ + pFsmContext->state = FBL_FSM_DEFAULT_STATE; + pFsmContext->pendingState = initialState; + pFsmContext->pendingEvent = (tFblFsmEvent)kFblFsmDefaultEvent_None; + + /* Enter provided initial state */ + FblFsmStateTask(pFsmContext); +} + +/********************************************************************************************************************** + * FblFsmDeinit + *********************************************************************************************************************/ +/*! \brief State machine deinitialization + * \param[in] pFsmContext Pointer to context of state machine + *********************************************************************************************************************/ +void FblFsmDeinit( tFblFsmContextPtr const pFsmContext ) +{ + /* Switch to internal default state to avoid further processing */ + pFsmContext->state = FBL_FSM_DEFAULT_STATE; + pFsmContext->pendingState = FBL_FSM_DEFAULT_STATE; + pFsmContext->pendingEvent = (tFblFsmEvent)kFblFsmDefaultEvent_None; +} + +/********************************************************************************************************************** + * FblFsmStateTask + *********************************************************************************************************************/ +/*! \brief State machine handling + * \details This function checks for pending events / state transitions and handles them appropriately. + * \param[in] pFsmContext Pointer to context of state machine + *********************************************************************************************************************/ +void FblFsmStateTask( tFblFsmContextPtr const pFsmContext ) +{ + tFblFsmState stateHierarchyExit[FBL_FSM_MAX_HIERARCHY_DEPTH]; + tFblFsmState stateHierarchyEntry[FBL_FSM_MAX_HIERARCHY_DEPTH]; + + tFblFsmState currentState; + tFblFsmState pendingState; + + vsint8 index; + vuint8 exitCount; + vuint8 entryCount; + vsint8 exitIndex; + vsint8 entryIndex; + + /* Check for pending event, which could cause state change */ + tFblFsmEvent event = pFsmContext->pendingEvent; + + if ((tFblFsmEvent)kFblFsmDefaultEvent_None != event) + { + /* Reset event */ + pFsmContext->pendingEvent = (tFblFsmEvent)kFblFsmDefaultEvent_None; + + /* Process event and trigger state change if necessary */ + FblFsmHandleEvent(pFsmContext, event, kFsmIterateHierarchy_Enabled); + } + + /* Check whether state has to be changed */ + while (FBL_FSM_DEFAULT_STATE != pFsmContext->pendingState) + { + currentState = pFsmContext->state; + pendingState = pFsmContext->pendingState; + + FBL_FSM_DEBUG_PRINT1(pFsmContext->instance, currentState, pendingState); + + /* Reset event which triggered state change */ + pFsmContext->pendingState = FBL_FSM_DEFAULT_STATE; + + /* Get state hierarchy of current state and pending state */ + exitCount = FblFsmGetStateHierachy(pFsmContext, currentState, stateHierarchyExit); + entryCount = FblFsmGetStateHierachy(pFsmContext, pendingState, stateHierarchyEntry); + + /* Check for re-entry of current state */ + if (currentState == pendingState) + { + exitIndex = 0; + entryIndex = 0; + } + else + { + exitIndex = ((vsint8)exitCount - 1); + entryIndex = ((vsint8)entryCount - 1); + + /* Search for common super state of current state and pending state */ + while ( (exitIndex >= 0) + && (stateHierarchyExit[exitIndex] == stateHierarchyEntry[entryIndex]) ) + { + exitIndex--; + entryIndex--; + } + + /* An exitIndex / entryIndex larger than 0 indicates that both state have a common super state */ + } + + /* Leave all super-states + * A state is always left, even if the pending state is the same (re-entry), + * but not if the target state is a sub-state of the current state. + * An exit handler is executed after the transition action has been executed */ + for (index = 0; index <= exitIndex; index++) + { + pFsmContext->state = stateHierarchyExit[index]; + + /* Leave previous state by calling exit handler */ + FblFsmHandleEvent(pFsmContext, (tFblFsmEvent)kFblFsmDefaultEvent_Exit, kFsmIterateHierarchy_Disabled); + } + + /* Enter all super-states + * A pending state is only entered if it is not a previous super-state */ + for (index = entryIndex; index >= 0; index--) + { + pFsmContext->state = stateHierarchyEntry[index]; + + /* Now enter new state by calling entry handler */ + FblFsmHandleEvent(pFsmContext, (tFblFsmEvent)kFblFsmDefaultEvent_Entry, kFsmIterateHierarchy_Disabled); + } + + /* Set final state, necessary if new state is super-state of previous state (no re-entry) */ + pFsmContext->state = pendingState; + } +} + +/********************************************************************************************************************** + * FblFsmTriggerEvent + *********************************************************************************************************************/ +/*! \brief Triggers event for given state machine + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event The event to be triggered + *********************************************************************************************************************/ +void FblFsmTriggerEvent( tFblFsmContextPtr const pFsmContext, tFblFsmEvent event ) +{ + pFsmContext->pendingEvent = event; +} + +/********************************************************************************************************************** + * FblFsmEventHandlerDefault + *********************************************************************************************************************/ +/*! \brief Default event handler + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event The event that triggered the handler execution + *********************************************************************************************************************/ +tFblFsmGuard FblFsmEventHandlerDefault( tFblFsmContextPtr const pFsmContext, tFblFsmEvent event ) /* PRQA S 3673 */ /* MD_MSR_Rule8.13 */ +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)pFsmContext; + (void)event; +#endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + /* Do nothing, but allow state transition */ + + return kFblFsmGuard_True; +} +#define FBLFSM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * END OF FILE: FBL_FSM.C + *********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_fsm.h b/Source/bsw/Fbl/fbl_fsm.h new file mode 100644 index 0000000..f1a4aa0 --- /dev/null +++ b/Source/bsw/Fbl/fbl_fsm.h @@ -0,0 +1,182 @@ +/********************************************************************************************************************** + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Event-driven hierarchical finite state machine interface + * + * ------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2023 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/*********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2012-10-30 visjhg - First implementation + * 01.00.01 2012-12-10 visjhg - Added "none" trigger + * 01.01.00 2013-12-11 visjhg ESCAN00071901 Renamed package to FblLib_Fsm + * visase - Performed MISRA checks + * 01.01.01 2019-01-24 visrie ESCAN00101864 No changes + * 01.02.00 2023-12-15 vistbe FBL-7986 Perform MISRA analysis + * Added/adapted MemMap sections + *********************************************************************************************************************/ + +#ifndef FBL_FSM_H +#define FBL_FSM_H + +/********************************************************************************************************************** + * VERSION + *********************************************************************************************************************/ + +/* --- Version --- */ +/* ##V_CFG_MANAGEMENT ##CQProject : FblLib_Fsm CQComponent : Implementation */ +#define FBLLIB_FSM_VERSION 0x0102u +#define FBLLIB_FSM_RELEASE_VERSION 0x00u + +/********************************************************************************************************************** + * DEFINES + *********************************************************************************************************************/ + +/** Default (invalid) state value */ +#define FBL_FSM_DEFAULT_STATE 0xFFFFu + +/********************************************************************************************************************** + * MACROS + *********************************************************************************************************************/ + +/** Dummy entry */ +#define FBL_FSM_TRIGGER_NONE() { FblFsmEventHandlerDefault, kFblFsmDefaultEvent_None, FBL_FSM_DEFAULT_STATE } +/** State entry handler */ +#define FBL_FSM_TRIGGER_ENTRY(action) { (action), kFblFsmDefaultEvent_Entry, FBL_FSM_DEFAULT_STATE } +/** State exit handler */ +#define FBL_FSM_TRIGGER_EXIT(action) { (action), kFblFsmDefaultEvent_Exit, FBL_FSM_DEFAULT_STATE } +/** Event handler for "any" event */ +#define FBL_FSM_TRIGGER_ANY(action, state) { (action), kFblFsmDefaultEvent_Any, (state) } +/** Internal event handler, no state transition */ +#define FBL_FSM_TRIGGER_INTERNAL(event, action) { (action), (event), FBL_FSM_DEFAULT_STATE } +/** State transition on event */ +#define FBL_FSM_TRIGGER_TRANSITION(event, state) { FblFsmEventHandlerDefault, (event), (state) } +/** State transition on event with additional action */ +#define FBL_FSM_TRIGGER_TRANSITION_ACTION(event, action, state) { (action), (event), (state) } +/** Switch state when guard condition is true */ +#define FBL_FSM_TRIGGER_CHOICE(guard, state) { (guard), kFblFsmDefaultEvent_Entry, (state) } +/** Else case of choice */ +#define FBL_FSM_TRIGGER_CHOICE_ELSE(state) { FblFsmEventHandlerDefault, kFblFsmDefaultEvent_Entry, (state) } +/** Unconditional state transition (any entry handler has to return negative guard result) */ +#define FBL_FSM_TRIGGER_UNCONDITIONAL(state) { FblFsmEventHandlerDefault, kFblFsmDefaultEvent_Entry, (state) } +/** Unconditional state transition with additional action (any entry handler has to return negative guard result) */ +#define FBL_FSM_TRIGGER_UNCONDITIONAL_ACTION(action, state) { (action), kFblFsmDefaultEvent_Entry, (state) } + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/** State type for state machine (the real states need to be defined by the component(s) using this module) */ +typedef vuint16 tFblFsmState; + +/** Event type for state machine (the real events need to be defined by the component(s) using this module) */ +typedef vuint16 tFblFsmEvent; + +#if defined( FBL_FSM_ENABLE_DEBUGGING ) +/** Instance number */ +typedef vuint8 tFblFsmInstance; +#endif /* FBL_FSM_ENABLE_DEBUGGING */ + +/** Event type (components using this module shall start to enumerate their events with kFblFsmDefaultEvent_Count) */ +typedef enum +{ + kFblFsmDefaultEvent_None, /**< No event */ + kFblFsmDefaultEvent_Entry, /**< State entry event */ + kFblFsmDefaultEvent_Exit, /**< State exit event */ + kFblFsmDefaultEvent_Any, /**< Don't care event */ + + kFblFsmDefaultEvent_Count /**< Decimal number of default events */ +} tFblFsmDefaultEvents; + +/** Guard type */ +typedef enum +{ + kFblFsmGuard_True, /**< True: State transition is allowed */ + kFblFsmGuard_False, /**< False: State transition is prohibited */ + kFblFsmGuard_Overwrite /**< Allow pending state to set next state (override state table configuration), defaults to no transition */ +} tFblFsmGuard; + +/** Forward declaration of context structure */ +typedef struct sFblFsmContext tFblFsmContext; + +/** Pointer to context structure */ +typedef V_MEMRAM1 tFblFsmContext V_MEMRAM2 V_MEMRAM3 * tFblFsmContextPtr; + +/** Event handler function pointer */ +typedef tFblFsmGuard (* tFblFsmEventHandler)( tFblFsmContextPtr const pFsmContext, tFblFsmEvent event ); + +typedef struct +{ + tFblFsmEventHandler handler; /**< Event handler */ + tFblFsmEvent trigger; /**< Event that triggers execution of handler */ + tFblFsmState nextState; /**< Next state if event handler returns kFblFsmGuard_True */ +} tFblFsmEventEntry; + +/** State definition */ +typedef struct +{ + tFblFsmState superState; /**< Super state (encapsulating state) */ + vuint16 triggerCount; /**< Size of array structure element 'triggers' points to */ + /** Array containing triggers (events) and the corresponding actions for state */ + V_MEMROM1 tFblFsmEventEntry V_MEMROM2 V_MEMROM3 * triggers; +} tFblFsmStateDefinition; + +/** Context structure */ +struct sFblFsmContext +{ + /** Pointer to array containing state definitions (set by component(s) using this module) */ + V_MEMROM1 tFblFsmStateDefinition V_MEMROM2 V_MEMROM3 * stateDefinitions; + vuint16 stateCount; /**< Number of elements in stateDefinitions (set by component(s) using this module) */ + tFblFsmState state; /**< Current state (intended for internal usage) */ + tFblFsmState pendingState; /**< Pending state (intended for internal usage) */ + tFblFsmEvent pendingEvent; /**< Pending event (intended for internal usage) */ +#if defined( FBL_FSM_ENABLE_DEBUGGING ) + tFblFsmInstance instance; /**< State machine instance number */ +#endif +}; + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#if defined( __cplusplus ) +extern "C" { +#endif +#define FBLFSM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +void FblFsmInitPowerOn( void ); +void FblFsmInit( tFblFsmContextPtr const pFsmContext, tFblFsmState initialState ); +void FblFsmDeinit( tFblFsmContextPtr const pFsmContext ); +void FblFsmStateTask( tFblFsmContextPtr const pFsmContext ); +void FblFsmTriggerEvent( tFblFsmContextPtr const pFsmContext, tFblFsmEvent event ); +tFblFsmGuard FblFsmEventHandlerDefault( tFblFsmContextPtr const pFsmContext, tFblFsmEvent event ); + +#define FBLFSM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( __cplusplus ) +} /* extern "C" */ +#endif + +#endif /* FBL_FSM_H */ + +/********************************************************************************************************************** + * END OF FILE: FBL_FSM.H + *********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_fsm_inc.h b/Source/bsw/Fbl/fbl_fsm_inc.h new file mode 100644 index 0000000..62f600e --- /dev/null +++ b/Source/bsw/Fbl/fbl_fsm_inc.h @@ -0,0 +1,49 @@ +/********************************************************************************************************************** + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Event-driven hierarchical finite state machine + * + * ------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2023 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/*********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2012-10-30 visjhg - First implementation + * 01.00.01 2012-12-10 visjhg - No changes + * 01.01.00 2013-12-11 visjhg ESCAN00071901 Renamed package to FblLib_Fsm + * visase - Performed MISRA checks + * 01.01.01 2019-01-24 visrie ESCAN00101864 Reworked include structure + * 01.02.00 2023-12-15 vistbe FBL-7986 Perform MISRA analysis + *********************************************************************************************************************/ + +#ifndef FBL_FSM_INC_H +#define FBL_FSM_INC_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +#include "fbl_inc.h" +#include "fbl_fsm_cfg.h" +#include "fbl_fsm.h" + +#endif /* __FBL_FSM_INC_H__ */ + +/********************************************************************************************************************** + * END OF FILE: FBL_FSM_INC.H + *********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_hw.c b/Source/bsw/Fbl/fbl_hw.c new file mode 100644 index 0000000..88e8e93 --- /dev/null +++ b/Source/bsw/Fbl/fbl_hw.c @@ -0,0 +1,236 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Provides hardware abstraction functions for ARM 32 systems + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2018-11-07 vistbe Initial version + * 01.00.01 2019-12-09 vistbe ESCAN00105142 No changes + * 01.01.00 2020-02-07 vistmo FBL-1452 Added support for S32G2xx + * 01.02.00 2020-11-03 vistmo FBL-2090 Added support for XMC4xxx + * 01.03.00 2020-12-09 visjdn FBL-2490 Added support for S32K3xx + * 01.04.00 2020-12-21 visrie FBL-2517 Added support for AWR1 + * 01.05.00 2021-01-28 visjdn FBL-2824 Added support for TPR12 + * 01.06.00 2021-05-19 visjdn FBL-3038 Added support for iMXRT1172 + * Added/adapted MemMap sections + * 01.07.00 2021-05-31 visjdn FBL-3545 Added support for AWR2 + * 01.08.00 2021-07-08 visjdn FBL-3694 Added support for Jacinto6 + * 01.09.00 2021-11-22 vistmo FBL-4275 Added support for Tayrona + * 01.10.00 2022-01-12 visjdn FBL-3720 Added support for Kinetis KW45B41Z + * 01.11.00 2022-03-09 visrie FBL-4770 No changes + * 01.12.00 2022-07-18 visjdn FBL-5115 Added support for SAF85xx + * 01.13.00 2023-02-09 fmenke FBL-6162 Added support for MSPM0 + * ESCAN00113692 Timer current value is too high after timer initialization + * 01.14.00 2023-04-20 jschmitding FBL-5733 Added support for TCC70xx + * 01.15.00 2023-07-12 fmenke FBL-6966 Add support for NCJ29D6 + * 01.16.00 2024-01-01 fmenke FBL-7559 No changes + * ESCAN00116504 No changes + * 01.17.00 2024-09-27 jschmitding FBL-9330 No changes + * 01.17.01 2024-10-22 visrie ESCAN00118141 No changes + * 01.18.00 2024-12-02 fmenke FBL-9747 Support StellarSr6 + * 01.19.00 2025-11-19 jostravsky FBL-11077 No changes + **********************************************************************************************************************/ + +#define FBL_HW_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLHAL_ARM32_VERSION != 0x0119u ) || \ + ( FBLHAL_ARM32_RELEASE_VERSION != 0x00u ) +# error "Error in fbl_hw.c: Source and header file are inconsistent!" +#endif + +#if ( FBLHAL_ARM32_VERSION != _FBLHAL_ARM32_VERSION ) || \ + ( FBLHAL_ARM32_RELEASE_VERSION != _FBLHAL_ARM32_RELEASE_VERSION ) +# error "Error in fbl_hw.c: Source and v_ver.h are inconsistent!" +#endif + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ +#if !defined( FBL_MEMCPY_WD_POLLING_MASK) +# define FBL_MEMCPY_WD_POLLING_MASK 0x3Fu +#endif + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +#if defined( FBL_USE_OWN_MEMCPY ) +# define FBLHW_MEMCPY_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * FblOwnMemcpy + **********************************************************************************************************************/ +/*! \brief Copies a given amount of bytes. + * \details This function copies a given amount of bytes. The Bootloader watchdog handling is called during + * copying. Can be used instead of a compiler library memcopy if watchdog handling is needed. + * \param[out] dest Pointer to destination + * \param[in] source Pointer to source + * \param[in] count Copy length in Byte + * \return Pointer to destination + **********************************************************************************************************************/ +void * FblOwnMemcpy (void * dest, const void * source, vuint32 count) +{ + vuint8 * localDest; + const vuint8 * localSource; + vuint32 i; + + /* Initialize variables */ + /* PRQA S 0316 2 */ /* MD_FblHw_0314_0316_0326_MemCpy */ + localDest = (vuint8 *)dest; + localSource = (const vuint8 *)source; + + for (i = 0u; i < count; i++) + { + if ((i & (FBL_MEMCPY_WD_POLLING_MASK )) == 0u) + { + FblLookForWatchdogVoid(); + } + localDest[i] = localSource[i]; + } + + return dest; +} +# define FBLHW_MEMCPY_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBL_USE_OWN_MEMCPY */ + +#define FBLHW_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * FblReadBlock + **********************************************************************************************************************/ +/*! \brief This function reads a given amount of bytes from an address. + * \param[in] address Memory address to read out + * \param[out] buffer Target buffer + * \param[in] length Number of bytes to read + * \return Number of actually copied bytes + **********************************************************************************************************************/ +tFblLength FblReadBlock( tFblAddress address, vuint8 *buffer, tFblLength length ) +{ + (void)MEMCPY(buffer, address, length); /* PRQA S 0314, 0326 */ /* MD_FblHw_0314_0316_0326_MemCpy */ + return length; +} + +/*********************************************************************************************************************** + * FblReadByte + **********************************************************************************************************************/ +/*! \brief This function can be used to read one byte from the given address. + * \param[in] Read address. + * \return Byte at memory location 'address' + **********************************************************************************************************************/ +vuint8 FblReadByte( tFblAddress address ) +{ + vuint8 buffer; + + (void)MEMCPY(&buffer, address, 1u); /* PRQA S 0314, 0326 */ /* MD_FblHw_0314_0316_0326_MemCpy */ + + return buffer; +} + +/*********************************************************************************************************************** + * FblTimerInit + **********************************************************************************************************************/ +/*! \brief Initialize system timer + **********************************************************************************************************************/ +/* PRQA S 0303 TAG_DrvFlash_0303_1 */ /* MD_FblHal_0303 */ +void FblTimerInit( void ) +{ + /* Disable both timers to make modifications */ + FBL_RTI_GCTRL &= FblInvert32Bit(FBL_RTI_GCTRL_TIMER_ENABLE); + /* Set prescaler: FRC=RTICLK/(prescaler+1) */ + FBL_RTI_CPUC(FBL_RTI_TIMER_MS) = FBL_TIMER_PRESCALER_VALUE; + /* Make sure Compare0 register is used for timer0 */ + FBL_RTI_COMPCTRL &= FblInvert32Bit(FBL_RTI_COMPCTRL_TIMER_SELECT); + /* Set Compare0 register (timer runs with half the frequency, see CPUC register) */ + FBL_RTI_COMP(0u) = FBL_TIMER_RELOAD_VALUE / (FBL_TIMER_PRESCALER_VALUE + 1uL); + FBL_RTI_UDCP(0u) = FBL_TIMER_RELOAD_VALUE / (FBL_TIMER_PRESCALER_VALUE + 1uL); + /* Make sure timer0 starts at 0 */ + FBL_RTI_FRC(FBL_RTI_TIMER_MS) = 0uL; + FBL_RTI_UC(FBL_RTI_TIMER_MS) = 0uL; + /* Enable both timers (millisecond and free running timer) */ + FBL_RTI_GCTRL |= FBL_RTI_GCTRL_TIMER_ENABLE; +} +/* PRQA L:TAG_DrvFlash_0303_1 */ + +/*********************************************************************************************************************** + * FblGetTimerValue + **********************************************************************************************************************/ +/*! \brief Returns free running timer value + * \pre Timer must be initialized + * \return Current timer value + **********************************************************************************************************************/ +/* PRQA S 0303 TAG_DrvFlash_0303_2 */ /* MD_FblHal_0303 */ +vuint16 FblGetTimerValue( void ) +{ + vuint32 timerValue; + + timerValue = FBL_RTI_FRC(FBL_RTI_TIMER_FREE); + + return (vuint16)(timerValue & 0xFFFFu); +} +/* PRQA L:TAG_DrvFlash_0303_2 */ + +/*********************************************************************************************************************** + * FblTimerStopp + **********************************************************************************************************************/ +/*! \brief Stops the system timer + **********************************************************************************************************************/ +/* PRQA S 0303 TAG_DrvFlash_0303_3 */ /* MD_FblHal_0303 */ +void FblTimerStopp( void ) +{ + FBL_RTI_GCTRL &= FblInvert32Bit(FBL_RTI_GCTRL_TIMER_ENABLE); +} +#define FBLHW_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/* PRQA L:TAG_DrvFlash_0303_3 */ + +/* Justification for module-specific MISRA deviations: + + MD_FblHal_0303: + Reason: Cast between a pointer to volatile object and an integral type. + Risk: No identifiable risk as casts are used to define SFRs here. + Prevention: No prevention required. + + MD_FblHw_0314_0316_0326_MemCpy: + Reason: The copy function have a void pointer as a function parameter. + Risk: No risk, because the underlying vuint8 pointer type is known. + Prevention: No prevention necessary. + + MD_FblHal_2741: + Reason: This is an assembler instruction that is not correctly interpreted during static code analysis. + Risk: No risk, because the assembler instruction will always return the value depending on the register. + Prevention: No prevention required. + +*/ +/*********************************************************************************************************************** + * END OF FILE: FBL_HW.C + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_hw.h b/Source/bsw/Fbl/fbl_hw.h new file mode 100644 index 0000000..120b3f3 --- /dev/null +++ b/Source/bsw/Fbl/fbl_hw.h @@ -0,0 +1,191 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Provides hardware abstraction functions for ARM 32 systems + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2018-11-07 vistbe Initial version + * 01.00.01 2019-12-09 vistbe ESCAN00105142 Compile Error in inline assembly + * 01.01.00 2020-02-07 vistmo FBL-1452 No changes + * 01.02.00 2020-11-03 vistmo FBL-2090 No changes + * 01.03.00 2020-12-09 visjdn FBL-2490 No changes + * 01.04.00 2020-12-21 visrie FBL-2517 Added support for AWR1 + * 01.05.00 2021-01-28 visjdn FBL-2824 Added support for TPR12 + * 01.06.00 2021-05-19 visjdn FBL-3038 Added/adapted MemMap sections + * 01.07.00 2021-05-31 visjdn FBL-3545 Added support for AWR2 + * 01.08.00 2021-07-08 visjdn FBL-3694 Added support for Jacinto6 + * 01.09.00 2021-11-22 vistmo FBL-4275 No changes + * 01.10.00 2022-01-12 visjdn FBL-3720 No changes + * 01.11.00 2022-03-09 visrie FBL-4770 Added support for ARM6 compiler + * 01.12.00 2022-07-18 visjdn FBL-5115 No changes + * 01.13.00 2023-02-09 fmenke FBL-6162 No changes + * ESCAN00113692 No changes + * 01.14.00 2023-04-20 jschmitding FBL-5733 Added support for TCC70xx + * 01.15.00 2023-07-12 fmenke FBL-6966 Add support for NCJ29D6 + * 01.16.00 2024-01-01 fmenke FBL-7559 No changes + * ESCAN00116504 No changes + * 01.17.00 2024-09-27 jschmitding FBL-9330 No changes + * 01.17.01 2024-10-22 visrie ESCAN00118141 Compiler error: missing brackets for JSR function parameter + * 01.18.00 2024-12-02 fmenke FBL-9747 Support StellarSr6 + * 01.19.00 2025-11-19 jostravsky FBL-11077 No changes + **********************************************************************************************************************/ + +#ifndef FBL_HW_H +#define FBL_HW_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#if defined( FBL_USE_OWN_MEMCPY ) +#else +# include +#endif /* FBL_USE_OWN_MEMCPY */ + +#if defined( V_COMP_ARM6 ) +# include +#endif + +#include "fbl_sfr.h" /* Special function register definition */ + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblHal_Arm32 CQComponent : Implementation */ +#define FBLHAL_ARM32_VERSION 0x0119u +#define FBLHAL_ARM32_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/** Memcpy function */ +#if defined( FBL_USE_OWN_MEMCPY ) +# define MEMCPY(dst, src, len) FblOwnMemcpy((void *)(dst), (const void *)(src), (vuint32)(len)) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ +#else +# define MEMCPY(dst, src, len) memcpy((void *)(dst), (const void *)(src), (size_t)(len)) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ +#endif /* FBL_USE_OWN_MEMCPY */ + +/*********************************************************************************************************************** + * MACROS FOR JUMPS + **********************************************************************************************************************/ +#if !defined( APPLSTART ) +# define APPLSTART (*((vuint32 *)&ApplIntJmpTable[1u])) /**< Startup code of application */ +#endif + +#define JSR(x) (*((void(*)(void))(x)))() /**< Jump to subroutine */ /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ + +#define JSR_APPL() JSR(APPLSTART) /**< Application start */ + +#define FblCheckBootVectTableIsValid() (ApplIntJmpTable[0u] == APPLVECT_FROM_BOOT) + +/* Timer handling ----------------------------------------------------------*/ +# define FblTimerGet() ((FBL_RTI_INTFLAG & 1uL) == 1uL) +# define FblTimerReset() FBL_RTI_INTFLAG = 1uL + + /* PRQA S 3453 1 */ /* MD_MSR_FctLikeMacro */ +#define FblFlashAddressGet3Bytes(array) (tFblAddress)( (tFblAddress)(((vuint8 *)array)[0u] << 16u) | \ + (tFblAddress)(((vuint8 *)array)[1u] << 8u) | \ + (tFblAddress)(((vuint8 *)array)[2u]) ) + +/* PRQA S 3453 1 */ /* MD_MSR_FctLikeMacro */ +#define FblDownloadLengthGet3Bytes(array) (tFblLength)( (tFblLength)(((vuint8 *)array)[0u] << 16u) | \ + (tFblLength)(((vuint8 *)array)[1u] << 8u) | \ + (tFblLength)(((vuint8 *)array)[2u]) ) +/* Read 4 bytes from diag buffer */ +/* PRQA S 3453 1 */ /* MD_MSR_FctLikeMacro */ +#define FblFlashAddressGet4Bytes(array) (tFblAddress)( (tFblAddress)(((vuint8 *)array)[0u] << 24u) | \ + (tFblAddress)(((vuint8 *)array)[1u] << 16u) | \ + (tFblAddress)(((vuint8 *)array)[2u] << 8u) | \ + (tFblAddress)(((vuint8 *)array)[3u]) ) + +/* PRQA S 3453 1 */ /* MD_MSR_FctLikeMacro */ +#define FblDownloadLengthGet4Bytes(array) (tFblLength)( (tFblLength)(((vuint8 *)array)[0u] << 24u) | \ + (tFblLength)(((vuint8 *)array)[1u] << 16u) | \ + (tFblLength)(((vuint8 *)array)[2u] << 8u) | \ + (tFblLength)(((vuint8 *)array)[3u]) ) + +/* Interrupt handling ----------------------------------------------------------*/ +#if defined( V_COMP_TI ) +# define FblInterruptDisable() __asm(" CPSID I") +# define FblInterruptEnable() __asm(" CPSIE I") +#elif defined( V_COMP_ARM6 ) +# define FblInterruptDisable() __disable_irq() +# define FblInterruptEnable() __enable_irq() +#else +# define FblInterruptDisable() __asm("CPSID I") +# define FblInterruptEnable() __asm("CPSIE I") +#endif + +/* FblHwRestoreFblContext() definition -----------------------------------------*/ +#define FblHwRestoreFblContext() + +/*********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ +#define FBLHW_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +void FblTimerInit( void ); +vuint16 FblGetTimerValue( void ); +void FblTimerStopp( void ); + +/* Memory access functions */ +tFblLength FblReadBlock( tFblAddress address, vuint8 *buffer, tFblLength length ); +vuint8 FblReadByte( tFblAddress address ); +#define FBLHW_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBL_USE_OWN_MEMCPY ) +# define FBLHW_MEMCPY_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +void * FblOwnMemcpy (void * dest, const void * source, vuint32 count); +# define FBLHW_MEMCPY_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBL_USE_OWN_MEMCPY */ + +#endif /* FBL_HW_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_HW.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_lbt_access.c b/Source/bsw/Fbl/fbl_lbt_access.c new file mode 100644 index 0000000..3176256 --- /dev/null +++ b/Source/bsw/Fbl/fbl_lbt_access.c @@ -0,0 +1,1428 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Interface layer for accessing the logical block table (LBT) + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2023 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2018-05-24 visci - Initial version + * 01.01.00 2018-11-27 visshs ESCAN00101459 Add Support for Secure Boot + * 01.02.00 2019-02-26 visrie ESCAN00102278 Added additional getter functions + * 01.02.01 2019-09-05 visrcn ESCAN00103604 Modified memory qualifiers + * 01.03.00 2022-03-31 visstn FBL-4366 Perform MISRA 2012 migration + * 01.04.00 2022-10-17 visjns FBL-4925 Change LBT access to use RAM + * 01.04.01 2023-04-24 vismix ESCAN00113819 Incorrect assertion expression in FblLbtActivateLbtBlockByAddress() + * 01.05.00 2023-12-14 vistbe FBL-7967 Add new filename attribute for LBT + **********************************************************************************************************************/ + +#define FBL_LBT_ACCESS_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLLIB_LBT_VERSION != 0x0105u ) || \ + ( FBLLIB_LBT_RELEASE_VERSION != 0x00u ) +# error "Error in fbl_lbt_access.c: Source and header file are inconsistent!" +#endif + +#if ( FBLLIB_LBT_VERSION != _FBLLIB_LBT_VERSION ) || \ + ( FBLLIB_LBT_RELEASE_VERSION != _FBLLIB_LBT_RELEASE_VERSION ) +# error "Error in fbl_lbt_access.c: Source and v_ver.h are inconsistent!" +#endif + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* Access of LBT in RAM */ +#if defined(FBL_LBT_ENABLE_RAM_BUFFER) +# define FBL_LBT_RAM_BUF_SIZE sizeof(tLogicalBlockTable) +#endif /* FBL_LBT_ENABLE_RAM_BUFFER */ + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +#if defined(FBL_LBT_ENABLE_RAM_BUFFER) +typedef const V_MEMRAM1 tLogicalBlockTable V_MEMRAM2 V_MEMRAM3 * tLogicalBlockTableConstPointer; +#endif /* FBL_LBT_ENABLE_RAM_BUFFER */ + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +#define FBLLBT_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +V_MEMRAM0 static V_MEMRAM1 tFblLbtBlockNr V_MEMRAM2 fblLbtBlockIteratorNr; +V_MEMRAM0 static V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 fblLbtBlockIteratorFilter; +V_MEMRAM0 static V_MEMRAM1 boolean V_MEMRAM2 fblLbtBlockIteratorDone; +#if defined(FBL_LBT_ENABLE_RAM_BUFFER) +V_MEMRAM0 static V_MEMRAM1 tLogicalBlockTable V_MEMRAM2 fblLbtRamBuffer; +V_MEMROM0 static tLogicalBlockTableConstPointer V_MEMROM1 V_MEMROM2 fblLbtActive = &fblLbtRamBuffer; +#else +V_MEMRAM0 static V_MEMROM1 tLogicalBlockTable V_MEMROM2 V_MEMROM3 * V_MEMRAM1 V_MEMRAM2 fblLbtActive; +#endif /* FBL_LBT_ENABLE_RAM_BUFFER */ + +#define FBLLBT_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLLBT_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +static boolean FblLbtBlockFilterHit(const V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor); +#if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) +static tFblResult FblLbtBlockCompare(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * block1, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * block2); +static tFblResult FblLbtCheckReferences(void); +#endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FblLbtBlockFilterHit + **********************************************************************************************************************/ +/*! \brief Check whether a certain block matches the filter settings + * \param[in] blockFilter Block filter settings + * \param[in] blockDescriptor Structure with block information + * \return Possible return values: + * - TRUE if the block matches the filter criteria + * - FALSE otherwise + **********************************************************************************************************************/ +static boolean FblLbtBlockFilterHit(const V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor) +{ + /* Default setting: open filter */ + boolean result = TRUE; + + /* Check if mandatory/optional filter is enabled */ + if (blockFilter->mandatoryType.enabled == TRUE) + { + /* Check if this is a mandatory block */ + if (blockDescriptor->mandatoryType == TRUE) + { + /* Block is mandatory: compare against filter value */ + result = (blockFilter->mandatoryType.value == TRUE) ? TRUE : FALSE; + } + else + { + /* Block is optional: compare against filter value */ + result = (blockFilter->mandatoryType.value == FALSE) ? TRUE : FALSE; + } + } + +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) + /* Check if block type filter is enabled */ + if (blockFilter->blockType.enabled == TRUE) + { + /* AND logic: check if filter is still 'open' */ + if (result == TRUE) + { + result = (boolean)((blockDescriptor->blockType == blockFilter->blockType.value) ? TRUE : FALSE); + } + } +#endif /* FBL_LBT_ENABLE_BLOCK_TYPE */ + + return result; +} + +#if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) +/*********************************************************************************************************************** + * FblLbtBlockCompare + **********************************************************************************************************************/ +/*! \brief Compare the parameters of two blocks (member-compare) + * \param[in] block1 Structure with parameters of first block + * \param[in] block2 Structure with parameters of second block + * \return Possible return values: + * - kFblOk if the two blocks are equal + * - kFblFailed otherwise + **********************************************************************************************************************/ +static tFblResult FblLbtBlockCompare(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * block1, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * block2) +{ + tFblResult result = kFblOk; + + if ( (block1->blockNr != block2->blockNr) + || (block1->mandatoryType != block2->mandatoryType) + || (block1->blockStartAddress != block2->blockStartAddress) + || (block1->blockLength != block2->blockLength) +#if defined( FBL_LBT_ENABLE_BLOCK_INDEX ) + || (block1->blockIndex != block2->blockIndex) +#endif +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) + || (block1->blockType != block2->blockType) +#endif +#if defined( FBL_LBT_ENABLE_HEADER_ADDRESS ) + || (block1->headerAddress != block2->headerAddress) +#endif +#if defined( FBL_LBT_ENABLE_BM_HEADER_ADDRESS ) + || (block1->bmHeaderAddress != block2->bmHeaderAddress) +#endif +#if defined( FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS ) + || (block1->maxProgAttempts != block2->maxProgAttempts) +#endif +#if defined( FBL_LBT_ENABLE_VERIFY_INPUT ) + || (block1->verifyInput != block2->verifyInput) +#endif +#if defined( FBL_LBT_ENABLE_VERIFY_PROCESSED ) + || (block1->verifyProcessed != block2->verifyProcessed) +#endif +#if defined( FBL_LBT_ENABLE_VERIFY_PIPELINED ) + || (block1->verifyPipelined != block2->verifyPipelined) +#endif +#if defined( FBL_LBT_ENABLE_VERIFY_OUTPUT ) + || (block1->verifyOutput != block2->verifyOutput) +#endif + ) + { + /* At least one of the block descriptor parameters doesn't match */ + result = kFblFailed; + } + + return result; +} + +/*********************************************************************************************************************** + * FblLbtCheckReferences + **********************************************************************************************************************/ +/*! \brief Check if the references which are used in the reprogrammable LBT are valid with the bootloader + * \return Possible return values: + * - kFblOk if all references are valid + * - kFblFailed otherwise + **********************************************************************************************************************/ +static tFblResult FblLbtCheckReferences(void) +{ + tFblResult result = kFblOk; + tFblLbtBlockFilter blockFilter = {0}; + tBlockDescriptor newLbtBlock = {0}; + vuint8 tableIdx = 0u; + + FblLbtBlockFilterInit(&blockFilter); + + newLbtBlock = FblLbtBlockFirst(&blockFilter); + while ( FblLbtBlockDone() == FALSE ) + { +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) + /* Compare actual block type against pre-defined list */ + result = kFblFailed; + for (tableIdx = 0u; tableIdx < fblLbtBlockTypes.typeCount; tableIdx++) + { + if (newLbtBlock.blockType == fblLbtBlockTypes.type[tableIdx]) + { + result = kFblOk; + break; + } + } +#endif /* FBL_LBT_ENABLE_BLOCK_TYPE */ + +#if defined( FBL_LBT_ENABLE_VERIFY_INPUT ) + if (result == kFblOk) + { + /* Compare actual verification function against pre-defined list */ + result = kFblFailed; + for (tableIdx = 0u; tableIdx < fblLbtVerificationFunc.funcCount; tableIdx++) + { + if (newLbtBlock.verifyInput == fblLbtVerificationFunc.func[tableIdx]) + { + result = kFblOk; + break; + } + } + } +#endif /* FBL_LBT_ENABLE_VERIFY_INPUT */ +#if defined( FBL_LBT_ENABLE_VERIFY_PROCESSED ) + if (result == kFblOk) + { + /* Compare actual verification function against pre-defined list */ + result = kFblFailed; + for (tableIdx = 0u; tableIdx < fblLbtVerificationFunc.funcCount; tableIdx++) + { + if (newLbtBlock.verifyProcessed == fblLbtVerificationFunc.func[tableIdx]) + { + result = kFblOk; + break; + } + } + } +#endif /* FBL_LBT_ENABLE_VERIFY_PROCESSED */ +#if defined( FBL_LBT_ENABLE_VERIFY_PIPELINED ) + if (result == kFblOk) + { + /* Compare actual verification function against pre-defined list */ + result = kFblFailed; + for (tableIdx = 0u; tableIdx < fblLbtVerificationFunc.funcCount; tableIdx++) + { + if (newLbtBlock.verifyPipelined == fblLbtVerificationFunc.func[tableIdx]) + { + result = kFblOk; + break; + } + } + } +#endif /* FBL_LBT_ENABLE_VERIFY_PIPELINED */ +#if defined( FBL_LBT_ENABLE_VERIFY_OUTPUT ) + if (result == kFblOk) + { + /* Compare actual verification function against pre-defined list */ + result = kFblFailed; + for (tableIdx = 0u; tableIdx < fblLbtVerificationFunc.funcCount; tableIdx++) + { + if (newLbtBlock.verifyOutput == fblLbtVerificationFunc.func[tableIdx]) + { + result = kFblOk; + break; + } + } + } +#endif /* FBL_LBT_ENABLE_VERIFY_OUTPUT */ + + if (result != kFblOk) + { + /* Unknown reference used: abort */ + break; + } + + newLbtBlock = FblLbtBlockNext(); + } + + return result; +} +#endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FblLbtInitPowerOn + **********************************************************************************************************************/ +/*! \brief Power-on initialization of the LBT access module + **********************************************************************************************************************/ +void FblLbtInitPowerOn(void) +{ +#if defined(FBL_LBT_ENABLE_RAM_BUFFER) + /* Initialize pointer with built-in LBT copied into RAM buffer */ /* PRQA S 0306 1 */ /* MD_FblLib_Lbt_0306 */ + (void)FblReadBlock((tFblAddress)&FblLogicalBlockTable, (vuint8*)&fblLbtRamBuffer, FBL_LBT_RAM_BUF_SIZE); +#else + /* Initialize pointer with built-in LBT */ + fblLbtActive = &FblLogicalBlockTable; +#endif /* FBL_LBT_ENABLE_RAM_BUFFER */ +} + +/*********************************************************************************************************************** + * FblLbtBlockFilterInit + **********************************************************************************************************************/ +/*! \brief Initialize/reset the block filter structure + * \param[out] blockFilter Structure with block filter parameters + **********************************************************************************************************************/ +void FblLbtBlockFilterInit(V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter) +{ + blockFilter->mandatoryType.enabled = FALSE; +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) + blockFilter->blockType.enabled = FALSE; +#endif +} + +/*********************************************************************************************************************** + * FblLbtBlockFilterSetMandatoryType + **********************************************************************************************************************/ +/*! \brief Set and enable the filter for the mandatory type + * \param[out] blockFilter Structure with block filter parameters + * \param[in] mandatoryType The mandatory type value which shall be filtered (optional/mandatory) + **********************************************************************************************************************/ +void FblLbtBlockFilterSetMandatoryType(V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter, + tFblLbtMandatoryType mandatoryType) +{ + blockFilter->mandatoryType.value = mandatoryType; + blockFilter->mandatoryType.enabled = TRUE; +} + +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) +/*********************************************************************************************************************** + * FblLbtBlockFilterSetBlockType + **********************************************************************************************************************/ +/*! \brief Set and enable the filter for the block type + * \param[out] blockFilter Structure with block filter parameters + * \param[in] blockType The block type value which shall be filtered + **********************************************************************************************************************/ +void FblLbtBlockFilterSetBlockType(V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter, + tFblLbtBlockType blockType) +{ + blockFilter->blockType.value = blockType; + blockFilter->blockType.enabled = TRUE; +} +#endif /* FBL_LBT_ENABLE_BLOCK_TYPE */ + +/*********************************************************************************************************************** + * FblLbtBlockFirst + **********************************************************************************************************************/ +/*! \brief Initialization/start function of the block iterator + * \param[in] blockFilter Structure with block filter parameters + * \return First block which matches the given filter settings + **********************************************************************************************************************/ +tBlockDescriptor FblLbtBlockFirst(const V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter) +{ + fblLbtBlockIteratorNr = 0u; + fblLbtBlockIteratorFilter = *blockFilter; + fblLbtBlockIteratorDone = FALSE; + + return FblLbtBlockNext(); +} + +/*********************************************************************************************************************** + * FblLbtBlockNext + **********************************************************************************************************************/ +/*! \brief Continue/next function of the block iterator + * \return Next block which matches the filter settings which have been passed to FblLbtBlockFirst + **********************************************************************************************************************/ +tBlockDescriptor FblLbtBlockNext(void) +{ + tBlockDescriptor blockDescriptor = {0}; + boolean filterResult = FALSE; + + /* Initialize block descriptor to avoid compiler warning (invalid descriptor will NOT be used, loop is aborted before) */ + blockDescriptor = FblLogicalBlockTable.logicalBlock[0u]; + + while (fblLbtBlockIteratorNr < fblLbtActive->noOfBlocks) + { + /* Retrieve next block from LBT */ + blockDescriptor = fblLbtActive->logicalBlock[fblLbtBlockIteratorNr]; + + /* Increment iterator */ + fblLbtBlockIteratorNr++; + + /* Test block descriptor against filter settings */ + filterResult = FblLbtBlockFilterHit(&fblLbtBlockIteratorFilter, &blockDescriptor); + if (filterResult == TRUE) + { + /* Current block descriptor matches the filter settings, return to caller */ + break; + } + } + + if ((fblLbtBlockIteratorNr >= fblLbtActive->noOfBlocks) && (filterResult == FALSE)) + { + /* No more blocks found, abort iteration */ + fblLbtBlockIteratorDone = TRUE; + } + + return blockDescriptor; +} + +/*********************************************************************************************************************** + * FblLbtBlockDone + **********************************************************************************************************************/ +/*! \brief Implementation of the exit condition of the block iterator + * \return Boolean value which reflects the exit condition + * - FALSE: Last block not reached yet + * - TRUE : Last block has been reached + **********************************************************************************************************************/ +boolean FblLbtBlockDone(void) +{ + return fblLbtBlockIteratorDone; +} + +/*********************************************************************************************************************** + * FblLbtGetBlockCount + **********************************************************************************************************************/ +/*! \brief Getter function for the actual block count of the active LBT + * \return Number of blocks in the active LBT + **********************************************************************************************************************/ +tFblLbtBlockCount FblLbtGetBlockCount(void) +{ + return (tFblLbtBlockCount)fblLbtActive->noOfBlocks; +} + +/*********************************************************************************************************************** + * FblLbtGetMagicFlag + **********************************************************************************************************************/ +/*! \brief Getter function to read the magic flag + * \return Magic flag value + **********************************************************************************************************************/ +tFblLbtMagicFlag FblLbtGetMagicFlag(void) +{ + return (tFblLbtMagicFlag)fblLbtActive->magicFlag; +} + +/*********************************************************************************************************************** + * FblLbtGetBlockNrByAddressLength + **********************************************************************************************************************/ +/*! \brief Look up and return the block number for a given memory range + * \param[in] address Start address of the memory range + * \param[in] length Length of the memory range + * \param[out] Block number of the respective block (if found) + * \return Possible return values: + * - kFblOk if block number could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockNrByAddressLength(tFblAddress address, tFblLength length, + V_MEMRAM1 tFblLbtBlockNr V_MEMRAM2 V_MEMRAM3 * blockNr) +{ + tFblResult result = kFblFailed; + tBlockDescriptor localBlockDescriptor = {0}; + tFblLbtBlockFilter blockFilter = {0}; + + /* Configure block filter (clear all filter settings) */ + FblLbtBlockFilterInit(&blockFilter); + + localBlockDescriptor = FblLbtBlockFirst(&blockFilter); + while (FblLbtBlockDone() == FALSE) + { + result = FblLbtCheckRangeContained(address, length, + localBlockDescriptor.blockStartAddress, + localBlockDescriptor.blockLength); + if (result == kFblOk) + { + *blockNr = localBlockDescriptor.blockNr; + break; + } + + localBlockDescriptor = FblLbtBlockNext(); + } + + return result; +} + +/*********************************************************************************************************************** + * FblLbtGetBlockDescriptorByNr + **********************************************************************************************************************/ +/*! \brief Look up and return the block descriptor with a certain block number value + * \param[in] blockNr Block number value of the block to be retrieved + * \param[out] blockDescriptor Parameter structure with the information of the respective block + * \return Possible return values: + * - kFblOk if descriptor could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockDescriptorByNr(tFblLbtBlockNr blockNr, + V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor) +{ + tFblResult result = kFblFailed; + + if (blockNr < fblLbtActive->noOfBlocks) + { + *blockDescriptor = fblLbtActive->logicalBlock[blockNr]; + result = kFblOk; + } + + return result; +} + +/*********************************************************************************************************************** + * FblLbtGetBlockDescriptorByAddressLength + **********************************************************************************************************************/ +/*! \brief Look up and return the block descriptor for a given memory range + * \param[in] address Start address of the memory range + * \param[in] length Length of the memory range + * \param[out] blockDescriptor Parameter structure with the information of the respective block + * \return Possible return values: + * - kFblOk if block descriptor could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockDescriptorByAddressLength(tFblAddress address, tFblLength length, + V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor) +{ + tFblResult result = kFblFailed; + tFblLbtBlockNr localBlockNr = 0u; + + result = FblLbtGetBlockNrByAddressLength(address, length, &localBlockNr); + + if (result == kFblOk) + { + result = FblLbtGetBlockDescriptorByNr(localBlockNr, blockDescriptor); + } + + return result; +} + +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) +/*********************************************************************************************************************** + * FblLbtGetBlockDescriptorByType + **********************************************************************************************************************/ +/*! \brief Look up and return the first block descriptor with a certain block type value + * \param[in] blockType Type value of the block to be retrieved + * \param[out] blockDescriptor Parameter structure with the information of the respective block + * \return Possible return values: + * - kFblOk if descriptor could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockDescriptorByType(tFblLbtBlockType blockType, + V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor) +{ + tFblResult result = kFblFailed; + tBlockDescriptor localBlockDescriptor = {0}; + tFblLbtBlockFilter blockFilter = {0}; + + /* Configure block filter (clear all filter settings) */ + FblLbtBlockFilterInit(&blockFilter); + + localBlockDescriptor = FblLbtBlockFirst(&blockFilter); + while ( FblLbtBlockDone() == FALSE ) + { + if (localBlockDescriptor.blockType == blockType) + { + *blockDescriptor = localBlockDescriptor; + result = kFblOk; + break; + } + + localBlockDescriptor = FblLbtBlockNext(); + } + + return result; +} +#endif /* FBL_LBT_ENABLE_BLOCK_TYPE */ + +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) +/*********************************************************************************************************************** + * FblLbtGetBlockTypeByNr + **********************************************************************************************************************/ +/*! \brief Look up and return the block type with a certain block index value + * \param[in] blockNr Block number value of the block to be retrieved + * \param[out] blockType Type of the respective block + * \return Possible return values: + * - kFblOk if block type could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockTypeByNr(tFblLbtBlockNr blockNr, + V_MEMRAM1 tFblLbtBlockType V_MEMRAM2 V_MEMRAM3 * blockType) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize block type to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.blockType = 0uL; + + if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk) + { + *blockType = blockDescriptor.blockType; + result = kFblOk; + } + + return result; +} +#endif /* FBL_LBT_ENABLE_BLOCK_TYPE */ + +#if defined( FBL_LBT_ENABLE_BLOCK_INDEX ) +/*********************************************************************************************************************** +* FblLbtGetBlockIndexByNr +**********************************************************************************************************************/ +/*! \brief Look up and return the block index with a certain block index value +* \param[in] blockNr Block number value of the block to be retrieved +* \param[out] blockIndex Index of the respective block +* \return Possible return values: +* - kFblOk if block type could be retrieved successfully +* - kFblFailed otherwise +**********************************************************************************************************************/ +tFblResult FblLbtGetBlockIndexByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tFblLbtBlockIndex V_MEMRAM2 V_MEMRAM3 * blockIndex) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize block type to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.blockIndex = 0uL; + + if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk) + { + *blockIndex = blockDescriptor.blockIndex; + result = kFblOk; + } + + return result; +} +#endif /* FBL_LBT_ENABLE_BLOCK_INDEX */ + +#if defined( FBL_LBT_ENABLE_HEADER_ADDRESS ) +/*********************************************************************************************************************** + * FblLbtGetBlockHeaderAddressByNr + **********************************************************************************************************************/ +/*! \brief Look up and return the block header address with a certain block index value + * \param[in] blockNr Block number value of the block to be retrieved + * \param[out] blockHeaderAddress Header address of the respective block + * \return Possible return values: + * - kFblOk if header address could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockHeaderAddressByNr(tFblLbtBlockNr blockNr, + V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * blockHeaderAddress) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize header address to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.headerAddress = 0uL; + + if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk) + { + *blockHeaderAddress = blockDescriptor.headerAddress; + result = kFblOk; + } + + return result; +} +#endif /* FBL_LBT_ENABLE_BLOCK_HEADER_ADDRESS */ + +#if defined( FBL_LBT_ENABLE_BM_HEADER_ADDRESS ) +/*********************************************************************************************************************** + * FblLbtGetBlockBmHeaderAddressByNr + **********************************************************************************************************************/ +/*! \brief Look up and return the bootmanager header address with a certain block index value + * \param[in] blockNr Block number value of the block to be retrieved + * \param[out] bmHeaderAddress BM Header address of the respective block + * \return Possible return values: + * - kFblOk if header address could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockBmHeaderAddressByNr(tFblLbtBlockNr blockNr, + V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * bmHeaderAddress) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize BM header address to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.bmHeaderAddress = 0uL; + + if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk) + { + *bmHeaderAddress = blockDescriptor.bmHeaderAddress; + result = kFblOk; + } + + return result; +} +#endif /* FBL_LBT_ENABLE_BM_HEADER_ADDRESS */ + +#if defined( FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS ) +/*********************************************************************************************************************** + * FblLbtGetBlockMaxProgAttemptsByNr + **********************************************************************************************************************/ +/*! \brief Look up and return the maximum programming attempts with a certain block index value + * \param[in] blockNr Block number value of the block to be retrieved + * \param[out] maxProgAttempts Maxmimum programming attempts of the respective block + * \return Possible return values: + * - kFblOk if maximum programming attempts could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockMaxProgAttemptsByNr(tFblLbtBlockNr blockNr, + V_MEMRAM1 tFblLbtMaxProgAttempts V_MEMRAM2 V_MEMRAM3 * maxProgAttempts) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize maximum programming attempts to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.maxProgAttempts = 0u; + + if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk) + { + *maxProgAttempts = blockDescriptor.maxProgAttempts; + result = kFblOk; + } + + return result; +} +#endif /* FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS */ + +#if defined( FBL_LBT_ENABLE_VERIFY_INPUT ) +/*********************************************************************************************************************** + * FblLbtGetBlockVerifyInputFuncByNr + **********************************************************************************************************************/ +/*! \brief Look up and return the verification function + * \param[in] blockNr Block number value of the block to be retrieved + * \param[out] blockVerifyFunc Address of the block specific verification function + * \return Possible return values: + * - kFblOk if verification function could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockVerifyInputFuncByNr(tFblLbtBlockNr blockNr, + V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.verifyInput = (tExportFct)0; + + if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk) + { + *blockVerifyFunc = blockDescriptor.verifyInput; + result = kFblOk; + } + + return result; +} +#endif /* FBL_LBT_ENABLE_VERIFY_INPUT */ + +#if defined( FBL_LBT_ENABLE_VERIFY_PROCESSED ) +/*********************************************************************************************************************** + * FblLbtGetBlockVerifyProcessedFuncByNr + **********************************************************************************************************************/ +/*! \brief Look up and return the verification function + * \param[in] blockNr Block number value of the block to be retrieved + * \param[out] blockVerifyFunc Address of the block specific verification function + * \return Possible return values: + * - kFblOk if verification function could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockVerifyProcessedFuncByNr(tFblLbtBlockNr blockNr, + V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.verifyProcessed = (tExportFct)0; + + if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk) + { + *blockVerifyFunc = blockDescriptor.verifyProcessed; + result = kFblOk; + } + + return result; +} +#endif /* FBL_LBT_ENABLE_VERIFY_PROCESSED */ + +#if defined( FBL_LBT_ENABLE_VERIFY_PIPELINED ) +/*********************************************************************************************************************** + * FblLbtGetBlockVerifyPipelinedFuncByNr + **********************************************************************************************************************/ +/*! \brief Look up and return the verification function + * \param[in] blockNr Block number value of the block to be retrieved + * \param[out] blockVerifyFunc Address of the block specific verification function + * \return Possible return values: + * - kFblOk if verification function could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockVerifyPipelinedFuncByNr(tFblLbtBlockNr blockNr, + V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.verifyPipelined = (tExportFct)0; + + if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk) + { + *blockVerifyFunc = blockDescriptor.verifyPipelined; + result = kFblOk; + } + + return result; +} +#endif /* FBL_LBT_ENABLE_VERIFY_PIPELINED */ + +#if defined( FBL_LBT_ENABLE_VERIFY_OUTPUT ) +/*********************************************************************************************************************** + * FblLbtGetBlockVerifyOutputFuncByNr + **********************************************************************************************************************/ +/*! \brief Look up and return the block header address with a certain block index value + * \param[in] blockNr Block number value of the block to be retrieved + * \param[out] blockVerifyFunc Address of the block specific verification function + * \return Possible return values: + * - kFblOk if verification function could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockVerifyOutputFuncByNr(tFblLbtBlockNr blockNr, + V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.verifyOutput = (tExportFct)0uL; + + if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk) + { + *blockVerifyFunc = blockDescriptor.verifyOutput; + result = kFblOk; + } + + return result; +} +#endif /* FBL_LBT_ENABLE_VERIFY_OUTPUT */ + +#if defined( FBL_LBT_ENABLE_BLOCK_INDEX ) +/*********************************************************************************************************************** + * FblLbtGetBlockDescriptorByIndex + **********************************************************************************************************************/ +/*! \brief Look up and return the block descriptor with a certain block index value + * \param[in] blockIndex Index value of the block to be retrieved + * \param[out] blockDescriptor Parameter structure with the information of the respective block + * \return Possible return values: + * - kFblOk if descriptor could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockDescriptorByIndex(tFblLbtBlockIndex blockIndex, + V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor) +{ + tFblResult result = kFblFailed; + tBlockDescriptor localBlockDescriptor = {0}; + tFblLbtBlockFilter blockFilter = {0}; + + /* Configure block filter (clear all filter settings) */ + FblLbtBlockFilterInit(&blockFilter); + + localBlockDescriptor = FblLbtBlockFirst(&blockFilter); + while ( FblLbtBlockDone() == FALSE ) + { + if (localBlockDescriptor.blockIndex == blockIndex) + { + *blockDescriptor = localBlockDescriptor; + result = kFblOk; + break; + } + + localBlockDescriptor = FblLbtBlockNext(); + } + + return result; +} + +/*********************************************************************************************************************** + * FblLbtGetBlockNrByIndex + **********************************************************************************************************************/ +/*! \brief Look up and return the block number with a certain block index value + * \param[in] blockIndex Index value of the block to be retrieved + * \param[out] blockNr Number of the respective block + * \return Possible return values: + * - kFblOk if block number could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockNrByIndex(tFblLbtBlockIndex blockIndex, + V_MEMRAM1 tFblLbtBlockNr V_MEMRAM2 V_MEMRAM3 * blockNr) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize block number to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.blockNr = 0u; + + if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk) + { + *blockNr = blockDescriptor.blockNr; + result = kFblOk; + } + + return result; +} + +# if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) +/*********************************************************************************************************************** + * FblLbtGetBlockTypeByIndex + **********************************************************************************************************************/ +/*! \brief Look up and return the block type with a certain block index value + * \param[in] blockIndex Index value of the block to be retrieved + * \param[out] blockType Type of the respective block + * \return Possible return values: + * - kFblOk if block type could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockTypeByIndex(tFblLbtBlockIndex blockIndex, + V_MEMRAM1 tFblLbtBlockType V_MEMRAM2 V_MEMRAM3 * blockType) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize block type to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.blockType = 0uL; + + if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk) + { + *blockType = blockDescriptor.blockType; + result = kFblOk; + } + + return result; +} +# endif /* FBL_LBT_ENABLE_BLOCK_TYPE */ + +# if defined( FBL_LBT_ENABLE_HEADER_ADDRESS ) +/*********************************************************************************************************************** + * FblLbtGetBlockHeaderAddressByIndex + **********************************************************************************************************************/ +/*! \brief Look up and return the block header address with a certain block index value + * \param[in] blockIndex Index value of the block to be retrieved + * \param[out] blockHeaderAddress Header address of the respective block + * \return Possible return values: + * - kFblOk if header address could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockHeaderAddressByIndex(tFblLbtBlockIndex blockIndex, + V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * blockHeaderAddress) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize header address to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.headerAddress = 0uL; + + if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk) + { + *blockHeaderAddress = blockDescriptor.headerAddress; + result = kFblOk; + } + + return result; +} +# endif /* FBL_LBT_ENABLE_BLOCK_HEADER_ADDRESS */ + +# if defined( FBL_LBT_ENABLE_BM_HEADER_ADDRESS ) +/*********************************************************************************************************************** + * FblLbtGetBlockBmHeaderAddressByIndex + **********************************************************************************************************************/ +/*! \brief Look up and return the bootmanager header address with a certain block index value + * \param[in] blockIndex Index value of the block to be retrieved + * \param[out] bmHeaderAddress BM Header address of the respective block + * \return Possible return values: + * - kFblOk if header address could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockBmHeaderAddressByIndex(tFblLbtBlockIndex blockIndex, + V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * bmHeaderAddress) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize BM header address to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.bmHeaderAddress = 0uL; + + if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk) + { + *bmHeaderAddress = blockDescriptor.bmHeaderAddress; + result = kFblOk; + } + + return result; +} +# endif /* FBL_LBT_ENABLE_BM_HEADER_ADDRESS */ + +# if defined( FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS ) +/*********************************************************************************************************************** + * FblLbtGetBlockMaxProgAttemptsByIndex + **********************************************************************************************************************/ +/*! \brief Look up and return the maximum programming attempts with a certain block index value + * \param[in] blockIndex Index value of the block to be retrieved + * \param[out] maxProgAttempts Maxmimum programming attempts of the respective block + * \return Possible return values: + * - kFblOk if maximum programming attempts could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockMaxProgAttemptsByIndex(tFblLbtBlockIndex blockIndex, + V_MEMRAM1 tFblLbtMaxProgAttempts V_MEMRAM2 V_MEMRAM3 * maxProgAttempts) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize maximum programming attempts to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.maxProgAttempts = 0u; + + if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk) + { + *maxProgAttempts = blockDescriptor.maxProgAttempts; + result = kFblOk; + } + + return result; +} +# endif /* FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS */ + +# if defined( FBL_LBT_ENABLE_VERIFY_INPUT ) +/*********************************************************************************************************************** + * FblLbtGetBlockVerifyInputFuncByIndex + **********************************************************************************************************************/ +/*! \brief Look up and return the verification function + * \param[in] blockIndex Index value of the block to be retrieved + * \param[out] blockVerifyFunc Address of the block specific verification function + * \return Possible return values: + * - kFblOk if verification function could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockVerifyInputFuncByIndex(tFblLbtBlockIndex blockIndex, + V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.verifyInput = (tExportFct)0; + + if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk) + { + *blockVerifyFunc = blockDescriptor.verifyInput; + result = kFblOk; + } + + return result; +} +# endif /* FBL_LBT_ENABLE_VERIFY_INPUT */ + +# if defined( FBL_LBT_ENABLE_VERIFY_PROCESSED ) +/*********************************************************************************************************************** + * FblLbtGetBlockVerifyProcessedFuncByIndex + **********************************************************************************************************************/ +/*! \brief Look up and return the verification function + * \param[in] blockIndex Index value of the block to be retrieved + * \param[out] blockVerifyFunc Address of the block specific verification function + * \return Possible return values: + * - kFblOk if verification function could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockVerifyProcessedFuncByIndex(tFblLbtBlockIndex blockIndex, + V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.verifyProcessed = (tExportFct)0; + + if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk) + { + *blockVerifyFunc = blockDescriptor.verifyProcessed; + result = kFblOk; + } + + return result; +} +# endif /* FBL_LBT_ENABLE_VERIFY_PROCESSED */ + +# if defined( FBL_LBT_ENABLE_VERIFY_PIPELINED ) +/*********************************************************************************************************************** + * FblLbtGetBlockVerifyPipelinedFuncByIndex + **********************************************************************************************************************/ +/*! \brief Look up and return the verification function + * \param[in] blockIndex Index value of the block to be retrieved + * \param[out] blockVerifyFunc Address of the block specific verification function + * \return Possible return values: + * - kFblOk if verification function could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockVerifyPipelinedFuncByIndex(tFblLbtBlockIndex blockIndex, + V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.verifyPipelined = (tExportFct)0; + + if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk) + { + *blockVerifyFunc = blockDescriptor.verifyPipelined; + result = kFblOk; + } + + return result; +} +# endif /* FBL_LBT_ENABLE_VERIFY_PIPELINED */ + +# if defined( FBL_LBT_ENABLE_VERIFY_OUTPUT ) +/*********************************************************************************************************************** + * FblLbtGetBlockVerifyOutputFuncByIndex + **********************************************************************************************************************/ +/*! \brief Look up and return the block header address with a certain block index value + * \param[in] blockIndex Index value of the block to be retrieved + * \param[out] blockVerifyFunc Address of the block specific verification function + * \return Possible return values: + * - kFblOk if verification function could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockVerifyOutputFuncByIndex(tFblLbtBlockIndex blockIndex, + V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc) +{ + tFblResult result = kFblFailed; + tBlockDescriptor blockDescriptor = {0}; + + /* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */ + blockDescriptor.verifyOutput = (tExportFct)0; + + if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk) + { + *blockVerifyFunc = blockDescriptor.verifyOutput; + result = kFblOk; + } + + return result; +} +# endif /* FBL_LBT_ENABLE_VERIFY_OUTPUT */ +#endif /* FBL_LBT_ENABLE_BLOCK_INDEX */ + +#if defined( FBL_LBT_ENABLE_FILE_NAME ) +/*********************************************************************************************************************** + * FblLbtGetBlockDescriptorByFilenameLength + **********************************************************************************************************************/ +/*! \brief Look up and return the block descriptor for a file name and length + * \param[in] fileName Name of the file + * \param[in] fileNameSize Size of the give file name +* \param[in] fileLength Length of the file to be downloaded + * \param[out] blockDescriptor Parameter structure with the information of the respective block + * \return Possible return values: + * - kFblOk if block descriptor could be retrieved successfully + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtGetBlockDescriptorByFilenameLength(const V_MEMRAM1 tFblLbtFileName V_MEMRAM2 V_MEMRAM3 * fileName, + tFblLbtFileNameSize fileNameSize, tFblLength fileLength, V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor) +{ + tFblResult result = kFblFailed; + tBlockDescriptor localBlockDescriptor = {0}; + tFblLbtBlockFilter blockFilter = {0}; + + /* Configure block filter (clear all filter settings) */ + FblLbtBlockFilterInit(&blockFilter); + + localBlockDescriptor = FblLbtBlockFirst(&blockFilter); + while ( FblLbtBlockDone() == FALSE ) + { + /* Check if file name exists for checked block and if file name size matches. + Also allow a length with one byte less to support strings without zero termination */ + if ((localBlockDescriptor.fileName != V_NULL) && + (localBlockDescriptor.fileNameSize > 0u) && + ((localBlockDescriptor.fileNameSize == fileNameSize) || + ((localBlockDescriptor.fileNameSize - 1u) == fileNameSize )) && + (localBlockDescriptor.blockLength >= fileLength)) + { + vuintx i; + + /* Compare file name */ + for (i = 0u; i < fileNameSize; i++) + { + if (fileName[i] != localBlockDescriptor.fileName[i]) + { + /* Missmatch detected -> File name is not equal */ + break; + } + } + + if (i == fileNameSize) + { + *blockDescriptor = localBlockDescriptor; + result = kFblOk; + break; + } + } + + localBlockDescriptor = FblLbtBlockNext(); + } + + return result; +} +#endif /* FBL_LBT_ENABLE_FILE_NAME */ + +/*********************************************************************************************************************** + * FblLbtCheckAddressRange + **********************************************************************************************************************/ +/*! \brief Check whether an address lies within a specified address range + * \param[in] address Address to be checked + * \param[in] rangeStart Start of range + * \param[in] rangeLength Length of range + * \return Possible return values: + * - kFblOk if address lies within range + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtCheckAddressRange(tFblAddress address, tFblAddress rangeStart, tFblLength rangeLength) +{ + tFblResult result = kFblFailed; + + if ( (address >= rangeStart) + && ((address - rangeStart) < rangeLength) ) + { + result = kFblOk; + } + + return result; +} + +/*********************************************************************************************************************** + * FblLbtCheckRangeContained + **********************************************************************************************************************/ +/*! \brief Check whether an address range lies within another specified address range + * \param[in] address Start address of range to be checked + * \param[in] length Length of range to be checked + * \param[in] rangeStart Start of range + * \param[in] rangeLength Length of range + * \return Possible return values: + * - kFblOk if range lies within range + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtCheckRangeContained(tFblAddress address, tFblLength length, tFblAddress rangeStart, tFblLength rangeLength) +{ + tFblResult result = kFblFailed; + + if ((FblLbtCheckAddressRange(address, rangeStart, rangeLength) == kFblOk) + && (length <= rangeLength) + && ((address - rangeStart) <= (rangeLength - length)) ) + { + result = kFblOk; + } + + return result; +} + +#if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) +/*********************************************************************************************************************** + * FblLbtCheckConsistency + **********************************************************************************************************************/ +/*! \brief Check consistency between the LBT which resides in the LBT block and the bootloader + * \return Possible return values: + * - kFblOk if the information in the new LBT is consistent with the bootloader + * - kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblLbtCheckConsistency(void) +{ + tFblResult result = kFblOk; + tFblLbtBlockNr localBlockNr = 0u; + tBlockDescriptor baseBlock = {0}; + tBlockDescriptor newBlock = {0}; + + /* Additional consistency checks should be performed by the generator which might be OEM/configuration specific, e.g.: + * - SBL and LBT block are unique and of type 'mandatory' + * - At least one logical block besides SBL/LBT is of type 'mandatory' + * - Block index of all blocks is unique + * - The configured logical blocks cover all blocks defined in the FBT + * - Block header address of all blocks lies inside the respective block area + * - Block header address has a reasonable distance from the presence pattern area + */ + + /* Temporarily switch to new LBT for consistency checks */ + FblLbtActivateLbtBlock(); + + /* Check if block count exceeds built-in maximum value */ + if (fblLbtActive->noOfBlocks > (tFblLbtBlockCount)FBL_LBT_BLOCK_COUNT) + { + result = kFblFailed; + } + + /* Check LBT against built-in FBT */ + if ((result == kFblOk) && (fblLbtActive->magicFlag != FblLogicalBlockTable.magicFlag)) + { + result = kFblFailed; + } + + /* Compare fixed blocks in built-in LBT against new LBT */ + if (result == kFblOk) + { + for (localBlockNr = 0u; localBlockNr < FblLogicalBlockTable.noOfBlocks; localBlockNr++) + { + baseBlock = FblLogicalBlockTable.logicalBlock[localBlockNr]; + result = FblLbtGetBlockDescriptorByNr(localBlockNr, &newBlock); + if (result == kFblOk) + { + result = FblLbtBlockCompare(&baseBlock, &newBlock); + } + if (result != kFblOk) + { + break; + } + } + } + + /* Check block type and verify functions against built-in values */ + if (result == kFblOk) + { + result = FblLbtCheckReferences(); + } + + /* Revert LBT pointer to built-in table */ + FblLbtInitPowerOn(); + + return result; +} + +/*********************************************************************************************************************** + * FblLbtActivateLbtBlock + **********************************************************************************************************************/ +/*! \brief Activate usage of the reprogrammable LBT + * \pre FblLbtCheckConsistency() has been executed with positive result + **********************************************************************************************************************/ +void FblLbtActivateLbtBlock(void) +{ + /* Switch to logical block table in LBT block */ +# if defined( FBL_LBT_ENABLE_RAM_BUFFER ) + FblLbtActivateLbtBlockByAddress(FblLogicalBlockTable.logicalBlock[FBL_MTAB_LBT_BLOCK_NUMBER].blockStartAddress); +# else + /* PRQA S 0306 1 */ /* MD_FblLib_Lbt_0306 */ + fblLbtActive = (V_MEMROM1 tLogicalBlockTable V_MEMROM2 V_MEMROM3 *)FblLogicalBlockTable.logicalBlock[FBL_MTAB_LBT_BLOCK_NUMBER].blockStartAddress; +# endif /* FBL_LBT_ENABLE_RAM_BUFFER */ +} +#endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ + +/*********************************************************************************************************************** + * FblLbtActivateLbtBlockByAddress + **********************************************************************************************************************/ +/*! \brief Activate usage of the reprogrammable LBT + * \details CAUTION: The function will set the internal LBT pointer without further consistency checks. It's in + * the responsibility of the caller to check the LBT consistency before accessing the contained + * information! + * \param[in] address Address of the logical block table, which should now be used + **********************************************************************************************************************/ +void FblLbtActivateLbtBlockByAddress(tFblAddress address) +{ + /* Switch to logical block table in LBT block */ +#if defined(FBL_LBT_ENABLE_RAM_BUFFER) + tFblLength readCount = FblReadProm(address, (vuint8*)&fblLbtRamBuffer, FBL_LBT_RAM_BUF_SIZE); + /* PRQA S 3205 1 */ /* MD_FblLib_Lbt_3205 */ + assertFbl(readCount == FBL_LBT_RAM_BUF_SIZE, kFblSysAssertParameterOutOfRange); +#else + /* PRQA S 0306 1 */ /* MD_FblLib_Lbt_0306 */ + fblLbtActive = (V_MEMROM1 tLogicalBlockTable V_MEMROM2 V_MEMROM3 *)address; +#endif /* FBL_LBT_ENABLE_RAM_BUFFER */ +} +#define FBLLBT_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* module specific MISRA deviations: + + MD_FblLib_Lbt_0306: + Reason: Address conversion between integer values and pointers is required to allow for hardware independent + configuration and address range checks. + Risk: The size of integer required to hold the result of a pointer cast is implementation-defined. + Prevention: The size of the respective integer data type which holds the address value is adapted on a hardware + specific basis. The correctness of the respective implementation is verified by runtime tests. + + MD_FblLib_Lbt_3205: + Reason: Depending on the configuration some variables are not referenced by the code. For simplicity the + variables are kept. + Risk: No identifiable risk. + Prevention: No prevention required. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_LBT_ACCESS.C + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_lbt_access.h b/Source/bsw/Fbl/fbl_lbt_access.h new file mode 100644 index 0000000..ba47823 --- /dev/null +++ b/Source/bsw/Fbl/fbl_lbt_access.h @@ -0,0 +1,190 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Interface layer for accessing the logical block table (LBT) + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2023 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2018-05-24 visci - Initial version + * 01.01.00 2018-11-27 visshs ESCAN00101459 Add Support for Secure Boot + * 01.02.00 2019-02-26 visrie ESCAN00102278 Added additional getter functions + * 01.02.01 2019-09-05 visrcn ESCAN00103604 Modified memory qualifiers + * 01.03.00 2022-03-31 visstn FBL-4366 Perform MISRA 2012 migration + * 01.04.00 2022-10-17 visjns FBL-4925 No changes + * 01.04.01 2023-04-24 vismix ESCAN00113819 No changes + * 01.05.00 2023-12-14 vistbe FBL-7967 Add new filename attribute for LBT + **********************************************************************************************************************/ + +#ifndef FBL_LBT_ACCESS_H +#define FBL_LBT_ACCESS_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblLib_Lbt CQComponent : Implementation */ +#define FBLLIB_LBT_VERSION 0x0105u +#define FBLLIB_LBT_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +/* Required due to usage of "boolean" type */ +#include "Platform_Types.h" + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +/** Settings for mandatoryType sub-filter */ +typedef struct +{ + tFblLbtMandatoryType value; + boolean enabled; +} tFblLbtMandatoryFilter; + +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) +/** Settings for blockType sub-filter */ +typedef struct +{ + tFblLbtBlockType value; + boolean enabled; +} tFblLbtTypeFilter; +#endif /* FBL_LBT_ENABLE_BLOCK_TYPE */ + +/** Global filter settings */ +typedef struct +{ + tFblLbtMandatoryFilter mandatoryType; +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) + tFblLbtTypeFilter blockType; +#endif +} tFblLbtBlockFilter; + +#define FBLLBT_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +void FblLbtInitPowerOn(void); + +/* Setter */ +void FblLbtBlockFilterInit(V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter); +void FblLbtBlockFilterSetMandatoryType(V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter, tFblLbtMandatoryType mandatoryType); +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) +void FblLbtBlockFilterSetBlockType(V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter, tFblLbtBlockType blockType); +#endif + +/* Getter */ +tFblLbtBlockCount FblLbtGetBlockCount(void); +tFblLbtMagicFlag FblLbtGetMagicFlag(void); +tFblResult FblLbtGetBlockNrByAddressLength(tFblAddress address, tFblLength length, V_MEMRAM1 tFblLbtBlockNr V_MEMRAM2 V_MEMRAM3 * blockNr); + +tFblResult FblLbtGetBlockDescriptorByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor); +tFblResult FblLbtGetBlockDescriptorByAddressLength(tFblAddress address, tFblLength length, V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor); +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) +tFblResult FblLbtGetBlockDescriptorByType(tFblLbtBlockType blockType, V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor); +#endif +#if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) +tFblResult FblLbtGetBlockTypeByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tFblLbtBlockType V_MEMRAM2 V_MEMRAM3 * blockType); +#endif +#if defined( FBL_LBT_ENABLE_BLOCK_INDEX ) +tFblResult FblLbtGetBlockIndexByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tFblLbtBlockIndex V_MEMRAM2 V_MEMRAM3 * blockIndex); +#endif +#if defined( FBL_LBT_ENABLE_HEADER_ADDRESS ) +tFblResult FblLbtGetBlockHeaderAddressByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * blockHeaderAddress); +#endif +#if defined( FBL_LBT_ENABLE_BM_HEADER_ADDRESS ) +tFblResult FblLbtGetBlockBmHeaderAddressByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * bmHeaderAddress); +#endif +#if defined( FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS ) +tFblResult FblLbtGetBlockMaxProgAttemptsByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tFblLbtMaxProgAttempts V_MEMRAM2 V_MEMRAM3 * maxProgAttempts); +#endif +#if defined( FBL_LBT_ENABLE_VERIFY_INPUT ) +tFblResult FblLbtGetBlockVerifyInputFuncByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc); +#endif +#if defined( FBL_LBT_ENABLE_VERIFY_PROCESSED ) +tFblResult FblLbtGetBlockVerifyProcessedFuncByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc); +#endif +#if defined( FBL_LBT_ENABLE_VERIFY_PIPELINED ) +tFblResult FblLbtGetBlockVerifyPipelinedFuncByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc); +#endif +#if defined( FBL_LBT_ENABLE_VERIFY_OUTPUT ) +tFblResult FblLbtGetBlockVerifyOutputFuncByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc); +#endif + +#if defined( FBL_LBT_ENABLE_BLOCK_INDEX ) +tFblResult FblLbtGetBlockDescriptorByIndex(tFblLbtBlockIndex blockIndex, V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor); +tFblResult FblLbtGetBlockNrByIndex(tFblLbtBlockIndex blockIndex, V_MEMRAM1 tFblLbtBlockNr V_MEMRAM2 V_MEMRAM3 * blockNr); +# if defined( FBL_LBT_ENABLE_BLOCK_TYPE ) +tFblResult FblLbtGetBlockTypeByIndex(tFblLbtBlockIndex blockIndex, V_MEMRAM1 tFblLbtBlockType V_MEMRAM2 V_MEMRAM3 * blockType); +# endif +# if defined( FBL_LBT_ENABLE_HEADER_ADDRESS ) +tFblResult FblLbtGetBlockHeaderAddressByIndex(tFblLbtBlockIndex blockIndex, V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * blockHeaderAddress); +# endif +# if defined( FBL_LBT_ENABLE_BM_HEADER_ADDRESS ) +tFblResult FblLbtGetBlockBmHeaderAddressByIndex(tFblLbtBlockIndex blockIndex, V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * bmHeaderAddress); +# endif +# if defined( FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS ) +tFblResult FblLbtGetBlockMaxProgAttemptsByIndex(tFblLbtBlockIndex blockIndex, V_MEMRAM1 tFblLbtMaxProgAttempts V_MEMRAM2 V_MEMRAM3 * maxProgAttempts); +# endif +# if defined( FBL_LBT_ENABLE_VERIFY_INPUT ) +tFblResult FblLbtGetBlockVerifyInputFuncByIndex(tFblLbtBlockIndex blockIndex, V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc); +# endif +# if defined( FBL_LBT_ENABLE_VERIFY_PROCESSED ) +tFblResult FblLbtGetBlockVerifyProcessedFuncByIndex(tFblLbtBlockIndex blockIndex, V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc); +# endif +# if defined( FBL_LBT_ENABLE_VERIFY_PIPELINED ) +tFblResult FblLbtGetBlockVerifyPipelinedFuncByIndex(tFblLbtBlockIndex blockIndex, V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc); +# endif +# if defined( FBL_LBT_ENABLE_VERIFY_OUTPUT ) +tFblResult FblLbtGetBlockVerifyOutputFuncByIndex(tFblLbtBlockIndex blockIndex, V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc); +# endif +#endif /* FBL_LBT_ENABLE_BLOCK_INDEX */ +#if defined( FBL_LBT_ENABLE_FILE_NAME ) +tFblResult FblLbtGetBlockDescriptorByFilenameLength(const V_MEMRAM1 tFblLbtFileName V_MEMRAM2 V_MEMRAM3 * fileName, + tFblLbtFileNameSize fileNameSize, tFblLength fileLength, V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor); +#endif /* FBL_LBT_ENABLE_FILE_NAME */ + +/* Iterator */ +tBlockDescriptor FblLbtBlockFirst(const V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter); +tBlockDescriptor FblLbtBlockNext(void); +boolean FblLbtBlockDone(void); + +/* Checker */ +tFblResult FblLbtCheckAddressRange(tFblAddress address, tFblAddress rangeStart, tFblLength rangeLength); +tFblResult FblLbtCheckRangeContained(tFblAddress address, tFblLength length, tFblAddress rangeStart, tFblLength rangeLength); + +#if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) +tFblResult FblLbtCheckConsistency(void); +void FblLbtActivateLbtBlock(void); +#endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ +void FblLbtActivateLbtBlockByAddress(tFblAddress address); + +#define FBLLBT_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBLLIB_LBT_ACCESS_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_LBT_ACCESS.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_main.c b/Source/bsw/Fbl/fbl_main.c new file mode 100644 index 0000000..36aa2cd --- /dev/null +++ b/Source/bsw/Fbl/fbl_main.c @@ -0,0 +1,603 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Main module of FBL + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2019-10-10 vistmo FBL-388 Adapt main function interface for vBaseEnv + * 05.01.00 2019-11-14 visrcn FBL-830 Add support for VTT use case + * 05.01.01 2020-02-27 vistbe ESCAN00105432 [DemoAppl] No diagnostic requests can be processed + * 06.00.00 2020-04-08 visrie FBL-1016 Support of EcuM functions, support of new FblSb interface + * 06.01.00 2020-04-29 vistmo FBL-1584 Adding OTA startup support + * 06.01.01 2020-10-28 visrcn ESCAN00107190 Compiler error: Wrong definition for FblMain function + * 06.01.02 2020-11-26 visrcn ESCAN00107979 Tester connection is not shutdown after StayInBoot check + * 06.02.00 2022-04-08 lhopfhauer FBL-4852 Add support for new swap API + * 06.03.00 2022-05-06 lhopfhauer FBL-5148 Encapsulate call of FblInterruptDisable + * 06.04.00 2022-07-06 fmenke FBL-5235 Use Pre Timer/Wd init as standard + * 06.05.00 2022-11-30 visrie FBL-6065 Encapsulate FblMain declaration + * 06.05.01 2023-04-06 lhopfhauer ESCAN00113532 [DemoAppl only] FblCwClrCheckForStartMsg is not cleared if Stay + * in Boot is enabled - DemoAppl is not responding + * 06.06.00 2023-05-24 fmenke FBL-7036 P2 timeout in tester after the programming session request + * 06.07.00 2025-06-18 vsarcmijo FBL-9710 Extend presence pattern to connect validity information + * ESCAN00116602 [DemoAppl only] Compiler error: FblCwClrCheckForStartMsg is not + * defined + * 06.08.00 2025-10-21 pharring FBL-11469 Set a state when FblRepeat is reached + **********************************************************************************************************************/ + +#define FBL_MAIN_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" + +#include "EcuM.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLMAIN_VERSION != 0x0608u ) || \ + ( FBLMAIN_RELEASE_VERSION != 0x00u ) +# error "Error in fbl_main.c: Source and header file are inconsistent!" +#endif + +#if ( FBLMAIN_VERSION != _FBL_MAIN_VERSION ) || \ + ( FBLMAIN_RELEASE_VERSION != _FBL_MAIN_RELEASE_VERSION) +# error "Error in fbl_main.c: Source and v_ver.h are inconsistent!" +#endif + +#if defined( _MICROSOFT_C_VTT_ ) +# define FBL_MAIN_ENABLE_VTT_USECASE +#endif /* _MICROSOFT_C_VTT_ */ + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#if !defined( FBL_BM_HEADER_ADDRESS ) +# define FBL_BM_HEADER_ADDRESS &FblBmHdrHeader +#endif /* FBL_BM_HEADER_ADDRESS */ + +/* FblStart feature */ +#if defined( FBL_ENABLE_FBL_START ) +# if !defined( FblStartReset ) +# define FblStartReset() ApplFblReset() +# endif +#endif /* FBL_ENABLE_FBL_START */ + +# if defined( FBL_ENABLE_STAY_IN_BOOT ) +# if !defined( kFblMainStartMessageDelay ) +# define kFblMainStartMessageDelay 20u /**< Start message delay default value: 20ms */ +# endif +# define kFblMainStartMessageReceived 0u /**< Indicates that a startup message has been received */ +# define kFblMainStartMessageTimeout 1u /**< No startup message has been received before timeout */ +# endif /* FBL_ENABLE_STAY_IN_BOOT */ + +/* Main state handling */ +#define FblMainSetStartFromReset() SetFblMainState( kFblMainStateStartFromReset ) +#define FblMainSetStartFromAppl() SetFblMainState( kFblMainStateStartFromAppl ) +#define FblMainSetStartFromXcp() SetFblMainState( kFblMainStateStartFromXcp ) +#define FblMainSetStartFromOta() SetFblMainState( kFblMainStateStartFromOta ) +#define FblMainSetApplicationValid() SetFblMainState( kFblMainStateApplicationValid ) +#define FblMainSetWaitStartMessage() { \ + SetFblMainState( kFblMainStateWaitStartMessage ); \ + startMessageDelay = kFblMainStartMessageDelay + 1u; \ + } +#define FblMainSetStartMessageReceived() SetFblMainState( kFblMainStateStartMessageReceived ) + +#define FblMainClrStartFromReset() ClrFblMainState( kFblMainStateStartFromReset ) +#define FblMainClrStartFromAppl() ClrFblMainState( kFblMainStateStartFromAppl ) +#define FblMainClrStartFromXcp() ClrFblMainState( kFblMainStateStartFromXcp ) +#define FblMainClrStartFromOta() ClrFblMainState( kFblMainStateStartFromOta ) +#define FblMainClrApplicationValid() ClrFblMainState( kFblMainStateApplicationValid ) +#define FblMainClrWaitStartMessage() ClrFblMainState( kFblMainStateWaitStartMessage ) +#define FblMainClrStartMessageReceived() ClrFblMainState( kFblMainStateStartMessageReceived ) + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +# define FBLHEADER_START_SEC_CONST +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/** FBL header data for access from application software */ +V_MEMROM0 V_MEMROM1 tFblHeader V_MEMROM2 FblHeader = /* PRQA S 1514 */ /* MD_FblMain_1514_FblHeader */ +{ + FBL_MAIN_HEADER_MAGIC_FLAG +# if defined( FBL_MTAB_NO_OF_BLOCKS ) + ,(tFblHeaderLogicalBlockTablePtr)(&FblLogicalBlockTable) + ,sizeof(FblLogicalBlockTable) +# else + ,V_NULL + ,0u +# endif +# if defined( FBL_ENABLE_COMMON_DATA ) + ,(tFblCommonDataPtr)(&fblCommonData) +# endif + ,FBL_BLOCK_START_ADDRESS + ,FBL_BLOCK_LENGTH + ,FBL_BM_HEADER_ADDRESS +}; +# define FBLHEADER_STOP_SEC_CONST +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define FBLMAIN_START_SEC_VAR +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ +# if defined( FBL_ENABLE_STAY_IN_BOOT ) +V_MEMRAM0 static V_MEMRAM1 vuint16 V_MEMRAM2 startMessageDelay; +# endif /* FBL_ENABLE_STAY_IN_BOOT */ + +V_MEMRAM0 V_MEMRAM1_NEAR tFblStateBitmap V_MEMRAM2_NEAR fblMainStates[FBL_STATE_INDEX(kFblMainNumberOfStates - 1u) + 1u]; + +#define FBLMAIN_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLMAIN_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +static void FblCheckProgrammingRequest(void); +# if defined( FBL_ENABLE_STAY_IN_BOOT ) +static void FblPostProcessStartMsg( vuintx startMsgResult ); +static void FblRepeatCheckForStartMsg(void); +# endif /* FBL_ENABLE_STAY_IN_BOOT */ + +static void FblInitPowerOn( void ); +static void FblInit( vuint8 initposition ); + +static void FblDeinit( void ); + +static void FblRepeat( void ); + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FblCheckProgrammingRequest + **********************************************************************************************************************/ +/*! \brief Evaluates the programming request flag and decides the next steps (e.g. stay in bootloader, check for + * stay-in-boot message or some SecureBoot specific operations). + **********************************************************************************************************************/ +static void FblCheckProgrammingRequest(void) +{ + /* Decide the next step of the Bootloader */ + switch (ApplFblExtProgRequest()) + { + case kProgRequest: + { + FblMainSetStartFromAppl(); + break; + } +# if defined( FBL_ENABLE_STAY_IN_BOOT ) + case kCheckStayInBootRequest: + { + /* Check for stay in boot message during startup */ + FblMainSetWaitStartMessage(); + break; + } +# endif /* FBL_ENABLE_STAY_IN_BOOT */ +# if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined ( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY ) + case kInitKeysRequest: /* Intentional fall through */ +# endif +# if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) + case kInitMacsRequest: /* Intentional fall through */ +# endif +# endif /* FBLBM_ENABLE_SECURE_BOOT */ + case kNoProgRequest: /* Intentional fall through */ + default: + { + /* Normal startup */ + FblMainSetStartFromReset(); + break; + } + } +} + +# if defined( FBL_ENABLE_STAY_IN_BOOT ) +/*********************************************************************************************************************** + * FblPostProcessStartMsg + **********************************************************************************************************************/ +/*! \brief Post-process result of start message reception + * \details This function post-processes the result of the startup message check - either + * the Bootloader is prepared or the application is started. + * \param[in] startMsgResult Indicates if a start message has been received or not + **********************************************************************************************************************/ +static void FblPostProcessStartMsg(vuintx startMsgResult) +{ + switch (startMsgResult) + { + case kFblMainStartMessageReceived: + { + FblMainSetStartMessageReceived(); + break; + } + case kFblMainStartMessageTimeout: + { +# if defined( FBL_NO_JSR_APPL ) +# else /* FBL_NO_JSR_APPL */ + /* Request shutdown from Com-Wrapper */ + FblCwShutdownRequest(kFblCwResetEcuRegularCase); + + while (!FblMainGetFblShutdownRequest()) + { + FblLookForWatchdogVoid(); + } + + FblDeinit(); + CallApplStart(); +# endif /* FBL_NO_JSR_APPL */ + break; + } + default: + { + assertFblInternal(0u, kFblSysAssertParameterOutOfRange); /* PRQA S 2741,4558 */ /* MD_FblMain_2741_4558 */ + break; + } + } +} +# endif /* FBL_ENABLE_STAY_IN_BOOT */ + +/*********************************************************************************************************************** + * FblInitPowerOn + **********************************************************************************************************************/ +/*! \brief Pre-initialization of Bootloader variables + * \details Initializes all variables needed to control the Bootloader + **********************************************************************************************************************/ +static void FblInitPowerOn(void) /* PRQA S 3006 */ /* MD_FblMain_3006 */ +{ + vuintx i; + +#if defined( FBL_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON ) + /* Disable global interrupt handling */ + FblInterruptDisable(); /* PRQA S 1006 */ /* MD_FblMain_1006 */ +#endif /* FBL_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON */ + +#if defined( FBL_MAIN_ENABLE_VTT_USECASE ) +#else + /* Check if bootloader header address is correctly configured in generation tool */ + /* PRQA S 0306 1 */ /* MD_FblMain_FblHeader */ + assertFblGen(FblHeaderLocal == FblHeaderTable, kFblSysAssertParameterOutOfRange); +#endif /* FBL_ENABLE_DEMOAPPL || FBL_MAIN_ENABLE_VTT_USECASE */ + + /* Initialization of main variables */ + for (i = 0u; i < (sizeof(fblMainStates) / sizeof(fblMainStates[0])); i++) + { + fblMainStates[i] = (tFblStateBitmap)0x00u; + } +# if defined( FBL_ENABLE_STAY_IN_BOOT ) + startMessageDelay = 0u; +# endif /* FBL_ENABLE_STAY_IN_BOOT */ + + /* Power on initialization of core modules */ + ClrWDInit(); + + FblDiagInitPowerOn(); + + MemDriver_InitPowerOn(); + /* Initialize intermediate access layer for LBT */ + FblLbtInitPowerOn(); + +#if defined( FBL_ENABLE_HARDWARE_SWAP ) + /* Initialize hardware swap module */ + FblSwapInitPowerOn(); +#endif + +# if defined( FBL_ENABLE_SECMOD_VECTOR ) + (void)SecM_InitPowerOn(V_NULL); +# endif /* FBL_ENABLE_SECMOD_VECTOR */ + +} + +/*********************************************************************************************************************** + * FblInit + **********************************************************************************************************************/ +/*! \brief Do initializations after reset or start out of application + **********************************************************************************************************************/ +/* PRQA S 6050 1 */ /* MD_MSR_STCAL */ +static void FblInit( vuint8 initposition ) +{ + /* User initialization before core initializations */ + ApplFblStartup(kFblInitPreCallback | initposition); /* PRQA S 2986 */ /* MD_FblMain_2986 */ + + switch (initposition) + { + /* Initialization steps the application validity is checked */ + case kFblInitBaseInitialization: + { + /* Initialize watchdog handling */ + FblInitWatchdog(); + /* Initialize Timer */ + FblTimerInit(); + break; + } + + /* Initialization steps after the application validity is checked */ + case kFblInitFblCommunication: + { + + EcuM_StartupTwo(); + + /* Initialize diagnostic module */ + FblDiagInit(); + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) + /* Initialize SecureBoot functionality */ + FblSb_Init(); +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) + /* Initialize extended presence pattern once */ + FblNvPatternSignedPresencePatternInit(); +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + break; + } + + /* Initialization steps executed after the Bootloader is invoked */ + case kFblInitFblFinalize: + { + + /* Diagnostic layer - init steps after NV-memory init */ + FblDiagPostInit(); + break; + } + + default: + { + assertFblInternal(0u, kFblSysAssertParameterOutOfRange); /* PRQA S 2741,4558 */ /* MD_FblMain_2741_4558 */ + break; + } + } + + /* User initialization after core initialization */ + ApplFblStartup(kFblInitPostCallback | initposition); +} + +/*********************************************************************************************************************** + * FblDeinit + **********************************************************************************************************************/ +/*! \brief Do necessary deinitializations + **********************************************************************************************************************/ +static void FblDeinit( void ) +{ + /* Deinitialize communication wrapper */ +# if( FBL_CW_API_REFERENCE_VERSION_MAJOR == 0x02u ) + FblCw_Deinit(); +# else + FblCwDeinit(); +# endif /* FBL_CW_API_REFERENCE_VERSION_MAJOR == 0x02u */ + +#if defined( FBL_WATCHDOG_ON ) + /* Synchronize watchdog before reset */ + ApplFblWDLong(); +#endif /* FBL_WATCHDOG_ON */ + FblTimerStopp(); /* PRQA S 0303 */ /* MD_FBL_0303_MemoryMappedRegAccess */ +} + +# if defined( FBL_ENABLE_STAY_IN_BOOT ) +/*********************************************************************************************************************** + * FblRepeatCheckForStartMsg + **********************************************************************************************************************/ +/*! \brief This function waits during the acceptance window if the start message is received. + * \pre Hardware has to be initialized. + **********************************************************************************************************************/ +static void FblRepeatCheckForStartMsg( void ) +{ + /* Set COM wrapper flag for start message window */ + FblCwSetCheckForStartMsg(); + while (FblMainGetWaitStartMessage()) + { + /* Check if 1ms hardware timer expired */ + if ((FblLookForWatchdog() & FBL_TM_TRIGGERED) == FBL_TM_TRIGGERED) + { + /* Handle timer each millisecond */ + startMessageDelay--; + if (startMessageDelay == 0u) + { + /* Start message wait time expired */ + FblMainClrWaitStartMessage(); + FblPostProcessStartMsg(kFblMainStartMessageTimeout); + } + } + + if (FblCwCheckStartMessage() == kFblOk) + { + /* Startup message has been received */ + FblMainClrWaitStartMessage(); + FblPostProcessStartMsg(kFblMainStartMessageReceived); + } + } + /* Start message window is closed now */ + FblCwClrCheckForStartMsg(); +} +# endif /* FBL_ENABLE_STAY_IN_BOOT */ + +/*********************************************************************************************************************** + * FblRepeat + **********************************************************************************************************************/ +/*! \brief This function contains the main loop of the FBL. + * \details In this loop, the Bus is polled and the watchdog is triggered. + * This function is used by the boot procedure for the start delay and for the real operation. + * \pre Hardware has to be initialized before. + * \return The return value is used by the boot procedure to determine whether to stay in FBL or start the appl. + **********************************************************************************************************************/ +static void FblRepeat( void ) +{ +#if defined( FBL_DIAG_ENABLE_CORE_ASYNC_ROUTINE ) + FblMainSetFblRepeatStarted(); +#endif /* FBL_DIAG_ENABLE_CORE_ASYNC_ROUTINE */ + + /* This loop will be left only for reset */ + while (!FblMainGetFblShutdownRequest()) + { + /* Check if 1ms hardware timer expired */ + if ((FblLookForWatchdog() & FBL_TM_TRIGGERED) == FBL_TM_TRIGGERED) + { + /* Run 1ms based tasks */ + FblDiagTimerTask(); + +#if defined( FBL_ENABLE_APPL_TIMER_TASK ) + /* Call cyclic function of fbl application module (if configured) */ + ApplFblTask(); +#endif /* FBL_ENABLE_APPL_TIMER_TASK */ + } + /* Run non-timer relevant operations */ + FblDiagStateTask(); + FblCwIdleTask(); + +# if defined( FBL_MEM_ENABLE_PIPELINING ) + if (FblMemTaskIsPending()) + { + FblMemTask(); + } +# endif /* FBL_MEM_ENABLE_PIPELINING */ + +#if defined( FBL_ENABLE_APPL_STATE_TASK ) + /* Call background function of fbl application module (if configured) */ + ApplFblStateTask(); +#endif /* FBL_ENABLE_APPL_STATE_TASK */ + + } +#if defined( FBL_DIAG_ENABLE_CORE_ASYNC_ROUTINE ) + FblMainClrFblRepeatStarted(); +#endif /* FBL_DIAG_ENABLE_CORE_ASYNC_ROUTINE */ +} + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FblMain + **********************************************************************************************************************/ +/*! \brief Wrapper function to call the actual FblMainInternal function + **********************************************************************************************************************/ +#if !defined( FBLBM_INSTANCE_BOOTMANAGER ) +void V_API_NEAR FblMain( void ) /* PRQA S 5209 */ /* MD_FblMain_5209 */ +{ + FblMainInternal(); +} +#endif /* !FBLBM_INSTANCE_BOOTMANAGER */ + +/*********************************************************************************************************************** + * FblMainInternal + **********************************************************************************************************************/ +/*! \brief Main function of the Bootloader. + * \details The FBL initializes the hardware and waits for a download request. + **********************************************************************************************************************/ +void V_API_NEAR FblMainInternal( void ) /* PRQA S 5209 */ /* MD_FblMain_5209 */ +{ + /* Initialize variables */ + FblInitPowerOn(); + + /* Base initialization step - valid for both application and Bootloader */ + FblInit(kFblInitBaseInitialization); + + /* Evaluate programming request flag and decide next bootloader step */ + FblCheckProgrammingRequest(); + + /* Bootloader initialization step 1 - hardware and basic communication */ + FblInit(kFblInitFblCommunication); +# if defined( FBL_ENABLE_STAY_IN_BOOT ) + /* Check for start message */ + FblRepeatCheckForStartMsg(); +# endif /* FBL_ENABLE_STAY_IN_BOOT */ + + + /* Bootloader initialization step 2 - full diagnostics initialization */ + FblInit(kFblInitFblFinalize); + + /* Bootloader execution */ + FblRepeat(); + + /* Deinitialize and reset bootloader */ + FblDeinit(); + ApplFblReset(); +} + +#define FBLMAIN_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_FBL_0303_MemoryMappedRegAccess: + Reason: Addressing memory mapped registers or other hardware specific feature requires casting a pointer type to + an integral type. This is a usual pattern for MCAL (Micro Controller Abstraction Layer) software. + Risk: Unintended read or write access into memory location. + Prevention: Code inspection focus on correct access to expected memory location. + + MD_FblMain_1006: + Reason: Assembler code is used to deactivate interrupts and set context information. + Risk: The code is not portable for different compilers. + Prevention: The assembler code provided by each FblHw module has to be tested. + + MD_FblMain_1514_FblHeader + Reason: MISRA: The object FblBmHeader is only referenced by function ..., in the translation unit where it is defined + This object is exported globally to other translation units + Risk: Name space pollution + Prevention: No Prevention necessary + + MD_FblMain_2741_4558: + Reason: Assertion macros have to be disabled in production code and are used only for development. + Risk: Assertion code may be enabled in production code unintentionally. If a assertion condition is unexpectedly + false, the code is active. A problem may occur if the Macro is additionally changed from single statement + to multiple statement. + Prevention: Macro is not allowed to be changed without review. Development code is automatically disabled via + configuration of project state "Production". + + MD_FblMain_2986: + Reason: This code is redundant but kept for clarity. + Risk: No risk. + Prevention: No prevention necessary. + + MD_FblMain_3006: + Reason: Assembler code is used to deactivate interrupts and set context information. + Risk: The code is not portable for different compilers. + Prevention: The assembler code provided by each FblHw module has to be tested. + + MD_FblMain_5209: + Reason: The Vector standard API for main function follows ANSI C typical definition of main function returning int. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblMain_FblHeader: + Reason: A memory address is compared to a configured value. The configured value is interpreted as an integer. + Risk: The comparison may fail due to different data types. + Prevention: If this check fails, the configuration checks done by assertions have to verified manually. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_MAIN.C + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_main.h b/Source/bsw/Fbl/fbl_main.h new file mode 100644 index 0000000..69cf91b --- /dev/null +++ b/Source/bsw/Fbl/fbl_main.h @@ -0,0 +1,180 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Main module of FBL + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2019-10-10 vistmo FBL-388 Adapt main function interface for vBaseEnv + * 05.01.00 2019-11-14 visrcn FBL-830 No changes + * 05.01.01 2020-02-27 vistbe ESCAN00105432 No changes + * 06.00.00 2020-04-08 visrie FBL-1016 No changes + * 06.01.00 2020-04-29 vistmo FBL-1584 Adding OTA startup support + * 06.01.01 2020-10-28 visrcn ESCAN00107190 Compiler error: Wrong definition for FblMain function + * 06.01.02 2020-11-26 visrcn ESCAN00107979 No changes + * 06.02.00 2022-04-08 lhopfhauer FBL-4852 No changes + * 06.03.00 2022-05-06 lhopfhauer FBL-5148 No changes + * 06.04.00 2022-07-06 fmenke FBL-5235 No changes + * 06.05.00 2022-11-30 visrie FBL-6065 Encapsulate FblMain declaration + * 06.05.01 2023-04-06 lhopfhauer ESCAN00113532 No changes + * 06.06.00 2023-05-24 fmenke FBL-7036 No changes + * 06.07.00 2025-06-18 vsarcmijo FBL-9710 Fix version defines + * ESCAN00116602 No changes + * 06.08.00 2025-10-21 pharring FBL-11469 Set a state when FblRepeat is reached + **********************************************************************************************************************/ + +#ifndef FBL_MAIN_H +#define FBL_MAIN_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_main_types.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblMain CQComponent : Implementation */ +#define FBLMAIN_VERSION 0x0608u +#define FBLMAIN_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + + +/*********************************************************************************************************************** + * Main state definitions + **********************************************************************************************************************/ +#define kFblMainStateStartFromReset 0u +#define kFblMainStateStartFromAppl 1u +#define kFblMainStateStartFromXcp 2u +#define kFblMainStateStartFromOta 3u +#define kFblMainStateApplicationValid 4u +#define kFblMainStateWaitStartMessage 5u +#define kFblMainStateStartMessageReceived 6u +#define kFblMainStateFblShutdownRequest 7u +#define kFblMainStateFblRepeatStarted 8u + +#define kFblMainNumberOfStates 9u + +/*********************************************************************************************************************** + * State handling framework + **********************************************************************************************************************/ +/* PRQA S 3453 3 */ /* MD_MSR_FctLikeMacro */ +#define GetFblMainState(state) FBL_STATE_TEST(fblMainStates, (state)) /**< Read fbl_main state bit */ +#define SetFblMainState(state) FBL_STATE_SET(fblMainStates, state) /**< Set fbl_main state bit */ +#define ClrFblMainState(state) FBL_STATE_CLR(fblMainStates, state) /**< Clear fbl_main state bit */ + +#define FblMainGetStartFromReset() GetFblMainState( kFblMainStateStartFromReset ) +#define FblMainGetStartFromAppl() GetFblMainState( kFblMainStateStartFromAppl ) +#define FblMainGetStartFromXcp() GetFblMainState( kFblMainStateStartFromXcp ) +#define FblMainGetStartFromOta() GetFblMainState( kFblMainStateStartFromOta ) +#define FblMainGetApplicationValid() GetFblMainState( kFblMainStateApplicationValid ) +#define FblMainGetWaitStartMessage() GetFblMainState( kFblMainStateWaitStartMessage ) +#define FblMainGetStartMessageReceived() GetFblMainState( kFblMainStateStartMessageReceived ) +#define FblMainGetFblShutdownRequest() GetFblMainState( kFblMainStateFblShutdownRequest ) +#define FblMainGetFblRepeatStarted() GetFblMainState( kFblMainStateFblRepeatStarted ) + +#define FblMainSetFblShutdownRequest() SetFblMainState( kFblMainStateFblShutdownRequest ) +#define FblMainClrFblShutdownRequest() ClrFblMainState( kFblMainStateFblShutdownRequest ) +#define FblSetShutdownRequest() FblMainSetFblShutdownRequest() + +#define FblMainSetFblRepeatStarted() SetFblMainState( kFblMainStateFblRepeatStarted ) +#define FblMainClrFblRepeatStarted() ClrFblMainState( kFblMainStateFblRepeatStarted ) + +/*********************************************************************************************************************** + * Initialization steps + **********************************************************************************************************************/ +#define kFblInitPowerOn 0x00u /**< Power-on initialization step */ +#define kFblInitBaseInitialization 0x01u /**< Init steps before application validity check */ +#define kFblInitFblCommunication 0x02u /**< Bootloader initialization first part - mainly communication */ +#define kFblInitFblFinalize 0x03u /**< Finalize Bootloader initialization if application isn't started */ + +#define kFblInitPreCallback 0x00u /**< Initialization callback before core init function */ +#define kFblInitPostCallback 0x80u /**< Initialization callback after core init function */ + +/*********************************************************************************************************************** +* COM WRAPPER COMPATIBILITY DEFINITIONS +**********************************************************************************************************************/ + +/* Define interface version for classic FblWrapperCom modules */ +# if !defined( FBL_CW_API_REFERENCE_VERSION_MAJOR ) +/** Major interface version identifies incompatible changes */ +# define FBL_CW_API_REFERENCE_VERSION_MAJOR 0x01u +/** Minor interface version identifies backward compatible changes */ +# define FBL_CW_API_REFERENCE_VERSION_MINOR 0x00u +/** Release interface version identifies cosmetic changes */ +# define FBL_CW_API_REFERENCE_VERSION_RELEASE 0x00u +# endif /* !defined FBL_CW_API_REFERENCE_VERSION_MAJOR */ + +# if !defined( FBL_CW_CFG_PTR ) +# define FBL_CW_CFG_PTR V_NULL +# endif /* !defined FBL_CW_CFG_PTR */ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBLMAIN_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +V_MEMRAM0 extern V_MEMRAM1_NEAR tFblStateBitmap V_MEMRAM2_NEAR fblMainStates[FBL_STATE_INDEX(kFblMainNumberOfStates - 1u) + 1u]; +# define FBLMAIN_STOP_SEC_VAR +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define FBLHEADER_START_SEC_CONST +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +V_MEMROM0 extern V_MEMROM1 tFblHeader V_MEMROM2 FblHeader; +# define FBLHEADER_STOP_SEC_CONST +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLMAIN_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if !defined( FBLBM_INSTANCE_BOOTMANAGER ) +void V_API_NEAR FblMain( void ); /* PRQA S 5209 */ /* MD_FblMain_5209 */ +#endif /* !FBLBM_INSTANCE_BOOTMANAGER */ +void V_API_NEAR FblMainInternal( void ); /* PRQA S 5209 */ /* MD_FblMain_5209 */ + +#define FBLMAIN_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * CONFIGURATION CHECKS + **********************************************************************************************************************/ +/* Check diagnostic task call cycle */ +# if defined( kDiagCallCycle ) +# if( kDiagCallCycle != 1u ) +# error "Diagnostic task call cycle has to be configured to 1ms." +# endif +# endif /* kDiagCallCycle */ + +#endif /* FBL_MAIN_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_MAIN.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_main_types.h b/Source/bsw/Fbl/fbl_main_types.h new file mode 100644 index 0000000..8c25a0e --- /dev/null +++ b/Source/bsw/Fbl/fbl_main_types.h @@ -0,0 +1,104 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Main module of FBL + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2019-10-10 vistmo FBL-388 No changes + * 05.01.00 2019-11-14 visrcn FBL-830 No changes + * 05.01.01 2020-02-27 vistbe ESCAN00105432 No changes + * 06.00.00 2020-04-08 visrie FBL-1016 No changes + * 06.01.00 2020-04-29 vistmo FBL-1584 No changes + * 06.01.01 2020-10-28 visrcn ESCAN00107190 No changes + * 06.01.02 2020-11-26 visrcn ESCAN00107979 No changes + * 06.02.00 2022-04-08 lhopfhauer FBL-4852 No changes + * 06.03.00 2022-05-06 lhopfhauer FBL-5148 No changes + * 06.04.00 2022-07-06 fmenke FBL-5235 No changes + * 06.05.00 2022-11-30 visrie FBL-6065 No changes + * 06.05.01 2023-04-06 lhopfhauer ESCAN00113532 No changes + * 06.06.00 2023-05-24 fmenke FBL-7036 No changes + * 06.07.00 2025-06-18 vsarcmijo FBL-9710 No changes + * ESCAN00116602 No changes + * 06.08.00 2025-10-21 pharring FBL-11469 No changes + **********************************************************************************************************************/ + +#ifndef FBL_MAIN_TYPES_H +#define FBL_MAIN_TYPES_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "bm_types.h" + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FblHeader access + **********************************************************************************************************************/ + +/* Define to access the FBL header structure */ +#define FblHeaderTable ((V_MEMROM1_FAR tFblHeader V_MEMROM2_FAR V_MEMROM3 *)(FBL_HEADER_ADDRESS)) +#define FblHeaderLocal ((V_MEMROM1_FAR tFblHeader V_MEMROM2_FAR V_MEMROM3 *)(&FblHeader)) + +/* Access macros for FblHeader elements for application */ +#if defined( FBL_ENABLE_COMMON_DATA ) +# define GetFblCommonDataPtr() (FblHeaderTable->pFblCommonData) +#endif + +#define FBL_MAIN_HEADER_MAGIC_FLAG 0x58462918u + +/*********************************************************************************************************************** + * TYPE DEFINITIONS + **********************************************************************************************************************/ + +#if defined( FBL_ENABLE_COMMON_DATA ) +/** Pointer to shared ROM constants */ +typedef V_MEMROM1_FAR void V_MEMROM2_FAR V_MEMROM3 * tFblCommonDataPtr; +#endif /* FBL_ENABLE_COMMON_DATA */ + +/** Pointer type to logical block table */ +typedef V_MEMROM1_FAR tLogicalBlockTable V_MEMROM2_FAR V_MEMROM3 * tFblHeaderLogicalBlockTablePtr; +/** Pointer type to BM header structure */ +typedef V_MEMROM1_FAR tFblBmHdrHeader V_MEMROM2_FAR V_MEMROM3 * tFblHeaderBmHeaderPtr; + +/** FBL header structure */ +typedef struct +{ + vuint32 magicFlag; + tFblHeaderLogicalBlockTablePtr pLogicalBlockTable; + tFblLength logicalBlockTableSize; +#if defined( FBL_ENABLE_COMMON_DATA ) + tFblCommonDataPtr pFblCommonData; /**< Common data structure - OEM dependent */ +#endif /* FBL_ENABLE_COMMON_DATA */ + tFblAddress fblStartAddress; + tFblLength fblLength; + tFblHeaderBmHeaderPtr bmHeader; +} tFblHeader; + +#endif /* FBL_MAIN_TYPES_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_MAIN_TYPES.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_mem.c b/Source/bsw/Fbl/fbl_mem.c new file mode 100644 index 0000000..20266b0 --- /dev/null +++ b/Source/bsw/Fbl/fbl_mem.c @@ -0,0 +1,6012 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Library containing common functionality for memory programming: + * - Erase of memory region + * - Data processing (e.g. decryption and decompression) + * - Segmentation and alignment + * - Signature / checksum verification over RAM and ROM contents + * - Pipelined programming + * + * Used by OEM dependent diagnostics to program incoming download data. + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2012-03-23 visjhg - Initial release + * 01.00.01 2012-03-26 visjhg - Added description to file header + * - Added unsigned qualifier to constants + * 01.01.00 2012-04-05 visjhg ESCAN00057963 Initialization of return value in segment end indication when + * remainder handling is disabled + * Changes and optimizations after code review + * 01.02.00 2012-04-27 visjhg ESCAN00058452 Added support for processed length + * ESCAN00058621 Added __ApplFblMemCopyBuffer + * 01.03.00 2012-06-22 visjhg ESCAN00059475 Restore preamble in segment end indication + * ESCAN00059477 Restore default preamble offset in segment end indication + * Disable remainder handling for volatile memory + * Check for potential buffer overflow in FblMemGetActiveBuffer + * 01.04.00 2013-02-01 visjhg ESCAN00064290 Extensions for multi processor systems (pass-through) + * Rework of block start indication interface + * Pass additional info in structure + * visjhg ESCAN00064292 Added block erase + * visjhg ESCAN00064296 Preamble length switchable at runtime + * visjhg ESCAN00064301 Added signature verification on ROM contents + * Rework of block verify interface + * Keep track of segment history (structure provided externally) + * Extended pass-through interface for BlockVerify to pass + * user-specific information + * visjhg ESCAN00061335 Accept buffer offsets differing from constant preamble length + * in data indication + * visjhg ESCAN00064333 Differentiate watchdog trigger w/ and w/o status + * visjhg ESCAN00061764 Rework of function return paths + * visjhg ESCAN00061814 Encapsulate FblMemQueuePrepend with FBL_ENABLE_DATA_PROCESSING + * visjhg ESCAN00064338 Added post handler for SegmentEndIndication + * visach ESCAN00062919 Adapted comments to use Doxygen + * visjhg ESCAN00064334 Added interface to remap error codes to OEM dependent value + * visjhg ESCAN00064339 Segmented data processing: data produced during one cycle may be + * smaller than buffer size + * visjhg ESCAN00064330 Explicit resume of suspended operation + * Added state "suspend pending" + * visjhg ESCAN00064343 Added support for multiple input sources + * visjhg ESCAN00064543 Release active buffer in case of failed processing + * visjhg ESCAN00064720 Replaced __ApplFblMemCheckDfi by __ApplFblMemIsDataProcessingRequired + * 01.05.00 2013-04-10 visjhg ESCAN00064871 Reserve space for remainder data to be programmed + * visjhg ESCAN00064890 Move processing queue handle to global context + * visjhg - Minor fixes + * visjhg ESCAN00065830 Encapsulate setting of gProgContext + * visjhg ESCAN00066375 Restore original data after programming padded buffer + * Relocate buffer offset or search matching input buffer + * visjhg ESCAN00066377 Encapsulate erase functionality + * visjhg ESCAN00066379 Added interface version compatibility check + * visjhg ESCAN00066380 Exported FblMemInit + * 01.06.00 2013-07-22 visase ESCAN00066743 Fixed compiler warning regarding gProgContext + * visjhg ESCAN00067433 Added FblMemDeinit + * visjhg ESCAN00068321 Force response pending for erase operation + * visjhg ESCAN00069161 Added pipelined verification + * Rework of block start and verify interface + * Changed processing queue from FIFO to priority queue + * Added jobs for finalization of data processing and remainder + * General refactoring + * visjhg ESCAN00069190 Rework suspend operation + * 01.07.00 2013-08-16 visjhg ESCAN00069507 Corrected input type of FblMemSetInteger + * visjhg ESCAN00069803 Enable/disable verification at run-time + * visjhg ESCAN00069781 Corrected net size of data processing buffer + * Added canary word to detect buffer overflows + * visjhg ESCAN00069797 Set low priority of data processing equal to input priority + * visjhg ESCAN00069843 Limit restoring of data after padding to segmented input use-case + * Use dedicated buffer to store temporary data + * 02.00.00 2013-12-12 visjhg ESCAN00069945 Encapsulate write finalization entry in gLengthLimits + * visjhg ESCAN00072568 Perform input verification initialization on first segment start + * visjhg ESCAN00071344 Processed length: Limit programming to area defined by block + * visjhg - Additional canary word in front of buffer + * visjhg ESCAN00072569 Raised major version to match API version + * visjhg ESCAN00072156 Encapsulation of FblMemGetSpecificRemainder + * visjhg ESCAN00072570 Removed encapsulation of gProgContext + * visjhg ESCAN00072631 Set programming state to pending in FblMemProgramBuffer + * 02.01.00 2014-03-12 visjhg ESCAN00073504 No changes + * visjhg ESCAN00074066 Explicitly resume operation for finalization of pipelined verification + * 02.02.00 2014-05-09 visjhg ESCAN00075225 Restore default input offset for RAM data + * visjhg - Remove explicit memory qualifiers from __ApplFblMemCopyBuffer + * 03.00.00 2015-03-03 visjhg ESCAN00076591 Added support for external stream output + * visjhg ESCAN00077689 Finalize data processing when remainder handling is disabled + * - Support combination of stream output and pipelined verification + * visjhg ESCAN00077891 Added job for handling of segment address (pipelined verification) + * visjhg ESCAN00081491 Added support for resumable programming + * visjhg ESCAN00081494 Added support for verification on processed input data + * visjhg ESCAN00081493 Added selective pipelined programming (forced flush when disabled) + * 03.01.00 2015-04-23 visjhg ESCAN00082572 Introduced job class for handling of pipelined queues + * visjhg ESCAN00082605 Added support for reporting of progress information + * visjhg ESCAN00082606 Added support for gap fill (requires ordered segments) + * 03.01.01 2015-04-27 visjhg ESCAN00082700 Removed assertion for consumed buffer in FblProcessJob + * 03.01.02 2015-05-27 visjhg ESCAN00083138 Reworked padding byte handling and gap fill calculations + * 03.01.03 2015-06-13 visjhg ESCAN00083358 Don't update position after hashing of segment address (pipelined verification) + * visjhg ESCAN00083390 Update buffer size of pipelined verification read jobs + * visjhg ESCAN00083391 Unconditionally unblock pipelined verification queue when + * FBL_MEM_ENABLE_VERIFY_PIPELINED_ADDRESS_LENGTH is enabled + * visjhg ESCAN00083392 Pass correct block length to output verification + * 03.02.00 2015-07-21 visjhg ESCAN00084101 Unconditionally limit write length for + * FBL_ENABLE_ADAPTIVE_DATA_TRANSFER_RCRRP + * visjhg ESCAN00084102 No changes + * 03.02.01 2015-08-19 visjhg ESCAN00084279 Re-initialize data processing on snapshot restoration + * visjhg ESCAN00084559 Clear write remainder on snapshot creation + * visjhg ESCAN00084560 Force finalization when programming unprocessed data + * 03.02.02 2015-09-04 visjhg ESCAN00084994 Postpone remainder handling after checkpoint indication + * 04.00.00 2015-09-17 visjhg ESCAN00085249 Support combination of input and processed verification + * visjhg ESCAN00085250 Run-time decision whether address and length info is included in verification + * visjhg ESCAN00085251 Pass external segment info to __ApplFblMemIsPipelinedProgrammingDisabled + * 04.01.00 2016-04-01 visjhg ESCAN00087997 Rx interrupt: Critical section around crucial accesses to programming state + * visjhg ESCAN00088935 Corrected segment info pointer passed to __ApplFblMemIsPipelinedProgrammingDisabled + * 04.02.00 2016-10-06 visjhg ESCAN00090120 Changed segmentIndex parameter of FblMemPrepareVerifyPipeJob to vuintx type + * vishrf ESCAN00091253 Change allowed state when all data has been processed within the + * last chunk of data + * 04.02.01 2017-05-31 visjhg ESCAN00094695 Explicitly align gRemainderBuffer + * visjhg ESCAN00095201 Limit data processing input to less than 64 kB + * visjhg ESCAN00095356 Disable length check in FblMemDataIndication when stream output is active + * 04.03.00 2017-07-26 visjhg ESCAN00095772 Disable remainder handling for processed input data + * visjhg ESCAN00095774 Added FblMemFlushInputData + * visjhg ESCAN00095683 Place FblMemResumeIndication in RAMCODE section + * visjhg ESCAN00096075 Re-initialize input verification routines on snapshot restoration + * 04.03.01 2017-08-07 visjhg ESCAN00096209 Only update running input data length when data is unprocessed + * 04.04.00 2018-08-22 visjhg ESCAN00100464 Only store segments in snapshot when BlockStartIndication was executed before + * visjhg ESCAN00097115 Increase gap fill buffer to maximum segment size when necessary + * visjhg ESCAN00100482 Added hook __ApplFblMemConditionCheck before and after memory operations + * 04.04.01 2018-09-25 visjhg ESCAN00100850 No changes + * 04.05.00 2018-11-30 visjhg ESCAN00101500 No changes + * 04.05.01 2019-01-23 visjhg ESCAN00101568 Update segment information for pass-through use-case + * 04.05.02 2019-08-20 vistbe ESCAN00103967 Reinitialization is not executed on slave instances of LibMem + * 04.05.03 2019-10-02 visrie ESCAN00104203 Fixed resumable pipelined verification + * 04.06.00 2019-10-29 vistmo FBL-813 Migration to MISRA 2012 + * 04.06.01 2020-03-18 visrie ESCAN00105683 Fixed pipelined verification handling + * 04.06.02 2020-05-11 visjdn ESCAN00105967 Fixed 0 length pipelined verification. + * 04.06.03 2020-07-03 vistmo ESCAN00106050 TransferData might be rejected + * 04.07.00 2021-04-12 lhopfhauer FBL-2187 Add support for Spec 1.3 + * Added/adapted MemMap sections + * 04.08.00 2021-06-11 visjdn FBL-3560 No changes + * 04.09.00 2021-07-09 lhopfhauer FBL-3442 Add option to avoid abortion of verification procedure in case of error + * Updated MISRA justifications + * 04.09.01 2021-11-05 lhopfhauer ESCAN00110663 Verification failure for flash driver download + * 04.10.00 2022-05-02 lhopfhauer FBL-5067 Support embedded signatures with processed verification + * 04.10.01 2022-08-03 fmenke ESCAN00112185 Wrong verification result may be returned if any verification fails + * 04.10.02 2023-05-08 lhopfhauer ESCAN00114573 Processed verification not working with embedded signatures/checksums + * 04.11.00 2023-08-04 visrie FBL-5709 Allow Input length verification in resumable + pipelined + * programming config + * 04.12.00 2023-09-04 vistmo FBL-7572 Allow processed verification in combination with stream output + * 04.12.01 2024-02-02 lhopfhauer ESCAN00116407 Out of bounds write access + * ESCAN00116408 Resume may not work + * ESCAN00116457 Assertion missing in FblMemGet/SetInteger + * 04.13.00 2025-09-16 pharring FBL-10120 Add support for FblLib_Logger + * 04.13.01 2025-11-07 aeller ESCAN00121551 Download may fail when decompression is invoked with pending metadata only byte + * ESCAN00121700 No changes + * 04.14.00 2025-11-25 fmenke FBL-11808 Support passthrough HSM update + **********************************************************************************************************************/ + +#define FBL_MEM_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" +#include "fbl_mem.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLLIB_MEM_VERSION != 0x0414u ) || \ + ( FBLLIB_MEM_RELEASE_VERSION != 0x00u ) +# error "Error in fbl_mem.c: Source and Header file are inconsistent!" +#endif + +#if ( FBLLIB_MEM_VERSION != _FBLLIB_MEM_VERSION ) || \ + ( FBLLIB_MEM_RELEASE_VERSION != _FBLLIB_MEM_RELEASE_VERSION ) +# error "Error in fbl_mem.c: Source and v_ver.h are inconsistent!" +#endif + +/* Interface version compatibility check */ +#if defined( FBL_MEM_API_REFERENCE_VERSION_MAJOR ) && \ + defined( FBL_MEM_API_REFERENCE_VERSION_MINOR ) +#else +# error "Error in fbl_mem.c: Interface version requirements not defined!" +#endif + +#if ( FBL_MEM_API_REFERENCE_VERSION_MAJOR != FBL_MEM_API_VERSION_MAJOR) || \ + ( FBL_MEM_API_REFERENCE_VERSION_MINOR > FBL_MEM_API_VERSION_MINOR) +# error "Error in fbl_mem.c: Interface version compatibility check failed!" +#endif + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/** Internal maximum segment size */ +#define FBL_MEM_SEGMENT_SIZE FBL_MAX_SEGMENT_SIZE + +/*-- Remap configuration switches--------------------------------------------*/ + +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) || \ + defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) +/** Input buffer changed after data indication: Store and restore preamble */ +# define FBL_MEM_ENABLE_PREAMBLE_HANDLING +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING || FBL_ENABLE_UNALIGNED_DATA_TRANSFER */ + +#if defined( FBL_ENABLE_DATA_PROCESSING ) || \ + defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) +/* No remainder handling necessary for single byte segments */ +# if ( FBL_MEM_SEGMENT_SIZE > 1u ) +/** Programming may result in remainder which has to be stored for next cycle */ +# define FBL_MEM_ENABLE_REMAINDER_HANDLING +# endif /* FBL_MEM_SEGMENT_SIZE > 1u */ +#endif /* FBL_ENABLE_DATA_PROCESSING || FBL_ENABLE_UNALIGNED_DATA_TRANSFER */ + +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) || \ + defined( FBL_ENABLE_ADAPTIVE_DATA_TRANSFER_RCRRP ) +/** Split buffer operations (write, data processing, verification and pass-through) into smaller pieces */ +# define FBL_MEM_ENABLE_SEGMENTATION +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING || FBL_ENABLE_ADAPTIVE_DATA_TRANSFER_RCRRP */ + +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) || \ + defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) +/** Keep track of running remaining length of input data */ +# define FBL_MEM_ENABLE_INPUT_LENGTH +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING || FBL_ENABLE_PROCESSED_DATA_LENGTH */ + +#if defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) && \ + defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +/** Allow use of any available input buffer and not only active one */ +# define FBL_MEM_ENABLE_VARYING_INPUT_BUFFER +#endif + +#if defined( FBL_MEM_WRITE_SEGMENTATION ) +#else +/** Set segmentation to default value */ +# define FBL_MEM_WRITE_SEGMENTATION (FBL_MEM_BUFFER_SIZE + FBL_MEM_SEGMENT_SIZE) +#endif /* FBL_MEM_WRITE_SEGMENTATION */ + +#if defined( FBL_ENABLE_DATA_PROCESSING ) +# if defined( FBL_MEM_ENABLE_SEGMENTATION ) +# define FBL_MEM_INTERNAL_PROC_SEGMENTATION FBL_MEM_PROC_SEGMENTATION +# if ( FBL_MEM_INTERNAL_PROC_SEGMENTATION == FBL_MEM_PROC_BUFFER_SIZE) +/* Segmented processing enabled, but data processing segmentation matches buffer size */ +# else +/* Split data processing into smaller pieces */ +# define FBL_MEM_ENABLE_PROC_SEGMENTATION +# endif +# else +/* Fill data processing buffer at once */ +# define FBL_MEM_INTERNAL_PROC_SEGMENTATION FBL_MEM_PROC_BUFFER_SIZE +# endif /* FBL_MEM_ENABLE_SEGMENTATION */ +# if defined( FBL_MEM_TRY_COUNTER_LIMIT_DATA_PROC ) +# else +/* Try counter limit for data processing to avoid endless loop */ +# define FBL_MEM_TRY_COUNTER_LIMIT_DATA_PROC 1u +# endif /* FBL_MEM_TRY_COUNTER_LIMIT_DATA_PROC */ +#endif /* FBL_ENABLE_DATA_PROCESSING */ + +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +/** Stream verification is active */ +# define FBL_MEM_ENABLE_VERIFY_STREAM +#endif /* FBL_MEM_ENABLE_VERIFY_INPUT | FBL_MEM_ENABLE_VERIFY_PROCESSED | FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +#if defined( FBL_MEM_ENABLE_VERIFY_STREAM ) || \ + defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) +/** Verification is active */ +# define FBL_MEM_ENABLE_VERIFICATION +#endif /* FBL_MEM_ENABLE_VERIFY_STREAM | FBL_MEM_ENABLE_VERIFY_OUTPUT */ + +#if defined( FBL_MEM_VERIFY_SEGMENTATION ) +# if defined( FBL_MEM_VERIFY_INPUT_SEGMENTATION ) +# else +/** Set input verification length to common segmentation length */ +# define FBL_MEM_VERIFY_INPUT_SEGMENTATION FBL_MEM_VERIFY_SEGMENTATION +# endif /* FBL_MEM_VERIFY_INPUT_SEGMENTATION */ +# if defined( FBL_MEM_VERIFY_PIPELINED_SEGMENTATION ) +# else +/** Set pipelined verification length to common segmentation length */ +# define FBL_MEM_VERIFY_PIPELINED_SEGMENTATION FBL_MEM_VERIFY_SEGMENTATION +# endif /* FBL_MEM_VERIFY_PIPELINED_SEGMENTATION */ +#endif /* FBL_MEM_VERIFY_SEGMENTATION */ + +#if defined( FBL_MEM_VERIFY_INPUT_SEGMENTATION ) +#else +/** Set input verification length to default value */ +# define FBL_MEM_VERIFY_INPUT_SEGMENTATION 64u +#endif /* FBL_MEM_VERIFY_INPUT_SEGMENTATION */ + +#if defined( FBL_MEM_VERIFY_PIPELINED_SEGMENTATION ) +#else +/** Set pipelined verification length to default value */ +# define FBL_MEM_VERIFY_PIPELINED_SEGMENTATION 64u +#endif /* FBL_MEM_VERIFY_PIPELINED_SEGMENTATION */ + +/** Response pending handling */ +# define FBL_MEM_ENABLE_RESPONSE_PENDING + +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +# if defined( FBL_MEM_ENABLE_SELECTIVE_PIPELINED_PROGRAMMING ) +# define FBL_MEM_ENABLE_INPUT_DATA_FLUSH +# endif /* FBL_MEM_ENABLE_SELECTIVE_PIPELINED_PROGRAMMING */ +#else +/** Flush input data in data indication function */ +# define FBL_MEM_ENABLE_INPUT_DATA_FLUSH +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + +#if defined( FBL_MEM_ENABLE_GAP_FILL ) +# if defined( FBL_MEM_GAP_FILL_SEGMENTATION ) +# else +/* Buffer size for gap fill function */ +# if defined( FBL_MEM_WRITE_SEGMENTATION ) +# if (FBL_MEM_SEGMENT_SIZE > FBL_MEM_WRITE_SEGMENTATION) +# define FBL_MEM_GAP_FILL_SEGMENTATION FBL_MEM_SEGMENT_SIZE +# else +# define FBL_MEM_GAP_FILL_SEGMENTATION FBL_MEM_WRITE_SEGMENTATION +# endif +# else +# define FBL_MEM_GAP_FILL_SEGMENTATION FBL_MEM_SEGMENT_SIZE +# endif /* FBL_MEM_WRITE_SEGMENTATION */ +# endif /* FBL_MEM_GAP_FILL_SEGMENTATION */ +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) +# if defined( FBL_MEM_PROGRESS_ERASE ) +# else +/** Progress percentage of erase operation */ +# define FBL_MEM_PROGRESS_ERASE 10u +# endif /* FBL_MEM_PROGRESS_ERASE */ +# if defined( FBL_MEM_PROGRESS_VERIFY ) +# else +/** Progress percentage of final verify operation */ +# define FBL_MEM_PROGRESS_VERIFY 10u +# endif /* FBL_MEM_PROGRESS_VERIFY */ +# if defined( FBL_MEM_PROGRESS_INITIAL ) +# else +/** Initial progress value of overall progress and partial progress */ +# define FBL_MEM_PROGRESS_INITIAL 0u +# endif /* FBL_MEM_PROGRESS_INITIAL */ +# if defined( FBL_MEM_PROGRESS_COMPLETE ) +# else +/** Final progress value of overall progress and partial progress */ +# define FBL_MEM_PROGRESS_COMPLETE 100u +# endif /* FBL_MEM_PROGRESS_COMPLETE */ +# if defined( FBL_MEM_PROGRESS_PROGRAM ) +# else +/** Progress percentage of program operation */ +# define FBL_MEM_PROGRESS_PROGRAM (FBL_MEM_PROGRESS_COMPLETE - FBL_MEM_PROGRESS_ERASE - FBL_MEM_PROGRESS_VERIFY) +# endif /* FBL_MEM_PROGRESS_PROGRAM */ +# if defined( FBL_MEM_PROGRESS_THRESHOLD_BYTES ) +# else +/** Threshold for consecutive calls to reporting callback (in bytes) */ +# define FBL_MEM_PROGRESS_THRESHOLD_BYTES 1024u +# endif /* FBL_MEM_PROGRESS_THRESHOLD_BYTES */ +# if defined( FBL_MEM_PROGRESS_THRESHOLD_PERCENTAGE ) +# else +/** Threshold for consecutive calls to reporting callback (in percentage points) */ +# define FBL_MEM_PROGRESS_THRESHOLD_PERCENTAGE 5u +# endif /* FBL_MEM_PROGRESS_THRESHOLD_PERCENTAGE */ +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + +/*-- Processing queue -------------------------------------------------------*/ +/* Number of input buffers */ +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +# if defined( FBL_MEM_PIPE_PROG_BUFFER_COUNT ) +/** Overwrite default value */ +# define FBL_MEM_QUEUE_ENTRIES_INPUT FBL_MEM_PIPE_PROG_BUFFER_COUNT +# else +/** Default value: Alternating input buffers */ +# define FBL_MEM_QUEUE_ENTRIES_INPUT 2u +# endif /* FBL_MEM_PIPE_PROG_BUFFER_COUNT */ +#else +/** Single buffer use-case */ +# define FBL_MEM_QUEUE_ENTRIES_INPUT 1u +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ +/** Actual buffer count + * Input queue shared amongst all input sources */ +#define FBL_MEM_BUFFER_COUNT_INPUT ((FBL_MEM_QUEUE_ENTRIES_INPUT + FBL_MEM_SOURCE_COUNT) - 1u) + +# define FBL_MEM_QUEUE_ENTRIES_VERIFY_INPUT 0u + +# define FBL_MEM_QUEUE_ENTRIES_VERIFY_PROCESSED 0u + +#if defined( FBL_ENABLE_DATA_PROCESSING ) +/** Reserve entries for write and finalization jobs */ +# define FBL_MEM_QUEUE_ENTRIES_DATA_PROC 2u +#else +# define FBL_MEM_QUEUE_ENTRIES_DATA_PROC 0u +#endif /* FBL_ENABLE_DATA_PROCESSING */ + +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) +/** Reserve entries for write and finalization jobs */ +# define FBL_MEM_QUEUE_ENTRIES_STREAM_OUTPUT 2u +#else +# define FBL_MEM_QUEUE_ENTRIES_STREAM_OUTPUT 0u +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ + +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) +/** Reserve entry for write remainder finalization + * Only added in case processing queue already used */ +# define FBL_MEM_QUEUE_ENTRIES_REMAINDER 1u +#else +# define FBL_MEM_QUEUE_ENTRIES_REMAINDER 0u +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + +# define FBL_MEM_QUEUE_ENTRIES_CHECKPOINT 0u + +#if defined( FBL_MEM_ENABLE_GAP_FILL ) +/** Reserve entry for gap fill */ +# define FBL_MEM_QUEUE_ENTRIES_GAP_FILL 1u +#else +# define FBL_MEM_QUEUE_ENTRIES_GAP_FILL 0u +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + +/** Total number of processing queue entries */ +#define FBL_MEM_QUEUE_ENTRIES_PROCESSING \ + ( FBL_MEM_QUEUE_ENTRIES_VERIFY_INPUT + FBL_MEM_QUEUE_ENTRIES_VERIFY_PROCESSED + FBL_MEM_QUEUE_ENTRIES_DATA_PROC \ + + FBL_MEM_QUEUE_ENTRIES_STREAM_OUTPUT + FBL_MEM_QUEUE_ENTRIES_INPUT + FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE \ + + FBL_MEM_QUEUE_ENTRIES_CHECKPOINT + FBL_MEM_QUEUE_ENTRIES_GAP_FILL ) + +#if ( FBL_MEM_QUEUE_ENTRIES_PROCESSING > 1u ) +/** Activate processing queue */ +# define FBL_MEM_ENABLE_PROC_QUEUE +/** Add remainder handling to processing queue */ +# define FBL_MEM_QUEUE_ENTRIES_TOTAL (FBL_MEM_QUEUE_ENTRIES_PROCESSING + FBL_MEM_QUEUE_ENTRIES_REMAINDER) +#else +/** Single buffer use-case: no processing queue required */ +# define FBL_MEM_DISABLE_PROC_QUEUE +#endif /* FBL_MEM_QUEUE_ENTRIES_PROCESSING > 1u */ + +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) +# if defined( FBL_MEM_ENABLE_PROC_QUEUE ) +# else +/** Update single write job to trigger remainder flush */ +# define FBL_MEM_ENABLE_REMAINDER_HANDLING_SINGLE_JOB +# endif /* FBL_MEM_ENABLE_PROC_QUEUE */ +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) +/* Processing queue specific */ + +/** Reserve two entries in data structure for explicit free and used head */ +# define FBL_MEM_RESERVED_QUEUE_ENTRIES 2u +/* Handles for free and used head */ +# define FBL_MEM_QUEUE_HANDLE_HEAD_USED 0u +# define FBL_MEM_QUEUE_HANDLE_HEAD_FREE 1u +/* Start handle for actual entries */ +# define FBL_MEM_QUEUE_HANDLE_ENTRY_OFFSET 2u + +/** Size of data structure for processing queue */ +# define FBL_MEM_QUEUE_SIZE_PROCESSING (FBL_MEM_RESERVED_QUEUE_ENTRIES + FBL_MEM_QUEUE_ENTRIES_TOTAL) +# if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +/** Size of data structure for pipelined programming queue */ +# define FBL_MEM_QUEUE_SIZE_PIPE_PROG (FBL_MEM_RESERVED_QUEUE_ENTRIES + FBL_MEM_QUEUE_ENTRIES_INPUT) +# endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +# define FBL_MEM_QUEUE_SIZE_PIPE_VERIFY (FBL_MEM_RESERVED_QUEUE_ENTRIES + FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE_READ) +# endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +/* + Access macros to check for empty queues + A queue is empty if the head references itself (cyclic double linked list) +*/ +# define FblMemQueueIsEmpty(queue) (FBL_MEM_QUEUE_HANDLE_HEAD_USED == (queue)[FBL_MEM_QUEUE_HANDLE_HEAD_USED].next) +# define FblMemQueueIsFull(queue) (FBL_MEM_QUEUE_HANDLE_HEAD_FREE == (queue)[FBL_MEM_QUEUE_HANDLE_HEAD_FREE].next) + +/* Access macros to get handle of first entry */ +# define FblMemQueueGetFirstUsedHandle(queue) ((queue)[FBL_MEM_QUEUE_HANDLE_HEAD_USED].next) +# define FblMemQueueGetLastUsedHandle(queue) ((queue)[FBL_MEM_QUEUE_HANDLE_HEAD_USED].prev) +# define FblMemQueueGetFirstFreeHandle(queue) ((queue)[FBL_MEM_QUEUE_HANDLE_HEAD_FREE].next) + +/** Access macro to entry using handle */ +# define FblMemQueueGetEntry(queue, handle) ((queue)[handle]) +/* Access macros to get first or last entry */ +# define FblMemQueueGetFirstUsedEntry(queue) (FblMemQueueGetEntry((queue), FblMemQueueGetFirstUsedHandle(queue))) +# define FblMemQueueGetLastUsedEntry(queue) (FblMemQueueGetEntry((queue), FblMemQueueGetLastUsedHandle(queue))) +# define FblMemQueueGetFirstFreeEntry(queue) (FblMemQueueGetEntry((queue), FblMemQueueGetFirstFreeHandle(queue))) +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ + +/* Default priorities for queue entries */ +# define FBL_MEM_QUEUE_PRIO_LOWEST 0x00u +# define FBL_MEM_QUEUE_PRIO_HIGHEST 0xFFu + +/** Null queue entry pointer */ +# define FBL_MEM_QUEUE_NULL ((V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 *)V_NULL) +/** Null job pointer */ +# define FBL_MEM_JOB_NULL ((V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 *)V_NULL) + +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +#else +/** Remap fill buffer for single input buffer use-case */ +# define FblMemGetPendingInputJob() (&FBL_MEM_INPUT_JOB[0]) +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + +/*-- Verification -----------------------------------------------------------*/ +/** Null verification status pointer */ +#define FBL_MEM_VERIFY_STATUS_NULL ((V_MEMRAM1 tFblMemVerifyStatus V_MEMRAM2 V_MEMRAM3 *)V_NULL) +#if defined( FBL_MEM_ENABLE_VERIFY_STREAM ) +/** Null input verification function pointer (use of 0 avoid cast from pointer to object) */ +# define FBL_MEM_VERIFY_FCT_INPUT_NULL ((tFblMemVerifyFctInput)0) +#endif /* FBL_MEM_ENABLE_VERIFY_STREAM */ +#if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) +/** Null input verification function pointer (use of 0 avoid cast from pointer to object) */ +# define FBL_MEM_VERIFY_FCT_OUTPUT_NULL ((tFblMemVerifyFctOutput)0) +#endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT */ + +/*-- Segment and platform alignment -----------------------------------------*/ + +/** Calculate remainder for given address range and segment size */ +#define FblMemGetRemainder(address, length, segSize) ((tFblLength)(((address) + (tFblAddress)(length)) & ((tFblAddress)(segSize) - 1u))) +/** Remainder for global segment size */ +#define FblMemGetGlobalRemainder(address, length) FblMemGetRemainder((address), (length), FBL_MEM_SEGMENT_SIZE) +/* Use global or device specific segment size for remainder determination? */ +# if defined( FBL_ENABLE_MULTIPLE_MEM_DEVICES ) && \ + defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) +# define FblMemGetWriteRemainder(address, length) FblMemGetSpecificRemainder((address), (length)) +# else +/** Only one device present, global remainder equals device specific remainder */ +# define FblMemGetWriteRemainder(address, length) FblMemGetGlobalRemainder((address), (length)) +# endif /* FBL_ENABLE_MULTIPLE_MEM_DEVICES || FBL_MEM_ENABLE_REMAINDER_HANDLING */ + +/* Buffer padding for potential write remainder */ +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) +/* Reserve space for remainder from previous cycle and one for buffer padding for last write */ +# define FBL_MEM_REMAINDER_PADDING (FBL_MEM_SEGMENT_SIZE - 1u) +/* Reserve space for buffer padding of last write */ +# define FBL_MEM_WRITE_PADDING (FBL_MEM_SEGMENT_SIZE - 1u) +#else +# define FBL_MEM_REMAINDER_PADDING 0u +# define FBL_MEM_WRITE_PADDING 0u +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + +#define FBL_MEM_TOTAL_PADDING (FBL_MEM_REMAINDER_PADDING + FBL_MEM_WRITE_PADDING) + +#if defined( FBL_ENABLE_SYSTEM_CHECK ) +/** Magic value of "canary" word used to detect buffer overflows (ASCII "Bird") */ +# define FBL_MEM_CANARY_VALUE 0x42697264uL +#endif /* FBL_ENABLE_SYSTEM_CHECK */ + +#if defined( C_CPUTYPE_32BIT ) || \ + defined( C_CPUTYPE_16BIT ) +# define FBL_MEM_PLATFORM_ALIGN 4u +# define FBL_MEM_PLATFORM_ALIGN_MASK 0x03u +#else /* C_CPUTYPE_8BIT */ +# define FBL_MEM_PLATFORM_ALIGN 1u +# define FBL_MEM_PLATFORM_ALIGN_MASK 0x00u +#endif /* C_CPUTYPE_32BIT || C_CPUTYPE_16BIT */ + +#if defined( FBL_ENABLE_SYSTEM_CHECK ) +/** Macro to generate basic data type including buffer alignment to platform requirements */ +# define FBL_MEM_ALIGNED_BUFFER_TYPE(size) \ + struct \ + { \ + /** Magic value of "canary" word used to detect buffer overflows */ \ + vuint32 canaryFront; \ + /** Reserve buffer for configured size and potential alignment */ \ + vuint8 data[size]; \ + /** Magic value of "canary" word used to detect buffer overflows */ \ + vuint32 canaryBack; \ + } +#else +/* Force alignment to 32 bit boundary (if required by platform) */ +# if defined( C_CPUTYPE_32BIT ) || \ + defined( C_CPUTYPE_16BIT ) +/** Macro to generate basic data type including buffer alignment to platform requirements */ +# define FBL_MEM_ALIGNED_BUFFER_TYPE(size) \ + struct \ + { \ + vuint32 alignDummy; \ + /** Reserve buffer for configured size and potential alignment */ \ + vuint8 data[size]; \ + } +# else /* C_CPUTYPE_8BIT */ +/** Macro to generate basic data type including buffer alignment to platform requirements */ +# define FBL_MEM_ALIGNED_BUFFER_TYPE(size) \ + struct \ + { \ + /** Reserve buffer for configured size and potential alignment */ \ + vuint8 data[size]; \ + } +# endif /* C_CPUTYPE_32BIT || C_CPUTYPE_16BIT */ +#endif /* FBL_ENABLE_SYSTEM_CHECK */ + +/** Round length up to next multiple of alignment */ +#define FBL_MEM_LENGTH_ALIGN(length, align) (((((length) - 1u) / (align)) + 1u) * (align)) + +/** Align space used by preamble to multiple of platform requirement */ +#define FBL_MEM_PREAMBLE_ALIGN(length) FBL_MEM_LENGTH_ALIGN((length), FBL_MEM_PLATFORM_ALIGN) +/** As preamble always lies within the actual buffer it can be subtracted from the total length */ +#define FBL_MEM_PREAMBLE_OFFSET(length) (FBL_MEM_PREAMBLE_ALIGN(length) - (length)) +/** Padded buffer size for input buffers (including maximum platform alignment) */ +#define FBL_MEM_PADDED_BUFFER_SIZE (FBL_MEM_BUFFER_SIZE + (FBL_MEM_PLATFORM_ALIGN - 1u) + FBL_MEM_TOTAL_PADDING) +#if defined( FBL_ENABLE_DATA_PROCESSING ) +/** Padded buffer size for data processing buffers */ +# define FBL_MEM_PADDED_PROC_BUFFER_SIZE (FBL_MEM_PROC_BUFFER_SIZE + FBL_MEM_TOTAL_PADDING) +#endif /* FBL_ENABLE_DATA_PROCESSING */ + +#if defined( FBL_MEM_ENABLE_MULTI_SOURCE ) +/** Dynamic input source */ +# define FBL_MEM_ACTIVE_SOURCE gActiveSource +#else +/** Fixed input source */ +# define FBL_MEM_ACTIVE_SOURCE 0u +# if defined( FBL_MEM_SOURCE_COUNT ) +# else +/** Set input source count if not already defined */ +# define FBL_MEM_SOURCE_COUNT 1u +# endif +#endif /* FBL_MEM_ENABLE_MULTI_SOURCE */ + +#if defined( FBL_MEM_ENABLE_DYNAMIC_PREAMBLE_LENGTH ) +/** Dynamic preamble length stored per input source */ +# define FBL_MEM_PREAMBLE_LENGTH gPreambleLength[FBL_MEM_ACTIVE_SOURCE] +#else +/** Fixed preamble length */ +# define FBL_MEM_PREAMBLE_LENGTH FBL_MEM_DEFAULT_PREAMBLE_LENGTH +#endif /* FBL_MEM_ENABLE_DYNAMIC_PREAMBLE_LENGTH */ + +/** Substitution macro to access input buffers depending on active input source */ +#define FBL_MEM_INPUT_JOB gInputJobs[FBL_MEM_ACTIVE_SOURCE] +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +/** Substitution macro to access pipelined programming queue depending on active input source */ +# define FBL_MEM_PIPE_PROG_QUEUE gPipeProgQueue[FBL_MEM_ACTIVE_SOURCE] +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + +/** Helper macro to get number of array entries */ +#define FBL_MEM_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + + +#if defined( FBL_MEM_ENABLE_SEGMENTATION ) || \ + defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +# if defined( FBL_ENABLE_ADAPTIVE_DATA_TRANSFER_RCRRP ) +/** Unconditionally limited for proper RCR-RP handling */ +# define FBL_MEM_FINALIZE_UNLIMITED_MODE kFblMemOperationMode_Unconditional +# else +/** Write complete remaining data at once during finalization */ +# define FBL_MEM_FINALIZE_UNLIMITED_MODE kFblMemOperationMode_Finalize +# endif /* FBL_ENABLE_ADAPTIVE_DATA_TRANSFER_RCRRP */ +#else +/** Do not limit input length, process complete buffer */ +# define FblMemLimitLength(inputLen, type, finalize) (inputLen) +#endif /* FBL_MEM_ENABLE_SEGMENTATION || FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +#if defined( __ApplFblMemCopyBuffer ) +#else +/* PRQA S 0602, 0603 2 */ /* MD_FblMem_0602_0603 */ +/** Copy input buffer to destination address */ +# define __ApplFblMemCopyBuffer(address, data, length) (void)MEMCPY((address), (data), (length)) +#endif /* __ApplFblMemCopyBuffer */ + +/** Null buffer pointer */ +# define FBL_MEM_BUFFER_NULL ((tFblMemRamData)V_NULL) + +/*-- Indication function order ----------------------------------------------*/ +/* + Allowed indication order: + + Init(PowerOn) + | + +-------->+--------+ + | V | + | +-> BlockErase | + | +-------+ | + | V | + | BlockStart <-+ + | | + | V + | SegmentStart <-+ + | | | + | V | + | +-> Data | + | +-----+ | + | V | + | SegmentEnd | + | +---------+ + | V + | BlockEnd + | | + | V + | BlockVerify <-+ + | | | + +---------+--------+ +*/ + +/* Bitmasks for allowed states */ +#define FBL_MEM_ALLOWED_NONE 0x00u +#define FBL_MEM_ALLOWED_BLOCK_START 0x01u +#define FBL_MEM_ALLOWED_SEGMENT_START 0x02u +#define FBL_MEM_ALLOWED_DATA_IND 0x04u +#define FBL_MEM_ALLOWED_SEGMENT_END 0x08u +#define FBL_MEM_ALLOWED_BLOCK_END 0x10u +#define FBL_MEM_ALLOWED_BLOCK_VERIFY 0x20u +#define FBL_MEM_ALLOWED_BLOCK_ERASE 0x40u + +/* Access macros for handling of allowed states */ +/** Reset all states */ +#define FblMemResetAllowed() FblMemSetAllowed(FBL_MEM_ALLOWED_NONE) +/** Set states according to bitmask (overwriting previous settings) */ +# define FblMemSetAllowed(mask) (gAllowedInd = (tFblMemAllowedInd)(mask)) +/** Add states according to bitmask (previous settings unchanged) */ +# define FblMemAddAllowed(mask) (gAllowedInd |= (tFblMemAllowedInd)(mask)) +/** Clear states according to bitmask */ +#define FblMemClrAllowed(mask) (gAllowedInd &= FblInvertBits(mask, tFblMemAllowedInd)) +/** Check for required states against bitmask */ +#define FblMemIsAllowed(mask) ((gAllowedInd & (tFblMemAllowedInd)(mask)) == (tFblMemAllowedInd)(mask)) +/** Check if any of the required states is currently allowed */ +#define FblMemIsAnyAllowed(mask) ((gAllowedInd & (tFblMemAllowedInd)(mask)) != (tFblMemAllowedInd)(FBL_MEM_ALLOWED_NONE)) + +/*-- Error handling ---------------------------------------------------------*/ +/** Dummy value for errors without extended status */ +#define FBL_MEM_EXT_STATUS_NONE 0x00u +/** Remap errors without extended status to common macro */ +#define FBL_MEM_SET_STATUS(status, var) FBL_MEM_SET_EXT_STATUS(status, FBL_MEM_EXT_STATUS_NONE, var) +/* Extended status configured? */ +#if defined( FBL_MEM_ENABLE_EXT_STATUS ) +# define FBL_MEM_SET_EXT_STATUS(status, ext, var) { \ + FBL_MEM_EXT_STATUS_ ## status(ext); \ + (var) = kFblMemStatus_ ## status; \ + } +/* Pass extended info without setting error code */ +# define FBL_MEM_SET_EXT_INFO(type, info) FBL_MEM_EXT_STATUS_ ## type(info) /* PRQA S 0342 */ /* MD_MSR_Rule20.10_0342 */ +#else +/* Set error code, no extended status */ +# define FBL_MEM_SET_EXT_STATUS(status, ext, var) (var) = kFblMemStatus_ ## status /* PRQA S 0342 */ /* MD_MSR_Rule20.10_0342 */ +# define FBL_MEM_SET_EXT_INFO(type, info) +#endif /* FBL_MEM_ENABLE_EXT_STATUS */ + + +/** Assertion codes */ +#define kFblMemAssertParameterOutOfRange 0x01u +#define kFblMemAssertUserResultOutOfRange 0x02u + +/*-- Critical sections ------------------------------------------------------*/ +/* Allow override in configuration */ +#if defined( __ApplFblMemEnterCriticalSection ) +#else +/** Enter critical section: Do nothing in default configuration */ +# define __ApplFblMemEnterCriticalSection() /* PRQA S 0602, 0603 */ /* MD_FblMem_0602_0603 */ +#endif /* __ApplFblMemEnterCriticalSection */ + +/* Allow override in configuration */ +#if defined( __ApplFblMemLeaveCriticalSection ) +#else +/** Leave critical section: Do nothing in default configuration */ +# define __ApplFblMemLeaveCriticalSection() /* PRQA S 0602, 0603 */ /* MD_FblMem_0602_0603 */ +#endif /* __ApplFblMemLeaveCriticalSection */ + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +/*-- Indication function order ----------------------------------------------*/ +/** States for indication order */ +typedef vuintx tFblMemAllowedInd; + +/*-- Buffer handling --------------------------------------------------------*/ +/** Job types */ +typedef enum +{ + kFblMemJobType_InputWrite = 0u /**< Input buffer, write through without any data processing */ +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + , kFblMemJobType_WriteFinalize /**< Trigger programming of write remainder */ +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ +#if defined( FBL_ENABLE_DATA_PROCESSING ) + , kFblMemJobType_ProcInput /**< Input buffer, process data before writing */ + , kFblMemJobType_ProcWrite /**< Write buffer for processed data */ + , kFblMemJobType_ProcFinalize /**< Trigger for data processing finalization */ +#endif /* FBL_ENABLE_DATA_PROCESSING */ +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +# if defined( FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH ) + , kFblMemJobType_VerifyPipeInfo /**< Update pipelined verification hash with segment information */ +# endif /* FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH */ + , kFblMemJobType_VerifyPipeRead /**< Read back data already programmed for pipelined verification */ + , kFblMemJobType_VerifyPipeUpdate /**< Update pipelined verification hash */ + , kFblMemJobType_VerifyPipeFinalize /**< Trigger finalization of pipelined verification */ +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + , kFblMemJobType_StreamInput /**< Input buffer, pass to stream output */ + , kFblMemJobType_StreamProc /**< Pass processed data to stream output */ + , kFblMemJobType_StreamFinalize /**< Trigger for data processing finalization */ +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + , kFblMemJobType_GapFill /**< Fill gaps between programmed segments */ +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + , kFblMemJobType_Max +} tFblMemJobType; + +/** Job class, initiate special handling on completion */ +#if defined( FBL_MEM_ENABLE_PIPELINING ) +typedef enum +{ + tFblMemJobClass_Default /**< Default job, no special handling required */ +# if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) + , tFblMemJobClass_PipeProg /**< Pipelined programming job */ +# endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + , tFblMemJobClass_VerifyPipe /**< Pipelined verification job */ +# endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ +} tFblMemJobClass; +#endif /* FBL_MEM_ENABLE_PIPELINING */ + +/** Flag to indicate finalization to subfunction */ +typedef enum +{ + kFblMemOperationMode_Normal = 0u, /**< Normal operation, job complete as soon as "used" member reaches zero */ + kFblMemOperationMode_Finalize, /**< Finalize operation */ + kFblMemOperationMode_Unconditional /**< Job unconditionally completed after first run */ +} tFblMemOperationMode; + +/** Aligned input buffer type */ +typedef FBL_MEM_ALIGNED_BUFFER_TYPE(FBL_MEM_PADDED_BUFFER_SIZE) tFblMemInputBuffer; +#if defined( FBL_ENABLE_DATA_PROCESSING ) +/** Aligned buffer type for data processing */ +typedef FBL_MEM_ALIGNED_BUFFER_TYPE(FBL_MEM_PADDED_PROC_BUFFER_SIZE) tFblMemProcBuffer; +#endif /* FBL_ENABLE_DATA_PROCESSING */ +#if defined( FBL_MEM_ENABLE_GAP_FILL ) +/** Aligned buffer type for gap fill */ +typedef FBL_MEM_ALIGNED_BUFFER_TYPE(FBL_MEM_GAP_FILL_SEGMENTATION) tFblMemGapFillBuffer; +#endif /* FBL_MEM_ENABLE_GAP_FILL */ +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) +/** Aligned buffer type for remainder handling */ +typedef FBL_MEM_ALIGNED_BUFFER_TYPE(FBL_MEM_SEGMENT_SIZE) tFblMemRemainderBuffer; +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + +/** Job information */ +typedef struct +{ + tFblMemRamData buffer; /**< Pointer to referenced buffer */ + tFblLength totalSize; /**< Total size of referenced buffer */ + tFblLength netSize; /**< Size actually usable for input data */ + tFblLength offset; /**< Offset of actual buffer content */ + tFblLength position; /**< Current position in buffer */ + tFblLength used; /**< Current data length */ +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) || \ + defined( FBL_MEM_ENABLE_GAP_FILL ) + tFblAddress baseAddress; /**< Memory base address */ +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED || FBL_MEM_ENABLE_RESUMABLE_PROGRAMMING || FBL_MEM_ENABLE_GAP_FILL */ + tFblMemJobType type; /**< Job type */ + tFblMemOperationMode completion; /**< Handling of job completion */ + vuintx segmentIndex; /**< Index of segment associated with job */ +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ +#if defined( FBL_MEM_ENABLE_PIPELINING ) + tFblMemJobClass jobClass; /**< Job class, initiate special handling on completion */ +#endif /* FBL_MEM_ENABLE_PIPELINING */ +} tFblMemJob; + +/** Module internal segment information */ +typedef struct +{ + tFblMemSegmentInfo input; /**< Input segment information */ + /* Internal attributes */ + tFblAddress writeAddress; /**< Current address */ + tFblLength writeRemainder; /**< Unwritten remainder */ + tFblLength writeLength; /**< Remaining length */ +#if defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) + tFblLength writtenLength; /**< Total written length */ +#endif /* FBL_ENABLE_PROCESSED_DATA_LENGTH */ +#if defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) + tFblLength inputAddress; /**< Running address of input data */ +#endif /* FBL_ENABLE_UNALIGNED_DATA_TRANSFER */ +#if defined( FBL_MEM_ENABLE_INPUT_LENGTH ) + tFblLength inputLength; /**< Running remaining length of input data */ +#endif /* FBL_MEM_ENABLE_INPUT_LENGTH */ +#if defined( FBL_ENABLE_DATA_PROCESSING ) || \ + defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) || \ + defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + tFblMemJobType jobType; /**< Remember input job types */ +#endif /* FBL_ENABLE_DATA_PROCESSING || FBL_MEM_ENABLE_STREAM_OUTPUT || FBL_MEM_ENABLE_PASSTHROUGH || FBL_MEM_ENABLE_REMAINDER_HANDLING */ + vuintx ownIndex; /**< Index of segment */ + vuintx nextIndex; /**< Index of next segment */ +} tFblMemSegmentInternal; + +/*-- Processing queue -------------------------------------------------------*/ +/** Priority of queue entry */ +typedef vuint8 tFblMemQueuePrio; + +/** Job priorities */ +/* PRQA S 0724 TAG_FblMem_0724 */ /* MD_FblMem_0724_EnumValNotUnique */ +typedef enum +{ + /* PRQA S 3205 1 */ /* MD_FblMem_3205_IdentifierNotUsed */ + kFblMemJobPrio_Lowest = FBL_MEM_QUEUE_PRIO_LOWEST, /**< Lowest job priority */ +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + kFblMemJobPrio_VerifyPipeFinalize, /**< Finalization of pipelined verification */ + kFblMemJobPrio_VerifyPipeInput, /**< Not actually used, but acts as a common priority + * for all pipelined verification jobs which + * generate input data for update job */ +# if defined( FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH ) + kFblMemJobPrio_VerifyPipeInfo = kFblMemJobPrio_VerifyPipeInput, /**< Pipelined verification segment information */ +# endif /* FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH */ + kFblMemJobPrio_VerifyPipeRead = kFblMemJobPrio_VerifyPipeInput, /**< Pipelined verification read */ + kFblMemJobPrio_VerifyPipeUpdate, /**< Pipelined verification update */ +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + kFblMemJobPrio_Write, /**< Helper entry for flushing of all pending write jobs */ +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + kFblMemJobPrio_GapFill, /**< Fill gaps between programmed segments */ +#endif /* FBL_MEM_ENABLE_GAP_FILL */ +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + /* PRQA S 3205 1 */ /* MD_FblMem_3205_IdentifierNotUsed */ + kFblMemJobPrio_WriteFinalize, /**< Finalize remainder write */ +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ +#if defined( FBL_ENABLE_DATA_PROCESSING ) + kFblMemJobPrio_ProcFinalize, /**< Finalization of data processing */ +#endif /* FBL_ENABLE_DATA_PROCESSING */ +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + kFblMemJobPrio_StreamFinalize, /**< Finalization of stream output */ +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ + kFblMemJobPrio_Input, /**< Not actually used, but acts as a common priority + * for all input jobs */ + /* PRQA S 3205 1 */ /* MD_FblMem_3205_IdentifierNotUsed */ + kFblMemJobPrio_InputWrite = kFblMemJobPrio_Input, /**< Input: Write through */ +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + /* PRQA S 3205 2 */ /* MD_FblMem_3205_IdentifierNotUsed */ + kFblMemJobPrio_StreamInput = kFblMemJobPrio_Input, /**< Input: Stream output */ + kFblMemJobPrio_StreamProcLow = kFblMemJobPrio_Input, /**< Stream output of processed data, low priority + * used when processing is split into smaller pieces + * Prevent overtaking by following input jobs */ +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ +#if defined( FBL_ENABLE_DATA_PROCESSING ) + kFblMemJobPrio_ProcInput = kFblMemJobPrio_Input, /**< Input: Data processing */ + /* PRQA S 3205 1 */ /* MD_FblMem_3205_IdentifierNotUsed */ + kFblMemJobPrio_ProcWriteLow = kFblMemJobPrio_Input, /**< Write operation of data processing, low priority + * used when processing is split into smaller pieces + * Prevent overtaking by following input jobs */ + kFblMemJobPrio_ProcWriteHigh, /**< Write operation of data processing, high priority + * used to flush buffer */ +#endif /* FBL_ENABLE_DATA_PROCESSING */ +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + /* PRQA S 3205 1 */ /* MD_FblMem_3205_IdentifierNotUsed */ + kFblMemJobPrio_StreamProcHigh, /**< Stream output of processed data, high priority + * used to flush buffer */ +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ + /* PRQA S 3205 1 */ /* MD_FblMem_3205_IdentifierNotUsed */ + kFblMemJobPrio_Highest = FBL_MEM_QUEUE_PRIO_HIGHEST /**< Highest job priority */ +} tFblMemJobPrio; /* PRQA S 3205 */ /* MD_FblMem_3205_IdentifierNotUsed */ +/* PRQA L:TAG_FblMem_0724 */ + +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) +/** Handle for queue entry */ +typedef vuintx tFblMemQueueHandle; + +/** Queue entry */ +typedef struct +{ + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * job; /**< Associated job */ + tFblMemQueuePrio prio; /**< Entry priority */ + tFblMemQueueHandle prev; /**< Handle of previous queue entry */ + tFblMemQueueHandle next; /**< Handle of next queue entry */ +} tFblMemQueueEntry; +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ + +#if defined( FBL_MEM_ENABLE_SEGMENTATION ) || \ + defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +/** Limitation of processed length per cycle */ +typedef struct +{ + tFblLength limit; /**< Length limit, 0 equals unlimited */ + tFblMemOperationMode unlimitedMode; /**< Operation mode which returns unlimited length */ +} tFblMemLengthLimit; +#endif /* FBL_MEM_ENABLE_SEGMENTATION || FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +/*-- Pipelined programming --------------------------------------------------*/ +#if defined( FBL_MEM_ENABLE_PIPELINING ) +/* + Context of active programming operation + Generation of RCR-RP message only applicable in service context + Otherwise service dispatching may not be in a state where RCR-RP is allowed +*/ +typedef enum +{ + kFblMemContext_Service = 0u, /**< Programming directly initiated by service dispatcher */ + kFblMemContext_Background /**< Background programming while data transfer is in progress */ +} tFblMemContext; +#endif /* FBL_MEM_ENABLE_PIPELINING */ + +/*-- Progress information ---------------------------------------------------*/ +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) +/** Progress reporting state */ +typedef enum +{ + kFblMemProgressState_Disabled, /**< Disable progress reporting */ + kFblMemProgressState_Enabled /**< Enable progress reporting */ +} tFblMemProgressState; + +/** Internal progress information */ +typedef struct +{ + vuint32 target; /**< Expected maximum value of partial operation in arbitrary unit (e.g. bytes) */ + vuint8 totalOffset; /**< Percentage offset of total operation for current operation type */ + vuint8 totalPercentage; /**< Percentage contribution to total operation of current operation type */ +} tFblMemProgressInfoInternal; +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + +/*-- Resumable programming --------------------------------------------------*/ + +/*-- Error handling ---------------------------------------------------------*/ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBLLIB_MEM_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/** State of programming operation */ +V_MEMRAM0 V_MEMRAM1 tFblMemProgState V_MEMRAM2 fblMemProgState; + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +/* PRQA S 3218 TAG_FblMem_3218 */ /* MD_FblMem_3218 */ + +/** States for indication order */ +V_MEMRAM0 static V_MEMRAM1 tFblMemAllowedInd V_MEMRAM2 gAllowedInd; +/** Error status for programming operations (potentially ran in background) */ +V_MEMRAM0 static V_MEMRAM1 tFblMemStatus V_MEMRAM2 gErrorStatus; + +#if defined( FBL_MEM_ENABLE_PIPELINING ) +/** Context of programming operation (service context / background context) */ +V_MEMRAM0 static V_MEMRAM1 tFblMemContext V_MEMRAM2 gProgContext; +#endif /* FBL_MEM_ENABLE_PIPELINING */ + +#if defined( FBL_MEM_ENABLE_GLOBAL_BLOCK_INFO ) +/** Block information */ +V_MEMRAM0 static V_MEMRAM1 tFblMemBlockInfo V_MEMRAM2 gBlockInfo; +#endif /* FBL_MEM_ENABLE_GLOBAL_BLOCK_INFO */ + +/** Segment information */ +V_MEMRAM0 static V_MEMRAM1 tFblMemSegmentInternal V_MEMRAM2 gSegInfo; + +#if defined( FBL_MEM_ENABLE_MULTI_SOURCE ) +/** Active input source */ +V_MEMRAM0 static V_MEMRAM1 tFblMemInputSource V_MEMRAM2 gActiveSource; +#endif + +#if defined( FBL_MEM_ENABLE_DYNAMIC_PREAMBLE_LENGTH ) +/** Preamble length stored per input source */ +V_MEMRAM0 static V_MEMRAM1 tFblLength V_MEMRAM2 gPreambleLength[FBL_MEM_SOURCE_COUNT]; +#endif /* FBL_MEM_ENABLE_DYNAMIC_PREAMBLE_LENGTH */ + +#if defined( FBL_MEM_ENABLE_PREAMBLE_HANDLING ) +/** Temporary buffer for storage of preamble */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 gPreambleBuffer[FBL_MEM_MAX_PREAMBLE_LENGTH]; +#endif /* FBL_MEM_ENABLE_PREAMBLE_HANDLING */ + +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) +/** Temporary buffer for write remainder */ +V_MEMRAM0 static V_MEMRAM1 tFblMemRemainderBuffer V_MEMRAM2 gRemainderBuffer; +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ +#if defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) +/** Temporary buffer for data overwritten by buffer padding */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 gPaddingBuffer[FBL_MEM_SEGMENT_SIZE]; +#endif /* FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ + +/*-- Input buffers ----------------------------------------------------------*/ +/** Data buffer(s) */ +V_MEMRAM0 static V_MEMRAM1 tFblMemInputBuffer V_MEMRAM2 gBasicInputBuffer[FBL_MEM_BUFFER_COUNT_INPUT]; +/** Input jobs */ +V_MEMRAM0 static V_MEMRAM1 tFblMemJob V_MEMRAM2 gInputJobs[FBL_MEM_SOURCE_COUNT][FBL_MEM_QUEUE_ENTRIES_INPUT]; + +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) +/** Write finalization job */ +V_MEMRAM0 static V_MEMRAM1 tFblMemJob V_MEMRAM2 gWriteFinalizeJob; +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + +/*-- On-the-fly verification ------------------------------------------------*/ + + +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +/** Pipelined verification jobs */ +V_MEMRAM0 static V_MEMRAM1 tFblMemJob V_MEMRAM2 gVerifyPipeReadJob[FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE_READ]; +V_MEMRAM0 static V_MEMRAM1 tFblMemJob V_MEMRAM2 gVerifyPipeUpdateJob; +V_MEMRAM0 static V_MEMRAM1 tFblMemJob V_MEMRAM2 gVerifyPipeFinalizeJob; +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 gVerifyPipeReadBuffer[FBL_MEM_VERIFY_PIPELINED_SEGMENTATION]; +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED_ADDRESS_LENGTH ) +/** Data buffer(s) for segment information */ +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 gVerifyPipeInfoBuffer[FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE_READ][FBL_MEM_VERIFY_ADDRESS_LENGTH_BUFFER_SIZE]; +# endif /* FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH */ +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +#if defined( FBL_ENABLE_DATA_PROCESSING ) +/*-- Data processing --------------------------------------------------------*/ +V_MEMRAM0 static V_MEMRAM1 tProcParam V_MEMRAM2 gProcParam; +/* Data processing jobs */ +V_MEMRAM0 static V_MEMRAM1 tFblMemJob V_MEMRAM2 gProcWriteJob; +V_MEMRAM0 static V_MEMRAM1 tFblMemJob V_MEMRAM2 gProcFinalizeJob; +/* Data processing buffer */ +V_MEMRAM0 static V_MEMRAM1 tFblMemProcBuffer V_MEMRAM2 gProcBuffer; + +# if defined( FBL_MEM_ENABLE_PROC_SEGMENTATION ) +/** Handle of data processing write job in processing queue + Defined globally as information has to be persistent across multiple calls of FblMemProcessJob */ +V_MEMRAM0 static V_MEMRAM1 tFblMemQueueHandle V_MEMRAM2 gProcHandle; +# endif /* FBL_MEM_ENABLE_PROC_SEGMENTATION */ +#endif /* FBL_ENABLE_DATA_PROCESSING */ + +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) +/*-- Stream output ----------------------------------------------------------*/ +V_MEMRAM0 static V_MEMRAM1 tFblMemStreamProcessing V_MEMRAM2 gStreamParam; +/* Stream output jobs */ +# if defined( FBL_ENABLE_DATA_PROCESSING ) +V_MEMRAM0 static V_MEMRAM1 tFblMemJob V_MEMRAM2 gStreamProcJob; +# endif /* FBL_ENABLE_DATA_PROCESSING */ +V_MEMRAM0 static V_MEMRAM1 tFblMemJob V_MEMRAM2 gStreamFinalizeJob; +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ + + +#if defined( FBL_MEM_ENABLE_GAP_FILL ) +V_MEMRAM0 static V_MEMRAM1 tFblMemJob V_MEMRAM2 gGapFillJob; +V_MEMRAM0 static V_MEMRAM1 tFblMemGapFillBuffer V_MEMRAM2 gGapFillBuffer; +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) +/*-- Progress information ---------------------------------------------------*/ +/** Current progress information */ +V_MEMRAM0 static V_MEMRAM1 tFblMemProgressInfo V_MEMRAM2 gProgressInfo; +/** Previously reported progress information */ +V_MEMRAM0 static V_MEMRAM1 tFblMemProgressInfo V_MEMRAM2 gPrevProgressInfo; + +/** Explicitely enable or disable reporting of erase progress */ +V_MEMRAM0 static V_MEMRAM1 tFblMemProgressState V_MEMRAM2 gProgressState; + +/** Internal progress information (current percentage contribution, target value) */ +V_MEMRAM0 static V_MEMRAM1 tFblMemProgressInfoInternal V_MEMRAM2 gProgressInfoInternal; +/** Value of progress remainder during previous update */ +V_MEMRAM0 static V_MEMRAM1 vuint32 V_MEMRAM2 gProgressPrevRemainder; +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) +/*-- Processing queue -------------------------------------------------------*/ +/** Processing queue */ +V_MEMRAM0 static V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 gProcessingQueue[FBL_MEM_QUEUE_SIZE_PROCESSING]; +# if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +/** Pipelined programming queue */ +V_MEMRAM0 static V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 gPipeProgQueue[FBL_MEM_SOURCE_COUNT][FBL_MEM_QUEUE_SIZE_PIPE_PROG]; +# endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +V_MEMRAM0 static V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 gVerifyPipeQueue[FBL_MEM_QUEUE_SIZE_PIPE_VERIFY]; +# endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ + +#define FBLLIB_MEM_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLLIB_MEM_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) +/** Mapping of priorities to job types + * Has to be same order as tFblMemJobType */ +V_MEMROM0 static V_MEMROM1 tFblMemQueuePrio V_MEMROM2 gJobPrio[] = +{ + (vuint8)kFblMemJobPrio_InputWrite /**< InputWrite */ +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + , (vuint8)kFblMemJobPrio_WriteFinalize /**< WriteFinalize */ +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ +# if defined( FBL_ENABLE_DATA_PROCESSING ) + , (vuint8)kFblMemJobPrio_ProcInput /**< ProcInput */ +# if defined( FBL_MEM_ENABLE_PROC_SEGMENTATION ) + , (vuint8)kFblMemJobPrio_ProcWriteLow /**< ProcWrite, low priority when processing is split into smaller pieces */ + /* kFblMemJobPrio_ProcWriteHigh not explicitely mapped as it is not used when inserting job, + * but only when temporarily updating the priority because of a full processing buffer */ +# else + , (vuint8)kFblMemJobPrio_ProcWriteHigh /**< ProcWrite, high priority used to flush buffer */ + /* kFblMemJobPrio_ProcWriteLow not used */ +# endif /* FBL_MEM_ENABLE_PROC_SEGMENTATION */ + , (vuint8)kFblMemJobPrio_ProcFinalize /**< ProcFinalize */ +# endif /* FBL_ENABLE_DATA_PROCESSING */ +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +# if defined( FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH ) + , (vuint8)kFblMemJobPrio_VerifyPipeInfo /**< VerifyPipeInfo */ +# endif /* FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH */ + , (vuint8)kFblMemJobPrio_VerifyPipeRead /**< VerifyPipeRead */ + , (vuint8)kFblMemJobPrio_VerifyPipeUpdate /**< VerifyPipeUpdate */ + , (vuint8)kFblMemJobPrio_VerifyPipeFinalize /**< VerifyPipeFinalize */ +# endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + , (vuint8)kFblMemJobPrio_StreamInput /**< StreamInput */ +# if defined( FBL_MEM_ENABLE_PROC_SEGMENTATION ) + , (vuint8)kFblMemJobPrio_StreamProcLow /**< StreamProc, low priority when processing is split into smaller pieces */ + /* kFblMemJobPrio_StreamProcHigh not explicitely mapped as it is not used when inserting job, + * but only when temporarily updating the priority because of a full processing buffer */ +# else + , (vuint8)kFblMemJobPrio_StreamProcHigh /**< StreamProc, high priority used to flush buffer */ + /* kFblMemJobPrio_StreamProcLow not used */ +# endif /* FBL_MEM_ENABLE_PROC_SEGMENTATION */ + , (vuint8)kFblMemJobPrio_StreamFinalize /**< StreamFinalize */ +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + , (vuint8)kFblMemJobPrio_GapFill /**< GapFill */ +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + , (vuint8)kFblMemJobPrio_Lowest /**< Concluding entry */ +}; +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ + +#if defined( FBL_MEM_ENABLE_SEGMENTATION ) || \ + defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +/** Limitation of processed length per cycle + * Has to be same order as tFblMemJobType */ +V_MEMROM0 static V_MEMROM1 tFblMemLengthLimit V_MEMROM2 gLengthLimits[] = +{ + { FBL_MEM_WRITE_SEGMENTATION, FBL_MEM_FINALIZE_UNLIMITED_MODE } /**< InputWrite */ +# if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + , { 0u, kFblMemOperationMode_Normal } /**< WriteFinalize, no actual input data */ +# endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ +# if defined( FBL_ENABLE_DATA_PROCESSING ) + , { 0xFFFFu, kFblMemOperationMode_Unconditional } /**< ProcInput, limited to 16 bit */ + , { FBL_MEM_WRITE_SEGMENTATION, FBL_MEM_FINALIZE_UNLIMITED_MODE } /**< ProcWrite */ + , { 0u, kFblMemOperationMode_Normal } /**< ProcFinalize, no actual input data */ +# endif /* FBL_ENABLE_DATA_PROCESSING */ +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +# if defined( FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH ) + , { FBL_MEM_VERIFY_ADDRESS_LENGTH_BUFFER_SIZE, kFblMemOperationMode_Unconditional } /**< VerifyPipeInfo, unconditionally limited by size of segment information */ +# endif /* FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH */ + , { FBL_MEM_VERIFY_PIPELINED_SEGMENTATION, kFblMemOperationMode_Unconditional } /**< VerifyPipeRead, unconditionally limited by temporary buffer */ + , { FBL_MEM_VERIFY_PIPELINED_SEGMENTATION, kFblMemOperationMode_Unconditional } /**< VerifyPipeUpdate, limited by VerifyPipeRead */ + , { 0u, kFblMemOperationMode_Normal } /**< VerifyPipeFinalize, no actual input data */ +# endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ +# if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + , { FBL_MEM_WRITE_SEGMENTATION, FBL_MEM_FINALIZE_UNLIMITED_MODE } /**< StreamInput */ + , { FBL_MEM_WRITE_SEGMENTATION, FBL_MEM_FINALIZE_UNLIMITED_MODE } /**< StreamProc */ + , { 0u, kFblMemOperationMode_Normal } /**< StreamFinalize, no actual input data */ +# endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + , { 0u, kFblMemOperationMode_Normal } /**< GapFill, limit applied in job processing */ +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + , { 0u, kFblMemOperationMode_Normal } /**< Concluding entry */ +}; +#endif /* FBL_MEM_ENABLE_SEGMENTATION || FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +/*-- Error handling ---------------------------------------------------------*/ + +/* PRQA L:TAG_FblMem_3218 */ + +#define FBLLIB_MEM_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLLIB_MEM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + + +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +static tFblMemTriggerStatus FblMemTriggerWatchdogExt( void ); +static void FblMemTriggerWatchdog( void ); +#if defined( FBL_MEM_ENABLE_RESPONSE_PENDING ) +static void FblMemResponsePending( void ); +#endif /* FBL_MEM_ENABLE_RESPONSE_PENDING */ + +static void FblMemInitInputQueue( void ); +static void FblMemInitStates( void ); +static tFblMemRamData FblMemInitInternal( void ); +static tFblMemStatus FblMemQueueBuffer( tFblMemConstRamData buffer, tFblLength offset, tFblLength length ); +static void FblMemProcessQueue( tFblMemOperationMode mode ); +static void FblMemFlushQueueByPrio( tFblMemQueuePrio prio ); +#if defined( FBL_MEM_ENABLE_PIPELINING ) +static void FblMemUnblockQueue( const V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue ); +#endif /* FBL_MEM_ENABLE_PIPELINING */ +#if defined( FBL_MEM_ENABLE_VERIFY_STREAM ) +static tFblMemStatus FblMemVerifyInput( V_MEMRAM1 tFblMemVerifyRoutineInput V_MEMRAM2 V_MEMRAM3 * routine, + const V_MEMRAM1 tFblMemVerifyData V_MEMRAM2 V_MEMRAM3 * data, vuint8 state, + V_MEMRAM1 tFblMemVerifyStatus V_MEMRAM2 V_MEMRAM3 * result ); +static tFblMemStatus FblMemInitVerifyInput( void ); +#endif /* FBL_MEM_ENABLE_VERIFY_STREAM */ +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +static V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * FblMemPrepareVerifyPipeJob( vuintx segmentIndex, tFblAddress address ); +static V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * FblMemUpdateVerifyPipeJob( vuintx segmentIndex, tFblAddress address, tFblLength length ); +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ +static tFblMemStatus FblMemProcessJob( V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * activeJob, tFblMemOperationMode mode ); +static tFblMemStatus FblMemProgramStream( const V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * programJob, + V_MEMRAM1 tFblLength V_MEMRAM2 V_MEMRAM3 * programLength, tFblMemOperationMode mode ); +static tFblLength FblMemPadLength( tFblAddress address, tFblLength length ); +static tFblLength FblMemPadBuffer( tFblAddress address, tFblLength length, tFblMemRamData data ); +#if defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) +static void FblMemUnpadBuffer( tFblMemRamData data, tFblLength padLen ); +#endif /* FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ +static tFblMemStatus FblMemCopyBuffer( tFblAddress programAddress, + const V_MEMRAM1 tFblLength V_MEMRAM2 V_MEMRAM3 * programLength, tFblMemConstRamData programData ); +static tFblMemStatus FblMemEraseRegionInternal( tFblAddress eraseAddress, tFblLength eraseLength ); +static tFblMemStatus FblMemProgramBufferInternal( tFblAddress programAddress, + V_MEMRAM1 tFblLength V_MEMRAM2 V_MEMRAM3 * programLength, tFblMemRamData programData, + tFblMemProgState checkPointState ); +# if defined( FBL_ENABLE_MULTIPLE_MEM_DEVICES ) && \ + defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) +static tFblLength FblMemGetSpecificRemainder( tFblAddress address, tFblLength length ); +# endif /* FBL_ENABLE_MULTIPLE_MEM_DEVICES && FBL_MEM_ENABLE_REMAINDER_HANDLING */ + +#if defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) +static tFblMemStatus FblMemRelocateBufferOffset( V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * activeJob, + tFblMemConstRamData buffer, tFblLength offset, tFblLength length ); +#endif /* FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ +#if defined( FBL_MEM_ENABLE_VARYING_INPUT_BUFFER ) +static tFblMemStatus FblMemSearchInputBuffer( tFblMemConstRamData buffer, tFblLength offset, tFblLength length ); +#endif /* FBL_MEM_ENABLE_VARYING_INPUT_BUFFER */ + +#if defined( FBL_MEM_ENABLE_SEGMENTATION ) || \ + defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +static tFblLength FblMemLimitLength( tFblLength inputLen, tFblMemJobType type, tFblMemOperationMode mode ); +#endif /* FBL_MEM_ENABLE_SEGMENTATION || FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +#if defined( FBL_MEM_ENABLE_PREAMBLE_HANDLING ) +static void FblMemStorePreamble( void ); +static void FblMemRestorePreamble( void ); +#endif /* FBL_MEM_ENABLE_PREAMBLE_HANDLING */ + +static tFblResult FblMemCheckAllowed( tFblMemAllowedInd check, tFblMemAllowedInd clear ); +static tFblMemRamData FblMemGetBuffer( const V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * job ); +#if defined( FBL_ENABLE_SYSTEM_CHECK ) +static void FblMemInitBufferIntegrity( void ); +static tFblMemStatus FblMemVerifyBufferIntegrity( void ); +#endif /* FBL_ENABLE_SYSTEM_CHECK */ + +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) +static void FblMemQueueInit( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, tFblMemQueueHandle length ); + +static tFblMemQueueHandle FblMemQueueMove( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + tFblMemQueueHandle handle, tFblMemQueueHandle prevNew ); + +# if defined( FBL_MEM_ENABLE_PIPELINING ) +static tFblMemQueueHandle FblMemQueueMoveFirstFreeEntry( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + tFblMemQueueHandle prevNew ); +static tFblMemQueueHandle FblMemQueueAppend( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue ); +# endif /* FBL_MEM_ENABLE_PIPELINING */ +static tFblMemQueueHandle FblMemQueueRemove( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + tFblMemQueueHandle handle ); +static tFblMemQueueHandle FblMemQueuePrioUpdate( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + tFblMemQueueHandle handle, tFblMemQueuePrio prio ); +static tFblMemQueueHandle FblMemQueuePrioInsert( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + tFblMemQueuePrio prio, V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * job ); +static tFblMemQueueHandle FblMemQueueDefaultPrioInsert( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * job, vuintx segmentIndex ); +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ + +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +static V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * FblMemGetPendingInputJob( void ); +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + +static void FblMemInitJob( V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * job, tFblMemRamData buffer, + tFblLength size, tFblMemJobType type ); + + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) +static vuint8 FblMemCalculateProgress( vuint32 current, vuint32 total, vuint8 percentage ); +static void FblMemInitProgress( void ); +static void FblMemReportProgress( void ); +static void FblMemSetupProgress( tFblMemProgressType type, tFblAddress logicalAddress, vuint32 segmentCount, + vuint8 totalOffset, vuint8 totalPercentage, vuint32 target ); +static void FblMemOffsetProgress( vuint32 totalDone, vuint32 totalTarget ); +static void FblMemUpdateProgress( vuint32 remainderPart ); +static void FblMemConcludeProgress( void ); +# if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) +# if defined( FBL_MEM_ENABLE_SWITCH_READMEMORY_PARAM ) +/* Parameters order changed in comparison to HIS security module specification */ +static tFblMemVerifySize FblMemProgressRead( tFblMemVerifyAddr address, tFblMemVerifySize length, tFblMemVerifyDataPtr buffer ); +# else +/* Parameters order as defined by HIS security module specification */ +static tFblMemVerifySize FblMemProgressRead( tFblMemVerifyAddr address, tFblMemVerifyDataPtr buffer, tFblMemVerifySize length ); +# endif /* FBL_MEM_ENABLE_SWITCH_READMEMORY_PARAM */ +# endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT */ +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + +/*********************************************************************************************************************** + * EXTERNAL DATA + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FblMemTriggerWatchdogExt + **********************************************************************************************************************/ +/*! \brief Call configured watchdog trigger routine + * \details If pipelined programming is supported and the trigger is called while a background programming operation + * is active, the default watchdog trigger is executed. + * Otherwise an erroneous RCR-RP could be generated before service dispatching is finished. + * E.g. ISO 14229 enforces that certain message checks (length, ...) are performed before the first RCR-RP + * transmission. + * For all other cases (non-pipelined programming, service context) the configured routine to support an + * adaptive RCR-RP generation is called instead. + * \return Watchdog trigger status + **********************************************************************************************************************/ +static tFblMemTriggerStatus FblMemTriggerWatchdogExt( void ) +{ + tFblMemTriggerStatus result; + +#if defined( FBL_MEM_ENABLE_PIPELINING ) && \ + defined( __ApplFblMemWdTrigger ) + /* Do not generate RCR-RP while programming in background context */ + if (kFblMemContext_Background == gProgContext) + { + /* Default watchdog trigger */ + result = __ApplFblMemWdTrigger(); + } + else +#endif /* FBL_MEM_ENABLE_PIPELINING && __ApplFblMemWdTrigger */ + { +#if defined( __ApplFblMemAdaptiveRcrRp ) + /* Trigger watchdog and dynamically generate RCR-RP */ + result = __ApplFblMemAdaptiveRcrRp(); +#else + /* Callback not configured, return default value */ + result = FBL_MEM_WD_TRIGGER_DEFAULT; +#endif /* __ApplFblMemAdaptiveRcrRp */ + } + + return result; +} + +/*********************************************************************************************************************** + * FblMemTriggerWatchdog + **********************************************************************************************************************/ +/*! \brief Call configured watchdog trigger routine + * \details Suppress watchdog trigger status (see FblMemTriggerWatchdogExt) + **********************************************************************************************************************/ +static void FblMemTriggerWatchdog( void ) +{ + (void)FblMemTriggerWatchdogExt(); +} + +#if defined( FBL_MEM_ENABLE_RESPONSE_PENDING ) +/*********************************************************************************************************************** + * FblMemResponsePending + **********************************************************************************************************************/ +/*! \brief Force RCR-RP by calling configured routine + * \details If pipelined programming is supported only execute function if called in service context. Otherwise an + * erroneous RCR-RP could be generated before service dispatching is finished + **********************************************************************************************************************/ +static void FblMemResponsePending( void ) +{ +# if defined( __ApplFblMemForcedRcrRp ) +# if defined( FBL_MEM_ENABLE_PIPELINING ) + /* Do not force RCR-RP while programming in background context */ + if (kFblMemContext_Service == gProgContext) +# endif /* FBL_MEM_ENABLE_PIPELINING */ + { +# if defined( __ApplFblMemIsRcrRpActive ) + /* Do not force RCR-RP if already active */ + if (kFblOk != __ApplFblMemIsRcrRpActive()) +# endif /* __ApplFblMemIsRcrRpActive */ + { + /* Force RCR-RP */ + __ApplFblMemForcedRcrRp(); + } + } +# endif /* __ApplFblMemForcedRcrRp */ +} +#endif /* FBL_MEM_ENABLE_RESPONSE_PENDING */ + +/*********************************************************************************************************************** + * FblMemGetBuffer + **********************************************************************************************************************/ +/*! \brief Get a pointer to the referenced buffer, taking into account the current position value + * \param[in] job Pointer to job information + * \return Pointer to current buffer position + * Null pointer in case referenced buffer is not defined + **********************************************************************************************************************/ +static tFblMemRamData FblMemGetBuffer( const V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * job ) +{ + tFblMemRamData jobBuffer; + + /* Get referenced buffer */ + jobBuffer = job->buffer; + + /* Check for undefined buffer (null pointer) */ + if (FBL_MEM_BUFFER_NULL != jobBuffer) + { + /* Check for potential buffer overflow */ + assertFblInternal((job->offset <= (job->totalSize - job->netSize)), kFblMemAssertParameterOutOfRange); + assertFblInternal((job->used <= (job->totalSize - job->offset)), kFblMemAssertParameterOutOfRange); + + /* Valid buffer pointer + Evaluate position */ + jobBuffer = &jobBuffer[job->position]; + } + + /* Return pointer to current buffer position */ + return jobBuffer; +} + +#if defined( FBL_ENABLE_SYSTEM_CHECK ) +/*********************************************************************************************************************** + * FblMemInitBufferIntegrity + **********************************************************************************************************************/ +/*! \brief Initialize "canary" words placed after aligned buffer contents + * \details "Canary" value is placed behind actual buffer contents and contains a magic value. + * In case of a buffer overrun it is likely that the "canary" is modified too. This can be used to + * detect the overrun. + **********************************************************************************************************************/ +static void FblMemInitBufferIntegrity( void ) +{ + vuintx idx; + + /* Data buffer(s) */ + for (idx = 0u; idx < FBL_MEM_BUFFER_COUNT_INPUT; idx++) + { + gBasicInputBuffer[idx].canaryFront = FBL_MEM_CANARY_VALUE; + gBasicInputBuffer[idx].canaryBack = FBL_MEM_CANARY_VALUE; + } + +# if defined( FBL_ENABLE_DATA_PROCESSING ) + /* Data processing buffer */ + gProcBuffer.canaryFront = FBL_MEM_CANARY_VALUE; + gProcBuffer.canaryBack = FBL_MEM_CANARY_VALUE; +# endif /* FBL_ENABLE_DATA_PROCESSING */ + +# if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + /* Remainder buffer */ + gRemainderBuffer.canaryFront = FBL_MEM_CANARY_VALUE; + gRemainderBuffer.canaryBack = FBL_MEM_CANARY_VALUE; +# endif /* FBL_ENABLE_DATA_PROCESSING */ + +# if defined( FBL_MEM_ENABLE_GAP_FILL ) + /* Gap fill buffer */ + gGapFillBuffer.canaryFront = FBL_MEM_CANARY_VALUE; + gGapFillBuffer.canaryBack = FBL_MEM_CANARY_VALUE; +# endif /* FBL_ENABLE_DATA_PROCESSING */ +} + +/*********************************************************************************************************************** + * FblMemVerifyBufferIntegrity + **********************************************************************************************************************/ +/*! \brief Verify "canary" words placed before and after aligned buffer contents + * \details "Canary" values are placed in front and behind actual buffer contents and contain a magic value. + * In case of a buffer overrun it is likely that the "canary" is modified too. This can be used to + * detect the overrun. + * \return kFblMemStatus_Ok if "canary" words of all aligned buffers are intact, + * kFblMemStatus_Failed otherwise + **********************************************************************************************************************/ +static tFblMemStatus FblMemVerifyBufferIntegrity( void ) +{ + tFblMemStatus retVal; + vuint32 aggregated; + vuintx idx; + + retVal = kFblMemStatus_Ok; + aggregated = 0x00uL; + + /* Data buffer(s) */ + for (idx = 0u; idx < FBL_MEM_BUFFER_COUNT_INPUT; idx++) + { + aggregated |= (FBL_MEM_CANARY_VALUE ^ gBasicInputBuffer[idx].canaryFront); + aggregated |= (FBL_MEM_CANARY_VALUE ^ gBasicInputBuffer[idx].canaryBack); + } + +# if defined( FBL_ENABLE_DATA_PROCESSING ) + /* Data processing buffer */ + aggregated |= (FBL_MEM_CANARY_VALUE ^ gProcBuffer.canaryFront); + aggregated |= (FBL_MEM_CANARY_VALUE ^ gProcBuffer.canaryBack); +# endif /* FBL_ENABLE_DATA_PROCESSING */ + +# if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + /* Remainder buffer */ + aggregated |= (FBL_MEM_CANARY_VALUE ^ gRemainderBuffer.canaryFront); + aggregated |= (FBL_MEM_CANARY_VALUE ^ gRemainderBuffer.canaryBack); +# endif /* FBL_ENABLE_DATA_PROCESSING */ + +# if defined( FBL_MEM_ENABLE_GAP_FILL ) + /* Gap fill buffer */ + aggregated |= (FBL_MEM_CANARY_VALUE ^ gGapFillBuffer.canaryFront); + aggregated |= (FBL_MEM_CANARY_VALUE ^ gGapFillBuffer.canaryBack); +# endif /* FBL_ENABLE_DATA_PROCESSING */ + + if (0x00uL != aggregated) + { + retVal = kFblMemStatus_Failed; + } + + return retVal; +} +#endif /* FBL_ENABLE_SYSTEM_CHECK */ + +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) +/* Queue handling ************************************************************/ + +/*********************************************************************************************************************** + * FblMemQueueInit + **********************************************************************************************************************/ +/*! \brief Initialize queue structure + * \details Implements two double linked lists, representing a used and a free queue. + * \param[in,out] queue Pointer to queue array + * \param[in] length Total length of queue, including used and free head + **********************************************************************************************************************/ +static void FblMemQueueInit( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, tFblMemQueueHandle length ) +{ + tFblMemQueueHandle handle; + tFblMemQueueHandle prevHandle; + tFblMemQueueHandle nextHandle; + + /* Start with empty queue by self-reference */ + queue[FBL_MEM_QUEUE_HANDLE_HEAD_USED].next = FBL_MEM_QUEUE_HANDLE_HEAD_USED; + queue[FBL_MEM_QUEUE_HANDLE_HEAD_USED].prev = FBL_MEM_QUEUE_HANDLE_HEAD_USED; + /* Set default values */ + queue[FBL_MEM_QUEUE_HANDLE_HEAD_USED].job = FBL_MEM_JOB_NULL; + queue[FBL_MEM_QUEUE_HANDLE_HEAD_USED].prio = FBL_MEM_QUEUE_PRIO_HIGHEST; + + /* Setup double linked list of empty queue entries */ + /* Head references last entry as predecessor */ + prevHandle = length - 1u; + nextHandle = FBL_MEM_QUEUE_HANDLE_HEAD_FREE; + + /* Append available entries to free queue */ + for (handle = FBL_MEM_QUEUE_HANDLE_HEAD_FREE; handle < length; handle++) + { + nextHandle++; + + /* Set predecessor and successor */ + queue[handle].prev = prevHandle; + queue[handle].next = nextHandle; + /* Set default values */ + queue[handle].job = FBL_MEM_JOB_NULL; + queue[handle].prio = FBL_MEM_QUEUE_PRIO_LOWEST; + + prevHandle = handle; + } + + /* Last entry references head as successor */ + queue[length - 1u].next = FBL_MEM_QUEUE_HANDLE_HEAD_FREE; +} + +/*********************************************************************************************************************** + * FblMemQueueMove + **********************************************************************************************************************/ +/*! \brief Cut queue entry from current position and place it at a different location (either in same or other queue) + * \pre FblMemQueueInit executed before, source queue not empty + * Passed handles have to represent actual predecessor and successor relationship + * \param[in,out] queue Pointer to queue array + * \param[in] handle Handle of queue entry to be moved + * \param[in] prevNew Handle of new predecessor + * \return Handle of affected entry + **********************************************************************************************************************/ +static tFblMemQueueHandle FblMemQueueMove( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + tFblMemQueueHandle handle, tFblMemQueueHandle prevNew ) +{ + tFblMemQueueHandle prevOld; + tFblMemQueueHandle nextOld; + tFblMemQueueHandle nextNew; + + /* Check for matching handles */ + if (handle == prevNew) + { + /* Entry placed at exact same location + No need to change anything */ + } + else + { + /* Get current predecessor and successor */ + prevOld = queue[handle].prev; + nextOld = queue[handle].next; + + /* Old queue empty? */ + assertFblInternal((queue[prevOld].next != prevOld), kFblMemAssertParameterOutOfRange); + + /* Remove entry from old queue */ + queue[prevOld].next = nextOld; + queue[nextOld].prev = prevOld; + + /* Get new predecessor */ + nextNew = queue[prevNew].next; + + /* Insert entry into new queue */ + queue[handle].prev = prevNew; + queue[prevNew].next = handle; + queue[handle].next = nextNew; + queue[nextNew].prev = handle; + } + + return handle; +} + +# if defined( FBL_MEM_ENABLE_PIPELINING ) +/*********************************************************************************************************************** + * FblMemQueueMoveFirstFreeEntry + **********************************************************************************************************************/ +/*! \brief Take first free entry, remove it from free queue and insert it into defined location in used queue. + * \pre FblMemQueueInit executed before, queue not full + * \param[in,out] queue Pointer to queue array + * \param[in] prevNew Handle of new predecessor + * \return Handle of moved entry + **********************************************************************************************************************/ +static tFblMemQueueHandle FblMemQueueMoveFirstFreeEntry( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + tFblMemQueueHandle prevNew ) +{ + /* Free queue empty? */ + assertFblInternal((!FblMemQueueIsFull(queue)), kFblMemAssertParameterOutOfRange); + + /* Move first free entry to new position */ + return FblMemQueueMove(queue, queue[FBL_MEM_QUEUE_HANDLE_HEAD_FREE].next, prevNew); +} + +/*********************************************************************************************************************** + * FblMemQueueAppend + **********************************************************************************************************************/ +/*! \brief Append entry to end of queue + * \details Take first free entry, remove it from free queue and insert it as last entry into used queue. + * \pre FblMemQueueInit executed before, queue not full + * \param[in,out] queue Pointer to queue array + * \return Handle of appended entry + **********************************************************************************************************************/ +static tFblMemQueueHandle FblMemQueueAppend( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue ) +{ + /* Insert at end of used queue + Place between current last entry and tail (== head) */ + return FblMemQueueMoveFirstFreeEntry(queue, queue[FBL_MEM_QUEUE_HANDLE_HEAD_USED].prev); +} + +# endif /* FBL_MEM_ENABLE_PIPELINING */ + +/*********************************************************************************************************************** + * FblMemQueueRemove + **********************************************************************************************************************/ +/*! \brief Remove specific entry from queue + * \details Take specific entry, remove it from queue and insert it as last entry into free queue. + * \pre FblMemQueueInit executed before, queue not empty + * \param[in,out] queue Pointer to queue array + * \param[in] handle Queue entry handle + * \return Handle of removed entry + **********************************************************************************************************************/ +static tFblMemQueueHandle FblMemQueueRemove( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + tFblMemQueueHandle handle ) +{ + /* Insert at end of free queue + Place between current last entry and tail (== head) */ + return FblMemQueueMove(queue, handle, queue[FBL_MEM_QUEUE_HANDLE_HEAD_FREE].prev); +} + +/*********************************************************************************************************************** + * FblMemQueuePrioUpdate + **********************************************************************************************************************/ +/*! \brief Update priority of a queue entry + * \details Take specific entry, remove it from queue and re-insert it according to the updated priority. + * \pre FblMemQueueInit executed before, queue not empty + * \param[in,out] queue Pointer to queue array + * \param[in] handle Queue entry handle + * \param[in] prio New priority value + * \return Handle of updated entry + **********************************************************************************************************************/ +static tFblMemQueueHandle FblMemQueuePrioUpdate( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + tFblMemQueueHandle handle, tFblMemQueuePrio prio ) +{ + tFblMemQueueHandle prevHandle; + + /* Start search at last entry */ + prevHandle = queue[FBL_MEM_QUEUE_HANDLE_HEAD_USED].prev; + + /* Skip all entries with lower priority + Remark: Search is assured to stop at head because it has the highest possible priority */ + while (queue[prevHandle].prio < prio) + { + prevHandle = queue[prevHandle].prev; + } + + /* Append after first entry with higher or equal priority */ + (void)FblMemQueueMove(queue, handle, prevHandle); + /* Update priority of inserted entry */ + queue[handle].prio = prio; + + return handle; +} + +/*********************************************************************************************************************** + * FblMemQueuePrioInsert + **********************************************************************************************************************/ +/*! \brief Insert entry into queue using given priority + * \details Take first free entry, remove it from free queue and insert it according to the given priority. + * Additionally set job associated with queue entry + * \pre FblMemQueueInit executed before, queue not empty + * \param[in,out] queue Pointer to queue array + * \param[in] prio Priority value + * \param[in] job Job associated with queue entry + * \return Handle of inserted entry + **********************************************************************************************************************/ +static tFblMemQueueHandle FblMemQueuePrioInsert( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + tFblMemQueuePrio prio, V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * job ) +{ + tFblMemQueueHandle handle; + + /* Free queue empty? */ + assertFblInternal((!FblMemQueueIsFull(queue)), kFblMemAssertParameterOutOfRange); + + /* Relocate first free entry according to given priority */ + handle = FblMemQueuePrioUpdate(queue, queue[FBL_MEM_QUEUE_HANDLE_HEAD_FREE].next, prio); + /* Set job of entry */ + queue[handle].job = job; + + return handle; +} + +/*********************************************************************************************************************** + * FblMemQueueDefaultPrioInsert + **********************************************************************************************************************/ +/*! \brief Insert entry into queue using default priority + * \details Take first free entry, remove it from free queue and insert it according to the default priority of + the given job's type. Additionally set job associated with queue entry and update segment index of job. + * \pre FblMemQueueInit executed before, queue not empty + * \param[in,out] queue Pointer to queue array + * \param[in] job Job associated with queue entry + * \param[in] segmentIndex Segment index assigned to job + * \return Handle of inserted entry + **********************************************************************************************************************/ +static tFblMemQueueHandle FblMemQueueDefaultPrioInsert( V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue, + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * job, vuintx segmentIndex ) +{ + /* Valid job type? */ + assertFblInternal((job->type < kFblMemJobType_Max), kFblMemAssertParameterOutOfRange); + + /* Remember segment index associated with job */ + job->segmentIndex = segmentIndex; + + return FblMemQueuePrioInsert(queue, gJobPrio[job->type], job); +} +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ + +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +/*********************************************************************************************************************** + * FblMemGetPendingInputJob + **********************************************************************************************************************/ +/*! \brief Get information of current pending job + * \details This is the very first entry in the free queue + * \pre Pipelined programming queue initialized + * \return Pointer to pending input job + **********************************************************************************************************************/ +static V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * FblMemGetPendingInputJob( void ) +{ + /* Free queue empty? */ + assertFblInternal((!FblMemQueueIsFull(FBL_MEM_PIPE_PROG_QUEUE)), kFblMemAssertParameterOutOfRange); + + /* Return job information of first free entry */ + return FblMemQueueGetFirstFreeEntry(FBL_MEM_PIPE_PROG_QUEUE).job; +} +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + +/*********************************************************************************************************************** + * FblMemInitJob + **********************************************************************************************************************/ +/*! \brief Initialize job information structure + * \details Assign given buffer to job and set type + * \param[in,out] job Job information to be initialized + * \param[in] buffer Buffer associated with job + * \param[in] size Size of given buffer + * \param[in] type Type of job + **********************************************************************************************************************/ +static void FblMemInitJob( V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * job, tFblMemRamData buffer, tFblLength size, + tFblMemJobType type ) +{ + /* Assign given buffer */ + job->buffer = buffer; + job->totalSize = size; + job->netSize = size; + /* Default values */ + job->offset = 0u; + job->position = 0u; + job->used = 0u; +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ +#if defined( FBL_MEM_ENABLE_PIPELINING ) + /* Default job */ + job->jobClass = tFblMemJobClass_Default; +#endif /* FBL_MEM_ENABLE_PIPELINING */ + /* Set job type */ + job->type = type; + /* Job complete as soon as "used" member reaches zero */ + job->completion = kFblMemOperationMode_Normal; +} + +/*********************************************************************************************************************** + * FblMemInitInputQueue + **********************************************************************************************************************/ +/*! \brief Initialize input queue + * \details Additionally job information of input buffers is prepared. + * Will also be carried out for single buffer use-case + **********************************************************************************************************************/ +static void FblMemInitInputQueue( void ) +{ + vuintx idx; + vuintx actualBasicIdx; +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) + vuintx basicIdx; + tFblMemQueueHandle queueHandle; +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + + /* First input buffer assigned to specified input source */ + actualBasicIdx = FBL_MEM_ACTIVE_SOURCE; + +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) + /* Setup pipelined programming queue */ + FblMemQueueInit(FBL_MEM_PIPE_PROG_QUEUE, FBL_MEM_ARRAY_SIZE(FBL_MEM_PIPE_PROG_QUEUE)); + + queueHandle = (tFblMemQueueHandle)FBL_MEM_QUEUE_HANDLE_ENTRY_OFFSET; + basicIdx = FBL_MEM_SOURCE_COUNT; + + for (idx = 0u; idx < FBL_MEM_QUEUE_ENTRIES_INPUT; idx++) + { + if (0u != idx) + { + actualBasicIdx = basicIdx; + basicIdx++; + } +#else + idx = 0u; + + { +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + /* Reset job information and assign actual buffers */ + /* PRQA S 2801, 2851 2 */ /* MD_FblMem_FalseFinding */ + FblMemInitJob( &FBL_MEM_INPUT_JOB[idx], gBasicInputBuffer[actualBasicIdx].data, + FBL_MEM_ARRAY_SIZE(gBasicInputBuffer[actualBasicIdx].data), kFblMemJobType_InputWrite ); + /* Overwrite net size, to exclude overhead for remainder and padding */ + FBL_MEM_INPUT_JOB[idx].netSize = FBL_MEM_BUFFER_SIZE; + /* Default offset to align actual data to platform requirements */ + FBL_MEM_INPUT_JOB[idx].offset = FBL_MEM_PREAMBLE_OFFSET(FBL_MEM_PREAMBLE_LENGTH); + +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) + /* Set dedicated job class */ + FBL_MEM_INPUT_JOB[idx].jobClass = tFblMemJobClass_PipeProg; + /* Assign job to input queue entry */ + FblMemQueueGetEntry(FBL_MEM_PIPE_PROG_QUEUE, queueHandle).job = &FBL_MEM_INPUT_JOB[idx]; + queueHandle++; +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + } +} + +/*********************************************************************************************************************** + * FblMemInitStates + **********************************************************************************************************************/ +/*! \brief Setup all data structures + * \pre FblMemInitPowerOn executed before + **********************************************************************************************************************/ +static void FblMemInitStates( void ) +{ + /* Setup idle state */ + fblMemProgState = kFblMemProgState_Idle; + gErrorStatus = kFblMemStatus_Ok; +#if defined( FBL_MEM_ENABLE_PIPELINING ) + gProgContext = kFblMemContext_Service; +#endif /* FBL_MEM_ENABLE_PIPELINING */ + + /* No operations allowed */ + FblMemResetAllowed(); +} + +/*********************************************************************************************************************** + * FblMemInitInternal + **********************************************************************************************************************/ +/*! \brief Setup all data structures + * \pre FblMemInitPowerOn executed before + * \return Pointer to active input buffer + **********************************************************************************************************************/ +static tFblMemRamData FblMemInitInternal( void ) +{ +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + vuintx idx; + tFblMemQueueHandle queueHandle; +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + + /* Setup idle state */ + FblMemInitStates(); + +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) + /* Setup processing queue */ + FblMemQueueInit(gProcessingQueue, FBL_MEM_ARRAY_SIZE(gProcessingQueue)); +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ + FblMemInitInputQueue(); + +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + FblMemInitJob(&gWriteFinalizeJob, gRemainderBuffer.data, FBL_MEM_SEGMENT_SIZE, kFblMemJobType_WriteFinalize); +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + +#if defined( FBL_ENABLE_DATA_PROCESSING ) + /* Reset current data length, no full re-initialization necessary */ + gProcWriteJob.used = 0u; +#endif /* FBL_ENABLE_DATA_PROCESSING */ + +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) && \ + defined( FBL_ENABLE_DATA_PROCESSING ) + /* Reset current data length, no full re-initialization necessary */ + gStreamProcJob.used = 0u; +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT && FBL_ENABLE_DATA_PROCESSING */ + +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Setup pipelined verification queue */ + FblMemQueueInit(gVerifyPipeQueue, FBL_MEM_ARRAY_SIZE(gVerifyPipeQueue)); + + queueHandle = (tFblMemQueueHandle)FBL_MEM_QUEUE_HANDLE_ENTRY_OFFSET; + +# if ( FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE_READ == 1u ) + idx = 0u; +# else + for (idx = 0u; idx < FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE_READ; idx++) +# endif /* FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE_READ */ + { + /* Initialize job */ +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED_ADDRESS_LENGTH ) + /* Assign dedicated buffer for segment information */ + FblMemInitJob(&gVerifyPipeReadJob[idx], gVerifyPipeInfoBuffer[idx], FBL_MEM_VERIFY_ADDRESS_LENGTH_BUFFER_SIZE, kFblMemJobType_VerifyPipeRead); +# else + FblMemInitJob(&gVerifyPipeReadJob[idx], FBL_MEM_BUFFER_NULL, 0, kFblMemJobType_VerifyPipeRead); +# endif + /* Set dedicated job class */ + gVerifyPipeReadJob[idx].jobClass = tFblMemJobClass_VerifyPipe; + + /* Assign job to verify queue entry */ + FblMemQueueGetEntry(gVerifyPipeQueue, queueHandle).job = &gVerifyPipeReadJob[idx]; +# if ( FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE_READ > 1u ) + queueHandle++; +# endif /* FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE_READ */ + } + + /* Initialize jobs for update and finalize */ + FblMemInitJob(&gVerifyPipeUpdateJob, gVerifyPipeReadBuffer, FBL_MEM_VERIFY_PIPELINED_SEGMENTATION, kFblMemJobType_VerifyPipeUpdate); + FblMemInitJob(&gVerifyPipeFinalizeJob, FBL_MEM_BUFFER_NULL, 0, kFblMemJobType_VerifyPipeFinalize); +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +#if defined( FBL_ENABLE_SYSTEM_CHECK ) + FblMemInitBufferIntegrity(); +#endif /* FBL_ENABLE_SYSTEM_CHECK */ + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + FblMemInitProgress(); +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + + /* Allow block start / erase indication */ + FblMemSetAllowed(FBL_MEM_ALLOWED_BLOCK_START | FBL_MEM_ALLOWED_BLOCK_ERASE); + + return FblMemGetActiveBuffer(); +} + +#if defined( FBL_MEM_ENABLE_PREAMBLE_HANDLING ) +/*********************************************************************************************************************** + * FblMemStorePreamble + **********************************************************************************************************************/ +/*! \brief Store the current buffer preamble (protocol information before actual data) + * \details Active fill buffer may be exchanged by subsequent operations, so preamble has to be restored for + * calling instance + * \pre FblMemInitPowerOn executed before, fill buffer available + **********************************************************************************************************************/ +static void FblMemStorePreamble( void ) +{ +#if defined( FBL_MEM_ENABLE_DYNAMIC_PREAMBLE_LENGTH ) + /* Verify preamble fits into reserved buffer */ + assertFblGen(FBL_MEM_PREAMBLE_LENGTH <= FBL_MEM_MAX_PREAMBLE_LENGTH, kFblMemAssertParameterOutOfRange); +#endif /* FBL_MEM_ENABLE_DYNAMIC_PREAMBLE_LENGTH */ + + /* Copy preamble from active fill to temporary buffer */ + (void)MEMCPY(gPreambleBuffer, FblMemGetActiveBuffer(), FBL_MEM_PREAMBLE_LENGTH); /* PRQA S 0314 */ /* MD_FblMem_0314_0326_MemCpy */ +} + +/*********************************************************************************************************************** + * FblMemRestorePreamble + **********************************************************************************************************************/ +/*! \brief Restore the previously stored preamble (protocol information before actual data) into the (new) active + * fill buffer + * \details Active buffer could be exchanged by preceding operations, so preamble has to be restored for calling + * instance + * \pre FblMemInitPowerOn executed before, fill buffer available + **********************************************************************************************************************/ +static void FblMemRestorePreamble( void ) +{ + /* Copy previously stored preamble from temporary to active fill buffer */ + (void)MEMCPY(FblMemGetActiveBuffer(), gPreambleBuffer, FBL_MEM_PREAMBLE_LENGTH); /* PRQA S 0314 */ /* MD_FblMem_0314_0326_MemCpy */ +} +#endif /* FBL_MEM_ENABLE_PREAMBLE_HANDLING */ + +#if defined( FBL_MEM_ENABLE_SEGMENTATION ) || \ + defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +/*********************************************************************************************************************** + * FblMemLimitLength + **********************************************************************************************************************/ +/*! \brief Length will be truncated if limit is exceeded + * \details Original value will be returned if finalization operation mode is set + * \param[in] inputLen Original length + * \param[in] type Type of active job + * \param[in] mode Current operation mode (used for finalization) + * \return Input length limited to given range + **********************************************************************************************************************/ +static tFblLength FblMemLimitLength( tFblLength inputLen, tFblMemJobType type, tFblMemOperationMode mode ) +{ + tFblLength lengthLimit; + tFblLength localInputLen; + + localInputLen = inputLen; + +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ +# if defined( FBL_MEM_ENABLE_SEGMENTATION ) +# else + (void)mode; +# endif /* FBL_MEM_ENABLE_SEGMENTATION */ +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + /* Valid job type? */ + assertFblInternal((type < kFblMemJobType_Max), kFblMemAssertParameterOutOfRange); + + lengthLimit = gLengthLimits[type].limit; + + if (lengthLimit > 0u) + { +# if defined( FBL_MEM_ENABLE_SEGMENTATION ) + /* Segmentation explicitly enabled + Truncate to given limit, unless unlimited mode for job type (typically finalize) is set */ + if ((gLengthLimits[type].unlimitedMode != mode) && (localInputLen > lengthLimit)) +# else + /* Truncate to given limit, if unconditional mode is configured for job type */ + if ((gLengthLimits[type].unlimitedMode == kFblMemOperationMode_Unconditional) && (localInputLen > lengthLimit)) +# endif /* FBL_MEM_ENABLE_SEGMENTATION */ + { + localInputLen = lengthLimit; + } + } + + return localInputLen; +} +#endif /* FBL_MEM_ENABLE_SEGMENTATION || FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +/*********************************************************************************************************************** + * FblMemPadLength + **********************************************************************************************************************/ +/*! \brief Calculate number of bytes required to pad provided address range to memory segment size + * \param[in] address Start address of memory range + * \param[in] length Length of memory range + * \return Number of required padding bytes + **********************************************************************************************************************/ +static tFblLength FblMemPadLength( tFblAddress address, tFblLength length ) +{ + tFblLength localAddress; + tFblLength localLength; + tFblLength padLen; + tFblAddress alignMask; + vsint16 oldSegment; + + /* Local copy of length */ + localLength = length; + /* Special handling required for zero length + Address used directly */ + if (length > 0u) + { + localLength--; + } + + /* Calculate end address */ + localAddress = address + localLength; + + /* Initialize padding length */ + padLen = 0u; + + /* Remember current memory segment */ + oldSegment = memSegment; + + /* Evaluate memory segment */ + memSegment = FblMemSegmentNrGet(localAddress); + + /* Check if segment was found */ + if (memSegment >= 0) + { + /* Bit mask for memory segment alignment */ + alignMask = (tFblAddress)(MemDriver_SegmentSize - 1uL); + + /* Padding length calculated for end address of data to be padded */ + /* Invert all masked bits */ + padLen = localAddress ^ alignMask; + + /* Modify padding length for special case (zero length) */ + if (0u == length) + { + padLen++; + } + + /* Apply mask to cut of unnecessary bits (e.g. additional address info, overflow of addition) */ + padLen &= alignMask; + } + + /* Restore memory segment */ + memSegment = oldSegment; + + return padLen; +} + +/*********************************************************************************************************************** + * FblMemPadBuffer + **********************************************************************************************************************/ +/*! \brief Fill up the provided buffer with kFillChar if not aligned to the memory segment size + * \pre Buffer provided has to be large enough to hold added padding bytes + * \param[in] address Start address of memory range + * \param[in] length Length of memory range + * \param[in,out] data Pointer to last byte of actual data + * \return Number of padded bytes + **********************************************************************************************************************/ +static tFblLength FblMemPadBuffer( tFblAddress address, tFblLength length, tFblMemRamData data ) +{ + tFblMemRamData padBuffer; + tFblLength padLen; + tFblLength idx; + + /* Calculate number of required padding bytes */ + padLen = FblMemPadLength(address, length); + + /* In case data was already aligned the last buffer byte may be located at the very last memory address + Prevent address wrap around by relocating buffer not until padding is necessary */ + if (padLen > 0u) + { + /* Input buffer points to last byte of actual data */ + padBuffer = &data[1]; + + /* Append data to align buffer to segment size */ + for (idx = 0u; idx < padLen; idx++) + { +#if defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) + /* Save original data, restored after programming operation */ + gPaddingBuffer[idx] = padBuffer[idx]; +#endif /* FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ + + padBuffer[idx] = kFillChar; + } + } + + return padLen; +} + +#if defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) +/*********************************************************************************************************************** + * FblMemUnpadBuffer + **********************************************************************************************************************/ +/*! \brief Restore previous state of buffer after padding with fill pattern + * \pre memSegment correctly initialized (only relevant for multiple memory devices configuration) + * FblMemPadBuffer called before with exact same parameters + * \param[in] data Pointer to last byte of actual data + * \param[in] padLen Number of previously padded bytes + **********************************************************************************************************************/ +static void FblMemUnpadBuffer( tFblMemRamData data, tFblLength padLen ) +{ + /* In case data was already aligned the last buffer byte may be located at the very last memory address + Prevent address wrap around by relocating buffer not until padding is necessary */ + if (padLen > 0u) + { + /* Restore original data, overwritten by padding */ + (void)MEMCPY(&data[1u], gPaddingBuffer, padLen); /* PRQA S 0314 */ /* MD_FblMem_0314_0326_MemCpy */ + } +} +#endif /* FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ + +/*********************************************************************************************************************** + * FblMemCopyBuffer + **********************************************************************************************************************/ +/*! \brief Performs program operation to volatile memory + * \param[in] programAddress Program address + * \param[in] programLength Length of data (output: length actually programmed) + * \param[in] programData Pointer to program data + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +static tFblMemStatus FblMemCopyBuffer( tFblAddress programAddress, + const V_MEMRAM1 tFblLength V_MEMRAM2 V_MEMRAM3 * programLength, tFblMemConstRamData programData ) +{ + /* Copy input buffer to destination address */ + __ApplFblMemCopyBuffer(programAddress, programData, *programLength); /* PRQA S 0314, 0326 */ /* MD_FblMem_0314_0326_MemCpy */ + + return kFblMemStatus_Ok; +} + +/*********************************************************************************************************************** + * FblMemEraseRegionInternal + **********************************************************************************************************************/ +/*! \brief Performs erase operation in non-volatile memory + * \details All memory segments fully or partially covered by given region are affected. Gaps in the memory segment + * definition are skipped. + * \pre Memory driver initialized + * \param[in] eraseAddress Start address of erase region + * \param[in] eraseLength Length of erase region + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +/* PRQA S 2889, 6010, 6030 1 */ /* MD_FblMem_2889, MD_MSR_STPTH, MD_MSR_STCYC */ +static tFblMemStatus FblMemEraseRegionInternal( tFblAddress eraseAddress, tFblLength eraseLength ) +{ + tFblMemStatus retVal; + IO_ErrorType flashErrorCode; + tFblLength eraseRemainder; + tFblLength currentLength; + tFblLength distance; + vsint16 nextMemSegment; + tFblAddress localEraseAddress; +#if defined( __ApplFblMemConditionCheck ) + tFblMemStatus customReturnCode; +#endif /* __ApplFblMemConditionCheck */ + + retVal = kFblMemStatus_Ok; + + localEraseAddress = eraseAddress; + eraseRemainder = eraseLength; + memSegment = FblMemSegmentNrGet(localEraseAddress); + + /* Check if there is a valid block for start address */ + if (memSegment < 0) + { + FBL_MEM_SET_EXT_INFO(EraseAddress, localEraseAddress); + FBL_MEM_SET_STATUS(EraseOutsideFbt, retVal); + } + else + { + nextMemSegment = memSegment; + + while (eraseRemainder > 0u) + { + /* Watchdog and response pending handling */ + FblMemTriggerWatchdog(); + /* Force response pending on first loop cycle */ + FblMemResponsePending(); + + /* Initialize error address */ + FBL_MEM_SET_EXT_INFO(EraseAddress, localEraseAddress); + +#if defined( __ApplFblMemDriverReady ) + /* Check if required flash driver is initialized */ + if (kFblOk != __ApplFblMemDriverReady(memSegment)) + { + /* Flash driver initialization failure */ + FBL_MEM_SET_STATUS(EraseDriverNotReady, retVal); + return retVal; + } +#endif + + /* Check if erase range crosses Flash block boundary */ + currentLength = (FlashBlock[memSegment].end - localEraseAddress) + 1u; + if (eraseRemainder > currentLength) + { + nextMemSegment = memSegment + 1; + + if (nextMemSegment >= (vsint16)kNrOfFlashBlock) + { + /* End of erase region lies behind defined memory */ + FBL_MEM_SET_STATUS(EraseOutsideFbt, retVal); + return retVal; + } + + /* Update remainder */ + distance = FlashBlock[nextMemSegment].begin - localEraseAddress; + if (distance <= eraseRemainder) + { + eraseRemainder -= distance; + } + else + { + /* End of erase region lies in gap */ + FBL_MEM_SET_STATUS(EraseOutsideFbt, retVal); + return retVal; + } + } + else + { + currentLength = eraseRemainder; + eraseRemainder = 0u; + } + +#if defined( __ApplFblMemConditionCheck ) + /* Check conditions before executing memory operation */ + customReturnCode = __ApplFblMemConditionCheck(); + + if (kFblMemStatus_Ok != customReturnCode) + { + retVal = customReturnCode; + return retVal; + } +#endif /* __ApplFblMemConditionCheck */ +#if defined( __ApplFblMemPreErase ) + /* Perform actions directly before memory driver erase */ + if (kFblOk != __ApplFblMemPreErase()) + { + FBL_MEM_SET_STATUS(ErasePreErase, retVal); + return retVal; + } +#endif /* __ApplFblMemPreErase */ + + flashErrorCode = MemDriver_REraseSync(currentLength, localEraseAddress); + +#if defined( __ApplFblMemPostErase ) + /* Perform actions directly after memory driver erase */ + if (kFblOk != __ApplFblMemPostErase()) + { + FBL_MEM_SET_STATUS(ErasePostErase, retVal); + return retVal; + } +#endif /* __ApplFblMemPostErase */ +#if defined( __ApplFblMemConditionCheck ) + /* Check conditions after executing memory operation */ + customReturnCode = __ApplFblMemConditionCheck(); + + if (kFblMemStatus_Ok != customReturnCode) + { + retVal = customReturnCode; + return retVal; + } +#endif /* __ApplFblMemConditionCheck */ + + if (IO_E_OK != flashErrorCode) + { + /* Error while erasing */ + FBL_MEM_SET_EXT_STATUS(DriverErase, flashErrorCode, retVal); + return retVal; + } + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Only report progress when explicitly enabled */ + if (kFblMemProgressState_Enabled == gProgressState) + { + FblMemUpdateProgress(eraseRemainder); + } +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + + /* Continue with next segment */ + memSegment = nextMemSegment; + localEraseAddress = FlashBlock[memSegment].begin; + } + } + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemProgramBufferInternal + **********************************************************************************************************************/ +/*! \brief Performs program operation to non-volatile memory + * \details If the length is not aligned to the segment size the odd bytes are padded with the configured fill + * character. + * Programming may be suspended by an external event. In this case parameter programLength will be + * updated to reflect the length actually programmed + * In case resumable programming is active, crossing a flash block boundary leads to the setting + * of the programming state to the passed value. + * \pre Memory driver initialized, address aligned to memory segment size + * \param[in] programAddress Program address + * \param[in,out] programLength Length of data (output: length actually programmed) + * \param[in,out] programData Pointer to program data (contents are padded in case length is not aligned to memory + * segment size!) + * \param[in] checkPointState Programming state value to be set in case a checkpoint is reached + * Typical values are either kFblMemProgState_Checkpoint (suspend programming and indicate checkpoint) + * or kFblMemProgState_Pending (continue programming) + * + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +/* PRQA S 2889, 6010, 6030, 6050 1 */ /* MD_FblMem_2889, MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL */ +static tFblMemStatus FblMemProgramBufferInternal( tFblAddress programAddress, + V_MEMRAM1 tFblLength V_MEMRAM2 V_MEMRAM3 * programLength, tFblMemRamData programData, tFblMemProgState checkPointState ) +{ + tFblMemStatus retVal; + tFblLength currentLength; + tFblLength localLength; + tFblLength segLength; + tFblLength padLength; + tFblLength bufferIndex; + tFblLength padOffset; + IO_ErrorType flashErrorCode; + tFblAddress localProgramAddress; +#if defined( __ApplFblMemConditionCheck ) + tFblMemStatus customReturnCode; +#endif /* __ApplFblMemConditionCheck */ + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)checkPointState; +#endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + retVal = kFblMemStatus_Ok; + padLength = 0u; /* PRQA S 2982 */ /* MD_FblMem_2982 */ + padOffset = 0u; /* PRQA S 2982 */ /* MD_FblMem_2982 */ + localProgramAddress = programAddress; + + /* Copy requested length to local variable */ + localLength = *programLength; + /* Start at beginning of buffer */ + bufferIndex = 0u; + + /* Loop while data left and operation not suspended by external event */ + while ((localLength > 0u) && (kFblMemProgState_Pending == fblMemProgState)) + { + /* Watchdog and response pending handling */ + FblMemTriggerWatchdog(); +#if defined( FBL_ENABLE_ADAPTIVE_DATA_TRANSFER_RCRRP ) + /* Disable forced RCR-RP for adaptive mode */ +#else + /* Force response pending on first loop cycle */ + FblMemResponsePending(); +#endif /* FBL_ENABLE_ADAPTIVE_DATA_TRANSFER_RCRRP */ + + /* Initialize error address */ + FBL_MEM_SET_EXT_INFO(ProgramAddress, localProgramAddress); + + /* Length to be programmed in current loop cycle */ + currentLength = localLength; + /* Evaluate memory segment */ + memSegment = FblMemSegmentNrGet(localProgramAddress); + + /* Check if segment was found */ + if (memSegment < 0) + { + FBL_MEM_SET_STATUS(ProgramOutsideFbt, retVal); + return retVal; + } + +#if defined( __ApplFblMemDriverReady ) + /* Check if required flash driver is initialized */ + if (kFblOk != __ApplFblMemDriverReady(memSegment)) + { + /* Flash driver initialization failure */ + FBL_MEM_SET_STATUS(ProgramDriverNotReady, retVal); + return retVal; + } +#endif + + /* Check if address is aligned to memory segment size */ + if (0u != (localProgramAddress & ((tFblAddress)MemDriver_SegmentSize - 1u))) + { + FBL_MEM_SET_STATUS(ProgramUnalignedAddress, retVal); + return retVal; + } + + /* Remaining length until end of current segment */ + segLength = (FlashBlock[memSegment].end - localProgramAddress) + 1u; + + /* Download memory overlaps segment: adjust to current segment */ + if (segLength < currentLength) + { + /* Adapt currentLength to segment programming size */ + currentLength = segLength; + } + +#if defined( FBL_ENABLE_FUNC_VIRTUAL_MEMORY ) + if (MemDriver_IsVirtualMem(localProgramAddress) == IO_E_OK) + { + /* Announce the end-address to the virtual memory driver */ + if (MemDriver_RVirtualMemPayloadEndSync(localProgramAddress + currentLength - 1u) != IO_E_OK) + { + FBL_MEM_SET_STATUS(ProgramDriverNotReady, retVal); + return retVal; + } + } +#endif /* FBL_ENABLE_FUNC_VIRTUAL_MEMORY */ + + if (segLength > currentLength) + { + /* Offset to last byte of actual data */ + padOffset = bufferIndex + (currentLength - 1u); + + /* Pad buffer to memory segment */ + padLength = FblMemPadBuffer(localProgramAddress, currentLength, &programData[padOffset]); + currentLength += padLength; + } + +#if defined( __ApplFblMemConditionCheck ) + /* Check conditions before executing memory operation */ + customReturnCode = __ApplFblMemConditionCheck(); + + if (kFblMemStatus_Ok != customReturnCode) + { + retVal = customReturnCode; + return retVal; + } +#endif /* __ApplFblMemConditionCheck */ +#if defined( __ApplFblMemPreWrite ) + /* Perform actions directly before memory driver write */ + if (kFblOk != __ApplFblMemPreWrite()) + { + FBL_MEM_SET_STATUS(ProgramPreWrite, retVal); + return retVal; + } +#endif /* __ApplFblMemPreWrite */ + + /* Pass programming request to memory driver */ + flashErrorCode = MemDriver_RWriteSync(&programData[bufferIndex], currentLength, localProgramAddress); + +#if defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) + /* Restore original data, overwritten by padding */ + FblMemUnpadBuffer(&programData[padOffset], padLength); +#endif /* FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ + +#if defined( __ApplFblMemPostWrite ) + /* Perform actions directly after memory driver write */ + if (kFblOk != __ApplFblMemPostWrite()) + { + FBL_MEM_SET_STATUS(ProgramPostWrite, retVal); + return retVal; + } +#endif /* __ApplFblMemPostWrite */ +#if defined( __ApplFblMemConditionCheck ) + /* Check conditions after executing memory operation */ + customReturnCode = __ApplFblMemConditionCheck(); + + if (kFblMemStatus_Ok != customReturnCode) + { + retVal = customReturnCode; + return retVal; + } +#endif /* __ApplFblMemConditionCheck */ + + /* Check result of programming operation */ + if (IO_E_OK != flashErrorCode) + { + FBL_MEM_SET_EXT_STATUS(DriverWrite, flashErrorCode, retVal); + return retVal; + } + + + /* Update address for next cycle */ + localProgramAddress += (tFblAddress)currentLength; + + if (localLength > currentLength) + { + /* Prepare buffer index for next loop */ + bufferIndex += currentLength; + localLength -= currentLength; + } + else + { + /* Lengths should be exactly the same here */ + assertFblInternal(((currentLength - padLength) == localLength), kFblMemAssertParameterOutOfRange); + + /* Buffer completely processed */ + localLength = 0u; + } + + } + + /* Return length actually written (without padding) */ + *programLength -= localLength; + + return retVal; +} + +# if defined( FBL_ENABLE_MULTIPLE_MEM_DEVICES ) && \ + defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) +/*********************************************************************************************************************** + * FblMemGetSpecificRemainder + **********************************************************************************************************************/ +/*! \brief Calculate remainder of given range specific for affected memory device + * \param[in] address Start address of memory range + * \param[in] length Length of memory range + * \return Remainder to full memory segment in byte + **********************************************************************************************************************/ +static tFblLength FblMemGetSpecificRemainder( tFblAddress address, tFblLength length ) +{ + tFblLength localRemainder; + vsint16 tempSegment; + + /* Initialize remainder */ + localRemainder = 0u; + + /* Re-evaluate memory segment */ + tempSegment = memSegment; + memSegment = FblMemSegmentNrGet(address + (length - 1u)); + + if (memSegment >= 0) + { + /* Calculate remainder */ + localRemainder = FblMemGetRemainder(address, length, MemDriver_SegmentSize); + } + + /* Restore previous memory segment value */ + memSegment = tempSegment; + + return localRemainder; +} +# endif /* FBL_ENABLE_MULTIPLE_MEM_DEVICES && FBL_MEM_ENABLE_REMAINDER_HANDLING */ + +#if defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) +/*********************************************************************************************************************** + * FblMemRelocateBufferOffset + **********************************************************************************************************************/ +/*! \brief Verify provided buffer lies within range of existing buffer and relocate offset accordingly + * \details Provided buffer has to reside completely in existing buffer + * \param[in,out] activeJob Information of buffer to be updated + * \param[in] buffer Pointer to provided buffer + * \param[in] offset Offset index into provided buffer + * \param[in] length Length of data in provided buffer + * \return kFblMemStatus_Ok if requested buffer lies inside provided information and offset could be relocated, + * kFblMemStatus_Failed otherwise + **********************************************************************************************************************/ +static tFblMemStatus FblMemRelocateBufferOffset( V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * activeJob, + tFblMemConstRamData buffer, tFblLength offset, tFblLength length ) +{ + tFblMemStatus retVal; + tFblMemConstRamData activeBuffer; + tFblLength activeOffset; + + retVal = kFblMemStatus_Failed; + activeBuffer = activeJob->buffer; + + /* Provided buffer has to reside in raw input buffer */ + if (buffer >= activeBuffer) + { + activeOffset = (tFblLength)(buffer - activeBuffer); /* PRQA S 0488 */ /* MD_FblMem_0488 */ + + /* Provided data has to lie within raw input buffer (excluding potential padding) */ + if ( (length <= activeJob->netSize) + && (offset <= (activeJob->netSize - length)) + && (activeOffset < activeJob->totalSize) + && ((offset + length + FBL_MEM_REMAINDER_PADDING) <= (activeJob->totalSize - activeOffset)) ) + { +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + /* Remainder requires reserved area in front of actual data (defined by current offset) */ + if ((activeOffset + offset) >= activeJob->offset) +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + { + /* Relocate offset to provided buffer */ + activeJob->offset = activeOffset; + retVal = kFblMemStatus_Ok; + } + } + } + + return retVal; +} +#endif /* FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ + +#if defined( FBL_MEM_ENABLE_VARYING_INPUT_BUFFER ) +/*********************************************************************************************************************** + * FblMemSearchInputBuffer + **********************************************************************************************************************/ +/*! \brief Search matching input buffer for provided buffer + * \details Look for input buffer in which provided buffer completely resides, respective job information is + * moved to beginning of free queue and offset is relocated to match provided buffer + * \param[in] buffer Pointer to provided buffer + * \param[in] offset Offset index into provided buffer + * \param[in] length Length of data in provided buffer + * \return kFblMemStatus_Ok if requested buffer lies inside of available buffer and offset could be relocated, + * kFblMemStatus_Failed otherwise + **********************************************************************************************************************/ +static tFblMemStatus FblMemSearchInputBuffer( tFblMemConstRamData buffer, tFblLength offset, tFblLength length ) +{ + tFblMemStatus retVal; + tFblMemQueueHandle queueHandle; + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * activeJob; + + retVal = kFblMemStatus_Failed; + + /* Get first buffer handle */ + queueHandle = FblMemQueueGetFirstFreeHandle(FBL_MEM_PIPE_PROG_QUEUE); + + /* Loop all free buffers */ + while (FBL_MEM_QUEUE_HANDLE_HEAD_FREE != queueHandle) + { + activeJob = FBL_MEM_PIPE_PROG_QUEUE[queueHandle].job; + + /* Check for matching input buffer */ + if (kFblMemStatus_Ok == FblMemRelocateBufferOffset(activeJob, buffer, offset, length)) + { + /* Move to beginning of free queue */ + (void)FblMemQueueMove(FBL_MEM_PIPE_PROG_QUEUE, queueHandle, FBL_MEM_QUEUE_HANDLE_HEAD_FREE); + retVal = kFblMemStatus_Ok; + + break; + } + + /* Get next free buffer */ + queueHandle = FBL_MEM_PIPE_PROG_QUEUE[queueHandle].next; + } + + return retVal; +} +#endif /* FBL_MEM_ENABLE_VARYING_INPUT_BUFFER */ + +/*********************************************************************************************************************** + * FblMemProgramStream + **********************************************************************************************************************/ +/*! \brief Take a byte stream to be programmed and align it to the memory requirements + * \details If the length is not aligned to the segment size the odd bytes are stored in a remainder buffer, + * which will be programmed on the next call. + * Programming may be suspended by an external event. In this case parameter programLength will be + * updated to reflect the length actually programmed. + * \pre FblMemSegmentStartIndication executed before + * \param[in] programJob Information of buffer to be programmed + * \param[in,out] programLength Requested program length (output: length actually programmed) + * \param[in] mode Operation mode (include remainder in case of finalization) + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +/* PRQA S 6010, 6030 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC */ +static tFblMemStatus FblMemProgramStream( const V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * programJob, + V_MEMRAM1 tFblLength V_MEMRAM2 V_MEMRAM3 * programLength, tFblMemOperationMode mode ) +{ + tFblMemStatus retVal; + tFblMemRamData programData; + tFblLength localLength; +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + tFblLength requestLength; + tFblLength localRemainder; +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ +# if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) +# else + (void)mode; +# endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ +#endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + FblMemTriggerWatchdog(); + + /* Store requested length to local variable */ + localLength = *programLength; + /* Pointer to current buffer position */ + programData = FblMemGetBuffer(programJob); + +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + localRemainder = 0u; + + /* No remainder handling required for volatile memory */ + if (kFblMemType_RAM != gSegInfo.input.type) + { + /* + Handle remainder from previous run + Special case where remainder is empty is not explicitly handled + as performing the following operations with a value of zero + doesn't have any side-effects + */ + + /* Check available space in front of current data */ + assertFblInternal(gSegInfo.writeRemainder <= programJob->position, kFblMemAssertParameterOutOfRange); + + /* Redirect programming pointer to make room for remainder */ + programData = &programJob->buffer[programJob->position - gSegInfo.writeRemainder]; + + /* Copy remainder in front of actual data */ + (void)MEMCPY(programData, gRemainderBuffer.data, gSegInfo.writeRemainder); /* PRQA S 0314 */ /* MD_FblMem_0314_0326_MemCpy */ + /* Update length to be programmed */ + localLength += gSegInfo.writeRemainder; + + /* Write complete data if explicit finalization is requested */ + if ( (kFblMemOperationMode_Finalize == mode) +# if defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) +# else + /* or end of requested segment is reached */ + || (localLength == gSegInfo.writeLength) +# endif /* FBL_ENABLE_PROCESSED_DATA_LENGTH */ + ) + { + /* No remainder left */ + } + else + { + /* Calculate new remainder, not aligned to segment size */ + localRemainder = FblMemGetWriteRemainder(gSegInfo.writeAddress, localLength); + + /* Handle special case: When the segment was already finalized, the padding isn't included in write address + Remainder calculation thus includes data already written, resulting in a value larger than the requested length + This would cause two range overflows, but is only a cosmetic issue, as it cancels out in the end */ + if (localRemainder > localLength) + { + localRemainder = 0u; + } + + /* Update length to be programmed */ + localLength -= localRemainder; + + } + } + + /* Remember actual programming length, may be altered by programming routine */ + requestLength = localLength; +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + + /* Verify complete programming length does not exceed previously requested memory range */ +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + if ((localLength + localRemainder) > gSegInfo.writeLength) +#else + if (localLength > gSegInfo.writeLength) +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + { + FBL_MEM_SET_STATUS(ProgramOverflow, retVal); + } + else + { + /* + Call programming function even if actual length is zero + In this case the input length will be completely moved to the remainder + */ + if (kFblMemType_RAM == gSegInfo.input.type) + { + /* Copy to volatile memory */ + retVal = FblMemCopyBuffer(gSegInfo.writeAddress, &localLength, programData); + } + else + { + /* Program non-volatile memory */ + retVal = FblMemProgramBufferInternal(gSegInfo.writeAddress, &localLength, programData, kFblMemProgState_Checkpoint); + } + } + + /* Check result */ + if (kFblMemStatus_Ok == retVal) + { + /* Returned length shall not exceed requested length */ + assertFblInternal(localLength <= gSegInfo.writeLength, kFblMemAssertParameterOutOfRange); + + /* Update segment information */ + gSegInfo.writeAddress += (tFblAddress)localLength; + /* Reduce expected remainder */ + gSegInfo.writeLength -= localLength; +#if defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) + /* Length actually written */ + gSegInfo.writtenLength += localLength; +#endif /* FBL_ENABLE_PROCESSED_DATA_LENGTH */ + +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + /* Everything consumed, program length already matches */ + if (requestLength == localLength) + { + /* Everything written, store new remaining data */ + gSegInfo.writeRemainder = localRemainder; + /* Call copy function even if remainder length is zero */ + (void)MEMCPY(gRemainderBuffer.data, &programData[localLength], localRemainder); /* PRQA S 0314 */ /* MD_FblMem_0314_0326_MemCpy */ + } + /* Data partially programmed (most likely suspended by external event) */ + else if (localLength > 0u) + { + /* Store consumed length */ + *programLength = localLength - gSegInfo.writeRemainder; + /* Some data written, no remainder */ + gSegInfo.writeRemainder = 0u; + } + else + { + /* Nothing consumed at all */ + *programLength = 0u; + /* Nothing written at all, remainder from previous run unchanged */ + } +#else + /* Store consumed length */ + *programLength = localLength; +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + } + + return retVal; +} + +#if defined( FBL_MEM_ENABLE_VERIFY_STREAM ) +/*********************************************************************************************************************** + * FblMemVerifyInput + **********************************************************************************************************************/ +/*! \brief Execute input verification operation + * \details Pass input data to given input verification routine + * No operation will be carried out if null pointer is passed as function + * \param[in] routine Input verification operation to be executed + * \param[in] data Verification data + * - FBL_MEM_VERIFY_STATE_INIT / FBL_MEM_VERIFY_STATE_FINALIZE: Usually irrelevant + * - FBL_MEM_VERIFY_STATE_COMPUTE: Data to be hashed + * - FBL_MEM_VERIFY_STATE_VERIFY: Reference checksum / signature + * state Sub-operation to be executed + * \param[in,out] result Pointer to extended verification result + * FBL_MEM_VERIFY_STATUS_NULL if neither relevant nor used + * \return kFblMemStatus_Ok if operation successfully executed, + * kFblMemStatus_Failed otherwise + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FblMem_3673 */ +static tFblMemStatus FblMemVerifyInput( V_MEMRAM1 tFblMemVerifyRoutineInput V_MEMRAM2 V_MEMRAM3 * routine, + const V_MEMRAM1 tFblMemVerifyData V_MEMRAM2 V_MEMRAM3 * data, vuint8 state, + V_MEMRAM1 tFblMemVerifyStatus V_MEMRAM2 V_MEMRAM3 * result ) +{ + tFblMemStatus retVal; + tFblMemVerifyStatus localResult; + + retVal = kFblMemStatus_Ok; + localResult = FBL_MEM_VERIFY_OK; + + /* Null pointer passed as verification function disables functionality */ + if (FBL_MEM_VERIFY_FCT_INPUT_NULL != routine->function) + { + routine->param->sigState = state; + routine->param->sigSourceBuffer = data->data; + routine->param->sigByteCount = (tFblMemVerifyLength)data->length; +# if defined( FBL_MEM_ENABLE_EXT_TRIGGER_INPUT_VERIFY ) + routine->param->wdTriggerFct = (tFblMemVerifyWdFct)&FblMemTriggerWatchdogExt; /* PRQA S 0313 */ /* MD_FblMem_0313 */ +# else + routine->param->wdTriggerFct = (tFblMemVerifyWdFct)&FblMemTriggerWatchdog; +# endif /* FBL_MEM_ENABLE_EXT_TRIGGER_INPUT_VERIFY */ + + /* Call verification function and set extended status */ + localResult = routine->function(routine->param); + if (FBL_MEM_VERIFY_OK != localResult) + { + retVal = kFblMemStatus_Failed; + } + } + + if (FBL_MEM_VERIFY_STATUS_NULL != result) + { + /* Pass extended result */ + *result |= localResult; + } + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemInitVerifyInput + **********************************************************************************************************************/ +/*! \brief Initialize input verification(s) + * \return kFblMemStatus_Ok if operation successfully executed, + * kFblMemStatus_Failed otherwise + **********************************************************************************************************************/ +static tFblMemStatus FblMemInitVerifyInput( void ) +{ + tFblMemStatus retVal; + tFblMemVerifyData verifyData; + + retVal = kFblMemStatus_Ok; + + /* Not used by initialization */ + verifyData.data = FBL_MEM_BUFFER_NULL; + verifyData.length = 0u; + + /* Inverted order of verification routines + Error code may be overwritten (simplifies implementation) */ +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Initialize the calculation */ + if (kFblMemStatus_Ok != FblMemVerifyInput( &gBlockInfo.verifyRoutinePipe, &verifyData, + FBL_MEM_VERIFY_STATE_INIT, FBL_MEM_VERIFY_STATUS_NULL )) + { + /* Overwrites previous error code */ + retVal = kFblMemStatus_Failed; + } +# endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + + + + return retVal; +} +#endif /* FBL_MEM_ENABLE_VERIFY_STREAM */ + + + +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +/*********************************************************************************************************************** + * FblMemPrepareVerifyPipeJob + **********************************************************************************************************************/ +/*! \brief Get active pipelined verification job + * \details If no previous job is pending for the requested segment, a new job is queued, using the provided address + * as starting point. + * \param[in] segmentIndex Index of requested segment + * \param[in] address Address of newly programmed data + * \return Pointer to the current verify job + **********************************************************************************************************************/ +static V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * FblMemPrepareVerifyPipeJob( vuintx segmentIndex, tFblAddress address ) +{ + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * verifyJob; + + verifyJob = FBL_MEM_JOB_NULL; + + /* Null pointer passed as verification function disables functionality */ + if (FBL_MEM_VERIFY_FCT_INPUT_NULL != gBlockInfo.verifyRoutinePipe.function) + { + /* Check for error condition */ + if (kFblMemStatus_Ok == gErrorStatus) + { + /* Verification job for current segment not yet included in processing queue */ + if ( (FblMemQueueIsEmpty(gVerifyPipeQueue)) + || (FblMemQueueGetLastUsedEntry(gVerifyPipeQueue).job->segmentIndex != segmentIndex) ) + { + /* Assert queue not full */ + assertFblInternal((!FblMemQueueIsFull(gVerifyPipeQueue)), kFblMemAssertParameterOutOfRange); + + /* Get first free job */ + verifyJob = FblMemQueueGetFirstFreeEntry(gVerifyPipeQueue).job; + + /* Start verification at current address */ + verifyJob->baseAddress = address; + verifyJob->position = 0u; + verifyJob->netSize = 0u; + verifyJob->totalSize = 0u; + + /* Add job to processing queue */ + (void)FblMemQueueDefaultPrioInsert(gProcessingQueue, verifyJob, segmentIndex); + /* Append input info to separate queue, managing verification jobs exclusively */ + (void)FblMemQueueAppend(gVerifyPipeQueue); + } + + /* Get active verification job */ + verifyJob = FblMemQueueGetLastUsedEntry(gVerifyPipeQueue).job; + } + } + + return verifyJob; +} + +/*********************************************************************************************************************** + * FblMemUpdateVerifyPipeJob + **********************************************************************************************************************/ +/*! \brief Update job of pipelined verification + * \details Add programmed data contents to queue, so it can be verified in parallel to data transmission. + * If no previous data is pending for the current segment, a new job is queued, using the provided address + * as starting point. + * The length is added to the last job in the queue. + * \param[in] segmentIndex Index of requested segment + * \param[in] address Address of newly programmed data + * \param[in] length Length of newly programmed data + * \return Pointer to the current verify job + **********************************************************************************************************************/ +static V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * FblMemUpdateVerifyPipeJob( vuintx segmentIndex, tFblAddress address, tFblLength length ) +{ + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * verifyJob; + + verifyJob = FBL_MEM_JOB_NULL; + + if (length > 0u) + { + verifyJob = FblMemPrepareVerifyPipeJob(segmentIndex, address); + + /* Check for null pointer */ + if (FBL_MEM_JOB_NULL != verifyJob) + { + /* Update pipelined verification information */ + verifyJob->used += length; + verifyJob->netSize += length; + verifyJob->totalSize += length; + } + } + + return verifyJob; +} +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +/*********************************************************************************************************************** + * FblMemProcessJob + **********************************************************************************************************************/ +/*! \brief Perform processing operations on provided job + * \details Depending on the type and configuration one of the following operations will be carried out: + * - Update verification with buffer contents + * - Read already programmed data in temporary buffer for verification + * - Process buffer contents (e.g. decryption or decompression) + * Result placed in intermediate buffer, which is prepended to the processing queue + * - Program buffer contents + * - Flush program remainder + * - Pass data to other instance + * Buffer may be processed at once or split into smaller segments, requiring multiple call cycles to + * finish the buffer + * This depends on the configuration and finalization flag + * \pre FblMemSegmentStartIndication executed before + * \param[in] activeJob Information of processed buffer + * \param[in] mode Operation mode used to trigger finalization + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +/* PRQA S 6010, 6030, 6050, 6080 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +static tFblMemStatus FblMemProcessJob( V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * activeJob, tFblMemOperationMode mode ) +{ + tFblLength actualLength; +#if defined( FBL_MEM_ENABLE_VERIFY_STREAM ) || \ + defined( FBL_ENABLE_DATA_PROCESSING ) || \ + defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + tFblMemRamData activeBuffer; +#endif /* FBL_MEM_ENABLE_VERIFY_STREAM || FBL_ENABLE_DATA_PROCESSING || FBL_MEM_ENABLE_STREAM_OUTPUT || FBL_MEM_ENABLE_PASSTHROUGH */ +#if defined( FBL_ENABLE_DATA_PROCESSING ) + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * procOutJob; + static vuint8 tryCounterDataProc; +#endif /* FBL_ENABLE_DATA_PROCESSING */ +#if defined( FBL_MEM_ENABLE_VERIFY_STREAM ) + tFblMemVerifyData verifyData; +#endif /* FBL_MEM_ENABLE_VERIFY_STREAM */ +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + tFblAddress prevAddress; + tFblLength prevRemainder; + tFblLength pipeVerificationLength; +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + tFblResult streamResult; +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + tFblAddress fillAddress; + tFblLength fillLength; + tFblLength tempLength; +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + tFblMemOperationMode finalizeStream; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ +# if defined( FBL_MEM_ENABLE_SEGMENTATION ) +# else + (void)mode; +# endif /* FBL_MEM_ENABLE_SEGMENTATION */ +#endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + /* Handle watchdog trigger */ + FblMemTriggerWatchdog(); + +#if defined( FBL_MEM_ENABLE_VERIFY_STREAM ) || \ + defined( FBL_ENABLE_DATA_PROCESSING ) || \ + defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + /* Get pointer to current buffer position */ + activeBuffer = FblMemGetBuffer(activeJob); +#endif /* FBL_MEM_ENABLE_VERIFY_STREAM || FBL_ENABLE_DATA_PROCESSING || FBL_MEM_ENABLE_STREAM_OUTPUT || FBL_MEM_ENABLE_PASSTHROUGH */ + /* Limit processed length to configured value */ + actualLength = FblMemLimitLength(activeJob->used, activeJob->type, mode); + + /* Handle buffer types */ + switch (activeJob->type) + { +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Pipelined verification */ +# if defined( FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH ) + case kFblMemJobType_VerifyPipeInfo: + { + /* Pass buffer to signature calculation */ + verifyData.data = activeBuffer; + verifyData.length = actualLength; + + /* Add current data to the signature */ + if (kFblMemStatus_Ok != FblMemVerifyInput( &gBlockInfo.verifyRoutinePipe, &verifyData, + FBL_MEM_VERIFY_STATE_COMPUTE, FBL_MEM_VERIFY_STATUS_NULL )) + { + /* Compute operation failed */ + FBL_MEM_SET_STATUS(VerifyCompute, gErrorStatus); + } + + /* Switch job type to read back programmed data */ + activeJob->type = kFblMemJobType_VerifyPipeRead; + /* Prevent modification of position value used by read back operation */ + activeJob->used -= actualLength; + actualLength = 0u; + + break; + } +# endif /* FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH */ + case kFblMemJobType_VerifyPipeRead: + { +# if defined( FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH ) + /* Reset to default completion mode, as address information operates in explicit finalization mode */ + activeJob->completion = kFblMemOperationMode_Normal; +# endif /* FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH */ + + /* Verify the pipelined read only in case there is data to be verified */ + if (0u != actualLength) + { + /* Read back a chunk of the already programmed data for verification */ +# if defined( FBL_MEM_ENABLE_SWITCH_READMEMORY_PARAM ) + /* Parameters order changed in comparison to HIS security module specification */ + if (gBlockInfo.readFct(activeJob->baseAddress + activeJob->position, actualLength, gVerifyPipeUpdateJob.buffer) != actualLength) +# else + /* Parameters order as defined by HIS security module specification */ + if (gBlockInfo.readFct(activeJob->baseAddress + activeJob->position, gVerifyPipeUpdateJob.buffer, actualLength) != actualLength) +# endif /* FBL_MEM_ENABLE_SWITCH_READMEMORY_PARAM */ + { + /* Read operation failed */ + FBL_MEM_SET_STATUS(VerifyCompute, gErrorStatus); + } + else + { + /* Data successfully read, pass to update routine */ + gVerifyPipeUpdateJob.position = 0u; + gVerifyPipeUpdateJob.used = actualLength; + + /* Queue updated job */ + (void)FblMemQueueDefaultPrioInsert(gProcessingQueue, &gVerifyPipeUpdateJob, activeJob->segmentIndex); + } + } + + break; + } + case kFblMemJobType_VerifyPipeUpdate: + { + /* Pass buffer to signature calculation */ + verifyData.data = activeBuffer; + verifyData.length = actualLength; + + /* Add current data to the signature */ + if (kFblMemStatus_Ok != FblMemVerifyInput( &gBlockInfo.verifyRoutinePipe, &verifyData, + FBL_MEM_VERIFY_STATE_COMPUTE, FBL_MEM_VERIFY_STATUS_NULL )) + { + /* Compute operation failed */ + FBL_MEM_SET_STATUS(VerifyCompute, gErrorStatus); + } + + break; + } + case kFblMemJobType_VerifyPipeFinalize: + { + /* Not used by finalization */ + verifyData.data = activeBuffer; + verifyData.length = actualLength; + + /* Finish the calculation */ + if (kFblMemStatus_Ok != FblMemVerifyInput( &gBlockInfo.verifyRoutinePipe, &verifyData, + FBL_MEM_VERIFY_STATE_FINALIZE, FBL_MEM_VERIFY_STATUS_NULL )) + { + /* Verify finalization failed */ + FBL_MEM_SET_STATUS(VerifyFinalize, gErrorStatus); + } + + break; + } +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ +#if defined( FBL_ENABLE_DATA_PROCESSING ) + /* Data processing */ + case kFblMemJobType_ProcInput: + case kFblMemJobType_ProcFinalize: + { +# if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + if (kFblOk == __ApplFblMemIsStreamOutputRequired(gSegInfo.input.dataFormat)) + { + procOutJob = &gStreamProcJob; + } + else +# endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ + { + procOutJob = &gProcWriteJob; + } + + /* Update position of output buffer to accommodate for programming remainder */ + procOutJob->position = gSegInfo.writeRemainder; + + /* Limit input length to 16 bit */ + if (actualLength > 0xFFFFu) + { + actualLength = 0xFFFFu; + } + + /* + Initialize parameters for data processing. + Note: Other members have been set during initialization + */ + gProcParam.dataBuffer = activeBuffer; + gProcParam.dataLength = (vuint16)actualLength; + /* Align output buffer according to current fill level */ + gProcParam.dataOutBuffer = &((FblMemGetBuffer(procOutJob))[procOutJob->used]); /* PRQA S 2822 */ /* MD_FblMem_2822 */ + gProcParam.dataOutLength = 0u; + + /* Call API function for user specific data processing */ + if (kFblOk != ApplFblDataProcessing(&gProcParam)) + { + FBL_MEM_SET_STATUS(DataProc, gErrorStatus); + } + else + { + if ((gProcParam.dataOutLength | gProcParam.dataLength) == 0u) + { + if (kFblMemJobType_ProcFinalize == activeJob->type) + { + /* Finalize data processing + gProcWriteJob already has correct values */ + if (kFblOk != ApplFblDeinitDataProcessing(&gProcParam)) + { + FBL_MEM_SET_STATUS(DataProcDeinit, gErrorStatus); + } + + /* Finish job processing */ + activeJob->completion = kFblMemOperationMode_Unconditional; + } + else + { + if (tryCounterDataProc >= FBL_MEM_TRY_COUNTER_LIMIT_DATA_PROC) + { + /* Nothing consumed or produced at all, avoid endless loop */ + FBL_MEM_SET_STATUS(DataProcConsume, gErrorStatus); + } + else + { + tryCounterDataProc++; + } + } + } + else + { + tryCounterDataProc = 0u; + } + } + + if (kFblMemStatus_Ok == gErrorStatus) + { + /* Update consumed length */ + actualLength = gProcParam.dataLength; + + /* Any data produced? */ + if (gProcParam.dataOutLength > 0u) + { + /* Output buffer changed? */ + assertFblUser((gProcParam.dataOutBuffer == &((FblMemGetBuffer(procOutJob))[procOutJob->used])), kFblMemAssertUserResultOutOfRange); /* PRQA S 2822 */ /* MD_FblMem_2822 */ + /* Output length exceeds configured limit? */ + assertFblUser((gProcParam.dataOutLength <= FBL_MEM_INTERNAL_PROC_SEGMENTATION), kFblMemAssertUserResultOutOfRange); + + /* Store processed data information */ + procOutJob->used += gProcParam.dataOutLength; + + /* Total used length exceeds buffer limits? */ + assertFblInternal((procOutJob->used <= (procOutJob->totalSize - procOutJob->offset)), kFblMemAssertParameterOutOfRange); + +# if defined( FBL_MEM_ENABLE_PROC_SEGMENTATION ) + /* Accumulate multiple data processing calls before passing output data to write routine */ + + /* Buffer was previously empty + Add behind current input data using low prio so that data will definitely be programmed after processing */ + if (procOutJob->used == gProcParam.dataOutLength) + { + /* Insert processed data into the queue and remember handle */ + gProcHandle = FblMemQueueDefaultPrioInsert(gProcessingQueue, procOutJob, activeJob->segmentIndex); + } + + /* Buffer is (almost) filled and has to be programmed before continuing processing */ + if ((procOutJob->netSize - procOutJob->used) < FBL_MEM_INTERNAL_PROC_SEGMENTATION) + { + /* Move processed data buffer in front of input data job by updating to higher priority + Handle set during current or previous cycle */ + (void)FblMemQueuePrioUpdate(gProcessingQueue, gProcHandle, (tFblMemQueuePrio)kFblMemJobPrio_ProcWriteHigh); + } +# else + /* Insert processed data into the queue */ + (void)FblMemQueueDefaultPrioInsert(gProcessingQueue, procOutJob, activeJob->segmentIndex); +# endif /* FBL_MEM_ENABLE_PROC_SEGMENTATION */ + } + + } + + break; + } + case kFblMemJobType_ProcWrite: +#endif /* FBL_ENABLE_DATA_PROCESSING */ +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + case kFblMemJobType_WriteFinalize: +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + case kFblMemJobType_InputWrite: + { +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Remember current address and remainder length */ + prevAddress = gSegInfo.writeAddress; + prevRemainder = gSegInfo.writeRemainder; +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + if (kFblMemJobType_WriteFinalize == activeJob->type) + { + finalizeStream = kFblMemOperationMode_Finalize; + /* Update position of output buffer to accommodate for programming remainder */ + activeJob->position = gSegInfo.writeRemainder; + } +# if defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) +# else + else if (kFblMemJobType_InputWrite == activeJob->type) + { + /* Force programming of any potential remainder */ + finalizeStream = kFblMemOperationMode_Finalize; + } +# endif /* FBL_ENABLE_UNALIGNED_DATA_TRANSFER */ + else +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + { + finalizeStream = kFblMemOperationMode_Normal; + } + + /* Program data, error code reflects result of operation */ + gErrorStatus = FblMemProgramStream(activeJob, &actualLength, finalizeStream); + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Update progress information */ + if (kFblMemStatus_Ok == gErrorStatus) + { +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + FblMemUpdateProgress(gSegInfo.writeLength + gGapFillJob.used); +#else + FblMemUpdateProgress(gSegInfo.writeLength); +#endif + } +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + + + +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Update size of data for pipelined verification */ + pipeVerificationLength = ((actualLength + prevRemainder) - gSegInfo.writeRemainder); + +#if defined( FBL_VERIFICATION_SEGMENT_INDEX ) + /* Check if written data is part of the verification process */ + if ((prevAddress + pipeVerificationLength) > (gSegInfo.input.logicalLength + gSegInfo.input.targetAddress)) + { + /* Data (signature/CRC) might be written at addresses larger than logical end of data, prevent underflow */ + if (prevAddress > (gSegInfo.input.logicalLength + gSegInfo.input.targetAddress)) + { + /* No more data to verify, signature/CRC was written */ + pipeVerificationLength = 0u; + } + else + { + /* Verify data until signature/CRC starts */ + pipeVerificationLength = (gSegInfo.input.logicalLength + gSegInfo.input.targetAddress) - prevAddress; + } + } +#endif /* FBL_VERIFICATION_SEGMENT_INDEX */ + /* Update pipelined verification information + Start verification at current write address + Include currently written data without possible remainder */ + (void)FblMemUpdateVerifyPipeJob(gSegInfo.ownIndex, prevAddress, pipeVerificationLength); +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + + break; + } +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + case kFblMemJobType_StreamInput: + case kFblMemJobType_StreamProc: + case kFblMemJobType_StreamFinalize: + { + /* + Initialize parameters for stream output. + Note: Other members have been set during initialization + */ + gStreamParam.inputData = activeBuffer; + gStreamParam.inputLength = actualLength; + gStreamParam.consumedLength = 0u; + gStreamParam.producedLength = 0u; + gStreamParam.address = gSegInfo.writeAddress; + gStreamParam.length = gSegInfo.writeLength; + + if (kFblMemJobType_StreamFinalize == activeJob->type) + { + /* Call API function for user specific stream output */ + streamResult = ApplFblFinalizeStreamOutput(&gStreamParam); + } + else + { + /* Call API function for user specific stream output */ + streamResult = ApplFblStreamOutput(&gStreamParam); + } + + if (kFblOk != streamResult) + { + FBL_MEM_SET_STATUS(StreamOutput, gErrorStatus); + } + else + { + if ((gStreamParam.consumedLength | gStreamParam.producedLength) == 0u) + { + if (kFblMemJobType_StreamFinalize == activeJob->type) + { + /* Finalize stream output + Parameter already has correct values */ + if (kFblOk != ApplFblDeinitStreamOutput(&gStreamParam)) + { + FBL_MEM_SET_STATUS(StreamOutputDeinit, gErrorStatus); + } + + /* Finish job processing */ + activeJob->completion = kFblMemOperationMode_Unconditional; + } + else + { + /* Nothing consumed or produced at all, avoid endless loop */ + FBL_MEM_SET_STATUS(StreamOutputConsume, gErrorStatus); + } + } + } + + if (kFblMemStatus_Ok == gErrorStatus) + { + /* Update consumed length */ + actualLength = gStreamParam.consumedLength; + + /* Any data produced? */ + if (gStreamParam.producedLength > 0u) + { + /* Verify complete programming length does not exceed previously requested memory range */ + if (gStreamParam.producedLength > gSegInfo.writeLength) + { + FBL_MEM_SET_STATUS(StreamOutputConsume, gErrorStatus); + } + else + { +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Update pipelined verification information */ + (void)FblMemUpdateVerifyPipeJob(gSegInfo.ownIndex, gSegInfo.writeAddress, gStreamParam.producedLength); +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + + /* Update segment information */ + gSegInfo.writeAddress += gStreamParam.producedLength; + /* Reduce expected remainder */ + gSegInfo.writeLength -= gStreamParam.producedLength; +#if defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) + /* Length actually written */ + gSegInfo.writtenLength += gStreamParam.producedLength; +#endif /* FBL_ENABLE_PROCESSED_DATA_LENGTH */ + } + } + + } + + break; + } +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + case kFblMemJobType_GapFill: + { + /* Start address of current fill operation */ + fillAddress = activeJob->baseAddress + activeJob->position; + /* Remember total length */ + fillLength = actualLength; + /* Reset length actually filled */ + actualLength = 0u; + + /* Find start segment for current address */ + memSegment = FblMemSegmentNrGet(fillAddress); + + /* Valid segment addressed? */ + if (memSegment < 0) + { + /* Address lies in gap between flash blocks + Range till next block can be skipped */ + + /* Use last filled address to get follow-up segment */ + memSegment = FblMemSegmentNrGet(fillAddress - 1u) + 1; + + /* Check segment range */ + if ((memSegment >= (vsint16)kNrOfFlashBlock) || (memSegment <= 0)) + { + FBL_MEM_SET_STATUS(ProgramOutsideFbt, gErrorStatus); + } + else + { + /* Skip gap */ + if (FlashBlock[memSegment].begin > fillAddress) + { + /* Distance to start of next flash block can be skipped */ + tempLength = FlashBlock[memSegment].begin - fillAddress; + + if (tempLength < fillLength) + { + /* Range partially covers next flash block + Adapt fill range accordingly */ + actualLength = tempLength; + fillLength -= actualLength; + fillAddress = FlashBlock[memSegment].begin; + } + else + { + /* Full range lies within gap and can be skipped completely */ + actualLength = fillLength; + fillLength = 0u; + } + } + else + { + /* Full range lies within gap and can be skipped completely */ + actualLength = fillLength; + fillLength = 0u; + } + } + } + + if (kFblMemStatus_Ok == gErrorStatus) + { + /* Limit fill operation to configured segmentation (equals size of prepared buffer) */ + if (fillLength > FBL_MEM_GAP_FILL_SEGMENTATION) + { + fillLength = FBL_MEM_GAP_FILL_SEGMENTATION; + } + + /* Distance to end of current flash block */ + tempLength =(FlashBlock[memSegment].end - fillAddress) + 1u; + /* Limit fill range to current flash block */ + if (fillLength > tempLength) + { + fillLength = tempLength; + } + + /* Perform actual fill operation */ + if (fillLength > 0u) + { + /* Program non-volatile memory */ + gErrorStatus = FblMemProgramBufferInternal(fillAddress, &fillLength, gGapFillBuffer.data, kFblMemProgState_Pending); + + /* Update length actually processed */ + actualLength += fillLength; + } + } + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + if (kFblMemStatus_Ok == gErrorStatus) + { + /* Update programming progress */ + FblMemUpdateProgress(gSegInfo.writeLength + (gGapFillJob.used - actualLength)); + } +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + + break; + } +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + case kFblMemJobType_Max: + default: + { + /* Invalid buffer type */ + FBL_MEM_SET_STATUS(Failed, gErrorStatus); + + break; + } + } + + /* Update buffer usage */ + activeJob->position += actualLength; + activeJob->used -= actualLength; + +#if defined( FBL_ENABLE_SYSTEM_CHECK ) + if (kFblMemStatus_Ok == gErrorStatus) + { + if (kFblMemStatus_Ok != FblMemVerifyBufferIntegrity()) + { + /* Detected buffer corruption */ + FBL_MEM_SET_STATUS(Failed, gErrorStatus); + } + } +#endif /* FBL_ENABLE_SYSTEM_CHECK */ + + /* Return global error state as function may be called in both service and background context */ + return gErrorStatus; +} + +/*********************************************************************************************************************** + * FblMemProcessQueue + **********************************************************************************************************************/ +/*! \brief Process first job in processing queue (directly use single input job if un-queued) + * \details Remove finished job from processing queue (and pipelined queue in case of input job) + * Switch to idle mode if all pending jobs are finished + * \pre FblMemQueueBuffer executed before + * \param[in] mode Operation mode used to trigger finalization + **********************************************************************************************************************/ +/* PRQA S 6010, 6030, 6080 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STMIF */ +static void FblMemProcessQueue( tFblMemOperationMode mode ) +{ +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) + tFblMemQueueHandle activeHandle; +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ +#if defined( FBL_MEM_ENABLE_PIPELINING ) + V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * removeQueue; +#endif /* FBL_MEM_ENABLE_PIPELINING */ + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * activeJob; + + FblMemTriggerWatchdog(); + + /* + Critical section secures access to programming state + May also be altered in interrupt context + */ + __ApplFblMemEnterCriticalSection(); + + /* + Module in idle or error state? + Condition equals ((kFblMemProgState_Idle == fblMemProgState) || (kFblMemProgState_Error == fblMemProgState)) + */ + if (fblMemProgState < kFblMemProgState_Suspended) + { + /* Nothing to do */ + } +#if defined( FBL_MEM_ENABLE_PIPELINING ) + /* Only explicit pending state allowed while programming in background context */ + else if ( (kFblMemContext_Background == gProgContext) + && (kFblMemProgState_Pending != fblMemProgState) ) + { + /* Module suspended */ + } +#endif /* FBL_MEM_ENABLE_PIPELINING */ + else + { + /* Operation potentially paused during previous execution cycle */ + fblMemProgState = kFblMemProgState_Pending; + } + + /* + No further critical access to programming state + Critical section can be left + */ + __ApplFblMemLeaveCriticalSection(); + + if (kFblMemProgState_Pending == fblMemProgState) + { +#if defined( FBL_MEM_ENABLE_PIPELINING ) + removeQueue = FBL_MEM_QUEUE_NULL; +#endif /* FBL_MEM_ENABLE_PIPELINING */ +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) + /* Set active job, stored in first entry of processing queue */ + activeHandle = FblMemQueueGetFirstUsedHandle(gProcessingQueue); + activeJob = gProcessingQueue[activeHandle].job; +#else + /* Set active job to single input job */ + activeJob = &FBL_MEM_INPUT_JOB[0]; +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ + + /* Perform processing cycle on active job */ + if (kFblMemStatus_Ok == FblMemProcessJob(activeJob, mode)) + { + /* Buffer completely processed and completion mode allows job to be cleared? */ + if ( (kFblMemOperationMode_Unconditional == activeJob->completion) + || ((kFblMemOperationMode_Normal == activeJob->completion) && (0u == activeJob->used)) ) + { +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) + /* Remove buffer from processing queue */ + (void)FblMemQueueRemove(gProcessingQueue, activeHandle); + + if (FblMemQueueIsEmpty(gProcessingQueue)) +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ + { + /* Processing queue empty: switch to idle state */ + fblMemProgState = kFblMemProgState_Idle; + } + +#if defined( FBL_MEM_ENABLE_PIPELINING ) + /* Update additional queues */ + switch (activeJob->jobClass) + { +# if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) + /* Processed buffer is an input buffer */ + case tFblMemJobClass_PipeProg: + { + { + /* Remove from input buffer queue */ + removeQueue = FBL_MEM_PIPE_PROG_QUEUE; + } + + break; + } +# endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + case tFblMemJobClass_VerifyPipe: + { + /* Remove from verification job queue */ + removeQueue = gVerifyPipeQueue; + + break; + } +# endif + /* Default class: no special action required */ + case tFblMemJobClass_Default: + /* Ignore unknown job class */ + default: + { + /* Nothing to do */ + break; + } + } +#endif /* FBL_MEM_ENABLE_PIPELINING */ + } + } + else + { + /* Error while processing buffer: switch to error state */ + fblMemProgState = kFblMemProgState_Error; + +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) + /* Remove from input buffer queue, otherwise all buffer may be in use */ + removeQueue = FBL_MEM_PIPE_PROG_QUEUE; +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + } + +#if defined( FBL_MEM_ENABLE_PIPELINING ) + /* + Remove from input buffer queue + Buffer available for new data again + */ + if ( (FBL_MEM_QUEUE_NULL != removeQueue) + && (!FblMemQueueIsEmpty(removeQueue)) ) + { + (void)FblMemQueueRemove(removeQueue, FblMemQueueGetFirstUsedHandle(removeQueue)); + } +#endif /* FBL_MEM_ENABLE_PIPELINING */ + } +} + +/*********************************************************************************************************************** + * FblMemFlushQueueByPrio + **********************************************************************************************************************/ +/*! \brief Process all jobs in processing queue with priority greater or equal to given value + * \details Loop until processing queue is empty or a job with a priority lower to the given one is reached + * \pre FblMemQueueBuffer executed before + * \param[in] prio Lowest job priority to be processed + **********************************************************************************************************************/ +static void FblMemFlushQueueByPrio( tFblMemQueuePrio prio ) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ +# if defined( FBL_MEM_ENABLE_PROC_QUEUE ) +# else + (void)prio; +# endif /* FBL_MEM_ENABLE_PROC_QUEUE */ +#endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + /* Loop while jobs are pending */ + while ( (FblMemTaskIsPending()) +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) + /* Only jobs with priority greater or equal to given one are processed */ + && (FblMemQueueGetFirstUsedEntry(gProcessingQueue).prio >= prio) +#endif + ) + { + /* Execute processing cycle */ + FblMemProcessQueue(kFblMemOperationMode_Finalize); + } +} + +#if defined( FBL_MEM_ENABLE_PIPELINING ) +/*********************************************************************************************************************** + * FblMemUnblockQueue + **********************************************************************************************************************/ +/*! \brief Unblock queue by freeing at least one queue entry + * \details Loop until given queue isn't completely filled any more + * \pre FblMemQueueBuffer executed before + * \param[in] queue Pointer to queue which should be unblocked + **********************************************************************************************************************/ +static void FblMemUnblockQueue( const V_MEMRAM1 tFblMemQueueEntry V_MEMRAM2 V_MEMRAM3 * queue ) +{ + /* Loop while queue is completely filled and jobs are pending */ + while ( (FblMemQueueIsFull(queue)) && (FblMemTaskIsPending()) ) + { + /* Execute processing cycle */ + FblMemProcessQueue(kFblMemOperationMode_Normal); + } +} +#endif /* FBL_MEM_ENABLE_PIPELINING */ + +/*********************************************************************************************************************** + * FblMemQueueBuffer + **********************************************************************************************************************/ +/*! \brief Handle new chunk of input data + * \details If any combination of verification, data processing and pipelined programming is configured add jobs to + * processing queue + * Otherwise processing will directly work on single input buffer + * If pipelined programming is configured queue buffer and finish processing of one pending input buffer + * in case no free input buffer is available + * \pre FblMemInitPowerOn executed before, provided buffer and data offset equal the parameters of active + * input buffer + * \param[in] buffer Pointer to input buffer (including preamble) + * \param[in] offset Offset of actual data (after preamble) + * \param[in] length Length of data (without preamble) + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +static tFblMemStatus FblMemQueueBuffer( tFblMemConstRamData buffer, tFblLength offset, tFblLength length ) +{ + tFblMemStatus retVal; + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * activeJob; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ +# if defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) || \ + defined( FBL_ENABLE_SYSTEM_CHECK ) || \ + defined( FBL_ENABLE_ASSERTION ) +# else + (void)buffer; +# endif /* FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER || FBL_ENABLE_SYSTEM_CHECK || FBL_ENABLE_ASSERTION */ +#endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + +#if defined( FBL_MEM_ENABLE_VARYING_INPUT_BUFFER ) +#else + /* Received data resides in active fill buffer */ + activeJob = FblMemGetPendingInputJob(); +#endif /* FBL_MEM_ENABLE_VARYING_INPUT_BUFFER */ + +#if defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) || \ + defined( FBL_ENABLE_SYSTEM_CHECK ) +# if defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) +# if defined( FBL_MEM_ENABLE_VARYING_INPUT_BUFFER ) + if (kFblMemStatus_Ok != FblMemSearchInputBuffer(buffer, offset, length)) +# else + if (kFblMemStatus_Ok != FblMemRelocateBufferOffset(activeJob, buffer, offset, length)) +# endif /* FBL_MEM_ENABLE_VARYING_INPUT_BUFFER */ +# else /* FBL_ENABLE_SYSTEM_CHECK */ + /* Limit buffer handling to previously provided buffer */ + if ( (buffer != FblMemGetBuffer(activeJob)) + || (offset >= activeJob->netSize) + || (length > (activeJob->netSize - offset)) ) +# endif /* FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ + { + FBL_MEM_SET_STATUS(DataIndParam, retVal); + } + else +#else + assertFblUser(buffer == FblMemGetBuffer(activeJob), kFblMemAssertParameterOutOfRange); + assertFblUser(offset < activeJob->netSize, kFblMemAssertParameterOutOfRange); + assertFblUser(length <= (activeJob->netSize - offset), kFblMemAssertParameterOutOfRange); +#endif /* FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER || FBL_ENABLE_SYSTEM_CHECK */ + { +#if defined( FBL_MEM_ENABLE_VARYING_INPUT_BUFFER ) + activeJob = FblMemGetPendingInputJob(); +#endif /* FBL_MEM_ENABLE_VARYING_INPUT_BUFFER */ + + /* Evaluate current error state and directly return if not okay (error in background task) */ + if (kFblMemProgState_Error != fblMemProgState) + { + /* Update buffer state with provided information */ + activeJob->position = activeJob->offset + offset; + activeJob->used = length; +#if defined( FBL_ENABLE_DATA_PROCESSING ) || \ + defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) || \ + defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + /* + Switch type of input buffer to value set in segment indication: + write through, pass through, data processing or stream output + */ + activeJob->type = gSegInfo.jobType; +#endif /* FBL_ENABLE_DATA_PROCESSING || FBL_MEM_ENABLE_STREAM_OUTPUT || FBL_MEM_ENABLE_PASSTHROUGH || FBL_MEM_ENABLE_REMAINDER_HANDLING */ + + { +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Processing queue full */ + if (FblMemQueueIsFull(gVerifyPipeQueue)) + { +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED_ADDRESS_LENGTH ) + /* Last entry is exclusively used for storage of address information + This reserved job has to be free at all times so no blocking operation is necessary during segment start */ +# else + /* Verification job for current segment not yet included */ + if (FblMemQueueGetLastUsedEntry(gVerifyPipeQueue).job->segmentIndex != gSegInfo.ownIndex) +# endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED_ADDRESS_LENGTH */ + { + /* Free at least one queue entry */ + FblMemUnblockQueue(gVerifyPipeQueue); + } + } +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + } + +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Check for error condition */ + if (kFblMemProgState_Error != fblMemProgState) +# endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + { + /* Append buffer to processing queue */ + (void)FblMemQueueDefaultPrioInsert(gProcessingQueue, activeJob, gSegInfo.ownIndex); + +# if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) + /* Append input info to separate queue, managing input buffers exclusively */ + (void)FblMemQueueAppend(FBL_MEM_PIPE_PROG_QUEUE); + + + /* Free at least one queue entry */ + FblMemUnblockQueue(FBL_MEM_PIPE_PROG_QUEUE); +# endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + } +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ + +#if defined( FBL_MEM_ENABLE_PIPELINING ) + /* Check for error condition */ + if (kFblMemProgState_Error != fblMemProgState) +#endif /* FBL_MEM_ENABLE_PIPELINING */ + { + /* Set pending programming request flag */ + fblMemProgState = kFblMemProgState_Pending; + } + } + + /* Result depending on queue processing by FblMemUnblockQueue */ + retVal = gErrorStatus; + } + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemCheckAllowed + **********************************************************************************************************************/ +/*! \brief Check if all required states are set + * \details Clear certain states if successful, completely reset allowed states otherwise + * \pre Allowed state initialized before + * \param[in] check Bitmask of states which have to be active + * \param[in] clear Bitmask of states to be cleared in case check successful + * \return All required states set (kFblOk) or not (kFblFailed) + **********************************************************************************************************************/ +static tFblResult FblMemCheckAllowed( tFblMemAllowedInd check, tFblMemAllowedInd clear ) +{ + tFblResult retVal; + + /* + Check executed at beginning of (almost) every exported function + Trigger watchdog here + */ + FblMemTriggerWatchdog(); + + + /* Check for required states */ + if (FblMemIsAllowed(check)) + { + /* Success: clear requested states */ + FblMemClrAllowed(clear); + retVal = kFblOk; + } + else + { + /* Failure: completely reset states */ + FblMemResetAllowed(); + retVal = kFblFailed; + } + + return retVal; +} + + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) +/*********************************************************************************************************************** + * FblMemCalculateProgress + **********************************************************************************************************************/ +/*! \brief Calculate progress percentage + * \details Percentage is calculated according to the current progress, the expected maximum value and the resulting + * maximum percentage + * \param[in] current Current progress in arbitrary unit (e.g. bytes) + * \param[in] total Expected maximum value in arbitrary unit (e.g. bytes) + * \param[in] percentage Maximum reported percentage + * \return Current progress percentage + **********************************************************************************************************************/ +static vuint8 FblMemCalculateProgress( vuint32 current, vuint32 total, vuint8 percentage ) +{ + vuint8 progress; + + /* Init to maximum percentage */ + progress = percentage; + + /* Prevent division by zero */ + if ((0u != total) && (0u != percentage)) + { + /* Calculate progress value + Use different calculation paths depending on total value to prevent integer overflow or division by zero + Remark: Unsigned cast of -1 is guaranteed to result in maximum representable value */ + if (total < (0xFFFFFFFFuL / (vuint32)percentage)) + { + /* Applying multiplication to current value prevents loss of precision, + which otherwise could result in invalid percentages (e.g. 101%) */ + progress = (vuint8)(((current * percentage) / total) & 0xFFu); + } + else + { + /* Total value is large enough to provide sufficient precision */ + progress = (vuint8)((current / (total / percentage)) & 0xFFu); + } + } + + /* Limit reported progress to maximum percentage */ + if (progress > percentage) + { + progress = percentage; + } + + return progress; +} + +/*********************************************************************************************************************** + * FblMemInitProgress + **********************************************************************************************************************/ +/*! \brief Initialize progress states + * \details Called during startup + **********************************************************************************************************************/ +static void FblMemInitProgress( void ) +{ + /* Initialize progress information */ + gProgressInfo.type = kFblMemProgressType_Undefined; + + /* Ensure reporting is triggered after change of any value */ + gPrevProgressInfo.type = kFblMemProgressType_Undefined; + gPrevProgressInfo.totalProgress = FBL_MEM_PROGRESS_INITIAL; + gPrevProgressInfo.partialProgress = FBL_MEM_PROGRESS_INITIAL; +} + +/*********************************************************************************************************************** + * FblMemReportProgress + **********************************************************************************************************************/ +/*! \brief Report current progress + * \details Report current progress to user callback in case any of the following applies: + * - Type or segment count has changed since previous report + * - Partial progress completed, but not reported yet + * - Total or partial progress increased by at least the configured threshold since previous report + **********************************************************************************************************************/ +static void FblMemReportProgress( void ) +{ + /* Check for relevant changes since previous report */ + if ( (FBL_MEM_PROGRESS_COMPLETE == gProgressInfo.partialProgress) + || (gPrevProgressInfo.type != gProgressInfo.type) + || (gPrevProgressInfo.segmentCount != gProgressInfo.segmentCount) + || ((gProgressInfo.totalProgress - gPrevProgressInfo.totalProgress) >= (vuint8)FBL_MEM_PROGRESS_THRESHOLD_PERCENTAGE) + || ((gProgressInfo.partialProgress - gPrevProgressInfo.partialProgress) >= (vuint8)FBL_MEM_PROGRESS_THRESHOLD_PERCENTAGE) ) + { + /* Prevent re-reporting of completed partial progress */ + if (FBL_MEM_PROGRESS_COMPLETE != gPrevProgressInfo.partialProgress) + { + /* Inform user callback */ + __ApplFblMemReportProgress(&gProgressInfo); + + /* Remember reported progress */ + gPrevProgressInfo = gProgressInfo; + } + } +} + +/*********************************************************************************************************************** + * FblMemSetupProgress + **********************************************************************************************************************/ +/*! \brief Setup progress for new partial operation + * \details Stores the meta information (type, logical block address and segment count), sets up the percentage + * offset and current contribution of the total operation and stores the target value of the partial operation + * \param[in] type Type of partial operation + * \param[in] logicalAddress Logical start address of processed block + * \param[in] segmentCount Count of segment processed by partial operation, typically zero for erase and verification, + * segment index for programming and index of last segment incremented by one for concluding + * gap fill + * \param[in] totalOffset Percentage offset of total operation for current operation type + * \param[in] totalPercentage Percentage contribution to total operation of current operation type + * \param[in] target Expected maximum value of partial operation in arbitrary unit (e.g. bytes) + **********************************************************************************************************************/ +/* PRQA S 6060 1 */ /* MD_FblMem_6060 */ +static void FblMemSetupProgress( tFblMemProgressType type, tFblAddress logicalAddress, vuint32 segmentCount, + vuint8 totalOffset, vuint8 totalPercentage, vuint32 target ) +{ + /* Store meta information */ + gProgressInfo.type = type; + gProgressInfo.logicalAddress = logicalAddress; + gProgressInfo.segmentCount = segmentCount; + + /* Setup percentage offset and contribution of total operation */ + gProgressInfoInternal.totalOffset = totalOffset; + gProgressInfoInternal.totalPercentage = totalPercentage; + /* Store target value of partial operation */ + gProgressInfoInternal.target = target; + + /* Ensure first update is reported by setting default values for previously reported info */ + gProgressPrevRemainder = 0u; + gPrevProgressInfo.totalProgress = FBL_MEM_PROGRESS_INITIAL; + gPrevProgressInfo.partialProgress = FBL_MEM_PROGRESS_INITIAL; +} + +/*********************************************************************************************************************** + * FblMemOffsetProgress + **********************************************************************************************************************/ +/*! \brief Modify total percentages to reflect current progress + * \details During progress setup the total percentages reflect the complete contribution of all operations of the + * current type. This function offsets those values according to the current progress. + * \pre FblMemSetupProgress called before + * \param[in] totalDone Current total progress in arbitrary unit (e.g. bytes) + * \param[in] totalTarget Expected maximum value of total operation in arbitrary unit (e.g. bytes) + **********************************************************************************************************************/ +static void FblMemOffsetProgress( vuint32 totalDone, vuint32 totalTarget ) +{ + /* Update offset according to current progress */ + gProgressInfoInternal.totalOffset += + FblMemCalculateProgress(totalDone, totalTarget, gProgressInfoInternal.totalPercentage); + /* Cut down percentage contribution according to current progress */ + gProgressInfoInternal.totalPercentage = + FblMemCalculateProgress(gProgressInfoInternal.target, totalTarget, gProgressInfoInternal.totalPercentage); +} + +/*********************************************************************************************************************** + * FblMemUpdateProgress + **********************************************************************************************************************/ +/*! \brief Update the progress information + * \details Progress information is updated according to the progress of the current partial operation + * Update is performed in case any of the following applies: + * - First update + * - Progress increased by at least the configured threshold since previous update + * \pre FblMemSetupProgress and optionally FblMemOffsetProgress called before + * \param[in] remainderPart Remainder of current partial operation in arbitrary unit (e.g. bytes) + **********************************************************************************************************************/ +static void FblMemUpdateProgress( vuint32 remainderPart ) +{ + vuint32 done; + + /* Check for relevant changes since previous update */ + if ( (gProgressPrevRemainder < remainderPart) + || ((gProgressPrevRemainder - remainderPart) >= FBL_MEM_PROGRESS_THRESHOLD_BYTES) ) + { + /* Calculate current partial progress in arbitray unit */ + done = gProgressInfoInternal.target - remainderPart; + + /* Calculate progress percentages */ + gProgressInfo.totalProgress = + gProgressInfoInternal.totalOffset + + FblMemCalculateProgress(done, gProgressInfoInternal.target, gProgressInfoInternal.totalPercentage); + gProgressInfo.partialProgress = + FBL_MEM_PROGRESS_INITIAL + FblMemCalculateProgress(done, gProgressInfoInternal.target, FBL_MEM_PROGRESS_COMPLETE); + + /* Report updated progress */ + FblMemReportProgress(); + + /* Remember currently updated remainder value */ + gProgressPrevRemainder = remainderPart; + } +} + +/*********************************************************************************************************************** + * FblMemConcludeProgress + **********************************************************************************************************************/ +/*! \brief Conclude the current partial operation + * \details Explicitely set partial progress to maximum percentage and total progress according to the set up values + * \pre FblMemSetupProgress and optionally FblMemOffsetProgress called before + **********************************************************************************************************************/ +static void FblMemConcludeProgress( void ) +{ + /* Set progress percentages to maximum values */ + gProgressInfo.totalProgress = gProgressInfoInternal.totalOffset + gProgressInfoInternal.totalPercentage; + gProgressInfo.partialProgress = FBL_MEM_PROGRESS_COMPLETE; + + /* Report updated progress */ + FblMemReportProgress(); +} + +/*********************************************************************************************************************** + * FblMemProgressRead + **********************************************************************************************************************/ +/*! \brief Update verification progress + * \details Read operations of output verification are re-routed through this function to update the progress + * information according the current read address + * \param[in] address Memory address to read out + * \param[out] buffer Target buffer + * \param[in] length Number of bytes to read + * \return Number of actually copied bytes + **********************************************************************************************************************/ +# if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) +# if defined( FBL_MEM_ENABLE_SWITCH_READMEMORY_PARAM ) +/* Parameters order changed in comparison to HIS security module specification */ +static tFblMemVerifySize FblMemProgressRead( tFblMemVerifyAddr address, tFblMemVerifySize length, tFblMemVerifyDataPtr buffer ) +# else +/* Parameters order as defined by HIS security module specification */ +static tFblMemVerifySize FblMemProgressRead( tFblMemVerifyAddr address, tFblMemVerifyDataPtr buffer, tFblMemVerifySize length ) +# endif /* FBL_MEM_ENABLE_SWITCH_READMEMORY_PARAM */ +{ + vuint32 position; + + /* Calculate position relative to block start address */ + position = address - gBlockInfo.targetAddress; + /* Update progress with remainder */ + FblMemUpdateProgress(gBlockInfo.targetLength - position); + + /* Perform actual read operation */ + return gBlockInfo.readFct(address, buffer, length); +} +# endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT */ +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FblMemInitPowerOnExt + **********************************************************************************************************************/ +/*! \brief Initialize module + * \param[in] preambleLen Length of preamble stored during buffer switch + * \param[in] sourceHandle Handle of input source + * \return Pointer to initial input buffer + **********************************************************************************************************************/ +tFblMemRamData FblMemInitPowerOnExt( tFblLength preambleLen, tFblMemInputSource sourceHandle ) +{ +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + vuintx idx; +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ +# if defined( FBL_MEM_ENABLE_DYNAMIC_PREAMBLE_LENGTH ) +# else + (void)preambleLen; +# endif /* FBL_MEM_ENABLE_DYNAMIC_PREAMBLE_LENGTH */ +# if defined( FBL_MEM_ENABLE_MULTI_SOURCE ) +# else + (void)sourceHandle; +# endif /* FBL_MEM_ENABLE_MULTI_SOURCE */ +#endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + +#if defined( FBL_MEM_ENABLE_MULTI_SOURCE ) + /* Verify source handle lies within range */ + assertFblUser(sourceHandle < FBL_MEM_SOURCE_COUNT, kFblMemAssertParameterOutOfRange); +#endif /* FBL_MEM_ENABLE_MULTI_SOURCE */ + +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) + /* Verify job prio mapping array */ + assertFblInternal((vuintx)kFblMemJobType_Max == (FBL_MEM_ARRAY_SIZE(gJobPrio) - 1u), kFblMemAssertParameterOutOfRange); /* PRQA S 2742, 2880 */ /* MD_FblMem_AssertJobMax, MD_MSR_Unreachable */ +#endif /* FBL_MEM_ENABLE_PROC_QUEUE */ +#if defined( FBL_MEM_ENABLE_SEGMENTATION ) || \ + defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Verify length limit mapping array */ + assertFblInternal((vuintx)kFblMemJobType_Max == (FBL_MEM_ARRAY_SIZE(gLengthLimits) - 1u), kFblMemAssertParameterOutOfRange); /* PRQA S 2742, 2880 */ /* MD_FblMem_AssertJobMax, MD_MSR_Unreachable */ +#endif /* FBL_MEM_ENABLE_SEGMENTATION || FBL_MEM_ENABLE_VERIFY_PIPELINED */ + + +#if defined( FBL_ENABLE_DATA_PROCESSING ) + /* Initialize data processing info */ + FblMemInitJob(&gProcWriteJob, gProcBuffer.data, FBL_MEM_ARRAY_SIZE(gProcBuffer.data), kFblMemJobType_ProcWrite); + /* Overwrite net size, to exclude overhead for remainder and padding */ + gProcWriteJob.netSize = FBL_MEM_PROC_BUFFER_SIZE; + /* Initialize info to trigger data processing finalization */ + FblMemInitJob(&gProcFinalizeJob, FBL_MEM_BUFFER_NULL, 0, kFblMemJobType_ProcFinalize); + + /* + Always provide full configured segmentation size to data processing, + regardless of any remainder + */ + gProcParam.dataOutMaxLength = (vuint16)FBL_MEM_INTERNAL_PROC_SEGMENTATION; +# if defined( FBL_MEM_ENABLE_EXT_TRIGGER_DATA_PROC ) + gProcParam.wdTriggerFct = &FblMemTriggerWatchdogExt; +# else + gProcParam.wdTriggerFct = FblMemTriggerWatchdog; +# endif /* FBL_MEM_ENABLE_EXT_TRIGGER_DATA_PROC */ +#endif /* FBL_ENABLE_DATA_PROCESSING */ + +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + /* Initialize stream output info */ +# if defined( FBL_ENABLE_DATA_PROCESSING ) + FblMemInitJob(&gStreamProcJob, gProcBuffer.data, FBL_MEM_ARRAY_SIZE(gProcBuffer.data), kFblMemJobType_StreamProc); + /* Overwrite net size, to exclude overhead for remainder and padding */ + gStreamProcJob.netSize = FBL_MEM_PROC_BUFFER_SIZE; +# endif /* FBL_ENABLE_DATA_PROCESSING */ + /* Initialize info to trigger stream output finalization */ + FblMemInitJob(&gStreamFinalizeJob, FBL_MEM_BUFFER_NULL, 0, kFblMemJobType_StreamFinalize); + + gStreamParam.outputData = FBL_MEM_BUFFER_NULL; + gStreamParam.outputSize = 0u; + gStreamParam.watchdog = &FblMemTriggerWatchdog; +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ + + +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + /* Initialize gap fill job */ + FblMemInitJob(&gGapFillJob, FBL_MEM_BUFFER_NULL, FBL_MEM_ARRAY_SIZE(gGapFillBuffer.data), kFblMemJobType_GapFill); + + /* Fill gap fill buffer with fill character */ + for (idx = 0u; idx < FBL_MEM_ARRAY_SIZE(gGapFillBuffer.data); idx++) + { + gGapFillBuffer.data[idx] = kFillChar; + } +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + +#if defined( FBL_MEM_ENABLE_MULTI_SOURCE ) + gActiveSource = sourceHandle; +#endif /* FBL_MEM_ENABLE_MULTI_SOURCE */ + +#if defined( FBL_MEM_ENABLE_DYNAMIC_PREAMBLE_LENGTH ) + gPreambleLength[FBL_MEM_ACTIVE_SOURCE] = preambleLen; /* PRQA S 2842 */ /* MD_FblMem_2842 */ +#endif /* FBL_MEM_ENABLE_DYNAMIC_PREAMBLE_LENGTH */ + + /* Perform additional initialization and return initial buffer */ + return FblMemInitInternal(); +} + +/*********************************************************************************************************************** + * FblMemInitPowerOn + **********************************************************************************************************************/ +/*! \brief Initialize module + * \return Pointer to initial input buffer + **********************************************************************************************************************/ +tFblMemRamData FblMemInitPowerOn( void ) +{ + /* Perform initialization and return initial buffer */ + return FblMemInitPowerOnExt(FBL_MEM_DEFAULT_PREAMBLE_LENGTH, FBL_MEM_SOURCE_HANDLE_DEFAULT); +} + +/*********************************************************************************************************************** + * FblMemInit + **********************************************************************************************************************/ +/*! \brief (Re)-initialize input buffers + * \details Should be called before performing additional tasks in case a previous operation failed + * \pre FblMemInitPowerOn executed before + * \return Pointer to active input buffer + **********************************************************************************************************************/ +tFblMemRamData FblMemInit( void ) +{ + tFblMemRamData activeBuffer; + +#if defined( FBL_MEM_ENABLE_PREAMBLE_HANDLING ) + /* + Active fill buffer may change + Store preamble so operation is transparent for caller + */ + FblMemStorePreamble(); +#endif /* FBL_MEM_ENABLE_PREAMBLE_HANDLING */ + + /* Perform re-initialization and get active buffer */ + activeBuffer = FblMemInitInternal(); + + +#if defined( FBL_MEM_ENABLE_PREAMBLE_HANDLING ) + /* + Active fill buffer may have changed + Restore previously stored preamble so operation is transparent for caller + */ + FblMemRestorePreamble(); +#endif /* FBL_MEM_ENABLE_PREAMBLE_HANDLING */ + + return activeBuffer; +} + +/*********************************************************************************************************************** + * FblMemDeinit + **********************************************************************************************************************/ +/*! \brief De-initialize module + * \details Should be called when memory driver is de-initialized + **********************************************************************************************************************/ +void FblMemDeinit( void ) +{ + /* No further operations allowed, reset states */ + FblMemInitStates(); +} + +#if defined( FBL_MEM_ENABLE_MULTI_SOURCE ) +/*********************************************************************************************************************** + * FblMemLockInputSource + **********************************************************************************************************************/ +/*! \brief Lock input to specific source + * \param[in] sourceHandle Handle of input source + **********************************************************************************************************************/ +void FblMemLockInputSource( tFblMemInputSource sourceHandle ) +{ + /* Verify source handle lies within range */ + assertFblInternal(sourceHandle < FBL_MEM_SOURCE_COUNT, kFblMemAssertParameterOutOfRange); + + gActiveSource = sourceHandle; +} +#endif /* FBL_MEM_ENABLE_MULTI_SOURCE */ + +/*********************************************************************************************************************** + * FblMemGetActiveBuffer + **********************************************************************************************************************/ +/*! \brief Return active input buffer, which can be used for current data reception + * \details Buffer pointer includes previously set offset to accommodate for alignment requirements + * \pre FblMemInitPowerOn executed before + * \return Pointer to active input buffer + **********************************************************************************************************************/ +tFblMemRamData FblMemGetActiveBuffer( void ) +{ + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * inputJob; + + /* Get pending job info */ + inputJob = FblMemGetPendingInputJob(); + /* Reset position to current offset */ + inputJob->position = inputJob->offset; + + /* Return pointer to active fill buffer */ + return FblMemGetBuffer(inputJob); +} + +/*********************************************************************************************************************** + * FblMemBlockEraseIndication + **********************************************************************************************************************/ +/*! \brief Indicate start of a new block (just before first segment) + * \pre FblMemInitPowerOn executed before + * \param[in] block Pointer to block information structure + * Only address and length members have to be initialized + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +tFblMemStatus FblMemBlockEraseIndication( const V_MEMRAM1 tFblMemBlockInfo V_MEMRAM2 V_MEMRAM3 * block ) +{ + tFblMemStatus retVal; + + /* Check allowed states */ + if (kFblOk != FblMemCheckAllowed(FBL_MEM_ALLOWED_BLOCK_ERASE, FBL_MEM_ALLOWED_NONE)) + { + FBL_MEM_SET_STATUS(BlockEraseSequence, retVal); + } + else + { +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Setup erase progress */ + FblMemSetupProgress(kFblMemProgressType_Erase, block->logicalAddress, 0u, + FBL_MEM_PROGRESS_INITIAL, FBL_MEM_PROGRESS_ERASE, block->targetLength); + /* Report initial progress */ + FblMemUpdateProgress(block->targetLength); + + /* Explicitely enable progress information for erase operation */ + gProgressState = kFblMemProgressState_Enabled; +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + + /* Perform erase */ + retVal = FblMemEraseRegionInternal(block->targetAddress, block->targetLength); + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Conclude erase progress */ + FblMemConcludeProgress(); +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + } + + if (kFblMemStatus_Ok == retVal) + { + /* Allow block start / erase indication */ + FblMemSetAllowed(FBL_MEM_ALLOWED_BLOCK_START | FBL_MEM_ALLOWED_BLOCK_ERASE); + } + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemBlockStartIndication + **********************************************************************************************************************/ +/*! \brief Indicate start of a new block (just before first segment) + * \details Block may consist of one or more segments + * \pre FblMemInitPowerOn executed before + * FblMemInit executed before in case previous cycle failed + * \param[in] block Pointer to block information structure + * Required members depending on configuration + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +tFblMemStatus FblMemBlockStartIndication( V_MEMRAM1 tFblMemBlockInfo V_MEMRAM2 V_MEMRAM3 * block ) /* PRQA S 3673 */ /* MD_FblMem_3673 */ +{ + tFblMemStatus retVal; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ +# if defined( FBL_MEM_ENABLE_GLOBAL_BLOCK_INFO ) +# else + (void)block; +# endif /* FBL_MEM_ENABLE_GLOBAL_BLOCK_INFO */ +#endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + retVal = kFblMemStatus_Ok; + + /* Check allowed states */ + if (kFblOk != FblMemCheckAllowed(FBL_MEM_ALLOWED_BLOCK_START, FBL_MEM_ALLOWED_BLOCK_START)) + { + FBL_MEM_SET_STATUS(BlockStartSequence, retVal); + } + else + { +#if defined( FBL_ENABLE_SYSTEM_CHECK ) && \ + defined( FBL_MEM_ENABLE_VERIFICATION ) + /* At least one of the configured verification variants should be active */ +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + if (FBL_MEM_VERIFY_FCT_INPUT_NULL != block->verifyRoutinePipe.function) + { + } + else +# endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ +# if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) + if (FBL_MEM_VERIFY_FCT_OUTPUT_NULL != block->verifyRoutineOutput.function) + { + } + else +# endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT */ + { + FBL_MEM_SET_STATUS(BlockStartParam, retVal); + } +#endif /* FBL_ENABLE_SYSTEM_CHECK && FBL_MEM_ENABLE_VERIFICATION */ + } + +#if defined( FBL_ENABLE_FUNC_VIRTUAL_MEMORY ) + /* PRQA S 3415 1 */ /* MD_FblMem_3415 */ + if ((kFblMemStatus_Ok == retVal) && (IO_E_OK == MemDriver_IsVirtualMem(block->targetAddress))) + { + if (IO_E_OK != MemDriver_RVirtualMemInitSync(block->targetAddress)) + { + FBL_MEM_SET_STATUS(BlockStartSequence, retVal); + } + } +#endif /* FBL_ENABLE_FUNC_VIRTUAL_MEMORY */ + + if (kFblMemStatus_Ok == retVal) + { + /* Store block information */ +#if defined( FBL_MEM_ENABLE_GLOBAL_BLOCK_INFO ) + gBlockInfo = *block; +#endif /* FBL_MEM_ENABLE_GLOBAL_BLOCK_INFO */ +#if defined( FBL_MEM_ENABLE_SEGMENT_HANDLING ) + /* Reset segment list */ + gBlockInfo.segmentList->nrOfSegments = 0u; +#endif /* FBL_MEM_ENABLE_SEGMENT_HANDLING */ + + /* Setup index of first segment */ + gSegInfo.nextIndex = 0u; + + /* Allow segment start indication */ + FblMemSetAllowed(FBL_MEM_ALLOWED_SEGMENT_START); + } + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemBlockEndIndication + **********************************************************************************************************************/ +/*! \brief Indicate end of current block (after last segment) + * \details Finalize verification if configured + * \pre FblMemSegmentEndIndication executed before + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +/* PRQA S 6050, 6080 1 */ /* MD_MSR_STCAL, MD_MSR_STMIF */ +tFblMemStatus FblMemBlockEndIndication( void ) +{ + tFblMemStatus retVal; +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + tFblAddress baseAddress; + tFblLength baseLength; +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + + retVal = kFblMemStatus_Ok; + + /* Check allowed states */ + if (kFblOk != FblMemCheckAllowed(FBL_MEM_ALLOWED_BLOCK_END, FBL_MEM_ALLOWED_BLOCK_END)) + { + FBL_MEM_SET_STATUS(BlockEndSequence, retVal); + } + else + { +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + /* No gap fill required for volatile memory */ + if (kFblMemType_RAM != gSegInfo.input.type) + { + /* Address range information of last segment */ + baseAddress = gBlockInfo.segmentList->segmentInfo[gSegInfo.ownIndex].targetAddress; + baseLength = gBlockInfo.segmentList->segmentInfo[gSegInfo.ownIndex].length; + + /* Include padding previously applied to end of last segment */ + baseLength += FblMemPadLength(baseAddress, baseLength); + + /* Length till end of block + Subtract offset of segment start and length of segment (including padding) from block length + to prevent range overflow */ + gGapFillJob.used = (gBlockInfo.targetLength - (baseAddress - gBlockInfo.targetAddress)) - baseLength; + + /* Gap fill not necessary when segment ends at last block address */ + if (gGapFillJob.used > 0u) + { + /* Setup concluding gap fill from end of last segment to end of block */ + gGapFillJob.position = 0u; + /* Gap fill starts after end of last segment */ + gGapFillJob.baseAddress = baseAddress + baseLength; + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Setup gap fill progress */ + FblMemSetupProgress(kFblMemProgressType_GapFill, gBlockInfo.logicalAddress, gSegInfo.nextIndex, + FBL_MEM_PROGRESS_INITIAL + FBL_MEM_PROGRESS_ERASE, FBL_MEM_PROGRESS_PROGRAM, gGapFillJob.used); + /* Adjust total percentages */ + FblMemOffsetProgress((gGapFillJob.baseAddress - gBlockInfo.targetAddress), gBlockInfo.targetLength); + /* Report initial progress */ + FblMemUpdateProgress(gGapFillJob.used); +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + + /* Trigger concluding gap fill */ + (void)FblMemQueueDefaultPrioInsert(gProcessingQueue, &gGapFillJob, gSegInfo.ownIndex); + + /* Continue operation */ + fblMemProgState = kFblMemProgState_Pending; + + /* Finish processing of all pending buffers */ + FblMemFlushQueueByPrio((tFblMemQueuePrio)kFblMemJobPrio_Write); + } + } +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Conclude any pending progress (programming or gap fill) */ + FblMemConcludeProgress(); +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + + +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Null pointer passed as verification function disables functionality */ + if (FBL_MEM_VERIFY_FCT_INPUT_NULL != gBlockInfo.verifyRoutinePipe.function) + { + /* No additional segments for this block, trigger finalization of pipelined verification + Add to processing queue as other jobs may still be pending */ + (void)FblMemQueueDefaultPrioInsert(gProcessingQueue, &gVerifyPipeFinalizeJob, gSegInfo.ownIndex); + + /* Continue operation */ + fblMemProgState = kFblMemProgState_Pending; + } + else +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + { + /* Concluding else */ + } + } + + if (kFblMemStatus_Ok == retVal) + { + /* Allow block verify */ + FblMemSetAllowed(FBL_MEM_ALLOWED_BLOCK_VERIFY); + } + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemBlockVerify + **********************************************************************************************************************/ +/*! \brief Finalize block verification by calling extended API with options to abort + * verification in case of failure + * \details Hint: also call function if verification not configured + * \pre FblMemBlockEndIndication executed before + * \param[in] verifyData Pointer to verification structure + * Required members dependent on configuration + * \param[out] verifyResult Pointer to extended verification result + * Null pointer if no extended result required + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +tFblMemStatus FblMemBlockVerify( const V_MEMRAM1 tFblMemBlockVerifyData V_MEMRAM2 V_MEMRAM3 * verifyData, + V_MEMRAM1 tFblMemVerifyStatus V_MEMRAM2 V_MEMRAM3 * verifyResult ) +{ + return FblMemBlockVerifyExtended(verifyData, verifyResult, 0u); +} + +/*********************************************************************************************************************** + * FblMemBlockVerifyExtended + **********************************************************************************************************************/ +/*! \brief Finalize block verification + * \details Hint: also call function if verification not configured + * \pre FblMemBlockEndIndication executed before + * \param[in] verifyData Pointer to verification structure + * Required members dependent on configuration + * \param[in] option Indication which verification routines shall always be performed, + regardless of previous result. + 0 if verification shall be aborted as soon as a step fails (default) + * \param[out] verifyResult Pointer to extended verification result + * Null pointer if no extended result required + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +/* PRQA S 6010, 6030, 6080 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STMIF */ +tFblMemStatus FblMemBlockVerifyExtended( const V_MEMRAM1 tFblMemBlockVerifyData V_MEMRAM2 V_MEMRAM3 * verifyData, + V_MEMRAM1 tFblMemVerifyStatus V_MEMRAM2 V_MEMRAM3 * verifyResult, const tFblMemVerifyOption option ) +{ + tFblMemStatus retVal; + tFblMemVerifyStatus localResult; +#if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) + tFblMemVerifyStatus verifyOutputResult; +# if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT_FULL_BLOCK_LENGTH ) +# else + const V_MEMRAM1 tFblMemSegmentListEntry V_MEMRAM2 V_MEMRAM3 * lastSegment; +# endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT_FULL_BLOCK_LENGTH */ +#endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT */ + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ +# if !defined( FBL_MEM_ENABLE_VERIFICATION ) + (void)option; + (void)verifyData; +# endif /* !FBL_MEM_ENABLE_VERIFICATION */ +#endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + retVal = kFblMemStatus_Ok; + localResult = FBL_MEM_VERIFY_OK; + + /* Check allowed states */ + if (kFblOk != FblMemCheckAllowed(FBL_MEM_ALLOWED_BLOCK_VERIFY, FBL_MEM_ALLOWED_NONE)) + { + FBL_MEM_SET_STATUS(BlockVerifySequence, retVal); + } + else + { +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + /* Finish processing of all pending verification jobs */ + FblMemFlushQueueByPrio((tFblMemQueuePrio)kFblMemJobPrio_Lowest); + + /* Check for error condition */ + if (kFblMemProgState_Error == fblMemProgState) + { + /* Report error set by programming routines (previous or current) */ + retVal = gErrorStatus; + } + else +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + { +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) + if ((retVal == kFblMemStatus_Ok) || FBL_MEM_CHK_OPTION(option, FBL_MEM_VERIFY_PIPE_OPT)) /* PRQA S 2991, 2995 */ /* MD_FblMem_2991_2995 */ + { + /* Pipelined verification is used + Finalize by comparing with the transferred signature */ + if (kFblMemStatus_Ok != FblMemVerifyInput( &gBlockInfo.verifyRoutinePipe, &verifyData->verifyDataPipe, + FBL_MEM_VERIFY_STATE_VERIFY, &localResult )) + { + FBL_MEM_SET_STATUS(BlockVerifyPipeVerify, retVal); + } + } +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ +#if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) + if ((retVal == kFblMemStatus_Ok) || FBL_MEM_CHK_OPTION(option, FBL_MEM_VERIFY_OUTPUT_OPT)) /* PRQA S 2991, 2995 */ /* MD_FblMem_2991_2995 */ + { + /* Null pointer passed as verification function disables functionality */ + if (FBL_MEM_VERIFY_FCT_OUTPUT_NULL != gBlockInfo.verifyRoutineOutput.function) + { + /* Initialize verification parameter structure */ +# if defined( FBL_MEM_ENABLE_EXT_TRIGGER_OUTPUT_VERIFY ) + gBlockInfo.verifyRoutineOutput.param->wdTriggerFct = (tFblMemVerifyWdFct)&FblMemTriggerWatchdogExt; /* PRQA S 0313 */ /* MD_FblMem_0313 */ +# else + gBlockInfo.verifyRoutineOutput.param->wdTriggerFct = (tFblMemVerifyWdFct)&FblMemTriggerWatchdog; +# endif /* FBL_MEM_ENABLE_EXT_TRIGGER_OUTPUT_VERIFY */ +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Setup erase progress */ + FblMemSetupProgress(kFblMemProgressType_Verify, gBlockInfo.logicalAddress, 0u, + FBL_MEM_PROGRESS_INITIAL + FBL_MEM_PROGRESS_ERASE + FBL_MEM_PROGRESS_PROGRAM, FBL_MEM_PROGRESS_VERIFY, + gBlockInfo.targetLength); + /* Report initial progress */ + FblMemUpdateProgress(gBlockInfo.targetLength); + + /* Overwrite read function to keep track of progress */ + gBlockInfo.verifyRoutineOutput.param->readMemory = &FblMemProgressRead; +#else + gBlockInfo.verifyRoutineOutput.param->readMemory = gBlockInfo.readFct; +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + gBlockInfo.verifyRoutineOutput.param->verificationData = verifyData->verifyDataOutput.data; + + gBlockInfo.verifyRoutineOutput.param->blockStartAddress = gBlockInfo.targetAddress; +# if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT_FULL_BLOCK_LENGTH ) + gBlockInfo.verifyRoutineOutput.param->blockLength = gBlockInfo.targetLength; +# else + /* Total length covered by all programmed segments (from block start) */ + lastSegment = &(gBlockInfo.segmentList->segmentInfo[gBlockInfo.segmentList->nrOfSegments - 1u]); + + /* Segments have to be stored in increasing address order */ + gBlockInfo.verifyRoutineOutput.param->blockLength = (lastSegment->targetAddress - gBlockInfo.targetAddress) + + lastSegment->length; +# endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT_FULL_BLOCK_LENGTH */ + + /* Call verification function */ + verifyOutputResult = gBlockInfo.verifyRoutineOutput.function(gBlockInfo.verifyRoutineOutput.param); + localResult |= verifyOutputResult; /* PRQA S 2986 */ /* MD_FblMem_2986 */ + if (FBL_MEM_VERIFY_OK != verifyOutputResult) + { + FBL_MEM_SET_STATUS(BlockVerifyOutputVerify, retVal); + } + } + } +#else + { + /* Concluding else */ + } +#endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT */ + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Conclude pending verification progress */ + FblMemConcludeProgress(); +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + } + } + + if (kFblMemStatus_Ok == retVal) + { + /* Allow new block start / erase indication */ + FblMemAddAllowed(FBL_MEM_ALLOWED_BLOCK_START | FBL_MEM_ALLOWED_BLOCK_ERASE); + } + + if (FBL_MEM_VERIFY_STATUS_NULL != verifyResult) + { + /* Pass extended result */ + *verifyResult = localResult; + } + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemSegmentStartIndication + **********************************************************************************************************************/ +/*! \brief Indicate start of a new segment + * \details Segment may consist of one or more chunks of input data programmed into a contiguous memory range + * Update verification with logical address and length if configured + * Initialize data processing if configured + * \pre FblMemBlockStartIndication executed before + * \param[in] segment Pointer to segment information + * Target address (program operation) + * Target length (program operation) + * either unprocessed data length actually written to memory or processed data length of input + * data + * Logical address (verification operation) + * Logical length (verification operation) + * Type (RAM / ROM) + * Data format identifier (data processing) + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +/* PRQA S 6010, 6030, 6050, 6080 1 */ /* MD_MSR_STMIF, MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL */ +tFblMemStatus FblMemSegmentStartIndication( const V_MEMRAM1 tFblMemSegmentInfo V_MEMRAM2 V_MEMRAM3 * segment ) +{ + tFblMemStatus retVal; +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) && \ + defined( FBL_MEM_ENABLE_VERIFY_PIPELINED_ADDRESS_LENGTH ) + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * verifyJob; +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED && FBL_MEM_ENABLE_VERIFY_PIPELINED_ADDRESS_LENGTH */ +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + tFblAddress baseAddress; + tFblLength baseLength; +#endif /* FBL_MEM_ENABLE_GAP_FILL */ +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + tFblAddress progressAddress; + tFblLength progressRemainder; +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + + retVal = kFblMemStatus_Ok; + +#if defined( FBL_ENABLE_DATA_PROCESSING ) || \ + defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) || \ + defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + /* Remember input buffer type: write through */ + gSegInfo.jobType = kFblMemJobType_InputWrite; +#endif /* FBL_ENABLE_DATA_PROCESSING || FBL_MEM_ENABLE_STREAM_OUTPUT || FBL_MEM_ENABLE_PASSTHROUGH || FBL_MEM_ENABLE_REMAINDER_HANDLING */ + + /* Check allowed states */ + if (kFblOk != FblMemCheckAllowed(FBL_MEM_ALLOWED_SEGMENT_START, FBL_MEM_ALLOWED_SEGMENT_START)) + { + FBL_MEM_SET_STATUS(SegmentStartSequence, retVal); + } +#if defined( FBL_MEM_ENABLE_SEGMENT_HANDLING ) + else if (gBlockInfo.segmentList->nrOfSegments >= gBlockInfo.maxSegments) + { + /* Maximum number of segment list entries exceeded */ + FBL_MEM_SET_STATUS(SegmentStartSegmentCount, retVal); + } +#endif /* FBL_MEM_ENABLE_SEGMENT_HANDLING */ + else + { +#if defined( FBL_MEM_ENABLE_VERIFY_STREAM ) + /* Initialize verification on first segment */ + if (0u == gSegInfo.nextIndex) + { + /* Initialize the calculation */ + if (kFblMemStatus_Ok != FblMemInitVerifyInput()) + { + /* Overwrites previous error code */ + FBL_MEM_SET_STATUS(SegmentStartVerifyInit, retVal); + } + } + + if (kFblMemStatus_Ok == retVal) +#endif /* FBL_MEM_ENABLE_VERIFY_STREAM */ +#if defined( FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH ) + { + { +# if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) && \ + defined( FBL_MEM_ENABLE_VERIFY_PIPELINED_ADDRESS_LENGTH ) +# if defined( __ApplFblMemVerifyPipelinedIsAddressAndLengthIncluded ) + /* Skip update of signature information? */ + if (kFblOk == __ApplFblMemVerifyPipelinedIsAddressAndLengthIncluded(&gBlockInfo, segment)) +# endif + { + /* Get first free job + At least one (additional) job should be free at this point as the previous data indication(s) + unblocked the pipelined verification queue */ + verifyJob = FblMemPrepareVerifyPipeJob(gSegInfo.nextIndex, segment->targetAddress); + + /* Check for null pointer */ + if (FBL_MEM_JOB_NULL != verifyJob) + { + /* Switch job type to include segment information */ + verifyJob->type = kFblMemJobType_VerifyPipeInfo; + verifyJob->used = FBL_MEM_VERIFY_ADDRESS_LENGTH_BUFFER_SIZE; + verifyJob->netSize = FBL_MEM_VERIFY_ADDRESS_LENGTH_BUFFER_SIZE; + verifyJob->totalSize = FBL_MEM_VERIFY_ADDRESS_LENGTH_BUFFER_SIZE; + /* Do not remove verification job as it is reused for the read-back */ + verifyJob->completion = kFblMemOperationMode_Finalize; + + FblMemSetInteger(FBL_MEM_VERIFY_ADDRESS_LENGTH_SIZE, segment->logicalAddress, &verifyJob->buffer[0u]); + FblMemSetInteger(FBL_MEM_VERIFY_ADDRESS_LENGTH_SIZE, segment->logicalLength, &verifyJob->buffer[FBL_MEM_VERIFY_ADDRESS_LENGTH_SIZE]); + } + } +# endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED && FBL_MEM_ENABLE_VERIFY_PIPELINED_ADDRESS_LENGTH */ + } + } + + if (kFblMemStatus_Ok == retVal) +#endif /* FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH */ + { + /* Check whether data processing is requested */ + if (kFblOk == __ApplFblMemIsDataProcessingRequired(segment->dataFormat)) + { +#if defined( FBL_ENABLE_DATA_PROCESSING ) + /* Remember input buffer type: data processing */ + gSegInfo.jobType = kFblMemJobType_ProcInput; + + /* Initialize user specific processing of received data */ + gProcParam.mode = segment->dataFormat; + + /* Check result */ + if (kFblOk != ApplFblInitDataProcessing(&gProcParam)) + { + FBL_MEM_SET_STATUS(SegmentStartDataProcInit, retVal); + } +#else + /* Data processing not supported, refuse indication */ + FBL_MEM_SET_STATUS(SegmentStartDataProcInit, retVal); +#endif /* FBL_ENABLE_DATA_PROCESSING */ + } + } + +#if defined( __ApplFblMemIsStreamOutputRequired ) + if (kFblMemStatus_Ok == retVal) + { + /* Check whether stream output is requested */ + if (kFblOk == __ApplFblMemIsStreamOutputRequired(segment->dataFormat)) + { +# if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) +# if defined( FBL_ENABLE_DATA_PROCESSING ) + if (kFblOk == __ApplFblMemIsDataProcessingRequired(segment->dataFormat)) + { + /* Input buffer type (data processing) already set */ + } + else +# endif /* FBL_ENABLE_DATA_PROCESSING */ + { + /* Remember input buffer type: stream output */ + gSegInfo.jobType = kFblMemJobType_StreamInput; + } + + + /* Initialize user specific stream output of received data */ + gStreamParam.mode = segment->dataFormat; + gStreamParam.baseAddress = segment->targetAddress; + gStreamParam.baseLength = gBlockInfo.targetLength - (segment->targetAddress - gBlockInfo.targetAddress); + + /* Check result */ + if (kFblOk != ApplFblInitStreamOutput(&gStreamParam)) + { + FBL_MEM_SET_STATUS(SegmentStartStreamOutInit, retVal); + } +# else + /* Stream output not supported, refuse indication */ + FBL_MEM_SET_STATUS(SegmentStartStreamOutInit, retVal); +# endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ + } + } +#endif /* __ApplFblMemIsStreamOutputRequired */ + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Progress information for segment (without gap fill) */ + progressAddress = segment->targetAddress; + progressRemainder = segment->targetLength; +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + +#if defined( FBL_MEM_ENABLE_GAP_FILL ) + if (kFblMemStatus_Ok == retVal) + { + /* No gap fill required for volatile memory */ + if (kFblMemType_RAM != segment->type) + { + /* First segment of block? */ + if (0u == gSegInfo.nextIndex) + { + /* Fill from beginning of block */ + baseAddress = gBlockInfo.targetAddress; + baseLength = 0u; + } + else + { + /* Fill from end of previous segment */ + baseAddress = gBlockInfo.segmentList->segmentInfo[gSegInfo.ownIndex].targetAddress; + baseLength = gBlockInfo.segmentList->segmentInfo[gSegInfo.ownIndex].length; + } + + /* Include padding applied to end of previous segment */ + baseLength += FblMemPadLength(baseAddress, baseLength); + + /* Segments in ascending order? */ + assertFblInternal((segment->targetAddress >= baseAddress), kFblMemAssertParameterOutOfRange); + assertFblInternal(((segment->targetAddress - baseAddress) >= baseLength), kFblMemAssertParameterOutOfRange); + + /* Length till start of current segment + Subtract length of previous segment (including padding) from offset between segments + to prevent range overflow */ + gGapFillJob.used = (segment->targetAddress - baseAddress) - baseLength; + + /* Gap fill not necessary when segment starts directly after previous segment */ + if (gGapFillJob.used > 0u) + { + /* Setup gap fill */ + gGapFillJob.position = 0u; + /* Gap fill starts after end of previous segment */ + gGapFillJob.baseAddress = baseAddress + baseLength; + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Include gap fill range in progress information */ + progressAddress = gGapFillJob.baseAddress; + progressRemainder += gGapFillJob.used; +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + + /* Trigger gap fill */ + (void)FblMemQueueDefaultPrioInsert(gProcessingQueue, &gGapFillJob, gSegInfo.nextIndex); + +# if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) + /* Process operation in task */ + fblMemProgState = kFblMemProgState_Pending; +# endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + } + } + } +#endif /* FBL_MEM_ENABLE_GAP_FILL */ + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Setup programming progress (may include gap fill) */ + FblMemSetupProgress(kFblMemProgressType_Program, gBlockInfo.logicalAddress, gSegInfo.nextIndex, + FBL_MEM_PROGRESS_INITIAL + FBL_MEM_PROGRESS_ERASE, FBL_MEM_PROGRESS_PROGRAM, progressRemainder); + /* Adjust total percentages */ + FblMemOffsetProgress((progressAddress - gBlockInfo.targetAddress), gBlockInfo.targetLength); + /* Report initial progress */ + FblMemUpdateProgress(progressRemainder); +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + } + + if (kFblMemStatus_Ok == retVal) + { + /* Copy input parameters to local variable */ + gSegInfo.input = *segment; + + /* Initialize internal attributes */ + gSegInfo.writeAddress = segment->targetAddress; + gSegInfo.writeRemainder = 0u; +#if defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) + /* Available length from start of segment to end of block */ + gSegInfo.writeLength = gBlockInfo.targetLength - (segment->targetAddress - gBlockInfo.targetAddress); + gSegInfo.writtenLength = 0u; +#else + gSegInfo.writeLength = segment->targetLength; +#endif /* FBL_ENABLE_PROCESSED_DATA_LENGTH */ +#if defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) + /* Sliding input address required for remainder calculation */ + gSegInfo.inputAddress = segment->targetAddress; +#endif /* FBL_ENABLE_UNALIGNED_DATA_TRANSFER */ +#if defined( FBL_MEM_ENABLE_INPUT_LENGTH ) + /* Running input length required for early overflow detection */ + gSegInfo.inputLength = segment->targetLength; +#endif /* FBL_MEM_ENABLE_INPUT_LENGTH */ + + gSegInfo.ownIndex = gSegInfo.nextIndex; + gSegInfo.nextIndex++; + + /* Allow data indication */ + FblMemSetAllowed(FBL_MEM_ALLOWED_DATA_IND); + } + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemSegmentEndIndication + **********************************************************************************************************************/ +/*! \brief Indicate end of current segment + * \details Finish processing of all pending buffers, finalize data + * processing and program any remainder + * \pre FblMemDataIndication executed before + * \param[out] writeLength Pointer to length actually written + * \return Result of operation (potentially remapped to OEM specific NRC) + * May return error generated by background task operation + **********************************************************************************************************************/ +/* PRQA S 6010, 6030, 6050 1 */ /* MD_MSR_STMIF, MD_MSR_STPTH, MD_MSR_STCAL */ +tFblMemStatus FblMemSegmentEndIndication( V_MEMRAM1 tFblLength V_MEMRAM2 V_MEMRAM3 * writeLength ) +{ + tFblMemStatus retVal; +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING_SINGLE_JOB ) || \ + defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) || \ + defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * activeJob; +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING_SINGLE_JOB || FBL_ENABLE_UNALIGNED_DATA_TRANSFER || FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ +#if defined( FBL_MEM_ENABLE_SEGMENT_HANDLING ) + V_MEMRAM1 tFblMemSegmentListEntry V_MEMRAM2 V_MEMRAM3 * activeSegment; +#endif /* FBL_MEM_ENABLE_SEGMENT_HANDLING */ + + retVal = kFblMemStatus_Ok; + + /* Check allowed states */ + if (kFblOk != FblMemCheckAllowed(FBL_MEM_ALLOWED_SEGMENT_END, FBL_MEM_ALLOWED_DATA_IND | FBL_MEM_ALLOWED_SEGMENT_END)) + { + FBL_MEM_SET_STATUS(SegmentEndSequence, retVal); + } + else + { +#if defined( FBL_MEM_ENABLE_PREAMBLE_HANDLING ) + /* Active fill buffer may change + Store preamble so operation is transparent for caller */ + FblMemStorePreamble(); +#endif /* FBL_MEM_ENABLE_PREAMBLE_HANDLING */ + +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING_SINGLE_JOB ) + /* Active input job may be used as finalization trigger (flush remainder) */ + activeJob = FblMemGetPendingInputJob(); +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING_SINGLE_JOB */ + + { +#if defined( FBL_ENABLE_DATA_PROCESSING ) || \ + defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) || \ + defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + if (kFblMemProgState_Error != fblMemProgState) + { +# if defined( FBL_ENABLE_DATA_PROCESSING ) + /* Data processing active? */ + if (kFblOk == __ApplFblMemIsDataProcessingRequired(gSegInfo.input.dataFormat)) + { + /* Do not remove finalize job until no data is produced anymore */ + gProcFinalizeJob.completion = kFblMemOperationMode_Finalize; + + /* No additional data in this segment, trigger finalization of data processing + Add to queue as some jobs may still be pending */ + (void)FblMemQueueDefaultPrioInsert(gProcessingQueue, &gProcFinalizeJob, gSegInfo.ownIndex); + } +# endif /* FBL_ENABLE_DATA_PROCESSING */ + +# if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + /* Stream output active? */ + if (kFblOk == __ApplFblMemIsStreamOutputRequired(gSegInfo.input.dataFormat)) + { + /* Do not remove finalize job until no data is produced anymore */ + gStreamFinalizeJob.completion = kFblMemOperationMode_Finalize; + + /* No additional data in this segment, trigger finalization of stream output + Add to queue as some jobs may still be pending */ + (void)FblMemQueueDefaultPrioInsert(gProcessingQueue, &gStreamFinalizeJob, gSegInfo.ownIndex); + } + /* Skip write finalization */ + else +# endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ + { +# if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) +# if defined( FBL_MEM_ENABLE_PROC_QUEUE ) + /* Insert dummy info into queue to trigger finalization of write */ + (void)FblMemQueueDefaultPrioInsert(gProcessingQueue, &gWriteFinalizeJob, gSegInfo.ownIndex); +# else + /* Enable switch combination equals FBL_MEM_ENABLE_REMAINDER_HANDLING_SINGLE_JOB */ + + /* Re-use active input job as finalization trigger (flush remainder) + Change job type, all other members already have a consistent value */ + activeJob->type = kFblMemJobType_WriteFinalize; +# endif /* FBL_MEM_ENABLE_PROC_QUEUE */ +# endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING */ + } + +# if defined( FBL_MEM_ENABLE_PROC_QUEUE ) + if (!FblMemQueueIsEmpty(gProcessingQueue)) +# endif /* FBL_MEM_ENABLE_PROC_QUEUE */ + { + /* Continue operation */ + fblMemProgState = kFblMemProgState_Pending; + } + } +#endif /* FBL_ENABLE_DATA_PROCESSING || FBL_MEM_ENABLE_STREAM_OUTPUT || FBL_MEM_ENABLE_REMAINDER_HANDLING */ + } + +#if defined( FBL_MEM_ENABLE_PROC_QUEUE ) || \ + defined( FBL_MEM_ENABLE_REMAINDER_HANDLING ) + /* Finish processing of all pending buffers */ + FblMemFlushQueueByPrio((tFblMemQueuePrio)kFblMemJobPrio_Write); + + /* Check for error condition */ + if (kFblMemProgState_Error == fblMemProgState) + { + /* Report error set by programming routines (previous or current) */ + retVal = gErrorStatus; + } + else +#endif /* FBL_MEM_ENABLE_PROC_QUEUE || FBL_MEM_ENABLE_REMAINDER_HANDLING */ + { +#if defined( FBL_MEM_ENABLE_REMAINDER_HANDLING_SINGLE_JOB ) + /* Remainder handling finished, restore original job type */ + activeJob->type = kFblMemJobType_InputWrite; +#endif /* FBL_MEM_ENABLE_REMAINDER_HANDLING_SINGLE_JOB */ + +#if defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) + /* Requested data should be completely provided at this point */ + if (0u != gSegInfo.inputLength) +#else + /* Requested data should be completely programmed at this point */ + if (0u != gSegInfo.writeLength) +#endif /* FBL_ENABLE_PROCESSED_DATA_LENGTH */ + { + FBL_MEM_SET_STATUS(SegmentEndInsufficientData, retVal); + } +#if defined( __ApplFblMemPostSegmentEnd ) + else + { + /* Perform actions directly after segment end */ + if (kFblOk != __ApplFblMemPostSegmentEnd()) + { + FBL_MEM_SET_STATUS(SegmentEndPost, retVal); + } + } +#endif /* __ApplFblMemPostSegmentEnd */ + + /* Return written length */ +#if defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) + *writeLength = gSegInfo.writtenLength; +#else + *writeLength = gSegInfo.input.targetLength - gSegInfo.writeLength; +#endif /* FBL_ENABLE_PROCESSED_DATA_LENGTH */ + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + FblMemConcludeProgress(); +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + } + +#if defined( FBL_MEM_ENABLE_SEGMENT_HANDLING ) + /* Add segment to list */ + if (kFblMemStatus_Ok == retVal) + { + activeSegment = &(gBlockInfo.segmentList->segmentInfo[gBlockInfo.segmentList->nrOfSegments]); + activeSegment->targetAddress = gSegInfo.input.targetAddress; + activeSegment->transferredAddress = gSegInfo.input.logicalAddress; + activeSegment->length = *writeLength; + gBlockInfo.segmentList->nrOfSegments++; + } +#endif /* FBL_MEM_ENABLE_SEGMENT_HANDLING */ + +#if defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) || \ + defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) + /* Restore default offset to align actual data to platform requirements */ + activeJob = FblMemGetPendingInputJob(); + activeJob->offset = FBL_MEM_PREAMBLE_OFFSET(FBL_MEM_PREAMBLE_LENGTH); +#endif /* FBL_ENABLE_UNALIGNED_DATA_TRANSFER || FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ + +#if defined( FBL_MEM_ENABLE_PREAMBLE_HANDLING ) + /* + Active fill buffer may have changed + Restore previously stored preamble so operation is transparent for caller + */ + FblMemRestorePreamble(); +#endif /* FBL_MEM_ENABLE_PREAMBLE_HANDLING */ + } + + /* Check result of final programming */ + if (kFblMemStatus_Ok == retVal) + { + /* Allow additional segment start or block end indication */ + FblMemSetAllowed(FBL_MEM_ALLOWED_SEGMENT_START | FBL_MEM_ALLOWED_BLOCK_END); + } + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemDataIndication + **********************************************************************************************************************/ +/*! \brief Indicate new chunk of input data + * \details If pipelined programming is configured queue buffer and immediately return in case another input buffer + * is available + * Otherwise finish processing of one pending input buffer + * In non-pipelined mode indicated input buffer is directly processed + * \pre FblMemSegmentStartIndication executed before, provided buffer + * and data offset equal the parameters of active input buffer + * \param[in] buffer Pointer to input buffer (including preamble) + * \param[in] offset Offset of actual data (after preamble) + * \param[in] length Length of data (without preamble) + * \return Result of operation (potentially remapped to OEM specific NRC) + * May return error generated by background task operation + **********************************************************************************************************************/ +/* PRQA S 6010, 6030, 6050, 6080 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */ +tFblMemStatus FblMemDataIndication( tFblMemConstRamData buffer, tFblLength offset, tFblLength length ) +{ + tFblMemStatus retVal; +#if defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) || \ + defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) + V_MEMRAM1 tFblMemJob V_MEMRAM2 V_MEMRAM3 * activeJob; +#endif /* FBL_ENABLE_UNALIGNED_DATA_TRANSFER || FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ +#if defined( FBL_MEM_ENABLE_INPUT_LENGTH ) + tFblLength inputLength; + + /* Do not update running input length unless data is unprocessed */ + inputLength = 0u; /* PRQA S 2982 */ /* MD_FblMem_2982 */ +#endif /* FBL_MEM_ENABLE_INPUT_LENGTH */ + + retVal = kFblMemStatus_Ok; + + /* Check allowed states */ + if (kFblOk != FblMemCheckAllowed(FBL_MEM_ALLOWED_DATA_IND, FBL_MEM_ALLOWED_DATA_IND | FBL_MEM_ALLOWED_SEGMENT_END)) + { + FBL_MEM_SET_STATUS(DataIndSequence, retVal); + } + else + { +#if defined( FBL_ENABLE_SYSTEM_CHECK ) || \ + defined( FBL_MEM_ENABLE_INPUT_LENGTH ) +# if defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) + /* Unconditionally check input length */ + { +# else +# if defined( FBL_ENABLE_DATA_PROCESSING ) || \ + defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + { + /* + Data processed in any way? + Unprocessed data directly written through + */ +# if defined( FBL_ENABLE_DATA_PROCESSING ) + if (kFblOk == __ApplFblMemIsDataProcessingRequired(gSegInfo.input.dataFormat)) + { + } + else +# endif /* FBL_ENABLE_DATA_PROCESSING */ +# if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + if (kFblOk == __ApplFblMemIsStreamOutputRequired(gSegInfo.input.dataFormat)) + { + } + else +# endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ +# else + { +# endif /* FBL_ENABLE_DATA_PROCESSING ||FBL_MEM_ENABLE_STREAM_OUTPUT */ +# endif /* FBL_ENABLE_PROCESSED_DATA_LENGTH */ + { + /* + Verify newly provided data does not exceed length requested + in segment info + */ +# if defined( FBL_MEM_ENABLE_INPUT_LENGTH ) + /* Unprocessed data: Update running input data length */ + inputLength = length; + + if (gSegInfo.inputLength < length) +# else + if (gSegInfo.writeLength < length) +# endif /* FBL_MEM_ENABLE_INPUT_LENGTH */ + { + FBL_MEM_SET_STATUS(DataIndOverflow, retVal); + } + } + } +#endif /* FBL_ENABLE_SYSTEM_CHECK || FBL_ENABLE_PROCESSED_DATA_LENGTH */ + } + + if (kFblMemStatus_Ok == retVal) + { +#if defined( FBL_MEM_ENABLE_PREAMBLE_HANDLING ) + /* + Active fill buffer may change + Store preamble so operation is transparent for caller + */ + FblMemStorePreamble(); +#endif /* FBL_MEM_ENABLE_PREAMBLE_HANDLING */ + + /* Queue the active buffer for further processing */ + retVal = FblMemQueueBuffer(buffer, offset, length); + if (kFblMemStatus_Ok == retVal) + { +#if defined( FBL_MEM_ENABLE_INPUT_LENGTH ) + /* Keep track of expected input data length */ + gSegInfo.inputLength -= inputLength; +#endif /* FBL_MEM_ENABLE_INPUT_LENGTH */ + +#if defined( FBL_MEM_ENABLE_INPUT_DATA_FLUSH ) +# if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) + if (kFblOk == __ApplFblMemIsPipelinedProgrammingDisabled(&gBlockInfo, &(gSegInfo.input))) +# endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + { + /* Directly process all input data */ + FblMemFlushQueueByPrio((tFblMemQueuePrio)kFblMemJobPrio_Write); + } + + /* Check for programming error */ + if (kFblMemProgState_Error == fblMemProgState) + { + retVal = gErrorStatus; + } + else +#endif /* FBL_MEM_ENABLE_INPUT_DATA_FLUSH */ + { +#if defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) || \ + defined( FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER ) + /* Restore default offset to align actual data to platform requirements */ + activeJob = FblMemGetPendingInputJob(); + activeJob->offset = FBL_MEM_PREAMBLE_OFFSET(FBL_MEM_PREAMBLE_LENGTH); + +# if defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) + /* Remainder handling neither required for volatile memory nor for processed data */ + if (kFblMemType_RAM == gSegInfo.input.type) + { + } + else +# if defined( FBL_ENABLE_DATA_PROCESSING ) + if (kFblOk == __ApplFblMemIsDataProcessingRequired(gSegInfo.input.dataFormat)) + { + } + else +# endif /* FBL_ENABLE_DATA_PROCESSING */ +# if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) + if (kFblOk == __ApplFblMemIsStreamOutputRequired(gSegInfo.input.dataFormat)) + { + } + else +# endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ + { + /* Align active input buffer to current remainder */ + activeJob->offset += FblMemGetWriteRemainder(gSegInfo.inputAddress, length); + + /* Update sliding input address */ + gSegInfo.inputAddress += length; + } +# endif /* FBL_ENABLE_UNALIGNED_DATA_TRANSFER */ +#endif /* FBL_ENABLE_UNALIGNED_DATA_TRANSFER || FBL_MEM_ENABLE_SEGMENTED_INPUT_BUFFER */ + } + } + +#if defined( FBL_MEM_ENABLE_PREAMBLE_HANDLING ) + /* + Active fill buffer may have changed + Restore previously stored preamble so operation is transparent for caller + */ + FblMemRestorePreamble(); +#endif /* FBL_MEM_ENABLE_PREAMBLE_HANDLING */ + } + + if (kFblMemStatus_Ok == retVal) + { +#if defined( FBL_MEM_ENABLE_INPUT_LENGTH ) + /* No more data is expected, all data has been processed within the last chunk of data */ + if (gSegInfo.inputLength == 0u) + { + FblMemSetAllowed(FBL_MEM_ALLOWED_SEGMENT_END); + } + else +#endif /* FBL_MEM_ENABLE_INPUT_LENGTH */ + { + /* Allow additional data or segment end indication */ + FblMemSetAllowed(FBL_MEM_ALLOWED_DATA_IND | FBL_MEM_ALLOWED_SEGMENT_END); + } + } + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemTask + **********************************************************************************************************************/ +/*! \brief Perform background tasks + * \details If pipelined programming is configured pending buffers are processed until the operation is suspended by + * a Rx notification + * \pre FblMemInitPowerOn executed before + **********************************************************************************************************************/ +void FblMemTask( void ) +{ +#if defined( FBL_MEM_ENABLE_PIPELINING ) + switch (fblMemProgState) + { + /* Operation pending */ + case kFblMemProgState_Pending: + { + /* Switch to background context + * Affects watchdog and suspend handling */ + gProgContext = kFblMemContext_Background; + + /* + Loop while processing isn't paused by external event (e.g. data reception) + and buffers are pending + */ + while (kFblMemProgState_Pending == fblMemProgState) + { + /* Execute processing cycle */ + FblMemProcessQueue(kFblMemOperationMode_Normal); + } + + /* Suspend request received during processing */ + if (kFblMemProgState_SuspendPending == fblMemProgState) + { + fblMemProgState = kFblMemProgState_Suspended; + } + + /* Switch back (foreground) service context + * Affects watchdog and suspend handling */ + gProgContext = kFblMemContext_Service; + + break; + } + /* No operation pending */ + case kFblMemProgState_Idle: + case kFblMemProgState_Error: + /* Operation suspended by external event */ + case kFblMemProgState_Suspended: + case kFblMemProgState_SuspendPending: + /* Operation suspended by internal checkpoint event */ + case kFblMemProgState_Checkpoint: + /* Unknown state value */ + default: + { + /* Nothing to do */ + break; + } + } +#endif /* FBL_MEM_ENABLE_PIPELINING */ +} + +/*********************************************************************************************************************** + * FblMemFlushInputData + **********************************************************************************************************************/ +/*! \brief Flush any pending input data + * \details Process and program any pending input data passed via DataIndication. Pipelined verification tasks + * may still be pending afterwards. + * \pre FblMemInitPowerOn executed before + **********************************************************************************************************************/ +void FblMemFlushInputData( void ) +{ + /* Process all pending input data */ + FblMemFlushQueueByPrio((tFblMemQueuePrio)kFblMemJobPrio_Write); +} + +#define FBLLIB_MEM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# define FBLLIB_MEM_RAMCODE_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * FblMemResumeIndication + **********************************************************************************************************************/ +/*! \brief Resume suspended operation + * \details If pipelined programming is configured a pending operation which was suspended earlier through a RX + * notification will be resumed + * \pre FblMemInitPowerOn executed before + **********************************************************************************************************************/ +void FblMemResumeIndication( void ) +{ +#if defined( FBL_MEM_ENABLE_PIPELINING ) + /* Resume any pending operations */ + if (FblMemTaskIsPending()) + { + /* Continue operation on next call cycle of task + Note: fblMemProgState may already be pending and isn't necessarily suspended */ + fblMemProgState = kFblMemProgState_Pending; + } +#endif /* FBL_MEM_ENABLE_PIPELINING */ +} + +#if defined( FBL_MEM_ENABLE_PIPELINING ) +/*********************************************************************************************************************** + * FblMemRxNotification + **********************************************************************************************************************/ +/*! \brief Suspend any pending programming operation + * \details If memory driver supports pausing of active operation call respective user callback too + * \pre FblMemInitPowerOn executed before + **********************************************************************************************************************/ +void FblMemRxNotification( void ) +{ + /* + Notification may be executed in interrupt context + Critical section secures access to programming state + */ + __ApplFblMemEnterCriticalSection(); + + /* + Actions only necessary if programming is pending + Condition equals ((fblMemProgState == kFblMemProgState_Pending) || (fblMemProgState == kFblMemProgState_Checkpoint)) + */ + if (fblMemProgState >= kFblMemProgState_Checkpoint) + { + /* Suspend programming to handle received request */ + fblMemProgState = kFblMemProgState_SuspendPending; + + } + + /* Leave critical section */ + __ApplFblMemLeaveCriticalSection(); +} +#endif /* FBL_MEM_ENABLE_PIPELINING */ + +# define FBLLIB_MEM_RAMCODE_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLLIB_MEM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + + + +/*********************************************************************************************************************** + * FblMemEraseRegion + **********************************************************************************************************************/ +/*! \brief Performs erase operation in non-volatile memory + * \details All memory segments fully or partially covered by given region are affected. Gaps in the memory segment + * definition are skipped. + * \pre Memory driver initialized + * \param[in] eraseAddress Start address of erase region + * \param[in] eraseLength Length of erase region + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +tFblMemStatus FblMemEraseRegion( tFblAddress eraseAddress, tFblLength eraseLength ) +{ + tFblMemStatus retVal; + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) + /* Disable progress information */ + gProgressState = kFblMemProgressState_Disabled; +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + + retVal = FblMemEraseRegionInternal(eraseAddress, eraseLength); + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemProgramBuffer + **********************************************************************************************************************/ +/*! \brief Performs program operation to non-volatile memory + * \details If the length is not aligned to the segment size the odd bytes are padded with the configured fill + * character. + * Programming may be suspended by an external event. In this case parameter programLength will be + * updated to reflect the length actually programmed + * \pre Memory driver initialized, address aligned to memory segment size + * \param[in] programAddress Program address + * \param[in,out] programLength Length of data (output: length actually programmed) + * \param[in,out] programData Pointer to program data (contents are padded in case length is not aligned to memory + * segment size!) + * \return Result of operation (potentially remapped to OEM specific NRC) + **********************************************************************************************************************/ +tFblMemStatus FblMemProgramBuffer( tFblAddress programAddress, + V_MEMRAM1 tFblLength V_MEMRAM2 V_MEMRAM3 * programLength, tFblMemRamData programData ) +{ + tFblMemProgState activeProgState; + tFblMemStatus retVal; + + { + /* Remember active programming state */ + activeProgState = fblMemProgState; + + /* Operation potentially paused during previous execution cycle */ + fblMemProgState = kFblMemProgState_Pending; + + /* Perform actual programming */ + retVal = FblMemProgramBufferInternal(programAddress, programLength, programData, kFblMemProgState_Pending); + + /* Restore previous programming state */ + fblMemProgState = activeProgState; + } + + return retVal; +} + +/*********************************************************************************************************************** + * FblMemSetInteger + **********************************************************************************************************************/ +/*! \brief Convert given integer value to big-endian byte array + * \param[in] count Number of relevant bytes + * \param[in] input Input value + * \param[out] buffer Pointer to output buffer + **********************************************************************************************************************/ +void FblMemSetInteger( vuintx count, vuint32 input, tFblMemRamData buffer ) +{ + vuint32 localInput = input; + vuintx localCount = count; + + /* Integer to array conversion only supported for up to 32-bit values */ + assertFblInternal(count <= sizeof(vuint32), kFblMemAssertParameterOutOfRange); + + /* Loop relevant bytes */ + while (localCount > 0u) + { + localCount--; + /* Store most significant byte first */ + buffer[localCount] = (vuint8)(localInput & 0xFFu); + /* Shift in next byte */ + localInput >>= 8u; + } +} + +/*********************************************************************************************************************** + * FblMemGetInteger + **********************************************************************************************************************/ +/*! \brief Convert given big-endian byte array to integer value + * \param[in] count Number of relevant bytes + * \param[in] buffer Pointer to input buffer + * \return Integer value + **********************************************************************************************************************/ +vuint32 FblMemGetInteger( vuintx count, tFblMemConstRamData buffer ) +{ + vuint32 output = 0u; + vuintx idx = 0u; + vuintx localCount = count; + + /* Array to integer conversion only supported for up to 32-bit values */ + assertFblInternal(count <= sizeof(vuint32), kFblMemAssertParameterOutOfRange); + + /* Loop relevant bytes */ + while (localCount > 0u) + { + /* Most significant byte first */ + output <<= 8u; + /* Add current byte */ + output |= (vuint32)buffer[idx]; + + idx++; + localCount--; + } + + return output; +} + +#define FBLLIB_MEM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_FblMem_0306: + Reason: Address conversion between integer values and pointers is required to allow for hardware independent + configuration and address range checks. + Risk: The size of integer required to hold the result of a pointer cast is implementation defined. + Prevention: The size of the respective integer data type which holds the address value is adapted on a hardware + specific basis. + + MD_FblMem_0310_3305: + Reason: Snapshot stored in byte buffer. This way caller doesn't need to know specific structure type. + Risk: Byte buffer size or alignment not suitable for direct access through structure pointer. + Prevention: Offset calculated to align pointer to platform requirements. + Effective size after alignment checked against actual structure requirements. + + MD_FblMem_0313: + Reason: Functions pointers may be cast to different types if function parameters or function return values + are not used by callers. + Risk: Calling a function with erroneus call context or without a return value while expecting a return value + Prevention: Check if new type is compatible with target type: + - in case of function parameter change: Are paremeters of new type compatible with parameters of + target type or are function parameters of target type unused in active configuration? + - in case of return type change: is return value of target type compatible with return value of new + type or is a return value from target type never expected if target type returns void? + + MD_FblMem_0314_0326_MemCpy: + Reason: The copy function have a void pointer as a function parameter and an integer is casted to pointer void. + Risk: No risk, because the underlying pointer type is known and the cast is safe. + Prevention: No prevention necessary. + + MD_FblMem_0488: + Reason: Calling instance passes an arbitrary buffer pointer. Relative offset to internal buffer has to be + calculated. + Risk: 1) Range overflow caused by subtraction. + 2) Accessing memory outside of allocated buffer. + Prevention: Input and internal pointer have exact same type + 1) Input pointer compared against internal buffer before subtraction. + 2) Pointer arithmetic not used to access data directly. Instead calculated offset and input length are verified + against constraints given by internal buffer. Actual data accesses use array indexing. + + MD_FblMem_0602_0603: + Reason: Usage of reserved identifiers with leading underscores is accepted for compatibility reasons. + Risk: Name conflicts. + Prevention: Compile and link of the different variants in the component and integration test. + + MD_FblMem_0724_EnumValNotUnique: + Reason: The same numerical value is associated to different enum entries, to allows each entry value to be used in + the appropriate context, keeping a better code structure and understanding. + Risk: Enum values can potentially be assigned with the same value unintentionally. + Prevention: Correct design. + + MD_FblMem_2822: + Reason: Apparent NULL pointer which are actually correctly assigned at runtime. + Risk: The pointer is not initialized. + Prevention: A correct design prevent missing or uncorrect initialization. + + MD_FblMem_2842: + Reason: Checks over out of boundary for arrays are usually done at compile time through Assertions, therefore there + is no need to perform further checks at runtime. + Risk: An out of boundary access is not detected through assertions and happens at runtime. + Prevention: The code shall be correctly designed in order to avoid any kind of out of boundary access. + + MD_FblMem_2889: + Reason: Multiple return paths are used to reduce code complexity, increase readability and reducing nesting level. + Risk: Some operations intended to conclude the function (e.g. states cleaning) can be unintentionally jumped. + Prevention: Code inspection and runtime tests. + + MD_FblMem_2982: + Reason: Depending on configuration different paths may be executed. Initialization makes sure no invalid variable + contents are used accidentally. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblMem_2986: + Reason: Code is only redundant in certain configurations. + Risk: No identifiable risk + Prevention: No prevention required. + + MD_FblMem_2991_2995: + Reason: The result of this logical operation might not always be true depending on configuration. Check is kept + to avoid excessive encapsulation which might decrease readability. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblMem_3205_IdentifierNotUsed: + Reason: Some enumerations are not used in all the configurations or just define the extreme limits of the enumeration (MIN, MAX). + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblMem_3218: + Reason: The local data buffers of this module are kept at a central location for a better overview and maintenance. + Risk: Scope is larger than required (whole file instead of one function). Some other function could access + the variable. + Prevention: Restrict the functionality in this module to the intended purpose. Don't add functions which shall not + be able to access the local data buffers. + + MD_FblMem_3415: + Reason: If condition relies on lazy evaluation, second argument only executed if ROM download is active. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblMem_3673: + Reason: Depending on configuration the parameter is actually modified inside the calling hierarchy. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblMem_6060: + Reason: Reducing the number of parameters can only be achieved by using a data grouping structure (i.e. structs) + or by splitting the function in different sub-functions, but both will affect the readability and the + maintenability of the function. + Risk: Stack usage and runtime too high for target uC. + Prevention: Test of resulting code on target uC. User must check stack usage in project context. + + MD_FblMem_AssertJobMax: + Reason: For certain configurations this check is always false. However, this check can only be done at runtime. + Risk: No risk. + Prevention: No prevention required. (Note: assertions are disabled in production software). + + MD_FblMem_FalseFinding + Reason: Manual evaluation shows that QAC throws a false finding. This was confirmed by using a different + QAC version with the same MISRA ruleset. + Risk: No risk. + Prevention: No prevention required. +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_MEM.C + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_mem.h b/Source/bsw/Fbl/fbl_mem.h new file mode 100644 index 0000000..6904e99 --- /dev/null +++ b/Source/bsw/Fbl/fbl_mem.h @@ -0,0 +1,1151 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Library containing common functionality for memory programming: + * - Erase of memory region + * - Data processing (e.g. decryption and decompression) + * - Segmentation and alignment + * - Signature / checksum verification over RAM contents + * - Pipelined programming + * + * Used by OEM dependent diagnostics to program incoming download data. + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2012-03-23 visjhg - Initial release + * 01.00.01 2012-03-26 visjhg - Added description to file header + * 01.01.00 2012-04-05 visjhg ESCAN00057963 No changes + * Changes and optimizations after code review + * 01.02.00 2012-04-27 visjhg ESCAN00058452 Added support for processed length + * ESCAN00058453 Removed fbl_mem_cfg.h include + * ESCAN00058621 No changes + * 01.03.00 2012-06-22 visjhg ESCAN00059475 No changes + * ESCAN00059477 No changes + * 01.04.00 2013-02-01 visjhg ESCAN00064290 Extensions for multi processor systems (pass-through) + * Rework of block start indication interface + * Pass additional info in structure + * visjhg ESCAN00064292 Added block erase + * visjhg ESCAN00064296 Preamble length switchable at runtime + * visjhg ESCAN00064301 Added signature verification on ROM contents + * Rework of block verify interface + * Keep track of segment history (structure provided externally) + * visjhg - Added additional error codes for new functionality + * visjhg ESCAN00061335 No changes + * visjhg ESCAN00064333 No changes + * visjhg ESCAN00061764 No changes + * visjhg ESCAN00061814 No changes + * visjhg ESCAN00064338 Added post handler for SegmentEndIndication + * visach ESCAN00062919 Adapted comments to use Doxygen + * visjhg ESCAN00064334 Added interface to remap error codes to OEM dependent value + * visjhg ESCAN00064339 Segmented data processing: data produced during one cycle may be + * smaller than buffer size + * visjhg ESCAN00064330 Explicit resume of suspended operation + * Added state "suspend pending" + * Added active operation check + * visjhg ESCAN00064343 Added support for multiple input sources + * visjhg - Added additional error codes for new functionality + * visjhg - Additional integration time checks + * visjhg ESCAN00064543 No changes + * visjhg ESCAN00064720 Replaced __ApplFblMemCheckDfi by __ApplFblMemIsDataProcessingRequired + * 01.05.00 2013-04-10 visjhg ESCAN00064871 No changes + * visjhg ESCAN00064890 No changes + * visjhg - No changes + * visjhg ESCAN00065830 No changes + * visjhg ESCAN00066375 No changes + * visjhg ESCAN00066377 Encapsulate erase functionality + * visjhg ESCAN00066379 Added interface version compatibility check + * visjhg ESCAN00066380 Exported FblMemInit + * 01.06.00 2013-07-22 visase ESCAN00066743 No changes + * visjhg ESCAN00067433 Added FblMemDeinit + * Updated interface version + * visjhg ESCAN00068321 Force response pending for erase operation + * visjhg ESCAN00069161 Added pipelined verification + * Rework of block start and verify interface + * Changed verification configuration options and error codes + * Updated interface version (incompatible changes) + * visjhg ESCAN00069190 No changes + * 01.07.00 2013-08-16 visjhg ESCAN00069507 No changes + * visjhg ESCAN00069803 Updated interface version (enable/disable verification at run-time) + * ESCAN00069781 No changes + * ESCAN00069797 No changes + * visjhg ESCAN00069843 No changes + * 02.00.00 2013-12-12 visjhg ESCAN00069945 No changes + * visjhg ESCAN00072568 Error / status for BlockStartVerifyInit replaced by SegmentStartVerifyInit + * visjhg ESCAN00071344 No changes + * visjhg ESCAN00072569 Raised major version to match API version + * visjhg ESCAN00072156 No changes + * visjhg ESCAN00072570 No changes + * visjhg ESCAN00072631 No changes + * 02.01.00 2014-03-12 visjhg ESCAN00073504 Changed signature of input verification function type + * visjhg ESCAN00074066 No changes + * 02.02.00 2014-05-09 visjhg ESCAN00075225 No changes + * visjhg - Removed some integration time checks + * 03.00.00 2015-03-03 visjhg - Changed compatibility remapping for extended status (SegmentStartVerifyInit) + * visjhg ESCAN00076591 Updated interface version (support for external stream output) + * visjhg ESCAN00077689 No changes + * visjhg ESCAN00077891 No changes + * visjhg ESCAN00081491 Added support for resumable programming + * visjhg ESCAN00081494 Added support for verification on processed input data + * visjhg ESCAN00081493 Added selective pipelined programming (forced flush when disabled) + * 03.01.00 2015-04-23 visjhg ESCAN00082572 No changes + * visjhg ESCAN00082605 Added support for reporting of progress information + * visjhg ESCAN00082606 Added support for gap fill (requires ordered segments) + * 03.01.01 2015-04-27 visjhg ESCAN00082700 No changes + * 03.01.02 2015-05-27 visjhg ESCAN00083138 No changes + * 03.01.03 2015-06-13 visjhg ESCAN00083358 No changes + * visjhg ESCAN00083390 No changes + * visjhg ESCAN00083391 No changes + * visjhg ESCAN00083392 Updated interface version + * 03.02.00 2015-07-21 visjhg ESCAN00084101 No changes + * visjhg ESCAN00084102 Added parameter type structure for stream processing + * 03.02.01 2015-08-19 visjhg ESCAN00084279 No changes + * visjhg ESCAN00084559 No changes + * visjhg ESCAN00084560 No changes + * 03.02.02 2015-09-04 visjhg ESCAN00084994 No changes + * 04.00.00 2015-09-17 visjhg ESCAN00085249 Support combination of input and processed verification + * Updated interface version + * visjhg ESCAN00085250 No changes + * visjhg ESCAN00085251 No changes + * 04.01.00 2016-04-01 visjhg ESCAN00087997 Updated interface version + * visjhg ESCAN00088935 No changes + * 04.02.00 2016-10-06 visjhg ESCAN00090120 No changes + * vishrf ESCAN00091253 No changes + * 04.02.01 2017-05-31 visjhg ESCAN00094695 No changes + * visjhg ESCAN00095201 No changes + * visjhg ESCAN00095356 No changes + * visjhg - Updated interface version + * 04.03.00 2017-07-26 visjhg ESCAN00095772 No changes + * visjhg ESCAN00095774 Added FblMemFlushInputData + * Updated interface version + * visjhg ESCAN00095683 Place FblMemResumeIndication in RAMCODE section + * visjhg ESCAN00096075 No changes + * 04.03.01 2017-08-07 visjhg ESCAN00096209 No changes + * 04.04.00 2018-08-22 visjhg ESCAN00100464 No changes + * visjhg ESCAN00097115 No changes + * visjhg ESCAN00100482 Updated interface version (addition of __ApplFblMemConditionCheck) + * 04.04.01 2018-09-25 visjhg ESCAN00100850 Updated interface version (preamble for MCMP download use-case) + * 04.05.00 2018-11-30 visjhg ESCAN00101500 Added custom error codes to tFblMemStatus + * Updated interface version + * 04.05.01 2019-01-23 visjhg ESCAN00101568 No changes + * 04.05.02 2019-08-20 vistbe ESCAN00103967 Updated interface version + * 04.05.03 2019-10-02 visrie ESCAN00104203 Fixed resumable pipelined verification + * 04.06.00 2019-10-29 vistmo FBL-813 Migration to MISRA 2012 + * 04.06.01 2020-03-18 visrie ESCAN00105683 No changes + * 04.06.02 2020-05-11 visjdn ESCAN00105967 No changes + * 04.06.03 2020-07-03 vistmo ESCAN00106050 No changes + * 04.07.00 2021-04-12 lhopfhauer FBL-2187 Added/adapted MemMap sections + * 04.08.00 2021-06-11 visjdn FBL-3560 Add support for more than 256 download segments + * 04.09.00 2021-07-09 lhopfhauer FBL-3442 Add option to avoid abortion of verification procedure in case of error + * Updated MISRA justifications + * 04.09.01 2021-11-05 lhopfhauer ESCAN00110663 No changes + * 04.10.00 2022-05-02 lhopfhauer FBL-5067 No changes + * 04.10.01 2022-08-03 fmenke ESCAN00112185 No changes + * 04.10.02 2023-05-08 lhopfhauer ESCAN00114573 No changes + * 04.11.00 2023-08-04 visrie FBL-5709 No changes + * 04.12.00 2023-09-04 vistmo FBL-7572 Allow processed verification in combination with stream output + * 04.12.01 2024-02-02 lhopfhauer ESCAN00116407 Out of bounds write access + * ESCAN00116408 Resume may not work + * ESCAN00116457 No changes + * 04.13.00 2025-09-16 pharring FBL-10120 Add support for FblLib_Logger + * 04.13.01 2025-11-07 aeller ESCAN00121551 No changes + * ESCAN00121700 No changes + * 04.14.00 2025-11-25 fmenke FBL-11808 No changes + **********************************************************************************************************************/ + +#ifndef FBL_MEM_H +#define FBL_MEM_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblLib_Mem CQComponent : Implementation */ +#define FBLLIB_MEM_VERSION 0x0414u +#define FBLLIB_MEM_RELEASE_VERSION 0x00u + +/* Interface version */ +/** Major interface version identifies incompatible changes */ +#define FBL_MEM_API_VERSION_MAJOR 0x04u +/** Minor interface version identifies backward compatible changes */ +#define FBL_MEM_API_VERSION_MINOR 0x07u +/** Release interface version identifies cosmetic changes */ +#define FBL_MEM_API_VERSION_RELEASE 0x00u + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_mem_oem.h" + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* FblLib_Logger defines */ + +/** + Check for pending operations + Enter task on states "pending", "suspend pending" and "suspended" + Condition equals + ( (fblMemProgState == kFblMemProgState_Pending) || (fblMemProgState == kFblMemProgState_Checkpoint) + || (fblMemProgState == kFblMemProgState_SuspendPending) || (fblMemProgState == kFblMemProgState_Suspended) ) +*/ +#define FblMemTaskIsPending() (fblMemProgState >= kFblMemProgState_Suspended) +/** + Check for active operations + Condition equals + ( (fblMemProgState == kFblMemProgState_Pending) || (fblMemProgState == kFblMemProgState_Checkpoint) + || (fblMemProgState == kFblMemProgState_SuspendPending) ) +*/ +#define FblMemTaskIsActive() (fblMemProgState >= kFblMemProgState_SuspendPending) + +/** Default source handle */ +#define FBL_MEM_SOURCE_HANDLE_DEFAULT 0u + +#if defined( FBL_MEM_SOURCE_COUNT ) +# if (FBL_MEM_SOURCE_COUNT > 1u) +# if defined( FBL_MEM_ENABLE_MULTI_SOURCE ) +# else +/** Multiple input sources */ +# define FBL_MEM_ENABLE_MULTI_SOURCE +# endif /* FBL_MEM_ENABLE_MULTI_SOURCE */ +# endif /* FBL_MEM_SOURCE_COUNT > 1u */ +#endif /* FBL_MEM_SOURCE_COUNT */ + +/* No additional remapping required, simply cast to expected type */ +# define FblMemRemapStatus(status) ((FBL_MEM_STATUS_TYPE)(status)) + +#if defined( FBL_MEM_PROC_SEGMENTATION ) +#else +/** Set data processing segmentation to default value */ +# define FBL_MEM_PROC_SEGMENTATION FBL_MEM_PROC_BUFFER_SIZE +#endif /* FBL_MEM_PROC_SEGMENTATION */ + +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +/** If the read-verify operation takes a long time and delays the download of a logical block, this define can be + * overwritten to shift the delay by read-verify towards the end of the logical block download. The total time for + * the logical block download will NOT change, however. The value of this define should be at most the maximum number + * of download segments - 1 */ +# if defined( FBL_MEM_VERIFY_PIPELINED_JOB_COUNT ) +# else /* FBL_MEM_VERIFY_PIPELINED_JOB_COUNT */ +# define FBL_MEM_VERIFY_PIPELINED_JOB_COUNT 1u +# endif /* FBL_MEM_VERIFY_PIPELINED_JOB_COUNT */ +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +/*-- Compatibility remapping of configuration switches-----------------------*/ + + +#if defined( FBL_ENABLE_GAP_FILL ) +# if defined( FBL_MEM_ENABLE_GAP_FILL) || \ + defined( FBL_MEM_DISABLE_GAP_FILL ) +/* Gap fill handling explicitly defined outside */ +# else +# define FBL_MEM_ENABLE_GAP_FILL +# endif /* FBL_MEM_ENABLE_GAP_FILL */ +#endif /* FBL_ENABLE_GAP_FILL */ + + +/*-- Remap configuration switches--------------------------------------------*/ +#if ( defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) && \ + defined( FBL_MEM_ENABLE_VERIFY_PIPELINED_ADDRESS_LENGTH ) ) +/** On-the-fly verification includes address and length information */ +# define FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH +/** Size of address and length information */ +# define FBL_MEM_VERIFY_ADDRESS_LENGTH_SIZE 4u +/** Size of address and length information */ +# define FBL_MEM_VERIFY_ADDRESS_LENGTH_BUFFER_SIZE (2u * FBL_MEM_VERIFY_ADDRESS_LENGTH_SIZE) +#endif /* (FBL_MEM_ENABLE_VERIFY_INPUT && FBL_MEM_ENABLE_VERIFY_INPUT_ADDRESS_LENGTH) || (FBL_MEM_ENABLE_VERIFY_PIPELINED && FBL_MEM_ENABLE_VERIFY_PIPELINED_ADDRESS_LENGTH) */ + +#if defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +# if defined( FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH ) +/** Reserve an additional entry for address information */ +# define FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE_READ (FBL_MEM_VERIFY_PIPELINED_JOB_COUNT + 1u) +# else /* FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH */ +/** Reserve one entry in dedicated queue per job */ +# define FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE_READ (FBL_MEM_VERIFY_PIPELINED_JOB_COUNT) +# endif /* FBL_MEM_ENABLE_VERIFY_ADDRESS_LENGTH */ +/** Reserve configured number of entries for read, update and finalization jobs */ +# define FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE (FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE_READ + 2u) +#else /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ +# define FBL_MEM_QUEUE_ENTRIES_VERIFY_PIPE 0u +#endif /* FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) || \ + defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) +/** Pipelined operation */ +# define FBL_MEM_ENABLE_PIPELINING +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING || FBL_MEM_ENABLE_VERIFY_PIPELINED */ + +#if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) || \ + defined( FBL_MEM_ENABLE_GAP_FILL ) +# if defined( FBL_MEM_ENABLE_SEGMENT_HANDLING ) || \ + defined( FBL_MEM_DISABLE_SEGMENT_HANDLING ) +/* Segment handling explicitly defined outside + If segments are required by signature/checksum verification on output data + but segment handlings is disabled the correct segments have to be handled outside! */ +# else +/** Segment handling required for signature/checksum verification on output data */ +# define FBL_MEM_ENABLE_SEGMENT_HANDLING +# endif /* FBL_MEM_ENABLE_SEGMENT_HANDLING */ +#endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT || FBL_MEM_ENABLE_GAP_FILL */ + +#if defined( FBL_MEM_ENABLE_VERIFY_OUTPUT ) || \ + defined( FBL_MEM_ENABLE_VERIFY_PIPELINED ) || \ + defined( FBL_MEM_ENABLE_SEGMENT_HANDLING ) || \ + defined( FBL_ENABLE_PROCESSED_DATA_LENGTH ) || \ + defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) || \ + defined( FBL_MEM_ENABLE_GAP_FILL ) || \ + defined( FBL_MEM_ENABLE_PROGRESS_INFO ) +/** Persistent storage of block information */ +# define FBL_MEM_ENABLE_GLOBAL_BLOCK_INFO +#endif /* FBL_MEM_ENABLE_VERIFY_OUTPUT || FBL_MEM_ENABLE_VERIFY_INPUT || FBL_MEM_ENABLE_VERIFY_PIPELINED || FBL_MEM_ENABLE_SEGMENT_HANDLING || FBL_MEM_ENABLE_PASSTHROUGH || FBL_ENABLE_PROCESSED_DATA_LENGTH || FBL_MEM_ENABLE_STREAM_OUTPUT || FBL_MEM_ENABLE_GAP_FILL || FBL_MEM_ENABLE_PROGRESS_INFO */ + +/* + Allow overwrite of certain data types or defines by using + FBL_MEM_VERIFY__OVERWRITE defines / macros +*/ +/*-- On-the-fly verification ------------------------------------------------*/ +#if defined( FBL_MEM_VERIFY_OK_OVERWRITE ) +#define FBL_MEM_VERIFY_OK (FBL_MEM_VERIFY_OK_OVERWRITE) +#else +#define FBL_MEM_VERIFY_OK (tFblMemVerifyStatus)(SECM_OK) +#endif +#if defined( FBL_MEM_VERIFY_STATE_INIT_OVERWRITE ) +#define FBL_MEM_VERIFY_STATE_INIT (FBL_MEM_VERIFY_STATE_INIT_OVERWRITE) +#else +#define FBL_MEM_VERIFY_STATE_INIT kHashInit +#endif +#if defined( FBL_MEM_VERIFY_STATE_COMPUTE_OVERWRITE ) +#define FBL_MEM_VERIFY_STATE_COMPUTE (FBL_MEM_VERIFY_STATE_COMPUTE_OVERWRITE) +#else +#define FBL_MEM_VERIFY_STATE_COMPUTE kHashCompute +#endif +#if defined( FBL_MEM_VERIFY_STATE_FINALIZE_OVERWRITE ) +#define FBL_MEM_VERIFY_STATE_FINALIZE (FBL_MEM_VERIFY_STATE_FINALIZE_OVERWRITE) +#else +#define FBL_MEM_VERIFY_STATE_FINALIZE kHashFinalize +#endif +#if defined( FBL_MEM_VERIFY_STATE_VERIFY_OVERWRITE ) +#define FBL_MEM_VERIFY_STATE_VERIFY (FBL_MEM_VERIFY_STATE_VERIFY_OVERWRITE) +#else +#define FBL_MEM_VERIFY_STATE_VERIFY kSigVerify +#endif + +/*-- Error handling ---------------------------------------------------------*/ + +/* Helper macros for status definitions */ +#define FBL_MEM_STATUS_NAME(name) kFblMemStatus_ ## name /* PRQA S 0342 */ /* MD_MSR_Rule20.10_0342 */ +#define FBL_MEM_STATUS_DEFINE(name) FBL_MEM_STATUS_ ## name /* PRQA S 0342 */ /* MD_MSR_Rule20.10_0342 */ + +#if defined( FBL_MEM_ENABLE_STATUS_OVERWRITE ) +/** Overwrite error codes by OEM dependent value */ +# define FBL_MEM_STATUS_DEFINITION(name) FBL_MEM_STATUS_NAME(name) = FBL_MEM_STATUS_DEFINE(name) +#else +/** Use automatically numbered error codes */ +# define FBL_MEM_STATUS_DEFINITION(name) FBL_MEM_STATUS_NAME(name) +#endif /* FBL_MEM_ENABLE_STATUS_OVERWRITE */ + +#if defined( FBL_MEM_ENABLE_STATUS_OVERWRITE ) + + + +# if defined( FBL_MEM_STATUS_ProgramOverflow ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_ProgramOverflow FBL_MEM_STATUS_Failed +# endif + + +# if defined( FBL_MEM_STATUS_VerifyCompute ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_VerifyCompute +# endif + +# if defined( FBL_MEM_STATUS_VerifyFinalize ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_VerifyFinalize +# endif + +# if defined( FBL_MEM_STATUS_SegmentStartVerifyInit ) +# else +# if defined( FBL_MEM_STATUS_BlockStartVerifyInit ) +/* Compatibility remapping (API < 2.2.0) */ +# define FBL_MEM_STATUS_SegmentStartVerifyInit FBL_MEM_STATUS_BlockStartVerifyInit +# else +# error Status overwrite value missing: FBL_MEM_STATUS_SegmentStartVerifyInit +# endif +# endif +# if defined( FBL_MEM_EXT_STATUS_BlockStartVerifyInit ) +/* Compatibility remapping (API < 2.2.0) */ +# define FBL_MEM_EXT_STATUS_SegmentStartVerifyInit(status) FBL_MEM_EXT_STATUS_BlockStartVerifyInit(status) +# endif + +# if defined( FBL_MEM_STATUS_BlockEndVerifyFinalize ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_BlockEndVerifyFinalize +# endif + +# if defined( FBL_MEM_STATUS_BlockVerifyInputVerify ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_BlockVerifyInputVerify FBL_MEM_STATUS_Failed +# endif + +# if defined( FBL_MEM_STATUS_BlockVerifyPipeVerify ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_BlockVerifyPipeVerify +# endif + +# if defined( FBL_MEM_STATUS_BlockVerifyOutputVerify ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_BlockVerifyOutputVerify +# endif + +# if defined( FBL_MEM_STATUS_BlockStartParam ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_BlockStartParam +# endif + +# if defined( FBL_MEM_STATUS_SegmentStartVerifyCompute ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_SegmentStartVerifyCompute +# endif + +# if defined( FBL_MEM_STATUS_DataProc ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_DataProc +# endif + +# if defined( FBL_MEM_STATUS_DataProcConsume ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_DataProcConsume +# endif + +# if defined( FBL_MEM_STATUS_DataProcDeinit ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_DataProcDeinit +# endif + +# if defined( FBL_MEM_STATUS_SegmentStartStreamOutInit ) +# else +/* Status code not defined: remap to data processing code */ +# define FBL_MEM_STATUS_SegmentStartStreamOutInit FBL_MEM_STATUS_SegmentStartDataProcInit +# endif + +# if defined( FBL_MEM_STATUS_StreamOutput ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_StreamOutput FBL_MEM_STATUS_Failed +# endif + +# if defined( FBL_MEM_STATUS_StreamOutputConsume ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_StreamOutputConsume FBL_MEM_STATUS_Failed +# endif + +# if defined( FBL_MEM_STATUS_StreamOutputOverflow ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_StreamOutputOverflow FBL_MEM_STATUS_Failed +# endif + +# if defined( FBL_MEM_STATUS_StreamOutputDeinit ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_StreamOutputDeinit FBL_MEM_STATUS_Failed +# endif + +# if defined( FBL_MEM_STATUS_DriverResumeWrite ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_DriverResumeWrite FBL_MEM_STATUS_Failed +# endif + +# if defined( FBL_MEM_STATUS_DriverRemainder ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_DriverRemainder FBL_MEM_STATUS_Failed +# endif + +# if defined( FBL_MEM_STATUS_BlockEraseSequence ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_BlockEraseSequence +# endif + +# if defined( FBL_MEM_STATUS_EraseOutsideFbt ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_EraseOutsideFbt +# endif + +# if defined( FBL_MEM_STATUS_EraseDriverNotReady ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_EraseDriverNotReady +# endif + +# if defined( __ApplFblMemPreErase ) +# if defined( FBL_MEM_STATUS_ErasePreErase ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_ErasePreErase +# endif +# else +# if defined( FBL_MEM_STATUS_ErasePreErase ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_ErasePreErase FBL_MEM_STATUS_Failed +# endif +# endif /* FBL_MEM_ENABLE_ERASE && __ApplFblMemPreErase */ + +# if defined( __ApplFblMemPostErase ) +# if defined( FBL_MEM_STATUS_ErasePostErase ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_ErasePostErase +# endif +# else +# if defined( FBL_MEM_STATUS_ErasePostErase ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_ErasePostErase FBL_MEM_STATUS_Failed +# endif +# endif /* FBL_MEM_ENABLE_ERASE && __ApplFblMemPostErase */ + +# if defined( __ApplFblMemDriverReady ) +# if defined( FBL_MEM_STATUS_EraseDriverNotReady ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_EraseDriverNotReady +# endif +# else +# if defined( FBL_MEM_STATUS_EraseDriverNotReady ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_EraseDriverNotReady FBL_MEM_STATUS_Failed +# endif +# endif /* FBL_MEM_ENABLE_ERASE && __ApplFblMemDriverReady */ + +# if defined( FBL_MEM_STATUS_SegmentStartSegmentCount ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_SegmentStartSegmentCount +# endif + +# if defined( __ApplFblMemPostSegmentEnd ) +# if defined( FBL_MEM_STATUS_SegmentEndPost ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_SegmentEndPost +# endif +# else +# if defined( FBL_MEM_STATUS_SegmentEndPost ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_SegmentEndPost FBL_MEM_STATUS_Failed +# endif +# endif /* __ApplFblMemPostSegmentEnd */ + +# if defined( __ApplFblMemDriverReady ) +# if defined( FBL_MEM_STATUS_ProgramDriverNotReady ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_ProgramDriverNotReady +# endif +# else +# if defined( FBL_MEM_STATUS_ProgramDriverNotReady ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_ProgramDriverNotReady FBL_MEM_STATUS_Failed +# endif +# endif /* __ApplFblMemDriverReady */ + +# if defined( __ApplFblMemPreWrite ) +# if defined( FBL_MEM_STATUS_ProgramPreWrite ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_ProgramPreWrite +# endif +# else +# if defined( FBL_MEM_STATUS_ProgramPreWrite ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_ProgramPreWrite FBL_MEM_STATUS_Failed +# endif +# endif /* __ApplFblMemPreWrite */ + +# if defined( __ApplFblMemPostWrite ) +# if defined( FBL_MEM_STATUS_ProgramPostWrite ) +# else +# error Status overwrite value missing: FBL_MEM_STATUS_ProgramPostWrite +# endif +# else +# if defined( FBL_MEM_STATUS_ProgramPostWrite ) +# else +/* Status code not required: remap to default */ +# define FBL_MEM_STATUS_ProgramPostWrite FBL_MEM_STATUS_Failed +# endif +# endif /* __ApplFblMemPostWrite */ + +#endif /* FBL_MEM_ENABLE_STATUS_OVERWRITE || FBL_MEM_ENABLE_STATUS_REMAPPING */ + + +/* Options for extended verification API */ +#define FBL_MEM_VERIFY_INPUT_OPT 0u +#define FBL_MEM_VERIFY_PROC_OPT 1u +#define FBL_MEM_VERIFY_PIPE_OPT 2u +#define FBL_MEM_VERIFY_OUTPUT_OPT 3u + +#define FBL_MEM_CHK_OPTION(a, b) (( a & (1u << b) ) != 0u) + +#define FBL_MEM_OPT_INPUT_MASK (1u << FBL_MEM_VERIFY_INPUT_OPT) +#define FBL_MEM_OPT_PROC_MASK (1u << FBL_MEM_VERIFY_PROC_OPT) +#define FBL_MEM_OPT_Pipe_MASK (1u << FBL_MEM_VERIFY_PIPE_OPT) +#define FBL_MEM_OPT_OUTPUT_MASK (1u << FBL_MEM_VERIFY_OUTPUT_OPT) + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ +/*-- On-the-fly verification ------------------------------------------------*/ +#if defined( FBL_MEM_VERIFY_STATUS_TYPE_OVERWRITE ) +typedef FBL_MEM_VERIFY_STATUS_TYPE_OVERWRITE tFblMemVerifyStatus; +#else +typedef SecM_StatusType tFblMemVerifyStatus; +#endif /* FBL_MEM_VERIFY_STATUS_TYPE_OVERWRITE */ +#if defined( FBL_MEM_VERIFY_PARAM_TYPE_INPUT_OVERWRITE ) +typedef FBL_MEM_VERIFY_PARAM_TYPE_INPUT_OVERWRITE tFblMemVerifyParamInput; +#else +typedef SecM_SignatureParamType tFblMemVerifyParamInput; +#endif /* FBL_MEM_VERIFY_PARAM_TYPE_INPUT_OVERWRITE */ +#if defined( FBL_MEM_VERIFY_PARAM_TYPE_OUTPUT_OVERWRITE ) +typedef FBL_MEM_VERIFY_PARAM_TYPE_OUTPUT_OVERWRITE tFblMemVerifyParamOutput; +#else +typedef SecM_VerifyParamType tFblMemVerifyParamOutput; +#endif /* FBL_MEM_VERIFY_PARAM_TYPE_OUTPUT_OVERWRITE */ +#if defined( FBL_MEM_VERIFY_LENGTH_TYPE_OVERWRITE ) +typedef FBL_MEM_VERIFY_LENGTH_TYPE_OVERWRITE tFblMemVerifyLength; +#else +typedef SecM_LengthType tFblMemVerifyLength; +#endif /* FBL_MEM_VERIFY_LENGTH_TYPE_OVERWRITE */ +#if defined( FBL_MEM_VERIFY_SIZE_TYPE_OVERWRITE ) +typedef FBL_MEM_VERIFY_SIZE_TYPE_OVERWRITE tFblMemVerifySize; +#else +typedef SecM_SizeType tFblMemVerifySize; +#endif /* FBL_MEM_VERIFY_SIZE_TYPE_OVERWRITE */ +#if defined( FBL_MEM_VERIFY_ADDRESS_TYPE_OVERWRITE ) +typedef FBL_MEM_VERIFY_ADDRESS_TYPE_OVERWRITE tFblMemVerifyAddr; +#else +typedef SecM_AddrType tFblMemVerifyAddr; +#endif /* FBL_MEM_VERIFY_ADDRESS_TYPE_OVERWRITE */ +#if defined( FBL_MEM_VERIFY_DATA_PTR_TYPE_OVERWRITE ) +typedef FBL_MEM_VERIFY_DATA_PTR_TYPE_OVERWRITE tFblMemVerifyDataPtr; +#else +typedef V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tFblMemVerifyDataPtr; +#endif /* FBL_MEM_VERIFY_DATA_PTR_TYPE_OVERWRITE */ +#if defined( FBL_MEM_VERIFY_WD_FCT_TYPE_OVERWRITE ) +typedef FBL_MEM_VERIFY_WD_FCT_TYPE_OVERWRITE tFblMemVerifyWdFct; +#else +typedef FL_WDTriggerFctType tFblMemVerifyWdFct; +#endif /* FBL_MEM_VERIFY_WD_FCT_TYPE_OVERWRITE */ +#if defined( FBL_MEM_VERIFY_READ_FCT_TYPE_OVERWRITE ) +typedef FBL_MEM_VERIFY_READ_FCT_TYPE_OVERWRITE tFblMemVerifyReadFct; +#else +typedef FL_ReadMemoryFctType tFblMemVerifyReadFct; +#endif /* FBL_MEM_VERIFY_READ_FCT_TYPE_OVERWRITE */ +#if defined( FBL_MEM_VERIFY_FCT_INPUT_TYPE_OVERWRITE ) +typedef FBL_MEM_VERIFY_FCT_INPUT_TYPE_OVERWRITE(tFblMemVerifyFctInput); +#else +typedef FBL_CALL_TYPE tFblMemVerifyStatus (*tFblMemVerifyFctInput) (V_MEMRAM1 tFblMemVerifyParamInput V_MEMRAM2 V_MEMRAM3 *fp); +#endif /* FBL_MEM_VERIFY_FCT_INPUT_TYPE_OVERWRITE */ +#if defined( FBL_MEM_VERIFY_FCT_OUTPUT_TYPE_OVERWRITE ) +typedef FBL_MEM_VERIFY_FCT_OUTPUT_TYPE_OVERWRITE(tFblMemVerifyFctOutput); +#else +typedef FBL_CALL_TYPE tFblMemVerifyStatus (*tFblMemVerifyFctOutput) (V_MEMRAM1 tFblMemVerifyParamOutput V_MEMRAM2 V_MEMRAM3 *fp); +#endif /* FBL_MEM_VERIFY_FCT_OUTPUT_TYPE_OVERWRITE */ + +#if defined( FBL_MEM_SEGMENT_LIST_TYPE_OVERWRITE ) +typedef FBL_MEM_SEGMENT_LIST_TYPE_OVERWRITE tFblMemSegmentList; +#else +typedef FL_SegmentListType tFblMemSegmentList; +#endif /* FBL_MEM_SEGMENT_LIST_TYPE_OVERWRITE */ +#if defined( FBL_MEM_SEGMENT_LIST_ENTRY_TYPE_OVERWRITE ) +typedef FBL_MEM_SEGMENT_LIST_ENTRY_TYPE_OVERWRITE tFblMemSegmentListEntry; +#else +typedef FL_SegmentInfoType tFblMemSegmentListEntry; +#endif /* FBL_MEM_SEGMENT_LIST_ENTRY_TYPE_OVERWRITE */ + +/* Options type for extended verification API */ +typedef vuint8 tFblMemVerifyOption; + +/** Error codes reported by FblMem routines */ +typedef enum +{ + /* Define status codes: kFblMemStatus_ */ + /* Default */ + FBL_MEM_STATUS_DEFINITION(Ok) /* 0x00 */ + ,FBL_MEM_STATUS_DEFINITION(Failed) /* 0x01 */ + /* BlockErase indication */ + ,FBL_MEM_STATUS_DEFINITION(BlockEraseSequence) /* 0x02 */ + /* BlockStart indication */ + ,FBL_MEM_STATUS_DEFINITION(BlockStartSequence) /* 0x03 */ + ,FBL_MEM_STATUS_DEFINITION(BlockStartParam) /* 0x04 */ + /* BlockEnd indication */ + ,FBL_MEM_STATUS_DEFINITION(BlockEndSequence) /* 0x05 */ + ,FBL_MEM_STATUS_DEFINITION(BlockEndVerifyFinalize) /* 0x06 */ + /* BlockVerify */ + ,FBL_MEM_STATUS_DEFINITION(BlockVerifySequence) /* 0x07 */ + ,FBL_MEM_STATUS_DEFINITION(BlockVerifyInputVerify) /* 0x08 */ + ,FBL_MEM_STATUS_DEFINITION(BlockVerifyProcessedVerify) /* 0x09 */ + ,FBL_MEM_STATUS_DEFINITION(BlockVerifyPipeVerify) /* 0x0A */ + ,FBL_MEM_STATUS_DEFINITION(BlockVerifyOutputVerify) /* 0x0B */ + /* SegmentStart indication */ + ,FBL_MEM_STATUS_DEFINITION(SegmentStartSequence) /* 0x0C */ + ,FBL_MEM_STATUS_DEFINITION(SegmentStartDataProcInit) /* 0x0D */ + ,FBL_MEM_STATUS_DEFINITION(SegmentStartStreamOutInit) /* 0x0E */ + ,FBL_MEM_STATUS_DEFINITION(SegmentStartVerifyInit) /* 0x0F */ + ,FBL_MEM_STATUS_DEFINITION(SegmentStartVerifyCompute) /* 0x10 */ + ,FBL_MEM_STATUS_DEFINITION(SegmentStartSegmentCount) /* 0x11 */ + /* SegmentEnd indication */ + ,FBL_MEM_STATUS_DEFINITION(SegmentEndSequence) /* 0x12 */ + ,FBL_MEM_STATUS_DEFINITION(SegmentEndInsufficientData) /* 0x13 */ + ,FBL_MEM_STATUS_DEFINITION(SegmentEndPost) /* 0x14 */ + /* Data indication */ + ,FBL_MEM_STATUS_DEFINITION(DataIndSequence) /* 0x15 */ + ,FBL_MEM_STATUS_DEFINITION(DataIndParam) /* 0x16 */ + ,FBL_MEM_STATUS_DEFINITION(DataIndOverflow) /* 0x17 */ + /* Data processing */ + ,FBL_MEM_STATUS_DEFINITION(DataProc) /* 0x18 */ + ,FBL_MEM_STATUS_DEFINITION(DataProcConsume) /* 0x19 */ + ,FBL_MEM_STATUS_DEFINITION(DataProcDeinit) /* 0x1A */ + /* Stream output */ + ,FBL_MEM_STATUS_DEFINITION(StreamOutput) /* 0x1B */ + ,FBL_MEM_STATUS_DEFINITION(StreamOutputConsume) /* 0x1C */ + ,FBL_MEM_STATUS_DEFINITION(StreamOutputOverflow) /* 0x1D */ + ,FBL_MEM_STATUS_DEFINITION(StreamOutputDeinit) /* 0x1E */ + /* Memory driver */ + ,FBL_MEM_STATUS_DEFINITION(DriverResumeWrite) /* 0x1F */ + ,FBL_MEM_STATUS_DEFINITION(DriverWrite) /* 0x20 */ + ,FBL_MEM_STATUS_DEFINITION(DriverErase) /* 0x21 */ + ,FBL_MEM_STATUS_DEFINITION(DriverRemainder) /* 0x22 */ + ,FBL_MEM_STATUS_DEFINITION(DriverSuspendWrite) /* 0x23 */ + /* Programming operation */ + ,FBL_MEM_STATUS_DEFINITION(ProgramOverflow) /* 0x24 */ + ,FBL_MEM_STATUS_DEFINITION(ProgramOutsideFbt) /* 0x25 */ + ,FBL_MEM_STATUS_DEFINITION(ProgramUnalignedAddress) /* 0x26 */ + ,FBL_MEM_STATUS_DEFINITION(ProgramDriverNotReady) /* 0x27 */ + ,FBL_MEM_STATUS_DEFINITION(ProgramPreWrite) /* 0x28 */ + ,FBL_MEM_STATUS_DEFINITION(ProgramPostWrite) /* 0x29 */ + /* Erase operation */ + ,FBL_MEM_STATUS_DEFINITION(EraseOutsideFbt) /* 0x2A */ + ,FBL_MEM_STATUS_DEFINITION(EraseDriverNotReady) /* 0x2B */ + ,FBL_MEM_STATUS_DEFINITION(ErasePreErase) /* 0x2C */ + ,FBL_MEM_STATUS_DEFINITION(ErasePostErase) /* 0x2D */ + /* On-the-fly verification */ + ,FBL_MEM_STATUS_DEFINITION(VerifyCompute) /* 0x2E */ + ,FBL_MEM_STATUS_DEFINITION(VerifyFinalize) /* 0x2F */ + /* Pass-through */ + ,FBL_MEM_STATUS_DEFINITION(PassThroughLocal) /* 0x30 */ + ,FBL_MEM_STATUS_DEFINITION(PassThroughRemote) /* 0x31 */ +#if defined( FBL_MEM_STATUS_ConditionCheck0 ) + ,FBL_MEM_STATUS_DEFINITION(ConditionCheck0) /* 0x32 */ +#endif /* FBL_MEM_STATUS_ConditionCheck0 */ +#if defined( FBL_MEM_STATUS_ConditionCheck1 ) + ,FBL_MEM_STATUS_DEFINITION(ConditionCheck1) /* 0x33 */ +#endif /* FBL_MEM_STATUS_ConditionCheck1 */ +#if defined( FBL_MEM_STATUS_ConditionCheck2 ) + ,FBL_MEM_STATUS_DEFINITION(ConditionCheck2) /* 0x34 */ +#endif /* FBL_MEM_STATUS_ConditionCheck2 */ +#if defined( FBL_MEM_STATUS_ConditionCheck3 ) + ,FBL_MEM_STATUS_DEFINITION(ConditionCheck3) /* 0x35 */ +#endif /* FBL_MEM_STATUS_ConditionCheck3 */ +#if defined( FBL_MEM_STATUS_ConditionCheck4 ) + ,FBL_MEM_STATUS_DEFINITION(ConditionCheck4) /* 0x36 */ +#endif /* FBL_MEM_STATUS_ConditionCheck4 */ +#if defined( FBL_MEM_STATUS_ConditionCheck5 ) + ,FBL_MEM_STATUS_DEFINITION(ConditionCheck5) /* 0x37 */ +#endif /* FBL_MEM_STATUS_ConditionCheck5 */ +#if defined( FBL_MEM_STATUS_ConditionCheck6 ) + ,FBL_MEM_STATUS_DEFINITION(ConditionCheck6) /* 0x38 */ +#endif /* FBL_MEM_STATUS_ConditionCheck6 */ +#if defined( FBL_MEM_STATUS_ConditionCheck7 ) + ,FBL_MEM_STATUS_DEFINITION(ConditionCheck7) /* 0x39 */ +#endif /* FBL_MEM_STATUS_ConditionCheck7 */ +#if defined( FBL_MEM_STATUS_ConditionCheck8 ) + ,FBL_MEM_STATUS_DEFINITION(ConditionCheck8) /* 0x3A */ +#endif /* FBL_MEM_STATUS_ConditionCheck8 */ +#if defined( FBL_MEM_STATUS_ConditionCheck9 ) + ,FBL_MEM_STATUS_DEFINITION(ConditionCheck9) /* 0x3B */ +#endif /* FBL_MEM_STATUS_ConditionCheck9 */ +} tFblMemStatus; + +/** Memory type */ +typedef enum +{ + kFblMemType_RAM = 0u, /* Volatile memory */ + kFblMemType_ROM /* Non-volatile memory */ +} tFblMemType; + +/** State of programming operation */ +typedef enum +{ + kFblMemProgState_Idle = 0u, + kFblMemProgState_Error, + kFblMemProgState_Suspended, + kFblMemProgState_SuspendPending, + kFblMemProgState_Checkpoint, + kFblMemProgState_Pending +} tFblMemProgState; + +/** Pointer type to byte data in RAM */ +typedef V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tFblMemRamData; +/** Pointer type to constant byte data in RAM */ +typedef const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tFblMemConstRamData; + +/** Data format identifier */ +typedef vuint8 tFblMemDfi; + +/** Input verification routine */ +typedef struct +{ + tFblMemVerifyFctInput function; + V_MEMRAM1 tFblMemVerifyParamInput V_MEMRAM2 V_MEMRAM3 * param; +} tFblMemVerifyRoutineInput; + +/** Output verification routine */ +typedef struct +{ + tFblMemVerifyFctOutput function; + V_MEMRAM1 tFblMemVerifyParamOutput V_MEMRAM2 V_MEMRAM3 * param; +} tFblMemVerifyRoutineOutput; + +/** Information passed in block erase / start indication */ +typedef struct +{ + tFblAddress targetAddress; /**< Target address (erase operation) */ + tFblLength targetLength; /**< Target length (erase operation) */ + /* Used for signature verification */ + tFblAddress logicalAddress; /**< Logical address (verification operation) */ + tFblLength logicalLength; /**< Logical length (verification operation) */ + tFblMemVerifyRoutineInput verifyRoutineInput; /**< On-the-fly verification on input data */ + tFblMemVerifyRoutineInput verifyRoutineProcessed; /**< On-the-fly verification on processed data */ + tFblMemVerifyRoutineInput verifyRoutinePipe; /**< Pipelined verification on output data */ + tFblMemVerifyRoutineOutput verifyRoutineOutput; /**< Verification on output data */ + tFblMemVerifyReadFct readFct; /**< Memory read function, used by pipelined and output verification */ + V_MEMRAM1 tFblMemSegmentList V_MEMRAM2 V_MEMRAM3 * segmentList; /**< List of programmed segments, used by output verification */ + vuint32 maxSegments; /**< Maximum number of entries in segment list */ +} tFblMemBlockInfo; + +/** Verification data */ +typedef struct +{ + tFblMemRamData data; /**< Pointer to verification data (signature/checksum) */ + tFblLength length; /**< Length of verification data */ +} tFblMemVerifyData; + +/** Information passed in block verify */ +typedef struct +{ + tFblMemVerifyData verifyDataInput; /**< On-the-fly verification on input data */ + tFblMemVerifyData verifyDataProcessed; /**< On-the-fly verification on processed data */ + tFblMemVerifyData verifyDataPipe; /**< Pipelined verification on output data */ + tFblMemVerifyData verifyDataOutput; /**< Verification on output data */ +} tFblMemBlockVerifyData; + +/** Information passed in segment start indication */ +typedef struct +{ + tFblAddress targetAddress; /* Target address (program operation) */ + tFblLength targetLength; /* Target length (program operation) */ + /* Used for signature verification */ + tFblAddress logicalAddress; /* Logical address (verification operation) */ + tFblLength logicalLength; /* Logical length (verification operation) */ + /* Handling info */ + tFblMemType type; /* Type (RAM / ROM) */ + tFblMemDfi dataFormat; /* Data format identifier (data processing) */ +} tFblMemSegmentInfo; + +/** Return type for watchdog trigger */ +#if defined( FBL_MEM_TRIGGER_STATUS_OVERWRITE ) +typedef FBL_MEM_TRIGGER_STATUS_OVERWRITE tFblMemTriggerStatus; +#else +typedef vuint8 tFblMemTriggerStatus; +#endif + +/** Input source handle */ +typedef vuintx tFblMemInputSource; + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) +/** Operation types reported in progress information */ +typedef enum +{ + kFblMemProgressType_Erase, /**< Erase operation */ + kFblMemProgressType_Program, /**< Programming operation (may include gap fill) */ + kFblMemProgressType_GapFill, /**< Concluding gap fill operation */ + kFblMemProgressType_Verify, /**< Verification operation */ + kFblMemProgressType_Undefined /**< Undefined, used internally */ +} tFblMemProgressType; + +/** Progress information */ +typedef struct +{ + tFblMemProgressType type; /**< Operation type */ + tFblAddress logicalAddress; /**< Logical block address */ + vuint32 segmentCount; /**< Segment count + Typically zero for erase and verification, + segment index for programming and + index of last segment incremented by one for concluding gap fill */ + vuint8 totalProgress; /**< Total operation progress (current block) */ + vuint8 partialProgress; /**< Partial operation progress */ +} tFblMemProgressInfo; +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) +typedef struct +{ + tFblAddress baseAddress; /**< Address of base memory region allowed to be modified */ + tFblLength baseLength; /**< Length of base memory region allowed to be modified */ + tFblAddress address; /**< Current programming address (based on previously produced length) */ + tFblLength length; /**< Current programming remainder (based on previously produced length) */ + tFblMemConstRamData inputData; /**< Pointer to input data buffer */ + tFblMemRamData outputData; /**< Pointer to output data buffer (not used for stream output) */ + void (* watchdog)(void); /**< Watchdog trigger function */ + tFblLength inputLength; /**< Length of input data */ + tFblLength outputSize; /**< Size of output data buffer (not used for stream output) */ + tFblLength consumedLength; /**< Number of consumed input data bytes */ + tFblLength producedLength; /**< Number of produced output data bytes (stream output: directly programmed to memory) */ + vuint8 mode; /**< Applied data processing mode*/ +} tFblMemStreamProcessing; +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ + +/*-- Resumable programming --------------------------------------------------*/ + +#define FBLLIB_MEM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#if defined( __cplusplus ) +extern "C" { +#endif + +tFblMemRamData FblMemInitPowerOn( void ); +tFblMemRamData FblMemInitPowerOnExt( tFblLength preambleLen, tFblMemInputSource sourceHandle ); +tFblMemRamData FblMemInit( void ); +void FblMemDeinit( void ); +tFblMemRamData FblMemGetActiveBuffer( void ); +tFblMemStatus FblMemBlockEraseIndication( const V_MEMRAM1 tFblMemBlockInfo V_MEMRAM2 V_MEMRAM3 * block ); +tFblMemStatus FblMemBlockStartIndication( V_MEMRAM1 tFblMemBlockInfo V_MEMRAM2 V_MEMRAM3 * block ); +tFblMemStatus FblMemBlockEndIndication( void ); +tFblMemStatus FblMemBlockVerify( const V_MEMRAM1 tFblMemBlockVerifyData V_MEMRAM2 V_MEMRAM3 * verifyData, + V_MEMRAM1 tFblMemVerifyStatus V_MEMRAM2 V_MEMRAM3 * verifyResult ); +tFblMemStatus FblMemBlockVerifyExtended( const V_MEMRAM1 tFblMemBlockVerifyData V_MEMRAM2 V_MEMRAM3 * verifyData, + V_MEMRAM1 tFblMemVerifyStatus V_MEMRAM2 V_MEMRAM3 * verifyResult, const tFblMemVerifyOption option ); +tFblMemStatus FblMemSegmentStartIndication( const V_MEMRAM1 tFblMemSegmentInfo V_MEMRAM2 V_MEMRAM3 * segment ); +tFblMemStatus FblMemSegmentEndIndication( V_MEMRAM1 tFblLength V_MEMRAM2 V_MEMRAM3 * writeLength ); +tFblMemStatus FblMemDataIndication( tFblMemConstRamData buffer, tFblLength offset, tFblLength length ); +void FblMemTask( void ); +void FblMemFlushInputData( void ); + +/* Low level memory operations */ +tFblMemStatus FblMemEraseRegion( tFblAddress eraseAddress, tFblLength eraseLength ); +tFblMemStatus FblMemProgramBuffer( tFblAddress programAddress,V_MEMRAM1 tFblLength V_MEMRAM2 V_MEMRAM3 * programLength, + tFblMemRamData programData ); + +/* Helper functions */ +void FblMemSetInteger( vuintx count, vuint32 input, tFblMemRamData buffer ); +vuint32 FblMemGetInteger( vuintx count, tFblMemConstRamData buffer ); + +#if defined( FBL_MEM_ENABLE_MULTI_SOURCE ) +void FblMemLockInputSource( tFblMemInputSource sourceHandle ); +#endif + + + +#define FBLLIB_MEM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLLIB_MEM_RAMCODE_START_SEC_CODE_EXPORT +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +void FblMemResumeIndication( void ); +#if defined( FBL_MEM_ENABLE_PIPELINING ) +void FblMemRxNotification( void ); +#endif /* FBL_MEM_ENABLE_PIPELINING */ + +#define FBLLIB_MEM_RAMCODE_STOP_SEC_CODE_EXPORT +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( __cplusplus ) +} /* extern "C" */ +#endif + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBLLIB_MEM_START_SEC_VAR_EXPORT +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +V_MEMRAM0 extern V_MEMRAM1 tFblMemProgState V_MEMRAM2 fblMemProgState; + +#define FBLLIB_MEM_STOP_SEC_VAR_EXPORT +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * CONFIGURATION CHECKS + **********************************************************************************************************************/ + +/* Plausibility checks of configuration settings *****************************/ +/*-- Integration time -------------------------------------------------------*/ + + + + + + + + + + + + + + + + + + + + +/*-- Compatibility remapping of configuration switches-----------------------*/ + + + +/*-- Compile time -----------------------------------------------------------*/ +#if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) || \ + defined( FBL_ENABLE_ADAPTIVE_DATA_TRANSFER_RCRRP ) +# if defined( FBL_MEM_WRITE_SEGMENTATION ) +# else +# error Write segmentation not defined +# endif +# if defined( FBL_ENABLE_UNALIGNED_DATA_TRANSFER ) +# else +# if ( (FBL_MEM_WRITE_SEGMENTATION & (FBL_MAX_SEGMENT_SIZE - 1u)) != 0u ) +# error Write segmentation has to be multiple of segment size +# endif +# endif /* FBL_ENABLE_UNALIGNED_DATA_TRANSFER */ +#endif /* FBL_ENABLE_PIPELINED_PROGRAMMING || FBL_ENABLE_ADAPTIVE_DATA_TRANSFER_RCRRP */ + +# if defined( FBL_ENABLE_PIPELINED_PROGRAMMING ) +# if defined( FBL_MEM_PIPE_PROG_BUFFER_COUNT ) +# if ( FBL_MEM_PIPE_PROG_BUFFER_COUNT < 2 ) +# error Number of pipelined programming buffers has to be at least two +# endif +# endif /* FBL_MEM_PIPE_PROG_BUFFER_COUNT */ +# endif /* FBL_ENABLE_PIPELINED_PROGRAMMING */ + +#if defined( FBL_ENABLE_DATA_PROCESSING ) +# if defined( FBL_MEM_PROC_BUFFER_SIZE ) +# else +# error Data processing buffer size not defined +# endif +# if ( FBL_MEM_PROC_SEGMENTATION > 0xFFFFu ) +# error Data processing segmentation exceeds interface constraints +# endif +# if ( FBL_MEM_PROC_SEGMENTATION > FBL_MEM_PROC_BUFFER_SIZE ) +# error Data processing segmentation exceeds buffer size +# endif +# if ( FBL_MEM_PROC_SEGMENTATION == FBL_MEM_PROC_BUFFER_SIZE ) +# else +# endif +#endif /* FBL_ENABLE_DATA_PROCESSING */ + + +#if defined( FBL_MEM_BUFFER_SIZE ) +#else +# error Input buffer size not defined +#endif /* FBL_MEM_BUFFER_SIZE */ + +#if defined( FBL_MEM_DEFAULT_PREAMBLE_LENGTH ) +#else +# error Default preamble length not defined +#endif /* FBL_MEM_DEFAULT_PREAMBLE_LENGTH */ + +#if defined( FBL_MEM_MAX_PREAMBLE_LENGTH ) +#else +# error Maximum preamble length not defined +#endif /* FBL_MEM_MAX_PREAMBLE_LENGTH */ + +#if defined( FBL_MEM_WD_TRIGGER_DEFAULT ) +#else +# error Default watchdog trigger return code not defined +#endif /* FBL_MEM_WD_TRIGGER_DEFAULT */ + + +#if defined( FBL_MEM_ENABLE_STATUS_OVERWRITE ) +# if defined( FBL_MEM_STATUS_Ok ) && \ + defined( FBL_MEM_STATUS_Failed ) +# else +# error Status overwrite or remapping enabled, but actual values missing +# endif +#endif /* FBL_MEM_ENABLE_STATUS_OVERWRITE || FBL_MEM_ENABLE_STATUS_REMAPPING */ + +#if defined( FBL_MEM_STATUS_Ok ) || \ + defined( FBL_MEM_STATUS_Failed ) +# if defined( FBL_MEM_ENABLE_STATUS_OVERWRITE ) +# else +# error Status values defined, but neither status overwrite nor remapping enabled +# endif +#endif /* FBL_MEM_STATUS_Ok || FBL_MEM_STATUS_Failed */ + +#if defined( FBL_MEM_ENABLE_EXT_STATUS ) +# if defined( FBL_MEM_EXT_STATUS_Ok ) && \ + defined( FBL_MEM_EXT_STATUS_Failed ) +# else +# error Extended status enabled, but actual macros missing +# endif +#endif /* FBL_MEM_ENABLE_EXT_STATUS */ + +#if defined( FBL_MEM_EXT_STATUS_Ok ) || \ + defined( FBL_MEM_EXT_STATUS_Failed ) +# if defined( FBL_MEM_ENABLE_EXT_STATUS ) +# else +# error Extended status macros defined, but feature not enabled +# endif +#endif /* FBL_MEM_EXT_STATUS_Ok || FBL_MEM_EXT_STATUS_Failed */ + + +#if defined( FBL_MEM_ENABLE_STREAM_OUTPUT ) +# if defined( __ApplFblMemIsStreamOutputRequired ) +# else +# error Stream output enabled, but data format check not specified +# endif +#endif /* FBL_MEM_ENABLE_STREAM_OUTPUT */ + +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) +# if defined( FBL_ENABLE_PROCESSED_DATA_LENGTH) +# error Combination of progress information with processed data length not supported +# endif /* FBL_ENABLE_PROCESSED_DATA_LENGTH */ +# if defined( __ApplFblMemReportProgress ) +# else +# error Progress information enabled, but report callout not specified +# endif /* __ApplFblMemReportProgress */ +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + +#endif /* FBL_MEM_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_MEM.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_mem_oem.h b/Source/bsw/Fbl/fbl_mem_oem.h new file mode 100644 index 0000000..25c76f9 --- /dev/null +++ b/Source/bsw/Fbl/fbl_mem_oem.h @@ -0,0 +1,453 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief OEM dependent configuration for FblLib_Mem + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2026 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * TEMPLATE REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2012-03-23 visjhg - Initial release + * 01.00.01 2012-03-26 visjhg - Additional comments + * 01.01.00 2012-04-05 visjhg - Changes after code review + * 01.02.00 2012-04-27 visjhg - Updated type casts in macros using ternary operator + * 01.04.00 2013-02-01 visach ESCAN00062919 Adapted comments to use Doxygen + * visach - Correct macro __ApplFblMemDriverReady + * visjhg ESCAN00064292 Added pre and post handlers for erase routine + * visjhg ESCAN00064296 Renamed default preamble length define + * visjhg ESCAN00064301 Split verify functions for RAM and ROM verification + * visjhg ESCAN00064333 Differentiate watchdog trigger w/ and w/o status + * visjhg ESCAN00064334 Added interface to remap error codes to OEM dependent value + * visjhg - Added additional error codes for new functionality + * visjhg ESCAN00064720 Replaced __ApplFblMemCheckDfi by __ApplFblMemIsDataProcessingRequired + * 01.05.00 2013-04-10 visjhg ESCAN00066379 Added interface version compatibility check + * visjhg ESCAN00066377 Added additional error codes for new functionality + * 01.06.00 2013-07-22 visjhg ESCAN00067433 Updated interface version (added FblMemDeinit) + * visjhg ESCAN00069161 Updated interface version (added pipelined verification) + * Changed verification error codes + * 01.07.00 2013-08-16 visjhg ESCAN00069803 Updated interface version (enable/disable verification at run-time) + * visjhg - Corrected name of parameter type overwrite + * 02.00.00 2013-12-12 visjhg ESCAN00072568 Updated interface version (initialize verification in segment start) + * Error / status for BlockStartVerifyInit replaced by SegmentStartVerifyInit + * visjhg ESCAN00072569 Raised major version to match API version + * 02.01.00 2014-03-12 visjhg ESCAN00073504 Corrected overwrite macro names for verification functions + * 03.00.00 2015-03-03 visjhg ESCAN00076591 Added support for external stream output + * Added __ApplFblMemIsStreamOutputRequired + * Added additional error codes + * Updated interface version + * visjhg ESCAN00081493 Added __ApplFblMemIsPipelinedProgrammingDisabled + * 03.01.00 2015-04-23 visjhg ESCAN00082606 Added __ApplFblMemReportProgress + * 03.01.03 2015-06-15 visjhg ESCAN00083392 Added FBL_MEM_ENABLE_VERIFY_OUTPUT_FULL_BLOCK_LENGTH + * Added SEC_ENABLE_VERIFICATION_ADDRESS_LENGTH check + * Updated interface version + * 03.02.00 2015-07-21 visjhg ESCAN00084102 Updated interface version (parameter type structure for stream processing) + * 04.00.00 2015-09-17 visjhg ESCAN00085249 Updated interface version (explicit parameters for processed verification) + * visjhg ESCAN00085250 Run-time decision whether address and length info is included in verification + * Added __ApplFblMemVerifyInputIsAddressAndLengthIncluded, + * __ApplFblMemVerifyProcessedIsAddressAndLengthIncluded and + * __ApplFblMemVerifyPipelinedIsAddressAndLengthIncluded + * visjhg ESCAN00085251 Pass external segment info to __ApplFblMemIsPipelinedProgrammingDisabled + * 04.01.00 2016-04-01 visjhg ESCAN00087997 Added __ApplFblMemEnterCriticalSection and __ApplFblMemLeaveCriticalSection + * Updated interface version + * 04.02.01 2017-05-31 visjhg - Removed deprecated SEC_VER_DISABLE_LENGTH_AND_ADDRESS_INPUT + * Updated interface version + * 04.03.00 2017-07-06 visjhg ESCAN00095774 Added FblMemFlushInputData + * Updated interface version + * 04.04.00 2018-08-22 visjhg ESCAN00100482 Added hook __ApplFblMemConditionCheck + * Updated interface version + * 04.04.01 2018-09-25 visjhg ESCAN00100850 Matching preamble length for MCMP download use-case + * Updated interface version + * 04.05.00 2018-11-30 visjhg ESCAN00101500 Added custom error codes (typically used by __ApplFblMemConditionCheck) + * Updated interface version + * 04.05.02 2019-08-20 vistbe ESCAN00103967 Updated interface version + * 04.06.00 2019-10-29 vistmo FBL-813 Migration to MISRA 2012 + * -------------------------------------------------------------------------------------------------------------------- + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2022-08-15 vistmo FBL-5514 Support Additional OTA functionality + * ESCAN00112435 No changes + * ESCAN00112575 No changes + * 05.01.00 2022-10-04 jschmitding FBL-5917 No changes + * ESCAN00113919 No changes + * 05.01.01 2022-10-17 fmenke ESCAN00112879 No changes + * 05.01.02 2023-01-13 fmenke ESCAN00112890 No changes + * ESCAN00113612 No changes + * 05.02.00 2023-02-09 vistmo ESCAN00112972 No changes + * ESCAN00113292 No changes + * ESCAN00113835 No changes + * ESCAN00113843 No changes + * ESCAN00113764 No changes + * FBL-6438 No changes + * 05.02.01 2023-05-11 fmenke ESCAN00113831 No changes + * 05.03.00 2023-07-24 fmenke FBL-7335 No changes + * 05.03.01 2023-08-31 lhopfhauer ESCAN00115494 No changes + * 05.03.02 2024-07-16 erizk ESCAN00117344 No changes + * 05.03.03 2025-02-06 virchl ESCAN00118587 No changes + * 05.04.00 2025-02-28 jjohnson FBL-10065 No changes + * 05.04.01 2025-06-10 jostravsky ESCAN00120315 No changes + * 05.04.02 2025-07-08 visarcmijo ESCAN00119833 No changes + * 05.05.00 2025-09-01 fmenke FBL-11218 No changes + * ESCAN00120917 No changes + * 05.06.00 2025-10-28 mpatil FBL-11690 No changes + * 05.07.00 2026-01-13 dganesh FBL-12162 No changes + **********************************************************************************************************************/ + +#ifndef FBL_MEM_OEM_H +#define FBL_MEM_OEM_H + + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* PRQA S 0602, 0603 TAG_FblMemOem_0602_0603_1 */ /* MD_FblMemOem_0602_0603 */ + +/*-- Version information ----------------------------------------------------*/ + +/* Reference interface version */ +/** Major interface version identifies incompatible changes */ +#define FBL_MEM_API_REFERENCE_VERSION_MAJOR 0x04u +/** Minor interface version identifies backward compatible changes */ +#define FBL_MEM_API_REFERENCE_VERSION_MINOR 0x05u +/** Release interface version identifies cosmetic changes */ +#define FBL_MEM_API_REFERENCE_VERSION_RELEASE 0x00u + +/*-- Buffer configuration ---------------------------------------------------*/ + +/** Input buffer size */ +#define FBL_MEM_BUFFER_SIZE FBL_DIAG_BUFFER_LENGTH + +/** Preamble length for UDS download */ +#define FBL_MEM_PREAMBLE_LENGTH_UDS 2u +/** Preamble length for MCMP download */ +#define FBL_MEM_PREAMBLE_LENGTH_MCMP 1u + +/** Preamble length of default source */ +#if defined( FBL_MEM_SOURCE_PREAMBLE_LENGTH ) +/* Allow override for non-standard use-cases */ +#else +# if defined( MCMP_MEM_MODE_DYNAMIC ) +/* Mixed download over UDS and MCMP + UDS is default source */ +# define FBL_MEM_SOURCE_PREAMBLE_LENGTH FBL_MEM_PREAMBLE_LENGTH_UDS +# elif defined( MCMP_MEM_MODE_SLAVE ) +/* MCMP-only download */ +# define FBL_MEM_SOURCE_PREAMBLE_LENGTH FBL_MEM_PREAMBLE_LENGTH_MCMP +# else +/* UDS-only download */ +# define FBL_MEM_SOURCE_PREAMBLE_LENGTH FBL_MEM_PREAMBLE_LENGTH_UDS +# endif /* MCMP_MEM_MODE_ */ +#endif /* FBL_MEM_SOURCE_PREAMBLE_LENGTH */ + +/** Length of default preamble */ +#define FBL_MEM_DEFAULT_PREAMBLE_LENGTH FBL_MEM_SOURCE_PREAMBLE_LENGTH +/** Maximum preamble length */ +#define FBL_MEM_MAX_PREAMBLE_LENGTH FBL_MEM_SOURCE_PREAMBLE_LENGTH + +/* Allow override in configuration */ +# if defined( __ApplFblMemIsDataProcessingRequired ) +# else +/** Check whether specific data format identifier implies the need for data processing */ +# define __ApplFblMemIsDataProcessingRequired(dataFormat) \ + ((tFblResult)((kDiagSubNoDataProcessing == (dataFormat)) ? kFblFailed : kFblOk)) +# endif /* __ApplFblMemIsDataProcessingRequired */ +# if defined( FBL_MEM_ENABLE_SELECTIVE_PIPELINED_PROGRAMMING ) +/* Allow override in configuration */ +# if defined( __ApplFblMemIsPipelinedProgrammingDisabled ) +# else +/* + This is just an example for the macro definition + Remove macro and disable feature if not applicable +*/ +/** Check whether pipelined programming has to be disabled for specific block / segment / data format identifier */ +# define __ApplFblMemIsPipelinedProgrammingDisabled(pBlockInfo, pSegmentInfo) ((tFblResult)kFblFailed) +# endif /* __ApplFblMemIsPipelinedProgrammingDisabled */ +# endif /* FBL_MEM_ENABLE_SELECTIVE_PIPELINED_PROGRAMMING */ + +/*-- Verification -----------------------------------------------------------*/ + +/** Calculate CRC total over complete block + Otherwise start of block until last address of last segment is covered */ +#define FBL_MEM_DISABLE_VERIFY_OUTPUT_FULL_BLOCK_LENGTH + +/** Size of temporary verification result buffer */ +#define FBL_MEM_SIG_RESULT_BUFFER_SIZE kDiagSigBufLength +/** Overwrite input verification function type */ +#define FBL_MEM_VERIFY_FCT_INPUT_TYPE_OVERWRITE(type) FBL_CALL_TYPE tFblMemVerifyStatus (*type) (V_MEMRAM1 tFblMemVerifyParamInput V_MEMRAM2 V_MEMRAM3 *) + +/*-- Memory driver ----------------------------------------------------------*/ +/* + Perform actions directly before and after memory driver write + Remove macro if not applicable +*/ +#define __ApplFblMemPreWrite() FblDiagMemPreWrite() +#define __ApplFblMemPostWrite() FblDiagMemPostWrite() +/* + Perform actions directly before and after memory driver erase + Remove macro if not applicable +*/ +#define __ApplFblMemPreErase() FblDiagMemPreWrite() +#define __ApplFblMemPostErase() FblDiagMemPostWrite() +/* + Perform actions directly after segment end indication + Remove macro if not applicable +*/ +/* #define __ApplFblMemPostSegmentEnd() */ + +/*-- Watchdog ---------------------------------------------------------------*/ +/* Default return code */ +#define FBL_MEM_WD_TRIGGER_DEFAULT (FBL_NO_TRIGGER) +/* + Overwrite status type returned by watchdog trigger function + Remove macro if not applicable +*/ +#define FBL_MEM_TRIGGER_STATUS_OVERWRITE vuint8 +/* + Default watchdog trigger + Remove macro if not applicable +*/ +#define __ApplFblMemWdTrigger() FblLookForWatchdog() +/* + Watchdog trigger including adaptive generation of RCR-RP + Remove macro if not applicable +*/ +#define __ApplFblMemAdaptiveRcrRp() FblRealTimeSupport() +/* + Check whether RCR-RP is already active + Remove macro if not applicable or required (e.g. if kForceSendRpIfNotInProgress is available) +*/ +#define __ApplFblMemIsRcrRpActive() ((tFblResult)(GetRcrRpInProgress() ? kFblOk : kFblFailed)) +/* + Forced generation of RCR-RP (hint: use kForceSendRpIfNotInProgress if available) + Remove macro if not applicable +*/ +#define __ApplFblMemForcedRcrRp() DiagExRCRResponsePending(kForceSendResponsePending) + +/* Pass watchdog trigger with extended status result to data processing */ +#define FBL_MEM_ENABLE_EXT_TRIGGER_DATA_PROC +/* Pass watchdog trigger with extended status result to signature verification over input data */ +#define FBL_MEM_DISABLE_EXT_TRIGGER_INPUT_VERIFY +/* Pass watchdog trigger with extended status result to signature verification over output data */ +#define FBL_MEM_DISABLE_EXT_TRIGGER_OUTPUT_VERIFY + +/*-- Gap filling ------------------------------------------------------------*/ +/* Gap fill handling of LibMem explicitly disabled */ +#define FBL_MEM_DISABLE_GAP_FILL + +/*-- Progress information ---------------------------------------------------*/ +#if defined( FBL_MEM_ENABLE_PROGRESS_INFO ) +/* Allow override in configuration */ +# if defined( __ApplFblMemReportProgress ) +# else +/** Progress information reporting */ +/*# define __ApplFblMemReportProgress(progressInfo)*/ +# endif /* __ApplFblMemReportProgress */ +#endif /* FBL_MEM_ENABLE_PROGRESS_INFO */ + +/*-- Critical sections ------------------------------------------------------*/ +/* Allow override in configuration */ +#if defined( __ApplFblMemEnterCriticalSection ) +#else +/** Enter critical section */ +# define __ApplFblMemEnterCriticalSection() +#endif /* __ApplFblMemEnterCriticalSection */ + +/* Allow override in configuration */ +#if defined( __ApplFblMemLeaveCriticalSection ) +#else +/** Leave critical section */ +# define __ApplFblMemLeaveCriticalSection() +#endif /* __ApplFblMemLeaveCriticalSection */ + +/*-- Error handling ---------------------------------------------------------*/ +/** Overwrite error codes by OEM dependent value */ +#define FBL_MEM_ENABLE_STATUS_OVERWRITE +/* Enable interface to remap error codes to OEM dependent value */ +#define FBL_MEM_DISABLE_STATUS_REMAPPING +/* OEM dependent status type */ +#define FBL_MEM_STATUS_TYPE vuint8 + +#if defined( FBL_MEM_ENABLE_STATUS_OVERWRITE ) +/* Default */ +# define FBL_MEM_STATUS_Ok kDiagErrorNone +# define FBL_MEM_STATUS_Failed kDiagNrcConditionsNotCorrect +/* BlockErase indication */ +# define FBL_MEM_STATUS_BlockEraseSequence kDiagNrcRequestSequenceError +/* BlockStart indication */ +# define FBL_MEM_STATUS_BlockStartSequence kDiagNrcConditionsNotCorrect +# define FBL_MEM_STATUS_BlockStartParam kDiagNrcConditionsNotCorrect +/* BlockEnd indication */ +# define FBL_MEM_STATUS_BlockEndSequence kDiagNrcRequestSequenceError +# define FBL_MEM_STATUS_BlockEndVerifyFinalize kDiagNrcGeneralProgrammingFailure +/* BlockVerify */ +# define FBL_MEM_STATUS_BlockVerifySequence kDiagNrcRequestSequenceError +# define FBL_MEM_STATUS_BlockVerifyInputVerify kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_BlockVerifyProcessedVerify kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_BlockVerifyPipeVerify kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_BlockVerifyOutputVerify kDiagNrcGeneralProgrammingFailure +/* SegmentStart indication */ +# define FBL_MEM_STATUS_SegmentStartSequence kDiagNrcRequestSequenceError +# define FBL_MEM_STATUS_SegmentStartDataProcInit kDiagNrcRequestOutOfRange +# define FBL_MEM_STATUS_SegmentStartStreamOutInit kDiagNrcRequestOutOfRange +# define FBL_MEM_STATUS_SegmentStartVerifyInit kDiagNrcConditionsNotCorrect +# define FBL_MEM_STATUS_SegmentStartVerifyCompute kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_SegmentStartSegmentCount kDiagNrcRequestOutOfRange +/* SegmentEnd indication */ +# define FBL_MEM_STATUS_SegmentEndSequence kDiagNrcRequestSequenceError +# define FBL_MEM_STATUS_SegmentEndInsufficientData kDiagNrcRequestSequenceError +# define FBL_MEM_STATUS_SegmentEndPost kDiagNrcConditionsNotCorrect +/* Data indication */ +# define FBL_MEM_STATUS_DataIndSequence kDiagNrcRequestSequenceError +# define FBL_MEM_STATUS_DataIndParam kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_DataIndOverflow kDiagNrcTransferDataSuspended +/* Data processing */ +# define FBL_MEM_STATUS_DataProc kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_DataProcConsume kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_DataProcDeinit kDiagNrcGeneralProgrammingFailure +/* Stream output */ +# define FBL_MEM_STATUS_StreamOutput kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_StreamOutputConsume kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_StreamOutputOverflow kDiagNrcTransferDataSuspended +# define FBL_MEM_STATUS_StreamOutputDeinit kDiagNrcGeneralProgrammingFailure +/* Memory driver */ +# define FBL_MEM_STATUS_DriverResumeWrite kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_DriverWrite kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_DriverErase kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_DriverRemainder kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_DriverSuspendWrite kDiagNrcGeneralProgrammingFailure +/* Programming operation */ +# define FBL_MEM_STATUS_ProgramOverflow kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_ProgramOutsideFbt kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_ProgramUnalignedAddress kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_ProgramDriverNotReady kDiagNrcRequestSequenceError +# define FBL_MEM_STATUS_ProgramPreWrite kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_ProgramPostWrite kDiagNrcGeneralProgrammingFailure +/* Erase operation */ +# define FBL_MEM_STATUS_EraseOutsideFbt kDiagNrcRequestOutOfRange +# define FBL_MEM_STATUS_EraseDriverNotReady kDiagNrcConditionsNotCorrect +# define FBL_MEM_STATUS_ErasePreErase kDiagNrcConditionsNotCorrect +# define FBL_MEM_STATUS_ErasePostErase kDiagNrcConditionsNotCorrect +/* On-the-fly verification */ +# define FBL_MEM_STATUS_VerifyCompute kDiagNrcGeneralProgrammingFailure +# define FBL_MEM_STATUS_VerifyFinalize kDiagNrcGeneralProgrammingFailure +/* Pass-through */ +# define FBL_MEM_STATUS_PassThroughLocal kDiagNrcConditionsNotCorrect +# define FBL_MEM_STATUS_PassThroughRemote kDiagNrcConditionsNotCorrect +#endif /* FBL_MEM_ENABLE_STATUS_OVERWRITE || FBL_MEM_ENABLE_STATUS_REMAPPING */ + +#if defined( FBL_ENABLE_DEBUG_STATUS ) +/** Enable extended error status handling */ +# define FBL_MEM_ENABLE_EXT_STATUS + +/* Default */ +# define FBL_MEM_EXT_STATUS_Ok(status) +# define FBL_MEM_EXT_STATUS_Failed(status) +/* BlockErase indication */ +# define FBL_MEM_EXT_STATUS_BlockEraseSequence(status) +/* BlockStart indication */ +# define FBL_MEM_EXT_STATUS_BlockStartSequence(status) +# define FBL_MEM_EXT_STATUS_BlockStartParam(status) +/* BlockEnd indication */ +# define FBL_MEM_EXT_STATUS_BlockEndSequence(status) +# define FBL_MEM_EXT_STATUS_BlockEndVerifyFinalize(status) +/* BlockVerify */ +# define FBL_MEM_EXT_STATUS_BlockVerifySequence(status) +# define FBL_MEM_EXT_STATUS_BlockVerifySigVerify(status) +# define FBL_MEM_EXT_STATUS_BlockVerifyInputVerify(status) +# define FBL_MEM_EXT_STATUS_BlockVerifyProcessedVerify(status) +# define FBL_MEM_EXT_STATUS_BlockVerifyPipeVerify(status) +# define FBL_MEM_EXT_STATUS_BlockVerifyOutputVerify(status) +/* SegmentStart indication */ +# define FBL_MEM_EXT_STATUS_SegmentStartSequence(status) +# define FBL_MEM_EXT_STATUS_SegmentStartDataProcInit(status) +# define FBL_MEM_EXT_STATUS_SegmentStartStreamOutInit(status) +# define FBL_MEM_EXT_STATUS_SegmentStartVerifyInit(status) +# define FBL_MEM_EXT_STATUS_SegmentStartVerifyCompute(status) +# define FBL_MEM_EXT_STATUS_SegmentStartSegmentCount(status) FblErrStatSetError(FBL_ERR_TOO_MANY_SEGMENTS_IN_MODULE) +/* SegmentEnd indication */ +# define FBL_MEM_EXT_STATUS_SegmentEndSequence(status) +# define FBL_MEM_EXT_STATUS_SegmentEndInsufficientData(status) +# define FBL_MEM_EXT_STATUS_SegmentEndPost(status) +/* Data indication */ +# define FBL_MEM_EXT_STATUS_DataIndSequence(status) +# define FBL_MEM_EXT_STATUS_DataIndParam(status) +# define FBL_MEM_EXT_STATUS_DataIndOverflow(status) FblErrStatSetState(FBL_ERR_DATA_OVERFLOW) +/* Data processing */ +# define FBL_MEM_EXT_STATUS_DataProc(status) +# define FBL_MEM_EXT_STATUS_DataProcConsume(status) +# define FBL_MEM_EXT_STATUS_DataProcDeinit(status) +/* Stream output */ +# define FBL_MEM_EXT_STATUS_StreamOutput(status) +# define FBL_MEM_EXT_STATUS_StreamOutputConsume(status) +# define FBL_MEM_EXT_STATUS_StreamOutputOverflow(status) +# define FBL_MEM_EXT_STATUS_StreamOutputDeinit(status) +/* Memory driver */ +# define FBL_MEM_EXT_STATUS_DriverResumeWrite(status) +/* Status contains flash driver error code */ +# define FBL_MEM_EXT_STATUS_DriverWrite(status) { FblErrStatSetFlashDrvError(status); FblErrStatSetError(FBL_ERR_FLASH_PROG_ERROR); } +# define FBL_MEM_EXT_STATUS_DriverErase(status) { FblErrStatSetFlashDrvError(status); FblErrStatSetError(FBL_ERR_FLASH_ERASE_ERROR); } +# define FBL_MEM_EXT_STATUS_DriverRemainder(status) +# define FBL_MEM_EXT_STATUS_DriverSuspendWrite(status) +/* Programming operation */ +# define FBL_MEM_EXT_STATUS_ProgramOverflow(status) FblErrStatSetState(FBL_ERR_DATA_OVERFLOW) +# define FBL_MEM_EXT_STATUS_ProgramOutsideFbt(status) FblErrStatSetError(FBL_ERR_NO_MEMORY_REGION_FOUND) +# define FBL_MEM_EXT_STATUS_ProgramUnalignedAddress(status) FblErrStatSetError(FBL_ERR_FLASH_PROG_ERROR) +# define FBL_MEM_EXT_STATUS_ProgramDriverNotReady(status) FblErrStatSetError(FBL_ERR_FLASHCODE_INIT_FAILED) +# define FBL_MEM_EXT_STATUS_ProgramPreWrite(status) +# define FBL_MEM_EXT_STATUS_ProgramPostWrite(status) +/* Erase operation */ +# define FBL_MEM_EXT_STATUS_EraseOutsideFbt(status) FblErrStatSetError(FBL_ERR_NO_MEMORY_REGION_FOUND) +# define FBL_MEM_EXT_STATUS_EraseDriverNotReady(status) FblErrStatSetError(FBL_ERR_FLASHCODE_INIT_FAILED) +# define FBL_MEM_EXT_STATUS_ErasePreErase(status) +# define FBL_MEM_EXT_STATUS_ErasePostErase(status) +/* On-the-fly verification */ +# define FBL_MEM_EXT_STATUS_VerifyCompute(status) +# define FBL_MEM_EXT_STATUS_VerifyFinalize(status) +/* Pass-through */ +# define FBL_MEM_EXT_STATUS_PassThroughLocal(status) +# define FBL_MEM_EXT_STATUS_PassThroughRemote(status) + +/* Extended info: status contains current address */ +# define FBL_MEM_EXT_STATUS_ProgramAddress(status) FblErrStatSetAddress(status) +# define FBL_MEM_EXT_STATUS_EraseAddress(status) FblErrStatSetAddress(status) +#endif /* FBL_ENABLE_DEBUG_STATUS */ + +/* PRQA L:TAG_FblMemOem_0602_0603_1 */ +/* PRQA L:TAG_FblMemOem_3453_1 */ + +#endif /* FBL_MEM_OEM_H */ + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_FblMemOem_0602_0603: + Reason: Usage of reserved identifiers with leading underscores is accepted for compatibility reasons. + Risk: Name conflicts. + Prevention: Compile and link of the different variants in the component and integration test. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_MEM_OEM.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_nvpattern_oem.c b/Source/bsw/Fbl/fbl_nvpattern_oem.c new file mode 100644 index 0000000..4e4abf3 --- /dev/null +++ b/Source/bsw/Fbl/fbl_nvpattern_oem.c @@ -0,0 +1,131 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Implementation of pattern/mask based non-volatile information storage + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2026 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * TEMPLATE REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.04.00 2019-01-25 viskjs ESCAN00101824 Added patterns that can be validated multiple times + * ESCAN00101823 Added feature to store arbitrary values at end of logical block + * 01.04.01 2019-03-26 viskjs ESCAN00102200 No changes + * ESCAN00102204 No changes + * ESCAN00102646 No changes + * 01.04.02 2019-07-22 vistbe ESCAN00103605 No changes + * 01.04.03 2020-05-07 visjdn ESCAN00106002 No changes + * 01.04.04 2021-03-03 visrie ESCAN00108616 No changes + * ESCAN00108753 No changes + * FBL-3129 Added/adapted MemMap sections + * Update to MISRA 2012 + * 01.04.05 2021-03-16 visrie ESCAN00108859 No changes + * 01.05.00 2021-06-16 visrie FBL-3641 Support OTA use case and user extension + * -------------------------------------------------------------------------------------------------------------------- + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2022-08-15 vistmo FBL-5514 Support Additional OTA functionality + * ESCAN00112435 No changes + * ESCAN00112575 No changes + * 05.01.00 2022-10-04 jschmitding FBL-5917 No changes + * ESCAN00113919 No changes + * 05.01.01 2022-10-17 fmenke ESCAN00112879 No changes + * 05.01.02 2023-01-13 fmenke ESCAN00112890 No changes + * ESCAN00113612 No changes + * 05.02.00 2023-02-09 vistmo ESCAN00112972 No changes + * ESCAN00113292 No changes + * ESCAN00113835 No changes + * ESCAN00113843 No changes + * ESCAN00113764 No changes + * FBL-6438 No changes + * 05.02.01 2023-05-11 fmenke ESCAN00113831 No changes + * 05.03.00 2023-07-24 fmenke FBL-7335 No changes + * 05.03.01 2023-08-31 lhopfhauer ESCAN00115494 No changes + * 05.03.02 2024-07-16 erizk ESCAN00117344 No changes + * 05.03.03 2025-02-06 virchl ESCAN00118587 No changes + * 05.04.00 2025-02-28 jjohnson FBL-10065 No changes + * 05.04.01 2025-06-10 jostravsky ESCAN00120315 No changes + * 05.04.02 2025-07-08 visarcmijo ESCAN00119833 No changes + * 05.05.00 2025-09-01 fmenke FBL-11218 No changes + * ESCAN00120917 No changes + * 05.06.00 2025-10-28 mpatil FBL-11690 No changes + * 05.07.00 2026-01-13 dganesh FBL-12162 No changes + **********************************************************************************************************************/ + +#define FBL_NVPATTERN_OEM_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" +#include "fbl_nvpattern_oem.h" + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBLNVPATTERN_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined ( FBL_NVPATTERN_ENABLE_MULTIPLE_VALIDATION ) +V_MEMROM0 V_MEMROM1 vuint8 V_MEMROM2 fblNvPatternMultiplicity[] = +{ + 1u, /**< kFblNvPatternId_PartitionValidity can be validated/invalidated once after erasure */ + 1u, /**< kFblNvPatternId_ModuleValidity can be validated/invalidated once after erasure */ +# if defined( FBL_ENABLE_FLASH_ERASED_DETECTION ) + 1u, /**< kFblNvPatternId_ErasedState can be validated/invalidated once after erasure */ +# endif + FBL_NVPATTERN_USER_PATTERN_MULTIPLICITY +}; +#endif /* FBL_NVPATTERN_ENABLE_MULTIPLE_VALIDATION */ + +#if defined( FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES ) +V_MEMROM0 V_MEMROM1 tFblBlockProperty V_MEMROM2 fblNvBlockProperties[] = +{ + FBL_NVPATTERN_USER_PROPERTY_ENTRY +}; +#endif /* FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES */ + +#define FBLNVPATTERN_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_FblNvPatternOem_0724_EnumValNotUnique: + Reason: The same numerical value is associated to different enum entries, to allows each entry value to be used in + the appropriate context, keeping a better code structure and understanding. + Risk: Enum values can potentially be assigned with the same value unintentionally. + Prevention: Correct design. + + MD_FblNvPatternOem_3684: + Reason: The size of the array is determined only at compile time. + Risk: The code is less clear and require more analysis for a deep understanding. + Prevention: No prevention defined. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_NVPATTERN_OEM.C + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_nvpattern_oem.h b/Source/bsw/Fbl/fbl_nvpattern_oem.h new file mode 100644 index 0000000..4fb87f4 --- /dev/null +++ b/Source/bsw/Fbl/fbl_nvpattern_oem.h @@ -0,0 +1,196 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Implementation of pattern/mask based non-volatile information storage + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2026 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * TEMPLATE REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2017-02-24 visci - Initial version + * 01.01.00 2018-06-15 visci ESCAN00099699 No changes + * 01.02.00 2018-09-24 visrr ESCAN00100837 No changes + * 01.03.00 2018-12-07 visshs ESCAN00101559 No changes + * 01.04.00 2019-01-25 viskjs ESCAN00101824 Added patterns that can be validated multiple times + * ESCAN00101823 Added feature to store arbitrary values at end of logical block + * 01.04.01 2019-03-26 viskjs ESCAN00102200 No changes + * ESCAN00102204 No changes + * ESCAN00102646 No changes + * 01.04.02 2019-07-22 vistbe ESCAN00103605 No changes + * 01.04.03 2020-05-07 visjdn ESCAN00106002 No changes + * 01.04.04 2021-03-03 visrie ESCAN00108616 No changes + * ESCAN00108753 No changes + * FBL-3129 Added/adapted MemMap sections + * Update to MISRA 2012 + * 01.04.05 2021-03-16 visrie ESCAN00108859 No changes + * 01.05.00 2021-06-16 visrie FBL-3641 Support OTA use case and user extension + * -------------------------------------------------------------------------------------------------------------------- + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2022-08-15 vistmo FBL-5514 Support Additional OTA functionality + * ESCAN00112435 No changes + * ESCAN00112575 No changes + * 05.01.00 2022-10-04 jschmitding FBL-5917 No changes + * ESCAN00113919 No changes + * 05.01.01 2022-10-17 fmenke ESCAN00112879 No changes + * 05.01.02 2023-01-13 fmenke ESCAN00112890 No changes + * ESCAN00113612 No changes + * 05.02.00 2023-02-09 vistmo ESCAN00112972 No changes + * ESCAN00113292 No changes + * ESCAN00113835 No changes + * ESCAN00113843 No changes + * ESCAN00113764 No changes + * FBL-6438 No changes + * 05.02.01 2023-05-11 fmenke ESCAN00113831 No changes + * 05.03.00 2023-07-24 fmenke FBL-7335 No changes + * 05.03.01 2023-08-31 lhopfhauer ESCAN00115494 No changes + * 05.03.02 2024-07-16 erizk ESCAN00117344 No changes + * 05.03.03 2025-02-06 virchl ESCAN00118587 No changes + * 05.04.00 2025-02-28 jjohnson FBL-10065 No changes + * 05.04.01 2025-06-10 jostravsky ESCAN00120315 No changes + * 05.04.02 2025-07-08 visarcmijo ESCAN00119833 No changes + * 05.05.00 2025-09-01 fmenke FBL-11218 No changes + * ESCAN00120917 No changes + * 05.06.00 2025-10-28 mpatil FBL-11690 No changes + * 05.07.00 2026-01-13 dganesh FBL-12162 No changes + **********************************************************************************************************************/ + +#ifndef FBLLIB_NVPATTERN_OEM_H +#define FBLLIB_NVPATTERN_OEM_H + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* Check if multiple validation feature was explicitly enabled externally */ +# if !defined( FBL_NVPATTERN_ENABLE_MULTIPLE_VALIDATION ) +/* Disables NvPatterns which can be validated multiple times after erasing a logical block */ +# define FBL_NVPATTERN_DISABLE_MULTIPLE_VALIDATION +# endif /* !FBL_NVPATTERN_ENABLE_MULTIPLE_VALIDATION */ + +/* Check if block properties feature was explicitly enabled externally */ +# if !defined( FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES ) +/* Disables storing arbitrary data at the end of logical blocks */ +# define FBL_NVPATTERN_DISABLE_BLOCK_PROPERTIES +# endif /* !FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES */ + +/* Disable user patterns if they are not explicitly defined */ +#if !defined( FBL_NVPATTERN_USER_PATTERN_ID ) +# define FBL_NVPATTERN_USER_PATTERN_ID +#endif /* FBL_NVPATTERN_USER_PATTERN_ID */ +#if !defined( FBL_NVPATTERN_USER_PATTERN_MULTIPLICITY ) +# define FBL_NVPATTERN_USER_PATTERN_MULTIPLICITY +#endif /* FBL_NVPATTERN_USER_PATTERN_MULTIPLICITY */ +#if !defined( FBL_NVPATTERN_USER_PROPERTY_ID ) +# define FBL_NVPATTERN_USER_PROPERTY_ID +#endif /* FBL_NVPATTERN_USER_PROPERTY_ID */ +#if !defined( FBL_NVPATTERN_USER_PROPERTY_ENTRY ) +# define FBL_NVPATTERN_USER_PROPERTY_ENTRY +#endif /* FBL_NVPATTERN_USER_PROPERTY_ENTRY */ + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +/* + * This module is used to store NvPatterns and block properties at the end of logical blocks. + * Block properties are used to store arbitrary data of the length defined in fblNvPatternElementLength to memory. + * Block properties can be written once after erasure of the logical block. + * NvPatterns are used to store a boolean value (valid/invalid). They can be set to valid + * several times if the respective value in fblNvPatternMultiplicity is set to > 1. + * + * MEMORY LAYOUT: + * + * |--------------------------------| <-- UPPER END of pattern/property area (usually end of logical block) + * | kFblNvPatternId_First | First NvPattern + * | ... | + * | kFblNvPatternId_Final | + * | kFblNvPatternId_Separator | <-- SEPARATOR between patterns and block properties (do NOT delete this entry) + * | kFblNvProperty_First | First block property + * | ... | + * | kFblNvProperty_Final | + * | kFblNvPatternId_Last | <-- LOWER END of pattern/property area (do NOT delete this entry) + * | | + * + * Note: the actual pattern/block property size is determined by the page size. + * All data elements are aligned to multiples of the page size of the respective device! + */ + +/* PRQA S 0724 TAG_FblNvPatternOem_0724 */ /* MD_FblNvPatternOem_0724_EnumValNotUnique */ +/* Identifiers for patterns and block properties */ +typedef enum +{ + kFblNvPatternId_Invalid = 0u /* do NOT change this entry */ + + /* PartitionValidity (OTA) and ApplValidity (BM) uses the same value */ + ,kFblNvPatternId_PartitionValidity + ,kFblNvPatternId_ApplValidity = kFblNvPatternId_PartitionValidity + + /* ModuleValidity (OTA) and BlockValidity (BM) uses the same value */ + ,kFblNvPatternId_ModuleValidity + ,kFblNvPatternId_BlockValidity = kFblNvPatternId_ModuleValidity +#if defined( FBL_ENABLE_FLASH_ERASED_DETECTION ) + ,kFblNvPatternId_ErasedState +#endif + + FBL_NVPATTERN_USER_PATTERN_ID + +#if defined( FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES ) + ,kFblNvPatternId_Separator /* do NOT delete this entry */ + FBL_NVPATTERN_USER_PROPERTY_ID +#endif /* FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES */ + ,kFblNvPatternId_Last /* do NOT delete this entry */ +} tFblNvPatternId; +/* PRQA L:TAG_FblNvPatternOem_0724 */ + +#if defined( FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES ) +typedef struct +{ + IO_SizeType length; + tFblNvPatternId dependentPattern; +} tFblBlockProperty; +#endif /* FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES */ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBLNVPATTERN_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined ( FBL_NVPATTERN_ENABLE_MULTIPLE_VALIDATION ) +/* PRQA S 3684 1 */ /* MD_FblNvPatternOem_3684 */ +V_MEMROM0 extern V_MEMROM1 vuint8 V_MEMROM2 fblNvPatternMultiplicity[]; +#endif /* FBL_NVPATTERN_ENABLE_MULTIPATTERNS */ + +#if defined( FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES ) +/* PRQA S 3684 1 */ /* MD_FblNvPatternOem_3684 */ +V_MEMROM0 extern V_MEMROM1 tFblBlockProperty V_MEMROM2 fblNvBlockProperties[]; +#endif /* FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES */ + +#define FBLNVPATTERN_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* FBLLIB_NVPATTERN_OEM_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_NVPATTERN_OEM.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_ramio.c b/Source/bsw/Fbl/fbl_ramio.c new file mode 100644 index 0000000..6dce637 --- /dev/null +++ b/Source/bsw/Fbl/fbl_ramio.c @@ -0,0 +1,418 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief RAM driver functions + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2022 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2013-10-23 visjhg - Initial release + * 01.01.00 2015-11-27 visase ESCAN00086297 Allow to override the RAM buffer base address via configuration + * 01.02.00 2016-06-17 visci ESCAN00090364 Added support for flashCode use case + * 01.02.01 2018-03-22 visdkl ESCAN00098872 No changes + * 01.02.02 2021-03-08 vishor ESCAN00108134 Added/adapted MemMap sections + * 01.03.00 2022-03-17 visstn FBL-4366 Perform MISRA 2012 migration + **********************************************************************************************************************/ + +#define FBL_RAMIO_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_ramio_inc.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLWRAPPERFLASH_XRAMHIS_VERSION != 0x0103u ) || \ + ( FBLWRAPPERFLASH_XRAMHIS_RELEASE_VERSION != 0x00u ) +# error "Error in FBL_RAMIO.C: Source and header file are inconsistent!" +#endif + +/*********************************************************************************************************************** + * CONFIGURATION CHECKS + **********************************************************************************************************************/ + +/* Check if buffer size is correctly defined */ +#if defined( RAM_DRV_BUFFER_SIZE ) && ( RAM_DRV_BUFFER_SIZE > 0u ) +#else +# error "Error in FBL_RAMIO.C: Missing or wrong configuration of RAM_DRV_BUFFER_SIZE." +#endif + +/* Check if segment size and buffer size match each other */ +#if defined( RAM_DRV_SEGMENT_SIZE ) +# if ( RAM_DRV_SEGMENT_SIZE > 1u ) +# if ( 0u != (RAM_DRV_BUFFER_SIZE & (RAM_DRV_SEGMENT_SIZE - 1u)) ) +# error "Error in FBL_RAMIO.C: Inconsistent configuration of RAM_DRV_SEGMENT_SIZE and RAM_DRV_BUFFER_SIZE." +# endif +# endif +#endif + +/* Check if segment size has reasonable / supported value */ +#if defined( RAM_DRV_SEGMENT_SIZE ) +# if ( RAM_DRV_SEGMENT_SIZE == 1u ) || ( RAM_DRV_SEGMENT_SIZE == 2u ) || ( RAM_DRV_SEGMENT_SIZE == 4u ) +# else +# error "Error in FBL_RAMIO.C: Wrong configuration of RAM_DRV_SEGMENT_SIZE." +# endif +#endif + +#if defined( RAM_DRV_SEGMENT_SIZE ) && \ + defined( RAM_DRV_BASE_ADDRESS_OVERRIDE ) +/* Check alignment of base address */ +# if ( 0u != (RAM_DRV_BASE_ADDRESS_OVERRIDE & (RAM_DRV_SEGMENT_SIZE - 1u)) ) +# error "Error in FBL_RAMIO.C: Inconsistent configuration of RAM_DRV_SEGMENT_SIZE and RAM_DRV_BASE_ADDRESS_OVERRIDE." +# endif +#endif + +#if defined( RAM_DRV_POLLING_INTERVAL ) +# if ( 0u == RAM_DRV_POLLING_INTERVAL ) || \ + ( 0u != (RAM_DRV_POLLING_INTERVAL & (RAM_DRV_POLLING_INTERVAL - 1u)) ) +# error "Error in FBL_RAMIO.C: Wrong configuration of RAM_DRV_POLLING_INTERVAL (shall be 2^n)." +# endif +#endif + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#if defined( RAM_DRV_EXT_BUFFER ) +# define RAM_DRV_BUFFER RAM_DRV_EXT_BUFFER +#else +# define RAM_DRV_BUFFER g_RamData +#endif + +#if defined( RAM_DRV_BASE_ADDRESS_OVERRIDE ) +/** Allow to override the base address via fbl_ramio_cfg.h, e.g. if RAM_DRV_BUFFER shall be located at an arbitrary address */ +# define RAM_DRV_BASE_ADDRESS RAM_DRV_BASE_ADDRESS_OVERRIDE +#else +/** Base address of accessible RAM area */ +# define RAM_DRV_BASE_ADDRESS ((IO_PositionType)RAM_DRV_BUFFER) +#endif + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#if defined( RAM_DRV_EXT_BUFFER ) +#else +# define FBLRAMIO_START_SEC_VAR +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/** Global data buffer that can be accessed via RamDriver interface */ +V_MEMRAM0 static V_MEMRAM1 IO_U8 V_MEMRAM2 g_RamData[RAM_DRV_BUFFER_SIZE]; + +# define FBLRAMIO_STOP_SEC_VAR +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* RAM_DRV_EXT_BUFFER */ + +#define FBLRAMIO_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ +static IO_ErrorType V_API_NEAR RamDriver_GetOffset( IO_SizeType length, IO_PositionType address, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * pOffset ); + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * RamDriver_GetOffset + **********************************************************************************************************************/ +/*! \brief Get the local buffer offset + * \param[in] length The number of bytes to be modified + * \param[in] address The start address + * \param[out] offset The returned offset + * \return IO_E_OK if succeeded, IO_E_NOT_OK otherwise + **********************************************************************************************************************/ +static IO_ErrorType V_API_NEAR RamDriver_GetOffset( IO_SizeType length, IO_PositionType address, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * pOffset ) +{ + IO_ErrorType result; + IO_SizeType offset; + + result = IO_E_NOT_OK; + + /* Avoid compiler warning (comparison against 0 always true) */ +#if defined( RAM_DRV_BASE_ADDRESS_OVERRIDE ) +# if ( 0u != RAM_DRV_BASE_ADDRESS ) + if (address >= RAM_DRV_BASE_ADDRESS) /* PRQA S 0306 */ /* MD_FblRamio_0306 */ +# endif +#endif + { + offset = address - RAM_DRV_BASE_ADDRESS; /* PRQA S 0306 */ /* MD_FblRamio_0306 */ + + if ( (length <= RAM_DRV_BUFFER_SIZE) + && (offset <= (RAM_DRV_BUFFER_SIZE - length)) ) + { + *pOffset = offset; + result = IO_E_OK; + } + } + + return result; +} + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * RamDriver_InitSync + **********************************************************************************************************************/ +/*! \brief Initialize the RAM algorithm + * \param[in] address Unused parameter for HIS interface compliance + * \return The return code shows the success of the initialization + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +IO_ErrorType V_API_NEAR RamDriver_InitSync( void * address ) +{ + IO_ErrorType result; +#if defined( RAM_DRV_ENABLE_MEM_INIT ) + IO_U32 i; +#endif + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)address; +#endif + + result = IO_E_OK; + +#if defined( RAM_DRV_BASE_ADDRESS_OVERRIDE ) + /* Alignment check executed by preprocessor (see configuration checks section) */ +#else + /* PRQA S 2992, 2996, 0306 1 */ /* MD_FblRamio_2992_2996, MD_FblRamio_2992_2996, MD_FblRamio_0306 */ + if (0u != (RAM_DRV_BASE_ADDRESS & (RAM_DRV_SEGMENT_SIZE - 1u))) + { + /* RAM buffer is not aligned with configured segment size */ + result = IO_E_NOT_OK; + } +#endif /* RAM_DRV_BASE_ADDRESS_OVERRIDE */ + +#if defined( RAM_DRV_ENABLE_MEM_INIT ) + if (IO_E_OK == result) /* PRQA S 2991, 2995 */ /* MD_FblRamio_2991_2995 */ + { + for (i = 0u; i < (RAM_DRV_BUFFER_SIZE / RAM_DRV_SEGMENT_SIZE); i++) + { +# if ( RAM_DRV_SEGMENT_SIZE == 1u ) + ((IO_U8 *)RAM_DRV_BUFFER)[i] = 0u; +# elif ( RAM_DRV_SEGMENT_SIZE == 2u ) + ((IO_U16 *)RAM_DRV_BUFFER)[i] = 0u; /* PRQA S 0310, 3305 */ /* MD_FblRamio_0310_3305 */ +# elif ( RAM_DRV_SEGMENT_SIZE == 4u ) + ((IO_U32 *)RAM_DRV_BUFFER)[i] = 0u; /* PRQA S 0310, 3305 */ /* MD_FblRamio_0310_3305 */ +# endif + +# if defined( RAM_DRV_POLLING_INTERVAL ) + /* PRQA S 2985, 2991, 2995 1 */ /* MD_FblRamio_2985, MD_FblRamio_2991_2995, MD_FblRamio_2991_2995 */ + if (0u == (i & (RAM_DRV_POLLING_INTERVAL - 1u))) + { + RAM_DRV_POLLING_FUNCTION(); + } +# endif /* RAM_DRV_POLLING_INTERVAL */ + } + } +#endif /* RAM_DRV_ENABLE_MEM_INIT */ + + return result; +} + +/*********************************************************************************************************************** + * RamDriver_DeinitSync + **********************************************************************************************************************/ +/*! \brief Deinitialize the RAM algorithm + * \param[in] address Unused parameter for HIS interface compliance + * \return The return code shows the success of the deinitialization + **********************************************************************************************************************/ +IO_ErrorType V_API_NEAR RamDriver_DeinitSync( void * address ) +{ + IO_ErrorType result; + + /* Clean-up memory */ + result = RamDriver_InitSync(address); + + return result; +} + +/*********************************************************************************************************************** + * RamDriver_RWriteSync + **********************************************************************************************************************/ +/*! \brief Program RAM memory + * \param[in] writeBuffer Write data buffer + * \param[in] writeLength Number of bytes to be written + * \param[in] writeAddress The write address + * \return Status of RAM programming + **********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ +IO_ErrorType V_API_NEAR RamDriver_RWriteSync( IO_MemPtrType writeBuffer, IO_SizeType writeLength, IO_PositionType writeAddress ) +{ + IO_ErrorType result; + IO_SizeType offset; + IO_SizeType i; + + result = RamDriver_GetOffset(writeLength, writeAddress, &offset); + + if (IO_E_OK == result) + { + for (i = 0u; i < writeLength; i++) + { +#if defined( RAM_DRV_POLLING_INTERVAL ) + /* PRQA S 2985, 2991, 2995 1 */ /* MD_FblRamio_2985, MD_FblRamio_2991_2995, MD_FblRamio_2991_2995 */ + if (0u == (i & (RAM_DRV_POLLING_INTERVAL - 1u))) + { + RAM_DRV_POLLING_FUNCTION(); + } +#endif /* RAM_DRV_POLLING_INTERVAL */ + + RAM_DRV_BUFFER[offset] = writeBuffer[i]; + offset++; + } + } + + return result; +} + +/*********************************************************************************************************************** + * RamDriver_REraseSync + **********************************************************************************************************************/ +/*! \brief Erase RAM memory + * \pre RAM driver has to be initialized + * \param[in] eraseLength Number of bytes to be erased + * \param[in] eraseAddress The erase address + * \return Status of RAM erase + **********************************************************************************************************************/ +IO_ErrorType V_API_NEAR RamDriver_REraseSync( IO_SizeType eraseLength, IO_PositionType eraseAddress ) +{ +#if defined( RAM_DRV_DELETED ) + IO_ErrorType result; + IO_SizeType offset; + IO_SizeType i; + + result = RamDriver_GetOffset(eraseLength, eraseAddress, &offset); + + if (IO_E_OK == result) + { + for (i = 0u; i < eraseLength; i++) + { +# if defined( RAM_DRV_POLLING_INTERVAL ) + /* PRQA S 2985, 2991, 2995 1 */ /* MD_FblRamio_2985, MD_FblRamio_2991_2995, MD_FblRamio_2991_2995 */ + if (0u == (i & (RAM_DRV_POLLING_INTERVAL - 1u))) + { + RAM_DRV_POLLING_FUNCTION(); + } +# endif /* RAM_DRV_POLLING_INTERVAL */ + + RAM_DRV_BUFFER[offset] = RAM_DRV_DELETED; + offset++; + } + } + + return result; +#else /* ! RAM_DRV_DELETED */ +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)eraseLength; + (void)eraseAddress; +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + return IO_E_OK; +#endif /* ! RAM_DRV_DELETED */ +} + +/*********************************************************************************************************************** + * RamDriver_RReadSync + **********************************************************************************************************************/ +/*! \brief Read RAM memory + * \pre RAM driver has to be initialized + * \param[out] readBuffer Read data buffer + * \param[in] readLength Number of bytes to be read + * \param[in] readAddress The read address + * \return Status of RAM read + **********************************************************************************************************************/ +IO_ErrorType V_API_NEAR RamDriver_RReadSync( IO_MemPtrType readBuffer, IO_SizeType readLength, IO_PositionType readAddress ) +{ + IO_ErrorType result; + IO_SizeType offset; + IO_SizeType i; + + result = RamDriver_GetOffset(readLength, readAddress, &offset); + + if (IO_E_OK == result) + { + for (i = 0u; i < readLength; i++) + { +#if defined( RAM_DRV_POLLING_INTERVAL ) + /* PRQA S 2985, 2991, 2995 1 */ /* MD_FblRamio_2985, MD_FblRamio_2991_2995, MD_FblRamio_2991_2995 */ + if (0u == (i & (RAM_DRV_POLLING_INTERVAL - 1u))) + { + RAM_DRV_POLLING_FUNCTION(); + } +#endif /* RAM_DRV_POLLING_INTERVAL */ + + readBuffer[i] = RAM_DRV_BUFFER[offset]; + offset++; + } + } + + return result; +} + + +#define FBLRAMIO_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* Module specific MISRA deviations: + + MD_FblRamio_0306: + Reason: Address conversion between integer values and pointers is required to allow for hardware independent + configuration and address range checks. + Risk: The size of integer required to hold the result of a pointer cast is implementation defined. + Prevention: The size of the respective integer data type which holds the address value is adapted on a hardware + specific basis. + + MD_FblRamio_0310_3305: + Reason: Pointer is casted as different memory access sizes are utilized due to performance reasons. + Risk: Wrong pointer access is performed. + Prevention: Code inspection and test of the different variants in the component test. + + MD_FblRamio_2985: + Reason: Depending on configuration, RAM_DRV_POLLING_INTERVAL might be zero and thus + i & (RAM_DRV_POLLING_INTERVAL - 1u) might be redundant. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblRamio_2991_2995: + Reason: Depending on configuration, the controlling expression might always be true. This code structure maintains + readbillity. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblRamio_2992_2996: + Reason: Depending on configuration, the controlling expression might always be false. This code structure + maintains readbillity. + Risk: No identifiable risk. + Prevention: No prevention required. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_RAMIO.C + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_ramio.h b/Source/bsw/Fbl/fbl_ramio.h new file mode 100644 index 0000000..6a37445 --- /dev/null +++ b/Source/bsw/Fbl/fbl_ramio.h @@ -0,0 +1,92 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief RAM driver functions + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2022 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2013-10-23 visjhg - Initial release + * 01.01.00 2015-11-27 visase ESCAN00086297 No changes + * 01.02.00 2016-06-17 visci ESCAN00090364 No changes + * 01.02.01 2018-03-22 visdkl ESCAN00098872 No changes + * 01.02.02 2021-03-08 vishor ESCAN00108134 Added/adapted MemMap sections + * 01.03.00 2022-03-17 visstn FBL-4366 Perform MISRA 2012 migration + **********************************************************************************************************************/ + +#ifndef FBL_RAMIO_H +#define FBL_RAMIO_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblWrapperFlash_XRamHis CQComponent : Implementation */ +#define FBLWRAPPERFLASH_XRAMHIS_VERSION 0x0103u +#define FBLWRAPPERFLASH_XRAMHIS_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#define IO_DRIVERMODUS SYNCRON +#define IO_DEVICETYPE RANDOM + +#ifndef V_API_NEAR +# define V_API_NEAR +#endif + +#define RAM_DRIVER_VERSION_MAJOR ((FBLWRAPPERFLASH_XRAMHIS_VERSION >> 8u) & 0xFFu) +#define RAM_DRIVER_VERSION_MINOR ((FBLWRAPPERFLASH_XRAMHIS_VERSION >> 0u) & 0xFFu) +#define RAM_DRIVER_VERSION_PATCH FBLWRAPPERFLASH_XRAMHIS_RELEASE_VERSION + +/* RAM driver properties */ +#if defined( RAM_DRV_SEGMENT_SIZE ) +# define RAM_SEGMENT_SIZE RAM_DRV_SEGMENT_SIZE /**< Smallest writeable segment */ +#endif +#if defined( RAM_DRV_DELETED ) +# define FBL_RAM_DELETED RAM_DRV_DELETED /**< Erase value of RAM memory */ +#endif + +#define RamDriver_GetVersionOfDriver() ((IO_U32)(RAM_DRIVER_VERSION_MAJOR << 16u) | \ + (IO_U32)(RAM_DRIVER_VERSION_MINOR << 8u) | \ + RAM_DRIVER_VERSION_PATCH) + +/*********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLRAMIO_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +IO_ErrorType V_API_NEAR RamDriver_InitSync( void * address); +IO_ErrorType V_API_NEAR RamDriver_DeinitSync( void * address ); +IO_ErrorType V_API_NEAR RamDriver_RReadSync( IO_MemPtrType readBuffer, IO_SizeType readLength, IO_PositionType readAddress ); +IO_ErrorType V_API_NEAR RamDriver_RWriteSync( IO_MemPtrType writeBuffer, IO_SizeType writeLength, IO_PositionType writeAddress ); +IO_ErrorType V_API_NEAR RamDriver_REraseSync( IO_SizeType eraseLength, IO_PositionType eraseAddress ); + +#define FBLRAMIO_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* FBL_RAMIO_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_RAMIO.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_ramio_inc.h b/Source/bsw/Fbl/fbl_ramio_inc.h new file mode 100644 index 0000000..6644f2d --- /dev/null +++ b/Source/bsw/Fbl/fbl_ramio_inc.h @@ -0,0 +1,49 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief RAM driver functions + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2022 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2013-10-23 visjhg - Initial release + * 01.01.00 2015-11-27 visase ESCAN00086297 No changes + * 01.02.00 2016-06-17 visci ESCAN00090364 No changes + * 01.02.01 2018-03-22 visdkl ESCAN00098872 No changes + * 01.02.02 2021-03-08 vishor ESCAN00108134 No changes + * 01.03.00 2022-03-17 visstn FBL-4366 Perform MISRA 2012 migration + **********************************************************************************************************************/ + +#ifndef FBL_RAMIO_INC_H +#define FBL_RAMIO_INC_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "iotypes.h" +#include "fbl_ramio_cfg.h" +#include "fbl_ramio.h" + +#endif /* FBL_RAMIO_INC_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_RAMIO_INC.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_sfr.h b/Source/bsw/Fbl/fbl_sfr.h new file mode 100644 index 0000000..282119e --- /dev/null +++ b/Source/bsw/Fbl/fbl_sfr.h @@ -0,0 +1,112 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Register definitions for AWR1 and AWR2 + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.04.00 2020-12-21 visrie FBL-2517 Added support for AWR1 + * 01.05.00 2021-01-28 visjdn FBL-2824 Added support for TPR12 + * 01.06.00 2021-05-19 visjdn FBL-3038 No changes + * 01.07.00 2021-05-31 visjdn FBL-3545 No changes + * 01.08.00 2021-07-08 visjdn FBL-3694 No changes + * 01.09.00 2021-11-22 vistmo FBL-4275 No changes + * 01.10.00 2022-01-12 visjdn FBL-3720 No changes + * 01.11.00 2022-03-09 visrie FBL-4770 No changes + * 01.12.00 2022-07-18 visjdn FBL-5115 No changes + * 01.13.00 2023-02-09 fmenke FBL-6162 No changes + * ESCAN00113692 No changes + * 01.14.00 2023-04-20 jschmitding FBL-5733 No changes + * 01.15.00 2023-07-12 fmenke FBL-6966 No changes + * 01.16.00 2024-01-01 fmenke FBL-7559 No changes + * ESCAN00116504 No changes + * 01.17.00 2024-09-27 jschmitding FBL-9330 Add support Sitara AM263x + * 01.17.01 2024-10-22 visrie ESCAN00118141 No changes + * 01.18.00 2024-12-02 fmenke FBL-9747 No changes + * 01.19.00 2025-11-19 jostravsky FBL-11077 No changes + **********************************************************************************************************************/ + +#ifndef FBL_SFR_H +#define FBL_SFR_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if defined( FBL_SFR_BASE_ADRESSES_PRECONFIGURED ) +#else +# error "Error in fbl_sfr.h: Please add base addresses for your derivative to the .pcu file." +#endif /* FBL_SFR_BASE_ADRESSES_PRECONFIGURED */ + +/* PRQA S 3453 TAG_SfrDefinitionMacros */ /* MD_MSR_FctLikeMacro */ + +#ifndef FBL_IOS +# define FBL_IOS(type, base, offset) (*((volatile type *)((base) + (offset)))) +#endif + +/* RTI Registers */ +#define FBL_RTI_GCTRL FBL_IOS(vuint32, FBL_RTI_BASE, 0x0000uL) /** RTI Global Control */ +#define FBL_RTI_TBCTRL FBL_IOS(vuint32, FBL_RTI_BASE, 0x0004uL) /** RTI Timebase Control */ +#define FBL_RTI_CAPCTRL FBL_IOS(vuint32, FBL_RTI_BASE, 0x0008uL) /** RTI Capture Control */ +#define FBL_RTI_COMPCTRL FBL_IOS(vuint32, FBL_RTI_BASE, 0x000CuL) /** RTI Compare Control */ +#define FBL_RTI_FRC(x) FBL_IOS(vuint32, FBL_RTI_BASE, 0x0010uL + ((x) * 0x0020uL)) /** RTI Free Running Counter */ +#define FBL_RTI_UC(x) FBL_IOS(vuint32, FBL_RTI_BASE, 0x0014uL + ((x) * 0x0020uL)) /** RTI Up Counter */ +#define FBL_RTI_CPUC(x) FBL_IOS(vuint32, FBL_RTI_BASE, 0x0018uL + ((x) * 0x0020uL)) /** RTI Compare Up Counter */ +#define FBL_RTI_CAFRC(x) FBL_IOS(vuint32, FBL_RTI_BASE, 0x0020uL + ((x) * 0x0020uL)) /** RTI Capture Free Running Counter */ +#define FBL_RTI_CAUC(x) FBL_IOS(vuint32, FBL_RTI_BASE, 0x0024uL + ((x) * 0x0020uL)) /** RTI Capture Up Counter */ +#define FBL_RTI_COMP(x) FBL_IOS(vuint32, FBL_RTI_BASE, 0x0050uL + ((x) * 0x0008uL)) /** RTI Compare */ +#define FBL_RTI_UDCP(x) FBL_IOS(vuint32, FBL_RTI_BASE, 0x0054uL + ((x) * 0x0008uL)) /** RTI Update Compare */ +#define FBL_RTI_INTFLAG FBL_IOS(vuint32, FBL_RTI_BASE, 0x0088uL) /** RTI Interrupt Flag */ +#define FBL_RTI_CMPCLR(x) FBL_IOS(vuint32, FBL_RTI_BASE, 0x00B0uL + ((x) * 0x0004uL)) /** RTI Compare Clear */ + +#define FBL_RTI_TIMER_MS 0u /* Timer used for milliseconds */ +#define FBL_RTI_TIMER_FREE 1u /* Timer used as free running */ +#define FBL_RTI_GCTRL_TIMER_ENABLE 0x00000003uL /* Enable bits for timer 1 and 2 */ +#define FBL_RTI_COMPCTRL_TIMER_SELECT 1uL /* Select bit for Compare0 */ + +/* GPIO handling */ +#if defined( FBL_GIO_BASE ) +# define FBLHW_ENABLE_GPIO_HANDLING +#else +# define FBLHW_DISABLE_GPIO_HANDLING +#endif /* FBL_GIO_BASE */ + +#if defined( FBLHW_ENABLE_GPIO_HANDLING ) +/* GPIO Registers */ +# define FBL_GIO_GCR FBL_IOS(vuint32, FBL_GIO_BASE, 0x0000uL) /** GIO reset */ +# define FBL_GIO_WDN FBL_IOS(vuint32, FBL_GIO_BASE, 0x0004uL) /** GIO power down mode register */ +# define FBL_GIO_DIR(x) FBL_IOS(vuint32, FBL_GIO_BASE, 0x0034uL + ((x) * 0x0020uL)) /** GIO data direction of pins */ +# define FBL_GIO_DIN(x) FBL_IOS(vuint32, FBL_GIO_BASE, 0x0038uL + ((x) * 0x0020uL)) /** GIO data input for pins */ +# define FBL_GIO_DOUT(x) FBL_IOS(vuint32, FBL_GIO_BASE, 0x003CuL + ((x) * 0x0020uL)) /** GIO data output for pins */ +# define FBL_GIO_SET(x) FBL_IOS(vuint32, FBL_GIO_BASE, 0x0040uL + ((x) * 0x0020uL)) /** GIO data set */ +# define FBL_GIO_CLR(x) FBL_IOS(vuint32, FBL_GIO_BASE, 0x0044uL + ((x) * 0x0020uL)) /** GIO data clear */ +# define FBL_GIO_PDR(x) FBL_IOS(vuint32, FBL_GIO_BASE, 0x0048uL + ((x) * 0x0020uL)) /** GIO open drain */ +# define FBL_GIO_PULDIS(x) FBL_IOS(vuint32, FBL_GIO_BASE, 0x004CuL + ((x) * 0x0020uL)) /** GIO pul disable */ +# define FBL_GIO_PSL(x) FBL_IOS(vuint32, FBL_GIO_BASE, 0x0050uL + ((x) * 0x0020uL)) /** GIO pul select */ +#endif /* FBLHW_ENABLE_GPIO_HANDLING */ + +/* PRQA L:TAG_SfrDefinitionMacros */ + +#endif /* FBL_SFR_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_SFR.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_valstruct.c b/Source/bsw/Fbl/fbl_valstruct.c new file mode 100644 index 0000000..1576694 --- /dev/null +++ b/Source/bsw/Fbl/fbl_valstruct.c @@ -0,0 +1,1171 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Implementation of a download check by using an embedded validation structure + * Declaration of functions, variables and constants + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2023 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2016-07-01 visci - Initial version + * 01.01.00 2017-02-03 visci ESCAN00093858 Added support for compatibility check + * vacel Added blank check functionality + * Added API for external public key + * Reworked return value handling + * 01.01.01 2017-11-09 visci ESCAN00096836 Compiler warning: Function declared but not used + * 01.01.02 2018-03-23 visdkl ESCAN00097287 Bootloader does not properly use configuration of CLASS_DDD + * 01.02.00 2018-06-15 visci ESCAN00098963 Corrected return value for public key read failure + * 2018-09-24 visrr ESCAN00100838 Added user callout for different erase values in OTA use case + * 01.03.00 2019-01-25 visci ESCAN00098904 Improved verification sequence + * ESCAN00101065 Alignment for Blank Check is not applied correctly + * ESCAN00101321 Added option to skip download segment check + * 01.03.01 2019-02-06 visci ESCAN00102005 Signature is not taken into account when comparing segments + * 01.04.00 2019-06-14 visci ESCAN00102956 Internal checksum option fails if validation structure is not the + * last segment + * ESCAN00102957 Potential buffer overflow during internal checksum calculation + * 01.05.00 2019-06-25 visdlm ESCAN00103492 Added gap fill mechanism + * 01.05.01 2021-01-18 visjdn ESCAN00107640 Memory read error leads always to invalid format error + * 01.05.02 2021-06-01 vishor ESCAN00109198 The verification key will not be cleared from memory (RAM) after usage + * 01.06.00 2022-04-28 visstn FBL-4366 Perform MISRA 2012 migration + * 01.07.00 2022-10-12 visjdn FBL-5694 Support of Xiaomi validation structure + * 01.08.00 2022-11-25 vistbe FBL-6055 Extend configurability of checksum and signature + * 01.08.01 2023-02-02 vistbe ESCAN00113401 No changes + **********************************************************************************************************************/ + +#define FBL_VALSTRUCT_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" +#include "fbl_valstruct.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLVALSTRUCT_VERSION != 0x0108u ) || \ + ( FBLVALSTRUCT_RELEASE_VERSION != 0x01u ) +# error "Error in fbl_valstruct.c: Source and header file are inconsistent!" +#endif + +#if ( FBLVALSTRUCT_VERSION != _FBLVALSTRUCT_VERSION ) || \ + ( FBLVALSTRUCT_RELEASE_VERSION != _FBLVALSTRUCT_RELEASE_VERSION ) +# error "Error in fbl_valstruct.c: Source and v_ver.h are inconsistent!" +#endif + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#if defined( FBL_ENABLE_VALSTRUCT ) +/*** Validation structure defines ***/ +# define FBL_VALSTRUCT_PROLOG_SIZE (FBL_VALSTRUCT_TAG_SIZE + FBL_VALSTRUCT_VERSION_SIZE + FBL_VALSTRUCT_BLOCKCOUNT_SIZE + FBL_VALSTRUCT_ALFI_SIZE) +# define FBL_VALSTRUCT_BLOCKINFO_SIZE (FBL_VALSTRUCT_BLOCKADDRESS_SIZE + FBL_VALSTRUCT_BLOCKLENGTH_SIZE + FBL_VALSTRUCT_BLOCKCHECKSUM_SIZE) +# define FBL_VALSTRUCT_EPILOG_SIZE (FBL_VALSTRUCT_TAG_SIZE + FBL_VALSTRUCT_VALIDATESUM_SIZE) +# define FBL_VALSTRUCT_MAX_SIZE (FBL_VALSTRUCT_PROLOG_SIZE + (FBL_VALSTRUCT_BLOCKCOUNT_MAX * FBL_VALSTRUCT_BLOCKINFO_SIZE) + FBL_VALSTRUCT_EPILOG_SIZE) + +/* Offset values for validation struct members */ +# define FBL_VALSTRUCT_TAGBEGIN_OFFSET (0x00u) +# define FBL_VALSTRUCT_VERSION_OFFSET (FBL_VALSTRUCT_TAGBEGIN_OFFSET + FBL_VALSTRUCT_TAG_SIZE) +# define FBL_VALSTRUCT_BLOCKCOUNT_OFFSET (FBL_VALSTRUCT_VERSION_OFFSET + FBL_VALSTRUCT_VERSION_SIZE) +# define FBL_VALSTRUCT_ALFI_OFFSET (FBL_VALSTRUCT_BLOCKCOUNT_OFFSET + FBL_VALSTRUCT_BLOCKCOUNT_SIZE) +# define FBL_VALSTRUCT_BLOCKADDRESS_OFFSET(index) (FBL_VALSTRUCT_ALFI_OFFSET + FBL_VALSTRUCT_ALFI_SIZE + ((index) * FBL_VALSTRUCT_BLOCKINFO_SIZE)) +# define FBL_VALSTRUCT_BLOCKLENGTH_OFFSET(index) (FBL_VALSTRUCT_BLOCKADDRESS_OFFSET(index) + FBL_VALSTRUCT_BLOCKADDRESS_SIZE) +# define FBL_VALSTRUCT_BLOCKCHECKSUM_OFFSET(index) (FBL_VALSTRUCT_BLOCKLENGTH_OFFSET(index) + FBL_VALSTRUCT_BLOCKLENGTH_SIZE) +# define FBL_VALSTRUCT_TAGEND_OFFSET(blockcount) (FBL_VALSTRUCT_BLOCKADDRESS_OFFSET(0u) + ((blockcount) * FBL_VALSTRUCT_BLOCKINFO_SIZE)) +# define FBL_VALSTRUCT_VALIDATESUM_OFFSET(blockcount) (FBL_VALSTRUCT_TAGEND_OFFSET(blockcount) + FBL_VALSTRUCT_TAG_SIZE) + +/* Access macros to extract validation struct information from a RAM buffer */ +/* Note: this macro requires that the validation structure is built in big-endian mode! */ +# define FblValStructGetUint32(buffer) FblMemGetInteger(sizeof(vuint32), (buffer)) +# define FblValStructGetUint16(buffer) ((vuint16)(FblMemGetInteger(sizeof(vuint16), (buffer)) & 0xFFFFu)) +# define FblValStructGetUint8(buffer) ((vuint8)(FblMemGetInteger(sizeof(vuint8), (buffer)) & 0xFFu)) +# define FblValStructGetTagBegin(buffer) FblValStructGetUint32(&(buffer)[FBL_VALSTRUCT_TAGBEGIN_OFFSET]) +# define FblValStructGetVersion(buffer) FblValStructGetUint16(&(buffer)[FBL_VALSTRUCT_VERSION_OFFSET]) +# if (FBL_VALSTRUCT_BLOCKCOUNT_SIZE == 1u) +# define FblValStructGetBlockCount(buffer) FblValStructGetUint8(&(buffer)[FBL_VALSTRUCT_BLOCKCOUNT_OFFSET]) +# elif (FBL_VALSTRUCT_BLOCKCOUNT_SIZE == 2u) +# define FblValStructGetBlockCount(buffer) FblValStructGetUint16(&(buffer)[FBL_VALSTRUCT_BLOCKCOUNT_OFFSET]) +# endif +# if (FBL_VALSTRUCT_ALFI_SIZE == 1u) +# define FblValStructGetAlfi(buffer) FblValStructGetUint8(&(buffer)[FBL_VALSTRUCT_ALFI_OFFSET]) +# endif +# define FblValStructGetBlockAddress(buffer, index) FblValStructGetUint32(&(buffer)[FBL_VALSTRUCT_BLOCKADDRESS_OFFSET(index)]) +# define FblValStructGetBlockLength(buffer, index) FblValStructGetUint32(&(buffer)[FBL_VALSTRUCT_BLOCKLENGTH_OFFSET(index)]) +# define FblValStructGetBlockChecksum(buffer, index, cs) (void)MEMCPY(cs, &(buffer)[FBL_VALSTRUCT_BLOCKCHECKSUM_OFFSET(index)], FBL_VALSTRUCT_BLOCKCHECKSUM_SIZE) +# define FblValStructGetTagEnd(buffer, blockcount) FblValStructGetUint32(&(buffer)[FBL_VALSTRUCT_TAGEND_OFFSET(blockcount)]) +# define FblValStructGetValidateSum(buffer, blockcount) FblValStructGetUint16(&(buffer)[FBL_VALSTRUCT_VALIDATESUM_OFFSET(blockcount)]) + +/* Calculate the actual size of the validation structure based on the given block count */ +# define FblValStructGetTotalSize(blockcount) (FBL_VALSTRUCT_PROLOG_SIZE + ((blockcount) * FBL_VALSTRUCT_BLOCKINFO_SIZE) + FBL_VALSTRUCT_EPILOG_SIZE) + +/* Macros used to retrieve the requested ValStruct processing options */ +# define FblValStructOptionChecksumInternal(opt) (((opt) & FBL_VALSTRUCT_OPTION_CHECKSUM_INTERNAL) == FBL_VALSTRUCT_OPTION_CHECKSUM_INTERNAL) +# define FblValStructOptionBlankCheck(opt) (((opt) & FBL_VALSTRUCT_OPTION_BLANKCHECK) == FBL_VALSTRUCT_OPTION_BLANKCHECK) +# define FblValStructOptionGapFill(opt) (((opt) & FBL_VALSTRUCT_OPTION_GAP_FILL) == FBL_VALSTRUCT_OPTION_GAP_FILL) + +/* Configuration specific definition of output buffer size for verification */ +# if defined( SEC_ENABLE_SECURITY_CLASS_DDD ) +# if defined( SEC_ENABLE_CRC_WRITTEN_CLASS_DDD ) +# define FBL_VALSTRUCT_VERIFY_SIZE (FBL_VALSTRUCT_BLOCKCHECKSUM_SIZE + SEC_SIZE_CHECKSUM_CRC) +# else +# define FBL_VALSTRUCT_VERIFY_SIZE (FBL_VALSTRUCT_BLOCKCHECKSUM_SIZE) +# endif +# endif + +# if !defined( FBL_VALSTRUCT_GAP_FILL_SEGMENTATION ) +# if defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) +# define FBL_VALSTRUCT_GAP_FILL_SEGMENTATION FBL_MAX_SEGMENT_SIZE +# endif /* FBL_VALSTRUCT_ENABLE_GAP_FILL */ +# endif + +/* If signature support is not explictily enabled or disabled set it based on the security class */ +# if !defined( FBL_VALSTRUCT_ENABLE_SIGNATURE ) && !defined( FBL_VALSTRUCT_DISABLE_SIGNATURE ) +# if (SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC) +# define FBL_VALSTRUCT_ENABLE_SIGNATURE +# endif /* SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC */ +# endif /* !FBL_VALSTRUCT_ENABLE_SIGNATURE */ + +# if defined( FBL_VALSTRUCT_ENABLE_SIGNATURE ) && defined( FBL_VALSTRUCT_ENABLE_EXTERNAL_KEY ) +# if !defined( FblValStructClrPublicKey ) +# define FblValStructClrPublicKey(x) +# endif /* FblValStructClrPublicKey */ +# endif /* SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC */ +#endif /* FBL_ENABLE_VALSTRUCT */ + +/* Evaluate size of common buffer which is used for memory read/write operations. */ +#if !defined( FBL_VALSTRUCT_READ_BUFFER_SIZE ) +# if defined( FBL_ENABLE_VALSTRUCT ) +# if ((defined(FBL_VALSTRUCT_ENABLE_SIGNATURE)) && (FBL_VALSTRUCT_SIGNATURE_SIZE > FBL_VALSTRUCT_MAX_SIZE)) + /* Set buffer size to signature size */ +# define FBL_VALSTRUCT_READ_BUFFER_SIZE FBL_VALSTRUCT_SIGNATURE_SIZE +# else + /* Set buffer size to maximum possible size of validation structure */ + # define FBL_VALSTRUCT_READ_BUFFER_SIZE FBL_VALSTRUCT_MAX_SIZE +# endif +# endif /* FBL_ENABLE_VALSTRUCT */ +#endif + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +#if defined( FBL_ENABLE_VALSTRUCT ) +typedef struct +{ + vuintx alignDummy; + vuint8 data[FBL_VALSTRUCT_READ_BUFFER_SIZE]; +} tAlignedReadBuffer; + +/** Structure which keeps segment information */ +typedef tDiagSegmentList tVsSegInfo; + +/** Structure which keeps information about/from the validation structure */ +typedef struct +{ + tFblAddress address; /**< Start address of validation structure */ + tFblLength length; /**< Total length of validation structure */ + tVsSegInfo segInfo; /**< Segment information contained in validation structure */ + vuint8 vsSeg; /**< Index of segment which keeps the validation structure */ +} tVsInfo; +#endif /* FBL_ENABLE_VALSTRUCT */ + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +#if defined( FBL_ENABLE_VALSTRUCT ) +# define FBL_VALSTRUCT_START_SEC_VAR +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +V_MEMRAM0 static V_MEMRAM1 tAlignedReadBuffer V_MEMRAM2 readBuffer; /* PRQA S 3218 */ /* MD_FblValStruct_3218 */ +# if defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) +V_MEMRAM0 static V_MEMRAM1 vuint8 V_MEMRAM2 gapFillBuffer[FBL_VALSTRUCT_GAP_FILL_SEGMENTATION]; +# endif /* FBL_VALSTRUCT_ENABLE_GAP_FILL */ +# define FBL_VALSTRUCT_STOP_SEC_VAR +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBL_ENABLE_VALSTRUCT */ + +/*********************************************************************************************************************** + * PROTOTYPES + **********************************************************************************************************************/ + +#if defined( FBL_ENABLE_VALSTRUCT ) +# define FBL_VALSTRUCT_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +# if ( FBL_VALSTRUCT_VALIDATESUM_SIZE > 0u ) +static vuint16 FblValStructCalculateByteChecksum( const vuint8* address, tFblLength size ); +# endif +static tFblValStructResult FblValStructGetSegmentInfo( tVsInfo * vsInfo ); +static void FblValStructRemoveStructSegment( const tVsInfo * vsInfo, tDiagSegmentList * blockSegInfo ); +# if defined ( FBL_VALSTRUCT_ENABLE_SIGNATURE ) +static tFblValStructResult FblValStructVerification( const tVsInfo * vsInfo, + SecM_ByteType * verifyData ); +# endif /* FBL_VALSTRUCT_ENABLE_SIGNATURE */ +# if defined( FBL_VALSTRUCT_ENABLE_CHECKSUM_INTERNAL ) +static void FblValStructLocateStructSegment( tVsInfo * vsInfo ); +static tFblValStructResult FblValStructChecksumInternal( tVsInfo * vsInfo, + tDiagSegmentList * blockSegInfo ); +# endif +static tFblValStructResult FblValStructChecksumExternal( const tBlockDescriptor * blockDescriptor, + tVsInfo * vsInfo, + tDiagSegmentList * blockSegInfo); +static tFblValStructResult FblValStructCompareSegmentLocation( tVsInfo * vsInfo, + const tDiagSegmentList * blockSegInfo); +static tFblValStructResult FblValStructCompareSegmentChecksum( const tVsSegInfo * vsSegInfo, + const tDiagSegmentList * blockSegInfo ); +# if defined( FBL_VALSTRUCT_ENABLE_BLANK_CHECK ) +static tFblValStructResult FblValStructBlankCheck( tFblAddress memAddress, tFblLength memLength ); +# endif /* FBL_VALSTRUCT_ENABLE_BLANK_CHECK */ + +# if defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) +static tFblValStructResult FblValStructGapFill( tFblAddress memAddress, tFblLength memLength ); +# endif /* FBL_VALSTRUCT_ENABLE_GAP_FILL */ + +# if defined( FBL_VALSTRUCT_ENABLE_BLANK_CHECK ) || \ + defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) +static tFblAddress FblValStructSkipFilledArea( tFblAddress address, vsint16 memSeg ); +static tFblValStructResult FblValStructGapProcessing( const tBlockDescriptor * blockDescriptor, + const tDiagSegmentList * blockSegInfo ); +# endif +# define FBL_VALSTRUCT_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBL_ENABLE_VALSTRUCT */ + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +#if defined( FBL_ENABLE_VALSTRUCT ) +# define FBL_VALSTRUCT_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +# if ( FBL_VALSTRUCT_VALIDATESUM_SIZE > 0u ) +/*********************************************************************************************************************** + * FblValStructCalculateByteChecksum + **********************************************************************************************************************/ +/*! \brief Calculate a 16-bit sized byte checksum over the buffer content. + * \param[in] address Pointer to data buffer in RAM + * \param[in] size Size of data in buffer + * \return Calculated checksum value + **********************************************************************************************************************/ +static vuint16 FblValStructCalculateByteChecksum( const vuint8 * address, tFblLength size ) +{ + const vuint8 * bytePtr = address; + vuint16 byteChecksum = 0u; + + while (bytePtr < (&address[size])) + { + byteChecksum += *bytePtr; + bytePtr = &bytePtr[1u]; + + /* Keep up bootloader timing and watchdog service */ + if (((tFblAddress)bytePtr & 0xFu) == 0u) /* PRQA S 0306 */ /* MD_FblValStruct_0306 */ + { + /* Call service function every 16th loop cycle */ + (void)FblLookForWatchdog(); + } + } + + return byteChecksum; +} +# endif /* FBL_VALSTRUCT_VALIDATESUM_SIZE > 0u */ + +/*********************************************************************************************************************** + * FblValStructGetSegmentInfo + **********************************************************************************************************************/ +/*! \brief Check presence and integrity of the validation structure and extract the segment information. + * \param[in,out] vsInfo Start address (in) and length (out) of validation structure, segment information (out) + * \return kFblValStructOk = validation structure has been read successfully + * other value = reading of validation structure failed + **********************************************************************************************************************/ +/* PRQA S 6010, 6030 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC */ +static tFblValStructResult FblValStructGetSegmentInfo( tVsInfo * vsInfo ) +{ + tFblValStructResult result; + tFblLength vsTotalSize; + vuint16 segIndex, vsSegCount; +# if ( FBL_VALSTRUCT_VALIDATESUM_SIZE > 0u ) + vuint16 validateSum; +# endif + + /* Initialize return value */ + result = kFblValStructOk; + + /* Initialize total size */ + vsTotalSize = 0u; + + /* Read begin tag, version and block count of validation structure */ + if (FblReadProm(vsInfo->address, readBuffer.data, FBL_VALSTRUCT_PROLOG_SIZE) != FBL_VALSTRUCT_PROLOG_SIZE) + { + /* Memory read error (e.g. invalid memory region) */ + result = kFblValStructMemoryReadError; + } + +# if ( FBL_VALSTRUCT_TAG_SIZE > 0u ) + if (kFblValStructOk == result) + { + /* Check begin tag */ + if (FblValStructGetTagBegin(readBuffer.data) != FBL_VALSTRUCT_TAGBEGIN_PATTERN) + { + /* Begin tag invalid */ + result = kFblValStructInvalidFormat; + } + } +# endif + +# if ( FBL_VALSTRUCT_VERSION_SIZE > 0u ) + if (kFblValStructOk == result) + { + /* Check if structure version is supported */ + if (FblValStructIsVersionSupported(FblValStructGetVersion(readBuffer.data)) != kFblValStructOk) + { + /* Begin tag invalid */ + result = kFblValStructInvalidFormat; + } + } +# endif + + if (kFblValStructOk == result) + { + /* Check block count */ + vsSegCount = FblValStructGetBlockCount(readBuffer.data); + if (vsSegCount <= FBL_VALSTRUCT_BLOCKCOUNT_MAX) + { + vsInfo->segInfo.nrOfSegments = (vuint8)vsSegCount; + } + else + { + /* Maximum block count exceeded */ + result = kFblValStructInvalidFormat; + } + } + +# if (FBL_VALSTRUCT_ALFI_SIZE == 1u) + if (kFblValStructOk == result) + { + /* Check ALFI */ + if (FblValStructGetAlfi(readBuffer.data) != (FBL_VALSTRUCT_BLOCKADDRESS_SIZE + (FBL_VALSTRUCT_BLOCKLENGTH_SIZE << 4u))) + { + /* ALFI is invalid */ + result = kFblValStructInvalidFormat; + } + } +# endif + + if (kFblValStructOk == result) + { + /* Calculate total validation struct size */ + vsTotalSize = FblValStructGetTotalSize((vuint32) vsInfo->segInfo.nrOfSegments); /* PRQA S 2985 */ /* MD_FblValStruct_2985 */ + + /* Block count value OK, read the rest of the validation structure */ + if (FblReadProm((vsInfo->address + FBL_VALSTRUCT_PROLOG_SIZE), + &(readBuffer.data[FBL_VALSTRUCT_PROLOG_SIZE]), + (vsTotalSize - FBL_VALSTRUCT_PROLOG_SIZE)) != (vsTotalSize - FBL_VALSTRUCT_PROLOG_SIZE)) + { + /* Memory read error (e.g. invalid memory region) */ + result = kFblValStructMemoryReadError; + } + } + +# if ( FBL_VALSTRUCT_TAG_SIZE > 0u ) + if (kFblValStructOk == result) + { + /* Check end tag */ + if (FblValStructGetTagEnd(readBuffer.data, vsInfo->segInfo.nrOfSegments) != FBL_VALSTRUCT_TAGEND_PATTERN) + { + /* End tag invalid */ + result = kFblValStructInvalidFormat; + } + } +# endif + +# if ( FBL_VALSTRUCT_VALIDATESUM_SIZE > 0u ) + if (kFblValStructOk == result) + { + /* Check integrity of validation structure (verify byte checksum) */ + validateSum = FblValStructCalculateByteChecksum(readBuffer.data, (vsTotalSize - FBL_VALSTRUCT_VALIDATESUM_SIZE)); + if (validateSum != FblValStructGetValidateSum(readBuffer.data, vsInfo->segInfo.nrOfSegments)) + { + /* Validation information corrupt */ + result = kFblValStructInvalidFormat; + } + } +# endif + + if (kFblValStructOk == result) + { + /* Extract block information. This separate step ensures correct data */ + /* interpretation regardless of endianess and structure alignment. */ + for (segIndex = 0; segIndex < vsInfo->segInfo.nrOfSegments; segIndex++) + { + vsInfo->segInfo.segmentInfo[segIndex].targetAddress = FblValStructGetBlockAddress(readBuffer.data, segIndex); + vsInfo->segInfo.segmentInfo[segIndex].length = FblValStructGetBlockLength(readBuffer.data, segIndex); + /* PRQA S 0314 1 */ /* MD_FblValStruct_0314 */ + FblValStructGetBlockChecksum(readBuffer.data, segIndex, vsInfo->segInfo.segmentInfo[segIndex].checksum); + } + } + + /* Return total length of structure */ + vsInfo->length = vsTotalSize; + + return result; +} + +/*********************************************************************************************************************** + * FblValStructRemoveStructSegment + **********************************************************************************************************************/ +/*! \brief Determine download segment which keeps the validation structure and remove it from the list + * \pre vsInfo->vsSeg has to be set before (validation structure segment) + * \param[in] vsInfo Structure which keeps information about validation structure (out: vsSeg) + * \param[in,out] blockSegInfo Output segment list which contains the newly calculated checksum values + * \return kFblValStructOk = validation structure identified and removed + * other value = validation structure not found + **********************************************************************************************************************/ +static void FblValStructRemoveStructSegment( const tVsInfo * vsInfo, tDiagSegmentList * blockSegInfo ) +{ + vuint8 segIdx; + + /* Remove ValStruct segment from list */ + for (segIdx = vsInfo->vsSeg + 1u; segIdx < blockSegInfo->nrOfSegments; segIdx++) + { + blockSegInfo->segmentInfo[segIdx - 1u] = blockSegInfo->segmentInfo[segIdx]; + } + + /* Fix number of segments */ + blockSegInfo->nrOfSegments--; +} + +# if defined( FBL_VALSTRUCT_ENABLE_SIGNATURE ) +/*********************************************************************************************************************** + * FblValStructVerification + **********************************************************************************************************************/ +/*! \brief The flash memory content is verified according to the configured CCC algorithm + * \param[in] vsInfo Structure which keeps information about validation structure + * \param[in] verifyData Input buffer which keeps the signature data for comparison with the calculated value + * \return kFblValStructOk = Authentication succeeded + * other value = Authentication failed (or memory access error) + **********************************************************************************************************************/ +static tFblValStructResult FblValStructVerification( const tVsInfo * vsInfo, SecM_ByteType * verifyData ) +{ +# if defined( FBL_VALSTRUCT_ENABLE_EXTERNAL_KEY ) + SecM_AsymKeyType publicKey; +# endif + SecM_VerifyParamType verifyParam; + FL_SegmentInfoType verifySegmentInfo[1u]; + SecM_StatusType secStatus; + tFblValStructResult result; + + result = kFblValStructOk; + + /* Configure segment which shall be verified */ + verifySegmentInfo[0u].targetAddress = vsInfo->address; + verifySegmentInfo[0u].transferredAddress = verifySegmentInfo[0u].targetAddress; + verifySegmentInfo[0u].length = vsInfo->length; + verifyParam.segmentList.segmentInfo = verifySegmentInfo; + verifyParam.segmentList.nrOfSegments = 1u; + verifyParam.blockStartAddress = verifySegmentInfo[0u].targetAddress; + verifyParam.blockLength = verifySegmentInfo[0u].length; + verifyParam.verificationData = verifyData; + verifyParam.wdTriggerFct = (FL_WDTriggerFctType)FblRealTimeSupport; /* PRQA S 0313 */ /* MD_FblValStruct_0313_WDTriggerFctType */ + verifyParam.readMemory = (FL_ReadMemoryFctType)FblReadProm; +# if defined( FBL_VALSTRUCT_ENABLE_EXTERNAL_KEY ) + publicKey.shared.size = sizeof(SecM_RsaMod); + publicKey.individual.size = sizeof(SecM_RsaExp); + + if (kFblOk == FblValStructGetPublicKey(&publicKey)) + { + verifyParam.key = &publicKey; /* PRQA S 0315 */ /* MD_FblValStruct_0315 */ + } + else + { + /* An error occured and the key was not able to be retrieved */ + result = kFblValStructKeyError; + } +# else + /* Use the internal key */ + verifyParam.key = SEC_VERIFY_KEY_NULL; +# endif /* FBL_VALSTRUCT_ENABLE_EXTERNAL_KEY */ + + if (kFblValStructOk == result) /* PRQA S 2991, 2995 */ /* MD_FblValStruct_2991_2995 */ + { + /* Perform hash calculation and compare with decrypted signature */ + secStatus = FblValStructSignatureVerification(&verifyParam); + if (SECM_VER_OK != secStatus) + { + /* An error occurred during signature verification or the signature check failed */ + result = kFblValStructNotAuthentic; + } + } +# if defined( FBL_VALSTRUCT_ENABLE_EXTERNAL_KEY ) + FblValStructClrPublicKey(&publicKey); +# endif /* FBL_VALSTRUCT_ENABLE_EXTERNAL_KEY */ + + return result; +} +# endif /* FBL_VALSTRUCT_ENABLE_SIGNATURE */ + +# if defined( FBL_VALSTRUCT_ENABLE_CHECKSUM_INTERNAL ) +/*********************************************************************************************************************** + * FblValStructLocateStructSegment + **********************************************************************************************************************/ +/*! \brief Locate the position of the validation structure in the segment list of the validation structure + * \param[in,out] vsInfo Structure which keeps information about validation structure (out: vsSeg) + **********************************************************************************************************************/ +static void FblValStructLocateStructSegment( tVsInfo * vsInfo ) +{ + vuint8 segIdx; + vuint8 vsFound; + + /* Locate validation structure segment in segment list */ + segIdx = vsInfo->segInfo.nrOfSegments; + vsFound = 0u; + while (segIdx > 0u) + { + segIdx--; + if (vsInfo->address > vsInfo->segInfo.segmentInfo[segIdx].targetAddress) + { + /* Validation structure located above the current segment */ + vsInfo->vsSeg = segIdx + 1u; + vsFound = 1u; + break; + } + } + + if (vsFound == 0u) + { + /* Validation structure must be located in front of the first entry */ + vsInfo->vsSeg = 0u; + } +} + +/*********************************************************************************************************************** + * FblValStructChecksumInternal + **********************************************************************************************************************/ +/*! \brief Calculate the checksum (or CRC/hash) values for all segments in the validation structure + * \param[in,out] vsInfo Structure which keeps information about validation structure (out: vsSeg) + * \param[in,out] blockSegInfo Output segment list which contains the newly calculated checksum values + * \return kFblValStructOk = Checksum calculation successfully finished, information in blockSegInfo is valid + * other value = Error during checksum calculation, information in blockSegInfo is not valid + **********************************************************************************************************************/ +static tFblValStructResult FblValStructChecksumInternal( tVsInfo * vsInfo, tDiagSegmentList * blockSegInfo ) +{ + static SecM_ByteType verifyOutputBuf[FBL_VALSTRUCT_VERIFY_SIZE]; + tFblValStructResult result; + SecM_VerifyParamType localVerifyParam; + FL_SegmentInfoType verifySegmentInfo[1]; + vuint8 segIdx; + vuint8 vsInserted; + + result = kFblValStructOk; + + /* Locate validation structure segment (required for blank check!) */ + FblValStructLocateStructSegment(vsInfo); + + /* Add one segment for validation structure */ + blockSegInfo->nrOfSegments = vsInfo->segInfo.nrOfSegments + 1u; + + /* Iterate over all segments which are defined in the validation structure */ + vsInserted = 0u; + for (segIdx = 0u; segIdx < blockSegInfo->nrOfSegments; segIdx++) + { + if (segIdx == vsInfo->vsSeg) + { + /* Insert validation structure */ + blockSegInfo->segmentInfo[segIdx].targetAddress = vsInfo->address; + blockSegInfo->segmentInfo[segIdx].length = vsInfo->length; + vsInserted = 1u; + } + else + { + /* Copy address/length information */ + blockSegInfo->segmentInfo[segIdx].targetAddress = vsInfo->segInfo.segmentInfo[segIdx - vsInserted].targetAddress; + blockSegInfo->segmentInfo[segIdx].length = vsInfo->segInfo.segmentInfo[segIdx - vsInserted].length; + } + + /* Prepare input data for checksum calculation */ + verifySegmentInfo[0].length = blockSegInfo->segmentInfo[segIdx].length; + verifySegmentInfo[0].targetAddress = blockSegInfo->segmentInfo[segIdx].targetAddress; + verifySegmentInfo[0].transferredAddress = blockSegInfo->segmentInfo[segIdx].targetAddress; + localVerifyParam.segmentList.nrOfSegments = 1u; + localVerifyParam.segmentList.segmentInfo = verifySegmentInfo; + localVerifyParam.verificationData = verifyOutputBuf; + localVerifyParam.crcTotal = 0u; + localVerifyParam.wdTriggerFct = (FL_WDTriggerFctType)FblRealTimeSupport; /* PRQA S 0313 */ /* MD_FblValStruct_0313_WDTriggerFctType */ + localVerifyParam.readMemory = (FL_ReadMemoryFctType)FblReadProm; + + /* Do checksum verification */ + if (FblValStructChecksumVerification(&localVerifyParam) == SECM_VER_OK) + { + /* Copy checksum into segment list */ + (void)MEMCPY(blockSegInfo->segmentInfo[segIdx].checksum, /* PRQA S 0314 */ /* MD_FblValStruct_0314 */ + &verifyOutputBuf[FBL_VALSTRUCT_BLOCKCHECKSUM_VERIFY_OFFSET], + FBL_VALSTRUCT_BLOCKCHECKSUM_SIZE); + } + else + { + result = kFblValStructMemoryReadError; + break; + } + } + + return result; +} +# endif /* FBL_VALSTRUCT_ENABLE_CHECKSUM_INTERNAL */ + +/*********************************************************************************************************************** + * FblValStructChecksumExternal + **********************************************************************************************************************/ +/*! \brief Request segment information from external instance and check against validation structure + * \param[in] blockDescriptor Block descriptor structure + * \param[in,out] vsInfo Structure which keeps information about validation structure + * \param[in,out] blockSegInfo Download segment list + * \return kFblValStructOk = Passed segment information matches the information in the validation structure + * other value = Invalid number of segments passed or segment locations don't match + **********************************************************************************************************************/ +/* PRQA S 3673 3 */ /* MD_MSR_Rule8.13 */ +static tFblValStructResult FblValStructChecksumExternal( const tBlockDescriptor * blockDescriptor, + tVsInfo * vsInfo, + tDiagSegmentList * blockSegInfo ) +{ + tFblValStructResult result; + +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameter not used (configuration dependent): avoid compiler warning */ + (void)blockDescriptor; /* PRQA S 3112 */ /* MD_MSR_DummyStmt */ +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + /* Get download segments which are associated with this logical block */ + (void)FblValStructGetSegmentList(blockDescriptor->blockNr, blockSegInfo); + + /* Check the amount of segments which have been downloaded */ + if (blockSegInfo->nrOfSegments == (vsInfo->segInfo.nrOfSegments + 1u)) + { + /* Number of downloaded segments (excluding the ValStruct segment) matches the number in the ValStruct */ + result = FblValStructCompareSegmentLocation(vsInfo, blockSegInfo); + } + else + { + /* Mismatch between number of downloaded segments and blocks in validation structure; abort verification */ + result = kFblValStructBlockNumberMismatch; + } + + return result; +} + +/*********************************************************************************************************************** + * FblValStructCompareSegmentLocation + **********************************************************************************************************************/ +/*! \brief Compare the segment information from download and validation structure, remove ValStruct from list + * \param[in,out] vsInfo Structure which keeps information about validation structure (out: vsSeg) + * \param[in] blockSegInfo Download segment list + * \return kFblValStructOk = all segments are identical + * other value = address or length differences detected + **********************************************************************************************************************/ +static tFblValStructResult FblValStructCompareSegmentLocation( tVsInfo * vsInfo, + const tDiagSegmentList * blockSegInfo) +{ + tFblValStructResult result; + vuint8 segIdx, vsFound; + + result = kFblValStructOk; + vsInfo->vsSeg = 0u; + vsFound = 0u; + + for (segIdx = 0u; segIdx < blockSegInfo->nrOfSegments; segIdx++) + { + /* Check address and length against block info in validation structure */ + if ((blockSegInfo->segmentInfo[segIdx].targetAddress != vsInfo->segInfo.segmentInfo[segIdx - vsFound].targetAddress) || + (blockSegInfo->segmentInfo[segIdx].length != vsInfo->segInfo.segmentInfo[segIdx - vsFound].length)) + { + /* Check if the mismatch is caused by the segment which keeps the validation structure */ + if ((vsFound == 0u) && (blockSegInfo->segmentInfo[segIdx].targetAddress == vsInfo->address)) + { + if (blockSegInfo->segmentInfo[segIdx].length == vsInfo->length) + { + /* Validation structure segment found */ + vsInfo->vsSeg = segIdx; + vsFound = 1u; + } + else + { + /* Invalid length of validation structure */ + result = kFblValStructInvalidFormat; + } + } + else + { + /* Address/or length mismatch between download and validation structure */ + result = kFblValStructBlockMismatch; + } + } + + if (result != kFblValStructOk) + { + break; + } + } + + return result; +} + +/*********************************************************************************************************************** + * FblValStructCompareSegmentChecksum + **********************************************************************************************************************/ +/*! \brief Compare the segment information from download and validation structure + * \param[in] vsSegInfo Segment list from validation structure + * \param[in] blockSegInfo Download segment list + * \return kFblValStructOk = all segments are identical + * other value = checksum differences detected + **********************************************************************************************************************/ +static tFblValStructResult FblValStructCompareSegmentChecksum( const tVsSegInfo * vsSegInfo, const tDiagSegmentList * blockSegInfo ) +{ + tFblValStructResult result; + vuint8 segIdx, csIdx; + + result = kFblValStructOk; + + for (segIdx = 0; segIdx < vsSegInfo->nrOfSegments; segIdx++) + { + /* Compare calculated checksum/hash with value from validation structure */ + for (csIdx = 0; csIdx < FBL_VALSTRUCT_BLOCKCHECKSUM_SIZE; csIdx++) + { + if (vsSegInfo->segmentInfo[segIdx].checksum[csIdx] != blockSegInfo->segmentInfo[segIdx].checksum[csIdx]) + { + /* Checksum values differ, abort verification */ + result = kFblValStructChecksumValueMismatch; + break; + } + } + } + + return result; +} + +# if defined( FBL_VALSTRUCT_ENABLE_BLANK_CHECK ) +/*********************************************************************************************************************** + * FblValStructBlankCheck + **********************************************************************************************************************/ +/*! \brief Check whether the given memory area is erased (contains the respective erased value) + * \param[in] memAddress Start address of the memory area + * \param[in] memLength Length of the memory area + * \return kFblValStructOk = inter-segment memory areas are in state 'erased' + * kFblValStructBlankCheckFailed = non-erased memory area detected + **********************************************************************************************************************/ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +static tFblValStructResult FblValStructBlankCheck( tFblAddress memAddress, tFblLength memLength ) +{ + tFblValStructResult result; + tFblLength readLength; + IO_ErrorType memDrvResult; + vuint16 bufIdx; + vuint8 erasedVal; + tFblAddress localMemAddress = memAddress; + tFblLength localMemLength = memLength; + + /* Note: By definition, a logical block must be homogeneous (single memory device) and contiguous (no gaps) */ + memSegment = FblMemSegmentNrGet(localMemAddress); + + if (memSegment >= 0) + { + result = kFblValStructOk; + erasedVal = memDrvLst[FlashBlock[memSegment].device].erasedValue; + + while ((localMemLength > 0u) && (kFblValStructOk == result)) + { + readLength = (localMemLength >= FBL_VALSTRUCT_READ_BUFFER_SIZE) ? FBL_VALSTRUCT_READ_BUFFER_SIZE : localMemLength; + memDrvResult = MemDriver_RReadSync(readBuffer.data, readLength, localMemAddress); + + if ((IO_E_OK == memDrvResult) || (IO_E_ERASED == memDrvResult)) + { + for (bufIdx = 0u; bufIdx < readLength; bufIdx++) + { + /* Check if the pattern is in its initial state (i. e. the memory at the + pattern address is erased) */ + if (readBuffer.data[bufIdx] != (vuint8)erasedVal) + { + /* Memory content has been modified - return with negative result */ + result = kFblValStructBlankCheckFailed; + break; + } + } + + localMemAddress += readLength; + localMemLength -= readLength; + } + else + { + /* Failure reported by read function */ + result = kFblValStructBlankCheckFailed; + } + } + } + else + { + /* Invalid memory segment */ + result = kFblValStructBlankCheckFailed; + } + + return result; +} +# endif /* FBL_VALSTRUCT_ENABLE_BLANK_CHECK */ + +# if defined ( FBL_VALSTRUCT_ENABLE_GAP_FILL ) +/*********************************************************************************************************************** + * FblValStructGapFill + **********************************************************************************************************************/ +/*! \brief Fill gaps between programmed segments with kFillChar + * \param[in] memAddress Start address of the memory area + * \param[in] memLength Length of the memory area + * \return kFblValStructOk = inter-segment memory areas are filled successfully + * kFblValStructGapFillFailed = gap filling failed + **********************************************************************************************************************/ +static tFblValStructResult FblValStructGapFill(tFblAddress memAddress, tFblLength memLength) +{ + tFblValStructResult result; + tFblLength writeLength; + tFblAddress localMemAddress = memAddress; + tFblLength localMemLength = memLength; + + result = kFblValStructOk; + + while (localMemLength > 0u) + { + writeLength = (localMemLength >= FBL_VALSTRUCT_GAP_FILL_SEGMENTATION) ? FBL_VALSTRUCT_GAP_FILL_SEGMENTATION : localMemLength; + + if (kFblMemStatus_Ok == FblMemProgramBuffer(localMemAddress, &writeLength, gapFillBuffer)) + { + localMemAddress += writeLength; + localMemLength -= writeLength; + } + else + { + result = kFblValStructGapFillFailed; + break; + } + } + + return result; +} +# endif /* FBL_VALSTRUCT_ENABLE_GAP_FILL */ + +# if defined( FBL_VALSTRUCT_ENABLE_BLANK_CHECK ) || \ + defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) +/*********************************************************************************************************************** + * FblValStructSkipFilledArea + **********************************************************************************************************************/ +/*! \brief Skip memory area at segment end which has been filled with kFillChar + * \param[in] address Start address of the memory area + * \param[in] memSeg Index of memory segment in flash block table which relates to the specified address + * \return Aligned address + **********************************************************************************************************************/ +static tFblAddress FblValStructSkipFilledArea( tFblAddress address, vsint16 memSeg ) +{ + vuint16 segSize; + tFblLength unalignedLength; + tFblAddress alignedAddress = address; + + /* Retrieve write segment size of the respective memory device */ + segSize = memDrvLst[FlashBlock[memSeg].device].segmentSize; + + /* ESCAN00101065: Check alignment of read address */ + if ((address & (segSize - 1uL)) != 0uL) + { + /* Skip data which has been filled with kFillChar */ + unalignedLength = segSize - (address & (segSize - 1uL)); + alignedAddress += unalignedLength; + } + + return alignedAddress; +} + +/*********************************************************************************************************************** + * FblValStructGapProcessing + **********************************************************************************************************************/ +/*! \brief Depending on the configuration either blank check or gap filling will be executed + * \param[in] blockDescriptor Block descriptor structure + * \param[in] blockSegInfo Download segment list + * \return kFblValStructOk = processing successfully performed + * other value = either blank check or gap filling failed + **********************************************************************************************************************/ +static tFblValStructResult FblValStructGapProcessing( const tBlockDescriptor * blockDescriptor, + const tDiagSegmentList * blockSegInfo ) +{ + tFblValStructResult result; + tFblAddress procAddress; + tFblLength remainingLength; + vuint8 segIdx; + tBlockDescriptor localBlockDescriptor; +# if defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) + tFblLength idx; +# endif /* FBL_VALSTRUCT_ENABLE_GAP_FILL */ + + localBlockDescriptor = *blockDescriptor; + +# if defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) + /* Fill gap fill buffer with fill character */ + for (idx = 0u; idx < FBL_VALSTRUCT_GAP_FILL_SEGMENTATION; idx++) + { + gapFillBuffer[idx] = kFillChar; + } +# endif /* FBL_VALSTRUCT_ENABLE_GAP_FILL */ + + /* Adjust the size of the logical block according to presence pattern size */ + (void)ApplFblAdjustLbtBlockData(&localBlockDescriptor); + + procAddress = localBlockDescriptor.blockStartAddress; + /* Note: By definition, a logical block must be homogeneous (single memory device) and contiguous (no gaps) */ + memSegment = FblMemSegmentNrGet(procAddress); + + if (memSegment >= 0) + { + result = kFblValStructOk; + + for (segIdx = 0; segIdx < blockSegInfo->nrOfSegments; segIdx++) + { + /* Skip memory area at segment end which has been filled with kFillChar */ + procAddress = FblValStructSkipFilledArea(procAddress, memSegment); + + if (procAddress < blockSegInfo->segmentInfo[segIdx].targetAddress) + { + remainingLength = blockSegInfo->segmentInfo[segIdx].targetAddress - procAddress; + +# if defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) + result = FblValStructGapFill(procAddress, remainingLength); +# else /* FBL_VALSTRUCT_ENABLE_BLANK_CHECK */ + result = FblValStructBlankCheck(procAddress, remainingLength); +# endif /* FBL_VALSTRUCT_ENABLE_GAP_FILL */ + + if (kFblValStructOk != result) + { + break; + } + } + + procAddress = blockSegInfo->segmentInfo[segIdx].targetAddress + + blockSegInfo->segmentInfo[segIdx].length; + } + + if (kFblValStructOk == result) + { + /* Skip memory area at segment end which has been filled with kFillChar */ + procAddress = FblValStructSkipFilledArea(procAddress, memSegment); + + /* Check remaining part of logical block */ + if (procAddress < (localBlockDescriptor.blockStartAddress + localBlockDescriptor.blockLength)) + { + remainingLength = (localBlockDescriptor.blockStartAddress + localBlockDescriptor.blockLength) - procAddress; + +# if defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) + result = FblValStructGapFill(procAddress, remainingLength); +# else /* FBL_VALSTRUCT_ENABLE_BLANK_CHECK */ + result = FblValStructBlankCheck(procAddress, remainingLength); +# endif /* FBL_VALSTRUCT_ENABLE_GAP_FILL */ + } + } + } + else + { + /* Invalid memory segment */ +# if defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) + result = kFblValStructGapFillFailed; +# else /* FBL_VALSTRUCT_ENABLE_BLANK_CHECK */ + result = kFblValStructBlankCheckFailed; +# endif /* FBL_VALSTRUCT_ENABLE_GAP_FILL */ + } + + return result; +} +# endif /* FBL_VALSTRUCT_ENABLE_BLANK_CHECK || FBL_VALSTRUCT_ENABLE_GAP_FILL */ + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FblValStructValidateBlockExtended + **********************************************************************************************************************/ +/*! \brief The flash memory content is verified according to the information in the validation structure + * \pre Complete file must be successfully downloaded + * \param[in] blockDescriptor Block descriptor structure + * \param[in] option Parameter to influence the execution sequence + * \return kFblValStructOk = verification successfully performed + * other value = verification failed + **********************************************************************************************************************/ +/* PRQA S 6050 1 */ /* MD_MSR_STCAL */ +tFblValStructResult FblValStructValidateBlockExtended( const tBlockDescriptor * blockDescriptor, + const tFblValStructOption option ) +{ + static tVsInfo vsInfo; + static tDiagSegmentList blockSegInfo; + tFblValStructResult result; + +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)option; +# endif + /* Check if requested options can be handled with current pre-compile config */ +# if defined( FBL_VALSTRUCT_ENABLE_CHECKSUM_INTERNAL ) +# else + assertFblUser(! FblValStructOptionChecksumInternal(option), kFblSysAssertParameterOutOfRange); +# endif +# if defined( FBL_VALSTRUCT_ENABLE_BLANK_CHECK ) +# else + assertFblUser(! FblValStructOptionBlankCheck(option), kFblSysAssertParameterOutOfRange); +# endif +# if defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) +# else + assertFblUser(! FblValStructOptionGapFill(option), kFblSysAssertParameterOutOfRange); +# endif + + vsInfo.address = FblValStructGetVsAddress(blockDescriptor); + + /* Extract the block information from the validation structure */ + result = FblValStructGetSegmentInfo(&vsInfo); + +# if defined( FBL_VALSTRUCT_ENABLE_SIGNATURE ) + if (kFblValStructOk == result) + { + /* Read verification data from downloaded logical block */ + result = FblValStructGetSignature(blockDescriptor, readBuffer.data); /* PRQA S 0306 */ /* MD_FblValStruct_0306 */ + if (kFblValStructOk == result) + { + /* Check integrity and authenticity of validation structure */ + result = FblValStructVerification(&vsInfo, readBuffer.data); + } + } +# endif /* FBL_VALSTRUCT_ENABLE_SIGNATURE */ + + if (kFblValStructOk == result) + { + /* ESCAN00102005: Adapt validation structure dimension to match the respective data segment + * (required if signature is attached to validation structure segment) */ + vsInfo.address = FblValStructGetVsSegAddress(blockDescriptor); + vsInfo.length = FblValStructGetVsSegLength(vsInfo.length); + +# if defined( FBL_VALSTRUCT_ENABLE_CHECKSUM_INTERNAL ) + /* Decide whether the segment checksums shall be calculated internally or requested externally */ + if (FblValStructOptionChecksumInternal(option)) + { + /* Calculate the checksum of all segments and fill blockSegInfo structure */ + result = FblValStructChecksumInternal(&vsInfo, &blockSegInfo); + } + else +# endif /* FBL_VALSTRUCT_ENABLE_CHECKSUM_INTERNAL */ + { + /* Request segment information from external instance and check against validation structure */ + result = FblValStructChecksumExternal(blockDescriptor, &vsInfo, &blockSegInfo); + } + } + +# if defined( FBL_VALSTRUCT_ENABLE_BLANK_CHECK ) || \ + defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) + if (kFblValStructOk == result) + { + if ((FblValStructOptionBlankCheck(option)) || (FblValStructOptionGapFill(option))) + { + /* Perform gap processing (blank check or gap fill) */ + result = FblValStructGapProcessing(blockDescriptor, &blockSegInfo); + } + } +# endif /* FBL_VALSTRUCT_ENABLE_BLANK_CHECK || FBL_VALSTRUCT_ENABLE_GAP_FILL */ + + if (kFblValStructOk == result) + { + /* Remove validation structure segment */ + FblValStructRemoveStructSegment(&vsInfo, &blockSegInfo); + + /* Proceed with checking the checksum/hash of all blocks in the structure */ + result = FblValStructCompareSegmentChecksum(&vsInfo.segInfo, &blockSegInfo); + } + + return result; +} + +/*********************************************************************************************************************** + * FblValStructValidateBlock + **********************************************************************************************************************/ +/*! \brief The flash memory content is verified according to the information in the validation structure + * \pre Complete file must be successfully downloaded + * \param[in] blockDescriptor Block descriptor structure + * \return kFblValStructOk = verification successfully performed + * other value = verification failed + **********************************************************************************************************************/ +tFblValStructResult FblValStructValidateBlock( const tBlockDescriptor * blockDescriptor ) +{ + return FblValStructValidateBlockExtended(blockDescriptor, FBL_VALSTRUCT_OPTION_DEFAULT); +} +# define FBL_VALSTRUCT_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBL_ENABLE_VALSTRUCT */ + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* module specific MISRA deviations: + + MD_FblValStruct_0306: + Reason: Address conversion between integer values and pointers is required to allow for hardware independent + configuration and address range checks. + Risk: The size of integer required to hold the result of a pointer cast is implementation-defined. + Prevention: The size of the respective integer data type which holds the address value is adapted on a hardware + specific basis. + + MD_FblValStruct_0314: + Reason: The copy function have a void pointer as a function parameter and an integer is casted to pointer void. + Risk: No risk, because the underlying pointer type is known and the cast is safe. + Prevention: No prevention necessary. + + MD_FblValStruct_0315: + Reason: The underling type of verifyParam.key is pointer to void. As the type is defined outside the package, the + implicit conversion is necessary. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblValStruct_0313_WDTriggerFctType: + Reason: Security module expects a watchdog handler with return type 'void'. The usage of a wrapper function is + avoided due to higher voted requirements for minimized stack and runtime usage applied on the code. + Risk: Potentially undefined behavior of the used compiler which usually leads to a warning or error during + compilation. + Prevention: The respective functionality is part of integration testing and will hence be verified before delivery. + + MD_FblValStruct_2985: + Reason: Based on the configuration, some constants are zero, which leads to constant control expression. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FblValStruct_2991_2995: + Reason: The value of the if-controlling expression depends on the configuration. + Risk: No risk. + Prevention: No prevention necessary. + + MD_FblValStruct_3218: + Reason: Variable is accessed from multiple functions (configuration dependent). + Risk: Scope is larger than required (whole file instead of one function). Some other function could access + the variable. + Prevention: Restrict the functionality in this module to the intended purpose. Don't add functions which shall not + be able to access the local data buffers. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_VALSTRUCT.C + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_valstruct.h b/Source/bsw/Fbl/fbl_valstruct.h new file mode 100644 index 0000000..46c72bb --- /dev/null +++ b/Source/bsw/Fbl/fbl_valstruct.h @@ -0,0 +1,171 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Implementation of a download check by using an embedded validation structure + * Declaration of functions, variables and constants + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2023 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2016-07-01 visci - Initial version + * 01.01.00 2017-02-03 visci ESCAN00093858 Added support for compatibility check + * vacel Added blank check functionality + * Added API for external public key + * Reworked return value handling + * 01.01.01 2017-11-09 visci ESCAN00096836 No changes + * 01.01.02 2018-03-23 visdkl ESCAN00097287 Bootloader does not properly use configuration of CLASS_DDD + * 01.02.00 2018-06-15 visci ESCAN00098963 No changes + * 01.03.00 2019-01-25 visci ESCAN00098904 Improved verification sequence + * ESCAN00101065 Alignment for Blank Check is not applied correctly + * ESCAN00101321 Added option to skip download segment check + * 01.03.01 2019-02-06 visci ESCAN00102005 No changes + * 01.04.00 2019-06-14 visci ESCAN00102956 No changes + * ESCAN00102957 No changes + * 01.05.00 2019-06-25 visdlm ESCAN00103492 Added gap fill mechanism + * 01.05.01 2021-01-18 visjdn ESCAN00107640 No changes + * 01.05.02 2021-06-01 vishor ESCAN00109198 No changes + * 01.06.00 2022-04-28 visstn FBL-4366 Perform MISRA 2012 migration + * 01.07.00 2022-10-12 visjdn FBL-5694 Support of Xiaomi validation structure + * 01.08.00 2022-11-25 vistbe FBL-6055 Extend configurability of checksum and signature + * 01.08.01 2023-02-02 vistbe ESCAN00113401 Compiler error: error directive "Unsupported blockcount size" + **********************************************************************************************************************/ + +#ifndef FBL_VALSTRUCT_H +#define FBL_VALSTRUCT_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblLib_ValStruct CQComponent : Implementation */ +#define FBLVALSTRUCT_VERSION 0x0108u +#define FBLVALSTRUCT_RELEASE_VERSION 0x01u + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_valstruct_oem.h" + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* Defines used to request specific ValStruct processing options */ +#define FBL_VALSTRUCT_OPTION_NONE (0x00u) +#define FBL_VALSTRUCT_OPTION_CHECKSUM_INTERNAL FBL_BIT0 +#define FBL_VALSTRUCT_OPTION_BLANKCHECK FBL_BIT1 +#define FBL_VALSTRUCT_OPTION_GAP_FILL FBL_BIT2 + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +/* Define dedicated return value type based on tFblResult to indicate the deviation: + * - The return value in case of successful execution matches kFblOk + * - The negative return values (!= kFblOk) are module specific error codes (see fbl_valstruct_oem.h) + */ +typedef tFblResult tFblValStructResult; + +/* Data type which is used to pass processing options to FblValStructValidateBlockExtended() */ +typedef vuint8 tFblValStructOption; + +/*********************************************************************************************************************** + * PROTOTYPES + **********************************************************************************************************************/ + +#define FBL_VALSTRUCT_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +tFblValStructResult FblValStructValidateBlockExtended( const tBlockDescriptor * blockDescriptor, + const tFblValStructOption option ); +tFblValStructResult FblValStructValidateBlock( const tBlockDescriptor * blockDescriptor ); +#define FBL_VALSTRUCT_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * CONFIGURATION CHECKS + **********************************************************************************************************************/ + +#if defined( FBL_ENABLE_VALSTRUCT ) +# if defined( FBL_VALSTRUCT_READ_BUFFER_SIZE ) + /* Pre-defined buffer size, check validity */ +# if ( FBL_VALSTRUCT_READ_BUFFER_SIZE < FBL_VALSTRUCT_MAX_SIZE ) +# error "Validation structure: structure does not fit into read buffer" +# endif +# if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) && (FBL_VALSTRUCT_READ_BUFFER_SIZE < SEC_VERIFY_CLASS_CCC_VERIFY_SIZE) +# error "Validation structure: signature does not fit into read buffer" +# endif +# endif /* FBL_VALSTRUCT_READ_BUFFER_SIZE */ + +# if ( FBL_VALSTRUCT_BLOCKCOUNT_MAX > 254 ) +# error "Validation functionality: invalid maximum block count configured (max. value: 254)" +# endif + +/* Automatic definition of verification output buffer size (FBL_VALSTRUCT_VERIFY_SIZE) currently supports Class DDD + * with option "CRC Written" only */ +# if !defined( SEC_ENABLE_SECURITY_CLASS_DDD ) || \ + defined( SEC_ENABLE_CRC_TOTAL ) || \ + defined( SEC_ENABLE_VENDOR_CHECKSUM ) +# error "Validation structure: unsupported verification configuration" +# endif + +/* Check if blank check and gap filling functionality are enabled at the same time */ +# if defined( FBL_VALSTRUCT_ENABLE_BLANK_CHECK ) && \ + defined( FBL_VALSTRUCT_ENABLE_GAP_FILL ) +# error "Validation structure: unsupported validation structure processing configuration" +# endif /* FBL_VALSTRUCT_ENABLE_BLANK_CHECK && FBL_VALSTRUCT_ENABLE_GAP_FILL */ + +/* Check the size of the Blockcount to be 1 or 2 */ +# if (FBL_VALSTRUCT_BLOCKCOUNT_SIZE != 1u) && (FBL_VALSTRUCT_BLOCKCOUNT_SIZE != 2u) +# error "Unsupported blockcount size" +# endif /* (FBL_VALSTRUCT_BLOCKCOUNT_SIZE != 1u) && (FBL_VALSTRUCT_BLOCKCOUNT_SIZE != 2u) */ +#endif /* FBL_ENABLE_VALSTRUCT */ + +/* Automatic definition of the Alfi size in case it is not previously defined */ +#if !defined(FBL_VALSTRUCT_ALFI_SIZE) +# define FBL_VALSTRUCT_ALFI_SIZE 0x00u +#endif + +/* Default definition for checksum and signature size and function (can be overwritten) */ +#if !defined( FBL_VALSTRUCT_BLOCKCHECKSUM_SIZE ) +# define FBL_VALSTRUCT_BLOCKCHECKSUM_SIZE SEC_VERIFY_CLASS_DDD_VERIFY_SIZE +#endif + +#if !defined( FBL_VALSTRUCT_BLOCKCHECKSUM_VERIFY_OFFSET ) +# define FBL_VALSTRUCT_BLOCKCHECKSUM_VERIFY_OFFSET SEC_VERIFY_CLASS_DDD_VERIFY_OFFSET +#endif + +#if !defined( FblValStructChecksumVerification ) +# define FblValStructChecksumVerification SecM_VerificationClassDDD +#endif + +#if !defined( FBL_VALSTRUCT_SIGNATURE_SIZE ) +# define FBL_VALSTRUCT_SIGNATURE_SIZE SEC_VERIFY_CLASS_CCC_VERIFY_SIZE +#endif + +#if !defined( FblValStructSignatureVerification ) +# define FblValStructSignatureVerification SecM_VerificationClassCCC +#endif + +#endif /* FBL_VALSTRUCT_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_VALSTRUCT.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_valstruct_oem.h b/Source/bsw/Fbl/fbl_valstruct_oem.h new file mode 100644 index 0000000..daa1db3 --- /dev/null +++ b/Source/bsw/Fbl/fbl_valstruct_oem.h @@ -0,0 +1,178 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Implementation of a download check by using an embedded validation structure + * Declaration of functions, variables and constants + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2026 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * TEMPLATE REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2016-07-01 visci - Initial version + * 01.01.00 2017-02-03 vadcel ESCAN00093858 Added support for compatibility check + * Added blank check functionality + * Added API for external public key + * Reworked return value handling + * 01.01.01 2017-11-09 visci ESCAN00096836 No changes + * 01.01.02 2018-03-23 visdkl ESCAN00097287 Bootloader does not properly use configuration of CLASS_DDD + * 01.02.00 2018-06-15 visci ESCAN00098963 Corrected return value for public key read failure + * 01.03.00 2019-01-25 visci ESCAN00098904 Improved verification sequence + * ESCAN00101065 Alignment for Blank Check is not applied correctly + * ESCAN00101321 Added option to skip download segment check + * 01.03.01 2019-02-06 visci ESCAN00102005 No changes + * 01.04.00 2019-06-14 visci ESCAN00102956 No changes + * ESCAN00102957 No changes + * 01.05.00 2019-06-25 visdlm ESCAN00103492 Added gap fill mechanism + * -------------------------------------------------------------------------------------------------------------------- + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2022-08-15 vistmo FBL-5514 Support Additional OTA functionality + * ESCAN00112435 No changes + * ESCAN00112575 No changes + * 05.01.00 2022-10-04 jschmitding FBL-5917 No changes + * ESCAN00113919 No changes + * 05.01.01 2022-10-17 fmenke ESCAN00112879 No changes + * 05.01.02 2023-01-13 fmenke ESCAN00112890 No changes + * ESCAN00113612 No changes + * 05.02.00 2023-02-09 vistmo ESCAN00112972 No changes + * ESCAN00113292 No changes + * ESCAN00113835 No changes + * ESCAN00113843 No changes + * ESCAN00113764 No changes + * FBL-6438 No changes + * 05.02.01 2023-05-11 fmenke ESCAN00113831 No changes + * 05.03.00 2023-07-24 fmenke FBL-7335 No changes + * 05.03.01 2023-08-31 lhopfhauer ESCAN00115494 No changes + * 05.03.02 2024-07-16 erizk ESCAN00117344 No changes + * 05.03.03 2025-02-06 virchl ESCAN00118587 No changes + * 05.04.00 2025-02-28 jjohnson FBL-10065 No changes + * 05.04.01 2025-06-10 jostravsky ESCAN00120315 No changes + * 05.04.02 2025-07-08 visarcmijo ESCAN00119833 No changes + * 05.05.00 2025-09-01 fmenke FBL-11218 No changes + * ESCAN00120917 No changes + * 05.06.00 2025-10-28 mpatil FBL-11690 No changes + * 05.07.00 2026-01-13 dganesh FBL-12162 No changes + **********************************************************************************************************************/ + +#ifndef FBL_VALSTRUCT_OEM_H +#define FBL_VALSTRUCT_OEM_H + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#if defined( FBL_ENABLE_VALSTRUCT ) + +/** Specify default options for validation structure processing */ +# define FBL_VALSTRUCT_OPTION_DEFAULT (FBL_VALSTRUCT_OPTION_NONE) + +/** Maximum number of blocks in validation struct */ +# if !defined( FBL_VALSTRUCT_BLOCKCOUNT_MAX ) +/* At least two segments required for SBL */ +# define FBL_VALSTRUCT_BLOCKCOUNT_MAX (SWM_DATA_MAX_NOAR - 2u) +# endif + +/** Size of validation struct members */ +# if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +# define FBL_VALSTRUCT_TAG_SIZE 0x00u +# define FBL_VALSTRUCT_VERSION_SIZE 0x02u +# define FBL_VALSTRUCT_BLOCKCOUNT_SIZE 0x02u +# define FBL_VALSTRUCT_BLOCKADDRESS_SIZE 0x04u +# define FBL_VALSTRUCT_BLOCKLENGTH_SIZE 0x04u +# define FBL_VALSTRUCT_BLOCKCHECKSUM_SIZE 0x20u +# define FBL_VALSTRUCT_VALIDATESUM_SIZE 0x00u +# else +# define FBL_VALSTRUCT_TAG_SIZE 0x04u +# define FBL_VALSTRUCT_VERSION_SIZE 0x00u +# define FBL_VALSTRUCT_BLOCKCOUNT_SIZE 0x02u +# define FBL_VALSTRUCT_BLOCKADDRESS_SIZE 0x04u +# define FBL_VALSTRUCT_BLOCKLENGTH_SIZE 0x04u +# define FBL_VALSTRUCT_BLOCKCHECKSUM_SIZE 0x02u +# define FBL_VALSTRUCT_VALIDATESUM_SIZE 0x02u +# endif /* SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC */ + +/** Supported Valstruct version can be overwritten */ +# ifndef FBL_VALSTRUCT_VERSION +# define FBL_VALSTRUCT_VERSION 0x0000u +# endif /* FBL_VALSTRUCT_VERSION */ + +/** Define supported structure versions */ +# define FblValStructIsVersionSupported(ver) ((FBL_VALSTRUCT_VERSION == (ver)) ? kFblValStructOk : kFblValStructNotAuthentic) + +/** Provide base address of validation structure and signature as well as the respective download segment dimension */ + +/****** Ford (CCC + DDD use case, signature embedded before validation structure ******/ +# if ( SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC ) +/* Block header points to the verification structure, the signature is located below */ +# define FblValStructGetSigAddress(block) ((block)->headerAddress - SEC_VERIFY_CLASS_CCC_VERIFY_SIZE) +# define FblValStructGetVsAddress(block) ((block)->headerAddress) +# define FblValStructGetVsSegAddress(block) FblValStructGetSigAddress(block) +# define FblValStructGetVsSegLength(vsLength) (SEC_VERIFY_CLASS_CCC_VERIFY_SIZE + (vsLength)) + +/* Provide signature data */ +# define FblValStructGetSignature(block, buffer) (tFblValStructResult)((SEC_VERIFY_CLASS_CCC_VERIFY_SIZE == \ + FblReadProm(FblValStructGetSigAddress(block), (buffer), SEC_VERIFY_CLASS_CCC_VERIFY_SIZE)) ? \ + kFblValStructOk : kFblValStructMemoryReadError) + +# if defined( FBL_VALSTRUCT_ENABLE_EXTERNAL_KEY ) +/** Provide public key */ +# define FblValStructGetPublicKey(key) ApplFblReadVerificationKey(key) +# endif +# else /* SEC_ENABLE_SECURITY_CLASS_DDD */ +/* Block header points to the verification structure */ +# define FblValStructGetVsAddress(block) ((block)->headerAddress) +# define FblValStructGetVsSegAddress(block) FblValStructGetVsAddress(block) +# define FblValStructGetVsSegLength(vsLength) (vsLength) +# endif /* SEC_SECURITY_CLASS_VERIFY == SEC_CLASS_CCC */ + +/** Provide segment list with address, length and checksum for each segment */ +# define FblValStructGetSegmentList(block, segList) FblDiagGetSegmentList(block, segList) + +/** Options only relevant for OTA */ + +# if defined( FBL_ENABLE_GAP_FILL ) +# if defined( FBL_VALSTRUCT_ENABLE_GAP_FILL) || \ + defined( FBL_VALSTRUCT_DISABLE_GAP_FILL ) +/* Valstruct gap fill handling explicitly defined outside */ +# else +# define FBL_VALSTRUCT_ENABLE_GAP_FILL +# endif /* FBL_VALSTRUCT_ENABLE_GAP_FILL */ +# endif /* FBL_ENABLE_GAP_FILL */ + +#endif /* FBL_ENABLE_VALSTRUCT */ + +/** OEM specific return code mapping (tFblValStructResult) */ +#define kFblValStructOk 0u +#define kFblValStructNotAuthentic 1u +#define kFblValStructInvalidFormat 2u +#define kFblValStructBlockNumberMismatch 3u +#define kFblValStructChecksumValueMismatch 4u +#define kFblValStructMemoryReadError 5u +#define kFblValStructBlockMismatch 6u +#define kFblValStructKeyError 7u +#define kFblValStructBlankCheckFailed 8u +#define kFblValStructGapFillFailed 9u + +#endif /* FBL_VALSTRUCT_OEM_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_VALSTRUCT_OEM.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_wd.c b/Source/bsw/Fbl/fbl_wd.c new file mode 100644 index 0000000..f4474e9 --- /dev/null +++ b/Source/bsw/Fbl/fbl_wd.c @@ -0,0 +1,264 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Watchdog functions + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 03.00.00 2018-02-09 visach ESCAN00097885 Rework configuration + * 03.01.00 2019-08-13 vistbe FBL-370 Added support for generic MCMP slave + * 03.02.00 2019-11-01 visrcn FBL-512 Perform MISRA analysis + * 03.03.00 2022-01-20 visstn FBL-4299 Encapsulate ApplFblWDInit call + Update to MISRA2012 + * 03.04.00 2023-04-25 jschmitding FBL-6948 Improve P2* timeout timer define handling + * 03.05.00 2025-11-03 pharring FBL-11473 Add generic asynchronous routine handling + **********************************************************************************************************************/ + +#define FBL_WD_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLWD_VERSION != 0x0305u ) || \ + ( FBLWD_RELEASE_VERSION != 0x00u ) +# error "Error in fbl_wd.c: Source and header file are inconsistent!" +#endif + +#if ( FBLWD_VERSION != _FBLWD_VERSION ) || \ + ( FBLWD_RELEASE_VERSION != _FBLWD_RELEASE_VERSION ) +# error "Error in fbl_wd.c: Source and v_ver.h are inconsistent!" +#endif + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +# if !defined ( kFblGenericEventMargin ) +# if defined( kFblDiagP2StarMinThreshold ) +# define kFblGenericEventMargin kFblDiagP2StarMinThreshold +# else +# define kFblGenericEventMargin (kFblDiagTimeP2Star/2u) /**< Default value for P2 retransmit timings. */ +# endif /* kFblDiagP2StarMinThreshold */ +# endif /* kFblGenericEventMargin */ + +# define PerformGenericEventAction() \ + { \ + if (GetRcrRpInProgress()) \ + { \ + FblCwRetransmitRP(); \ + SetP2Timer(kFblDiagTimeP2Star); \ + } \ + } + + +/*********************************************************************************************************************** + * LOCAL DATA TYPES AND STRUCTURES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBLWD_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +V_MEMRAM0 V_MEMRAM1 vuint16 V_MEMRAM2 P2Timer; /**< P2 timeout timer, mapped to wdGenericEventTimer in header file */ + +V_MEMRAM0 V_MEMRAM1 vuint8 V_MEMRAM2 WDInitFlag; /**< Watchdog initialized flag */ + +#if defined( FBL_WATCHDOG_ON ) +/* PRQA S 1514 1 */ /* MD_FblWd_1514 */ +V_MEMRAM0 V_MEMRAM1 tWdTime V_MEMRAM2 WDTimer; /**< Counts timer events until next watchdog triggering */ +#endif /* FBL_WATCHDOG_ON */ + +/*********************************************************************************************************************** + * EXTERNAL DATA + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +#if defined( FBL_WATCHDOG_ON ) +#endif /* FBL_WATCHDOG_ON */ +#define FBLWD_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +#define FBLWD_INIT_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * FblInitWatchdog + **********************************************************************************************************************/ +/*! \brief Initialize module + * \return Reports if initialization was successful. + **********************************************************************************************************************/ +void V_API_NEAR FblInitWatchdog( void ) +{ + wdGenericEventTimer = 0x00u; + SetWDInit(); + +#if defined( FBL_DEF_ENABLE_NON_KB_MAIN ) +# if defined( FBL_WATCHDOG_ON ) + ApplFblWDInit(); +# endif /* FBL_WATCHDOG_ON */ +#endif /* FBL_DEF_ENABLE_NON_KB_MAIN */ +} +#define FBLWD_INIT_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLWD_RAMCODE_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * FblLookForWatchdogVoid + **********************************************************************************************************************/ +/*! \brief Polling of watchdog during longer operations. + * \details This function executes watchdog and timer handling code from RAM. Depending on the Bootloader + * configuration, additionally some communication tasks can be handled by this function. The return + * value of FblLookForWatchdog() is not returned by this function so it could be used by libraries which + * expect a void return value. + * \pre Watchdog code was copied to RAM, watchdog handling is initialized. + **********************************************************************************************************************/ +void V_API_NEAR FblLookForWatchdogVoid( void ) +{ + (void)FblLookForWatchdog(); +} +#define FBLWD_RAMCODE_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLWD_RAMCODE_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * FblLookForWatchdog + **********************************************************************************************************************/ +/*! \brief Polling of watchdog during longer operations. + * \details This function executes watchdog and timer handling code from RAM. Depending on the Bootloader + * configuration, additionally some communication tasks can be handled by this function. + * \pre Watchdog code was copied to RAM, watchdog handling is initialized. + * \return FBL_NO_TRIGGER if no timer/watchdog expired, FBL_TM_TRIGGERED if the millisecond timer expired, + * FBL_WD_TRIGGERED if watchdog handling code was called. + **********************************************************************************************************************/ +vuint8 V_API_NEAR FblLookForWatchdog( void ) /* PRQA S 6080 */ /* MD_MSR_STMIF */ +{ + vuint8 retValue = FBL_NO_TRIGGER; + + if (GetWDInit()) /* Check if watchdog already initialized */ + { + if (FblTimerGet() != 0x00u) + { + FblTimerReset(); + retValue |= FBL_TM_TRIGGERED; + + if (wdGenericEventTimer > 0x00u) + { + wdGenericEventTimer--; + if (wdGenericEventTimer < kFblGenericEventMargin) + { + PerformGenericEventAction(); + } + } + +# if defined( FBL_WATCHDOG_ON ) + if (WDTimer != 0x00u) + { + WDTimer--; + if (WDTimer == 0x00u) + { + ApplFblWDTrigger(); + WDTimer = FBL_WATCHDOG_TIME; + retValue |= FBL_WD_TRIGGERED; + } + } +# endif /* FBL_WATCHDOG_ON */ + + /* Check if the FBL or FD (erase/write) is active */ + if (0u != FblCwIsTimerTaskAllowed()) + { + /* the FBL is active, this task can now be called e.g. from the FLASH */ + FblCwTimerTask(); + } + + +# if defined( FBL_WD_TIMER_TASK ) + /* Execute configurable timer task + Task is not active until timer and watchdog have been initialized + Has to be executed from RAM or a lock mechanism needs to be implemented in macro to prevent execution while flash + operations are active */ + FBL_WD_TIMER_TASK(); +# endif /* FBL_WD_TIMER_TASK */ + } /* if (FblTimerGet() != 0x00u) */ + } /* if (GetWDInit()) */ + + /* Check if the FBL or FD (erase/write) is active */ + if (0u != FblCwIsStateTaskAllowed()) + { + /* the FBL is active, this task can now be called e.g. from FLASH */ + FblCwStateTask(); + } + +# if defined( FBL_WD_STATE_TASK ) + /* Execute configurable state task + Task is active immediately and will be executed on every function call + Has to be executed from RAM or a lock mechanism needs to be implemented in macro to prevent execution while flash + operations are active */ + FBL_WD_STATE_TASK(); +# endif /* FBL_WD_STATE_TASK */ + +# if defined( FBL_DIAG_ENABLE_CORE_ASYNC_ROUTINE ) + /* Check if the FblRepeat is reached */ + if (FblMainGetFblRepeatStarted()) + { + /* Call the async routines */ + FblDiagAsyncRoutineHandler(); + } +# endif /* FBL_DIAG_ENABLE_CORE_ASYNC_ROUTINE */ + + return retValue; +} +#define FBLWD_RAMCODE_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_FblWd_1514: + Reason: The variable is used by other modules and can't be declared static. + Risk: Name conflicts. + Prevention: Compile and link of the different variants in the component and integration test. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_WD.C + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/fbl_wd.h b/Source/bsw/Fbl/fbl_wd.h new file mode 100644 index 0000000..be15331 --- /dev/null +++ b/Source/bsw/Fbl/fbl_wd.h @@ -0,0 +1,118 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Header file for the watchdog functions + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 03.00.00 2018-02-09 visach ESCAN00097885 Rework configuration + * 03.01.00 2019-08-13 vistbe FBL-370 No changes + * 03.02.00 2019-11-01 visrcn FBL-512 Perform MISRA analysis + * 03.03.00 2022-01-20 visstn FBL-4299 Encapsulate ApplFblWDInit call + Update to MISRA2012 + * 03.04.00 2023-04-25 jschmitding FBL-6948 No changes + * 03.05.00 2025-11-03 pharring FBL-11473 No changes + **********************************************************************************************************************/ + +#ifndef FBL_WD_H +#define FBL_WD_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblWd CQComponent : Implementation */ +#define FBLWD_VERSION 0x0305u +#define FBLWD_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + + +/* Return values of LookForWatchdog */ +/* Indicates its internal action */ +#define FBL_NO_TRIGGER 0x00u /* No action performed (just watching the timer) */ +#define FBL_WD_TRIGGERED 0x03u /* Watchdog has been triggered */ +#define FBL_TM_TRIGGERED 0x02u /* Timer has expired and was re-triggered */ + +/* Macros for watchdog initialization */ +#define GetWDInit() (WDInitFlag == 0x01u) +#define SetWDInit() (WDInitFlag = 0x01u) +#define ClrWDInit() (WDInitFlag = 0x00u) + +/* Map wdGenericEventTimer to P2 timeout timer */ +# define wdGenericEventTimer P2Timer +/* Define P2Timer access macros */ +# define GetP2Timer() (P2Timer) +# define SetP2Timer(val) (P2Timer = (val)) +# define ClrP2Timer() (P2Timer = 0x00u) + +/*********************************************************************************************************************** + * GLOBAL DATA PROTOTYPES + **********************************************************************************************************************/ + +#define FBLWD_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +V_MEMRAM0 extern V_MEMRAM1 vuint16 V_MEMRAM2 P2Timer; +V_MEMRAM0 extern V_MEMRAM1 vuint8 V_MEMRAM2 WDInitFlag; + +#if defined( FBL_WATCHDOG_ON ) +# if ( FBL_WATCHDOG_TIME > 255u ) +typedef vuint16 tWdTime; +# else +typedef vuint8 tWdTime; +# endif + +V_MEMRAM0 extern V_MEMRAM1 tWdTime V_MEMRAM2 WDTimer; +#endif /* FBL_WATCHDOG_ON */ + +#define FBLWD_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLWD_INIT_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +void V_API_NEAR FblInitWatchdog ( void ); +#define FBLWD_INIT_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLWD_RAMCODE_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +void V_API_NEAR FblLookForWatchdogVoid( void ); +#define FBLWD_RAMCODE_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#define FBLWD_RAMCODE_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +vuint8 V_API_NEAR FblLookForWatchdog( void ); +#define FBLWD_RAMCODE_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + + +#endif /* FBL_WD_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_WD.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/flashdrv.h b/Source/bsw/Fbl/flashdrv.h new file mode 100644 index 0000000..ced273d --- /dev/null +++ b/Source/bsw/Fbl/flashdrv.h @@ -0,0 +1,92 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Flash Driver wrapper functions using an Autosar FLS driver + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2022 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2018-08-15 vistbe Initial version + * 01.01.00 2020-08-12 visrie FBL-1953 Add support for downloadable driver + * 01.02.00 2022-01-21 visjdn FBL-4535 Support secondary/tertiary use-case + **********************************************************************************************************************/ + +#ifndef FBLDRVFLASH_ASRFLSHIS_H +#define FBLDRVFLASH_ASRFLSHIS_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Fbl_Cfg.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* Flash driver specific version information */ +#define FLASH_DRIVER_VERSION_MAJOR (tFlashUint8)(FBLWRAPPERFLASH_ASRFLSHIS_VERSION >> 8u) +#define FLASH_DRIVER_VERSION_MINOR (tFlashUint8)(FBLWRAPPERFLASH_ASRFLSHIS_VERSION & 0xFFu) +#define FLASH_DRIVER_VERSION_PATCH (tFlashUint8)(FBLWRAPPERFLASH_ASRFLSHIS_RELEASE_VERSION) + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* Flash Driver hardware information */ +#define FLASH_DRIVER_VERSION_MCUTYPE 0x5Cu +#define FLASH_DRIVER_VERSION_MASKTYPE 0x00u +#define FLASH_DRIVER_VERSION_INTERFACE 0x00u + +/* Defines to access version and type information */ +#define FLASH_DRIVER_MCUTYPE(flashCode) (*(tFlashUint8*)((flashCode) + 0x03u)) +#define FLASH_DRIVER_MASKTYPE(flashCode) (*(tFlashUint8*)((flashCode) + 0x02u)) +#define FLASH_DRIVER_INTERFACE(flashCode) (*(tFlashUint8*)((flashCode) + 0x00u)) + +/* Flash driver is relocatable */ +#define FLASH_DRIVER_RELOCATABLE + +/* Minimum number of bytes that has to be programmed at a time */ +#if !defined( FLASH_SEGMENT_SIZE ) +# define FLASH_SEGMENT_SIZE 256u +#endif + +/* Value of deleted flash memory, usually 0xFF */ +#if !defined( FBL_FLASH_DELETED ) +# define FBL_FLASH_DELETED 0xFFu + +#endif +/* Common error codes */ +#define kFlashOk 0x00u /**< Function call successful */ +#define kFlashFailed 0x01u /**< Function call failed */ + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +typedef unsigned short tFlashErrorCode; +typedef unsigned char tFlashUint8; /**< equivalent to vuint8 */ +typedef unsigned long tFlashUint32; /**< equivalent to vuint32 */ + +#endif /* FBLDRVFLASH_ASRFLSHIS_H */ + +/*********************************************************************************************************************** + * END OF FILE: FLASHDRV.H + **********************************************************************************************************************/ diff --git a/Source/bsw/Fbl/v_ver.h b/Source/bsw/Fbl/v_ver.h new file mode 100644 index 0000000..99ba339 --- /dev/null +++ b/Source/bsw/Fbl/v_ver.h @@ -0,0 +1,176 @@ +/*---------------------------------------------------------------------------- + * License information: + * - Serialnumber: CBD2501331 + ---------------------------------------------------------------------------- + * Software is licensed for: + * Flex Automotive GmbH + * Package: FBL Ford SLP7 - in the project "On-Board charger (OBC)" for Ford + * Micro: AM263P4AFONFZCZRQ1 + * Compiler: Texas Instruments (LLVM-based) 3.2.0 LTS + ---------------------------------------------------------------------------*/ + +#ifndef __V_VER_H +# define __V_VER_H + + +/*---------------------------------------------------------------------------- + SIP version + ---------------------------------------------------------------------------*/ + +# define _VECTOR_SIP_VERSION 0x3407u +# define _VECTOR_SIP_RELEASE_VERSION 0x08u +# define _VECTOR_SIP_BUILD_VERSION 0x00u + + +/*---------------------------------------------------------------------------- + DrvMem_Mem_30_FblHis + ---------------------------------------------------------------------------*/ +# define _DRVMEM_MEM_30_FBLHIS_VERSION 0x0101u +# define _DRVMEM_MEM_30_FBLHIS_RELEASE_VERSION 0x01u + +/*---------------------------------------------------------------------------- + FblBm_Hdr + ---------------------------------------------------------------------------*/ +# define _FBLBM_HDR_VERSION 0x0202u +# define _FBLBM_HDR_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblBm_Main + ---------------------------------------------------------------------------*/ +# define _FBLBM_MAIN_VERSION 0x0612u +# define _FBLBM_MAIN_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblDiag_14229_Ford + ---------------------------------------------------------------------------*/ +# define _FBLDIAG_OEM_VERSION 0x0507u +# define _FBLDIAG_OEM_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblHal_Arm32 + ---------------------------------------------------------------------------*/ +# define _FBLHAL_ARM32_VERSION 0x0119u +# define _FBLHAL_ARM32_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblKbApi + ---------------------------------------------------------------------------*/ +# define _FBLKBAPI_VERSION 0x0217u +# define _FBLKBAPI_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblKbApi_Brs + ---------------------------------------------------------------------------*/ +# define _FBLKBAPI_HW_VERSION 0x0203u +# define _FBLKBAPI_HW_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblKbApi_Ford + ---------------------------------------------------------------------------*/ +# define _FBLKBAPI_OEM_VERSION 0x0911u +# define _FBLKBAPI_OEM_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblKbApi_Frame_Ford + ---------------------------------------------------------------------------*/ +# define _FBLKBAPI_FRAME_OEM_VERSION 0x0505u +# define _FBLKBAPI_FRAME_OEM_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblKbApi_FrameDiag_Ford + ---------------------------------------------------------------------------*/ +# define _FBLKBAPI_FRAMEDIAG_OEM_VERSION 0x0611u +# define _FBLKBAPI_FRAMEDIAG_OEM_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblKbApi_FrameNv_Ford + ---------------------------------------------------------------------------*/ +# define _FBLKBAPI_FRAMENV_OEM_VERSION 0x0706u +# define _FBLKBAPI_FRAMENV_OEM_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblKbApi_FrameWd + ---------------------------------------------------------------------------*/ +# define _FBLKBAPI_FRAMEWD_VERSION 0x0311u +# define _FBLKBAPI_FRAMEWD_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblLib_Fsm + ---------------------------------------------------------------------------*/ +# define _FBLLIB_FSM_VERSION 0x0102u +# define _FBLLIB_FSM_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblLib_Lbt + ---------------------------------------------------------------------------*/ +# define _FBLLIB_LBT_VERSION 0x0105u +# define _FBLLIB_LBT_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblLib_Mem + ---------------------------------------------------------------------------*/ +# define _FBLLIB_MEM_VERSION 0x0414u +# define _FBLLIB_MEM_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblLib_NvPattern + ---------------------------------------------------------------------------*/ +# define _FBLLIB_NVPATTERN_VERSION 0x0201u +# define _FBLLIB_NVPATTERN_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblLib_SecBoot_vHsm + ---------------------------------------------------------------------------*/ +# define _FBLLIB_SECBOOT_VHSM_VERSION 0x0206u +# define _FBLLIB_SECBOOT_VHSM_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblLib_ValStruct + ---------------------------------------------------------------------------*/ +# define _FBLVALSTRUCT_VERSION 0x0108u +# define _FBLVALSTRUCT_RELEASE_VERSION 0x01u + +/*---------------------------------------------------------------------------- + FblMain + ---------------------------------------------------------------------------*/ +# define _FBL_MAIN_VERSION 0x0608u +# define _FBL_MAIN_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblMio + ---------------------------------------------------------------------------*/ +# define _FBLMIO_VERSION 0x0104u +# define _FBLMIO_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblUpd_Main + ---------------------------------------------------------------------------*/ +# define _FBLUPD_MAIN_VERSION 0x0607u +# define _FBLUPD_MAIN_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblWd + ---------------------------------------------------------------------------*/ +# define _FBLWD_VERSION 0x0305u +# define _FBLWD_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblWrapperCom_PduR + ---------------------------------------------------------------------------*/ +# define _FBLWRAPPERCOM_PDUR_VERSION 0x0709u +# define _FBLWRAPPERCOM_PDUR_RELEASE_VERSION 0x00u + +/*---------------------------------------------------------------------------- + FblWrapperFlash_XVirtualHis + ---------------------------------------------------------------------------*/ +# define _FBLWRAPPERFLASH_VIRTUALIO_VERSION 0x0100u +# define _FBLWRAPPERFLASH_VIRTUALIO_RELEASE_VERSION 0x01u + +/*---------------------------------------------------------------------------- + SysService_SecModHis + ---------------------------------------------------------------------------*/ +# define _SYSSERVICE_SECMODHIS_VERSION 0x0315u +# define _SYSSERVICE_SECMODHIS_RELEASE_VERSION 0x00u + +#endif + diff --git a/Source/bsw/FblAsrStubs/BswM.h b/Source/bsw/FblAsrStubs/BswM.h new file mode 100644 index 0000000..23c5a6b --- /dev/null +++ b/Source/bsw/FblAsrStubs/BswM.h @@ -0,0 +1,40 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief BswM ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef BSWM_H +#define BSWM_H + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#define BswM_RequestMode(ModuleId, ErrorId) + +#endif /* BSWM_H */ + +/*********************************************************************************************************************** +* END OF FILE: BSWM.H +**********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/ComM.h b/Source/bsw/FblAsrStubs/ComM.h new file mode 100644 index 0000000..8720e1c --- /dev/null +++ b/Source/bsw/FblAsrStubs/ComM.h @@ -0,0 +1,40 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief ComM ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef COMM_H +#define COMM_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Rte_ComM_Type.h" + +#endif /* COMM_H */ + +/*********************************************************************************************************************** +* END OF FILE: COMM.H +**********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/ComM_BusSM.h b/Source/bsw/FblAsrStubs/ComM_BusSM.h new file mode 100644 index 0000000..edcd5bf --- /dev/null +++ b/Source/bsw/FblAsrStubs/ComM_BusSM.h @@ -0,0 +1,50 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief ComM_BusSM ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef COMM_BUSSM_H +#define COMM_BUSSM_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "ComM_Types.h" + +/*********************************************************************************************************************** + * EXTERNAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLASRSTUBS_COMM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +FUNC(void, COMM_CODE) ComM_BusSM_ModeIndication(NetworkHandleType Channel, P2VAR(ComM_ModeType, AUTOMATIC, COMM_APPL_VAR) ComMode); +#define FBLASRSTUBS_COMM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* COMM_BUSSM_H */ + +/*********************************************************************************************************************** +* END OF FILE: COMM_BUSSM.H +**********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/ComM_Types.h b/Source/bsw/FblAsrStubs/ComM_Types.h new file mode 100644 index 0000000..dc81e58 --- /dev/null +++ b/Source/bsw/FblAsrStubs/ComM_Types.h @@ -0,0 +1,47 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief ComM_Types ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef COMM_TYPES_H +#define COMM_TYPES_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "ComStack_Types.h" /* Include standard types */ +#include "ComM_GenTypes.h" + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +typedef uint8 ComM_ModeType; + +#endif /* COMM_TYPES_H */ + +/*********************************************************************************************************************** + * END OF FILE: COMM_TYPES.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/Dem.c b/Source/bsw/FblAsrStubs/Dem.c new file mode 100644 index 0000000..3cdfc87 --- /dev/null +++ b/Source/bsw/FblAsrStubs/Dem.c @@ -0,0 +1,80 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Dem ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Dem.h" +#include "fbl_inc.h" + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +#define FBLASRSTUBS_DEM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * Dem_ReportErrorStatus + **********************************************************************************************************************/ +/*! \brief Report error status dummy function + * \param[in] EventId + * \param[in] EventStatus + **********************************************************************************************************************/ +void Dem_ReportErrorStatus(Dem_EventIdType EventId, Dem_EventStatusType EventStatus) +{ +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)EventId; + (void)EventStatus; +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ +} + +/*********************************************************************************************************************** + * Dem_SetEventStatus + **********************************************************************************************************************/ +/*! \brief Set event status dummy function + * \param[in] EventId + * \param[in] EventStatus + **********************************************************************************************************************/ +Std_ReturnType Dem_SetEventStatus(Dem_EventIdType EventId, Dem_EventStatusType EventStatus) +{ + Std_ReturnType retval = E_OK; + +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + (void)EventId; + (void)EventStatus; +# endif /* V_ENABLE_USE_DUMMY_STATEMENT */ + + return retval; +} + +#define FBLASRSTUBS_DEM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * END OF FILE: DEM.C + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/Dem.h b/Source/bsw/FblAsrStubs/Dem.h new file mode 100644 index 0000000..fed671b --- /dev/null +++ b/Source/bsw/FblAsrStubs/Dem.h @@ -0,0 +1,82 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Dem ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef DEM_H +#define DEM_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Std_Types.h" /* AUTOSAR standard types */ +#include "FblAsrStubs_Cfg.h" + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#define DEM_AR_RELEASE_MAJOR_VERSION 4u +#define DEM_AR_RELEASE_MINOR_VERSION 3u +#define DEM_AR_RELEASE_REVISION_VERSION 0u + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +#define DEM_EVENT_STATUS_FAILED 1 +#define DEM_EVENT_STATUS_PASSED 2 +#define DEM_EVENT_STATUS_PREPASSED 3 +#define DEM_EVENT_STATUS_PREFAILED 4 + +#define Dem_FR_E_ACCESS 5 +#define Dem_FRIF_E_JLE_SYNC 6 +#define Dem_FRSM_E_CLUSTER_STARTUP 7 + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +typedef uint16 Dem_EventIdType; +typedef uint8 Dem_EventStatusType; + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define FBLASRSTUBS_DEM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +extern void Dem_ReportErrorStatus( Dem_EventIdType EventId, Dem_EventStatusType EventStatus); +extern Std_ReturnType Dem_SetEventStatus(Dem_EventIdType EventId, Dem_EventStatusType EventStatus); + +#define FBLASRSTUBS_DEM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* DEM_H */ + +/*********************************************************************************************************************** + * END OF FILE: DEM.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/FblAsrStubs.h b/Source/bsw/FblAsrStubs/FblAsrStubs.h new file mode 100644 index 0000000..b3349f8 --- /dev/null +++ b/Source/bsw/FblAsrStubs/FblAsrStubs.h @@ -0,0 +1,50 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Main header file of FblASrStubs + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 05.00.00 2021-03-12 vishor FBL-3157 Removed EcuM, Os and SchM stubs for proper handling of BRS for FBL + * 05.00.01 2021-03-31 visrie FBL-3000 Added ASR stubs: vHsm_Types, Rte_KeyM_Type + * Added/adapted MemMap sections + * 05.00.02 2022-09-26 visrie FBL-5936 Added byte order defines to v_cfg.h + * 05.00.03 2023-04-24 vismix ESCAN00113852 Memory abstraction doesn't work as expected if BswM_LinTp.h is used + * 05.00.04 2023-10-25 visrie ESCAN00107438 Compiler warning: typedef name has already been declared (with + * same type) for Csm_ResultType + * ESCAN00112632 No changes + * ESCAN00115668 Compiler error: Com_Types.h and Com_Cbk.h files are missing + * 06.00.00 2024-03-20 vishor FBL-7833 Add generator to create stub config files + * ESCAN00116488 Compiler error: Unresolved external Dem_SetEventStatus and AUTOSAR + * Software Specification Version missing + * 06.00.01 2024-04-18 viswmo ESCAN00117142 Compiler error: Undefined symbols ComM_LimitChannelToNoComMode + * and Rte_ModeType_ComMMode + * 06.01.00 2024-08-06 vistbe FBL-9077 Add BswM stubs for DoIP/DoIPInt + **********************************************************************************************************************/ + +#ifndef FBLASRSTUBS_H +#define FBLASRSTUBS_H + +#endif /* FBLASRSTUBS_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBLASRSTUBS.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/MemIf.h b/Source/bsw/FblAsrStubs/MemIf.h new file mode 100644 index 0000000..4967895 --- /dev/null +++ b/Source/bsw/FblAsrStubs/MemIf.h @@ -0,0 +1,46 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief MemIf ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef MEMIF_H +#define MEMIF_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ +#include "MemIf_Types.h" + +/********************************************************************************************************************** + * VERSION + *********************************************************************************************************************/ + +#define MEMIF_AR_RELEASE_MAJOR_VERSION 4u +#define MEMIF_AR_RELEASE_MINOR_VERSION 0u + +#endif /* MEMIF_H */ + +/*********************************************************************************************************************** + * END OF FILE: MEMIF.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/MemIf_Types.h b/Source/bsw/FblAsrStubs/MemIf_Types.h new file mode 100644 index 0000000..3aa14f3 --- /dev/null +++ b/Source/bsw/FblAsrStubs/MemIf_Types.h @@ -0,0 +1,112 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief MemIf_Types ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef MEMIF_TYPES_H +#define MEMIF_TYPES_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Std_Types.h" + +/********************************************************************************************************************** + * VERSION + *********************************************************************************************************************/ + +#define MEMIF_TYPES_AR_RELEASE_MAJOR_VERSION 4u +#define MEMIF_TYPES_AR_RELEASE_MINOR_VERSION 0u + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/* A memory hardware abstraction module's state is denoted in + * this type. Mainly used in MemIf_GetStatus and related + * APIs of memory hardware abstraction modules. + */ +typedef enum +{ + MEMIF_UNINIT = 0, + MEMIF_IDLE, + MEMIF_BUSY, + MEMIF_BUSY_INTERNAL +} MemIf_StatusType; + +/* A requested job can have one these values after it has been + * processed. Use in MemIf_GetJobResult and related memory + * hardware abstraction module APIs. + */ +typedef enum +{ + MEMIF_JOB_OK = 0, + MEMIF_JOB_FAILED, + MEMIF_JOB_PENDING, + MEMIF_JOB_CANCELED, + MEMIF_BLOCK_INCONSISTENT, + MEMIF_BLOCK_INVALID +} MemIf_JobResultType; + + +/* Specifies the processing speed of requested jobs. The exact + * processing duration in the different modes depends on + * configuration of the underlying memory hardware abstraction + * modules. + */ +typedef enum +{ + MEMIF_MODE_SLOW = 0, + MEMIF_MODE_FAST +} MemIf_ModeType; + +/* Workaround for AUTOSAR Release 2.0 Flash Drivers: + * + * Fls assumes, that MemIf provides MemIf_AddressType and MemIf_LenghthType. + * Eep assumes, that it should define its address types on its own. + * MemIf assumes, that Eep is right and hence does NOT provide these + * types. However, there are some implementations, that did not recognize + * this inconsistency, so we have to provide these types in order to + * get Flash drivers and Flash Eeprom Emulation integrated with the + * other BSW Modules. In order to minimize the risk of limiting the + * address range of underlying flash drivers, both types are based + * on 32bit-address range (allowing 4GB of data, which should be + * considerably adequate). This might not be the optimum data type + * on all platforms, but it's the safest. + */ +typedef uint32 MemIf_AddressType; +typedef uint32 MemIf_LengthType; + +/* + * Because of different spelling in AUTOSAR specifications both MEMIF_JOB_CANCELLED + * and MEMIF_JOB_CANCELED are supported for reasons of compatibility. + */ +#define MEMIF_JOB_CANCELLED MEMIF_JOB_CANCELED + +#endif /* MEMIF_TYPES_H */ + +/*********************************************************************************************************************** + * END OF FILE: MEMIF_TYPES.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/NvM_Cbk.h b/Source/bsw/FblAsrStubs/NvM_Cbk.h new file mode 100644 index 0000000..7f7f6e5 --- /dev/null +++ b/Source/bsw/FblAsrStubs/NvM_Cbk.h @@ -0,0 +1,34 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief NvM_Cbk ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef NVM_CBK_H +#define NVM_CBK_H + +#endif /* NVM_CBK_H */ + +/*********************************************************************************************************************** + * END OF FILE: NVM_CBK.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/Rte.h b/Source/bsw/FblAsrStubs/Rte.h new file mode 100644 index 0000000..77595ac --- /dev/null +++ b/Source/bsw/FblAsrStubs/Rte.h @@ -0,0 +1,40 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Rte ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef RTE_H +#define RTE_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Std_Types.h" + +#endif /* RTE_H */ + +/*********************************************************************************************************************** + * END OF FILE: RTE.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/Rte_ComM.h b/Source/bsw/FblAsrStubs/Rte_ComM.h new file mode 100644 index 0000000..d9946bf --- /dev/null +++ b/Source/bsw/FblAsrStubs/Rte_ComM.h @@ -0,0 +1,40 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Rte_ComM ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef RTE_COMM_H +#define RTE_COMM_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Rte_ComM_Type.h" + +#endif /* RTE_COMM_H */ + +/*********************************************************************************************************************** + * END OF FILE: RTE_COMM.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/Rte_ComM_Type.h b/Source/bsw/FblAsrStubs/Rte_ComM_Type.h new file mode 100644 index 0000000..171a147 --- /dev/null +++ b/Source/bsw/FblAsrStubs/Rte_ComM_Type.h @@ -0,0 +1,62 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Rte_ComM_type ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef RTE_COMM_TYPE_H +#define RTE_COMM_TYPE_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Rte_Type.h" + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +typedef ComM_ModeType Rte_ModeType_ComMMode; + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#ifndef COMM_NO_COMMUNICATION +# define COMM_NO_COMMUNICATION 0U +#endif + +#ifndef COMM_SILENT_COMMUNICATION +# define COMM_SILENT_COMMUNICATION 1U +#endif + +#ifndef COMM_FULL_COMMUNICATION +# define COMM_FULL_COMMUNICATION 2U +#endif + +#endif /* RTE_COMM_TYPE_H */ + +/*********************************************************************************************************************** + * END OF FILE: RTE_COMM_TYPE.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/Rte_Csm_Type.h b/Source/bsw/FblAsrStubs/Rte_Csm_Type.h new file mode 100644 index 0000000..ad41aea --- /dev/null +++ b/Source/bsw/FblAsrStubs/Rte_Csm_Type.h @@ -0,0 +1,40 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Rte_Csm_type ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef RTE_CSM_TYPE_H +#define RTE_CSM_TYPE_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Rte_Type.h" + +#endif /* RTE_CSM_TYPE_H */ + +/*********************************************************************************************************************** + * END OF FILE: RTE_CSM_TYPE.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/Rte_EcuM_Type.h b/Source/bsw/FblAsrStubs/Rte_EcuM_Type.h new file mode 100644 index 0000000..34b9aaa --- /dev/null +++ b/Source/bsw/FblAsrStubs/Rte_EcuM_Type.h @@ -0,0 +1,40 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Rte_EcuM_type ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef RTE_ECUM_TYPE_H +#define RTE_ECUM_TYPE_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Rte_Type.h" + +#endif /* RTE_ECUM_TYPE_H */ + +/*********************************************************************************************************************** + * END OF FILE: RTE_ECUM_TYPE.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/Rte_Type.h b/Source/bsw/FblAsrStubs/Rte_Type.h new file mode 100644 index 0000000..dbc53fa --- /dev/null +++ b/Source/bsw/FblAsrStubs/Rte_Type.h @@ -0,0 +1,50 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Rte_Type ASR4 stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef RTE_TYPE_H +#define RTE_TYPE_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Rte.h" + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +typedef uint8 EcuM_ModeType; + +typedef uint8 ComM_InhibitionStatusType; +typedef uint8 ComM_UserHandleType; +typedef uint8 ComM_ModeType; + +#endif /* RTE_TYPE_H */ + +/*********************************************************************************************************************** + * END OF FILE: RTE_TYPE.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblAsrStubs/v_cfg.h b/Source/bsw/FblAsrStubs/v_cfg.h new file mode 100644 index 0000000..0ec8203 --- /dev/null +++ b/Source/bsw/FblAsrStubs/v_cfg.h @@ -0,0 +1,99 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief v_cfg stub for flash bootloader + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + **********************************************************************************************************************/ + +#ifndef V_CFG_H +#define V_CFG_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "Platform_Types.h" + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#ifndef V_GEN_GENERATOR_MSR +# define V_GEN_GENERATOR_MSR +#endif + +#if defined( CPU_TYPE_64 ) +# if (CPU_TYPE == CPU_TYPE_64) +# if !defined( C_CPUTYPE_64BIT ) +# define C_CPUTYPE_64BIT +# endif +# endif +#endif + +#if (CPU_TYPE == CPU_TYPE_32) +# if !defined( C_CPUTYPE_32BIT ) +# define C_CPUTYPE_32BIT +# endif +#endif + +#if (CPU_TYPE == CPU_TYPE_16) +# if !defined( C_CPUTYPE_16BIT ) +# define C_CPUTYPE_16BIT +# endif +#endif + +#if (CPU_TYPE == CPU_TYPE_8) +# if !defined( C_CPUTYPE_8BIT ) +# define C_CPUTYPE_8BIT +# endif +#endif + +#if (CPU_BIT_ORDER == LSB_FIRST) +# if !defined( C_CPUTYPE_BITORDER_LSB2MSB ) +# define C_CPUTYPE_BITORDER_LSB2MSB +# endif +#endif + +#if (CPU_BIT_ORDER == MSB_FIRST) +# if !defined( C_CPUTYPE_BITORDER_MSB2LSB ) +# define C_CPUTYPE_BITORDER_MSB2LSB +# endif +#endif + +#if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) +# if !defined( C_CPUTYPE_LITTLEENDIAN ) +# define C_CPUTYPE_LITTLEENDIAN +# endif +#endif + +#if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) +# if !defined( C_CPUTYPE_BIGENDIAN ) +# define C_CPUTYPE_BIGENDIAN +# endif +#endif + +#endif /* V_CFG_H */ + +/*********************************************************************************************************************** + * END OF FILE: V_CFG.H + **********************************************************************************************************************/ + diff --git a/Source/bsw/FblBm/bm_main.c b/Source/bsw/FblBm/bm_main.c new file mode 100644 index 0000000..dd05e59 --- /dev/null +++ b/Source/bsw/FblBm/bm_main.c @@ -0,0 +1,2459 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Main module of BM + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 04.00.00 2019-10-10 vistmo FBL-390 Adapt main function interface for vBaseEnv + * 04.00.01 2019-11-05 visrie ESCAN00104616 No changes + * ESCAN00104790 No changes + * 05.00.00 2019-12-04 visrie FBL-456 Added support for new FblLibSecBoot interface + * ESCAN00104644 Initialize DET module + * ESCAN00105176 Added support for VTT use case + * 05.01.00 2020-01-13 visrie ESCAN00104481 No changes + * FBL-953 No changes + * 05.02.00 2020-02-28 vistbe FBL-949 No changes + * 06.00.00 2020-04-08 visrie FBL-1016 Support of EcuM functions + * 06.00.01 2020-04-08 visrie ESCAN00106837 Compiler error: wrong argument type at FblSb_VerifySegments + * 06.00.02 2020-10-28 visrcn ESCAN00107189 Compiler error: Wrong definition for FblMain function + * 06.01.00 2021-08-11 visrie FBL-3394 Move default implementation of CheckReprogFlag into FblBm_Ap + * Added/adapted MemMap sections + * 06.02.00 2022-02-04 visrie FBL-4602 Added support of new SecBoot API (VerifyHeaderRom) + * 06.02.01 2022-04-06 fmenke ESCAN00111029 [MCMP only] Compiler error: Label FblDiagInitPowerOn is not defined + * 06.03.00 2022-04-08 visrie FBL-4126 No changes + * 06.04.00 2022-04-11 lhopfhauer FBL-4822 Add support for new MagicFlag value and Swap API + * 06.04.01 2022-04-28 fmenke ESCAN00111741 SecureBoot for Bootloader not checked during reprogramming + * request started by application + * 06.05.00 2022-05-06 lhopfhauer FBL-5148 Encapsulate call of FblInterruptDisable + * 06.06.00 2022-07-13 fmenke FBL-5391 Add callout for missing optional dependency + * 06.06.01 2022-08-04 jschmitding ESCAN00112070 FblSb_VerifySegments is needlessly called twice. + * 06.07.00 2022-11-07 lhopfhauer FBL-4932 Adjust FBL LBT Check + * 06.08.00 2022-11-30 visrie FBL-6065 No changes + * 06.08.01 2024-03-04 visrie ESCAN00116460 Assertion missing in FblMemGet/SetInteger + * 06.09.00 2024-05-16 lhopfhauer FBL-8602 Add support for OEM updater solution + * 06.10.00 2024-11-15 erizk FBL-9652 Optimize startup times for secure boot + * 06.11.00 2025-05-23 dganesh FBL-9715 Extend presence pattern to connect validity information + * 06.12.00 2025-09-23 pharring FBL-10124 Add support for FblLib_Logger + **********************************************************************************************************************/ + +#define BM_MAIN_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" + +#include "fbl_main_types.h" +#include "bm_main.h" +#include "fbl_fsm.h" + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# include "fbl_secboot.h" +#endif + +#include "EcuM.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLBM_MAIN_VERSION != 0x0612u ) || \ + ( FBLBM_MAIN_RELEASE_VERSION != 0x00u ) +# error "Error in bm_main.c: Source and Header file are inconsistent!" +#endif + +#if ( FBLBM_MAIN_VERSION != _FBLBM_MAIN_VERSION ) || \ + ( FBLBM_MAIN_RELEASE_VERSION != _FBLBM_MAIN_RELEASE_VERSION ) +# error "Error in bm_main.c: Source and v_ver.h are inconsistent!" +#endif + +/* Interface version compatibility check: General callouts */ +#if defined( FBLBM_AP_API_VERSION_MAJOR ) && \ + defined( FBLBM_AP_API_VERSION_MINOR ) +#else +# error "Error in bm_main.c: Interface version requirements not defined!" +#endif + +#if ( FBLBM_AP_API_VERSION_MAJOR != FBLBM_API_VERSION_MAJOR ) || \ + ( FBLBM_AP_API_VERSION_MINOR > FBLBM_API_VERSION_MINOR ) +# error "Error in bm_main.c: Interface version compatibility check failed!" +#endif + +/* Interface version compatibility check: platform-specific callouts */ +#if defined( FBLBM_AP_HW_API_VERSION_MAJOR ) +# if defined( FBLBM_AP_HW_API_VERSION_MINOR ) +# else +# error "Error in bm_main.c: Interface version requirements not defined!" +# endif + +# if ( FBLBM_AP_HW_API_VERSION_MAJOR != FBLBM_API_VERSION_MAJOR ) || \ + ( FBLBM_AP_HW_API_VERSION_MINOR > FBLBM_API_VERSION_MINOR ) +# error "Error in bm_main.c: Interface version compatibility check failed!" +# endif +#endif + +/* Interface version compatibility check: OEM-specific callouts */ +#if defined( FBLBM_AP_OEM_API_VERSION_MAJOR ) +# if defined( FBLBM_AP_OEM_API_VERSION_MINOR ) +# else +# error "Error in bm_main.c: Interface version requirements not defined!" +# endif + +# if ( FBLBM_AP_OEM_API_VERSION_MAJOR != FBLBM_API_VERSION_MAJOR ) || \ + ( FBLBM_AP_OEM_API_VERSION_MINOR > FBLBM_API_VERSION_MINOR ) +# error "Error in bm_main.c: Interface version compatibility check failed!" +# endif +#endif + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#if defined( _MICROSOFT_C_VTT_ ) +# define FBLBM_MAIN_ENABLE_VTT_USECASE +#endif /* _MICROSOFT_C_VTT_ */ + +/** Helper macro for filling state structures (enhance readability) */ +#define FBLBM_SIZE_AND_ARRAY(array) FBLBM_ARRAY_SIZE(array), (array) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if (!defined( FBLBM_DISABLE_USE_VERIFY_HEADER_ROM ) && \ + ( ( FBLSB_API_REFERENCE_VERSION_MAJOR > 0x02u ) || \ + (( FBLSB_API_REFERENCE_VERSION_MAJOR == 0x02u ) && ( FBLSB_API_REFERENCE_VERSION_MINOR >= 0x02u )))) +# define FBLBM_ENABLE_USE_VERIFY_HEADER_ROM +# endif +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + +#if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) || defined( FBLBM_ENABLE_FBLLBT_VERIFICATION ) +# define FBLBM_DISABLE_EARLY_FBL_SEGMENTS_CHECK +#else +# define FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK +#endif + +/*********************************************************************************************************************** + * TYPEDEFS, ENUMS + **********************************************************************************************************************/ + +/** Bootmanager States */ /* PRQA S 3205 TAG_FblBmMain_3205_1 */ /* MD_FblBmMain_3205_UnusedIdentifiers */ +typedef enum +{ + FBLBM_STATE_POWER_ON, /* 0 */ + FBLBM_STATE_INIT, /* 1 */ + FBLBM_STATE_CHECK_FBL_VALIDITY, /* 2 */ + FBLBM_STATE_FAILSAFE_UPDATER_ENABLED, /* 3 */ + FBLBM_STATE_FAILSAFE_UPDATER_SEARCH_INIT, /* 4 */ + FBLBM_STATE_FAILSAFE_UPDATER_CHECK, /* 5 */ + FBLBM_STATE_FAILSAFE_UPDATER_SEARCH_NEXT, /* 6 */ + FBLBM_STATE_FAILSAFE_UPDATER_USER_CHECK, /* 7 */ + FBLBM_STATE_CALL_FAILSAFE_UPDATER, /* 8 */ + FBLBM_STATE_CHECK_PP_KEY_AVAILABILITY, /* 9 */ + FBLBM_STATE_CALL_FBL_PP_INIT_KEY, /* 10 */ + FBLBM_STATE_CHECK_SIGNED_PP_VALIDITY, /* 11 */ + FBLBM_STATE_SECURE_BOOT_ENABLED, /* 12 */ + FBLBM_STATE_CHECK_KEY_AVAILABILITY, /* 13 */ + FBLBM_STATE_CALL_FBL_INIT_KEY, /* 14 */ + FBLBM_STATE_INIT_FBL_MAC_ENABLED, /* 15 */ + FBLBM_STATE_CHECK_FBL_MAC_ERASED, /* 16 */ + FBLBM_STATE_CALL_FBL_INIT_CMAC, /* 17 */ + FBLBM_STATE_STAY_IN_BOOT_ENABLED, /* 18 */ + FBLBM_STATE_CHECK_APPL_START_FLAG, /* 19 */ + FBLBM_STATE_CHECK_FBL_LBT, /* 20 */ + FBLBM_STATE_CHECK_REPROG_FLAG, /* 21 */ + FBLBM_STATE_REPROG_LBT_ENABLED, /* 22 */ + FBLBM_STATE_CHECK_REPROG_LBT, /* 23 */ + FBLBM_STATE_TARGET_LIST_INIT, /* 24 */ + FBLBM_STATE_TARGET_CHECK, /* 25 */ + FBLBM_STATE_TARGET_LIST_NEXT, /* 26 */ + FBLBM_STATE_CALL_TARGET, /* 27 */ + FBLBM_STATE_CHECK_LATE_FBL_SEGMENTS, /* 28 */ + FBLBM_STATE_CHECK_FBL_VERIFICATION_STAY_IN_BOOT, /* 29 */ + FBLBM_STATE_CALL_FBL, /* 30 */ + FBLBM_STATE_CALL_FBL_STAY_IN_BOOT, /* 31 */ + FBLBM_STATE_CHECK_EARLY_FBL_SEGMENTS, /* 32 */ + FBLBM_STATE_FAIL /* 33 */ +} tFblBmState; + +/** Events for BM FSM: Only one Event "continue" */ +typedef enum +{ + FBLBM_EVENT_CONTINUE = kFblFsmDefaultEvent_Count /* 4 */ +} tFblBmEvent; +/* PRQA L:TAG_FblBmMain_3205_1 */ + +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLBM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +static void FblBmDeinit(void); + +/* Event Handlers */ +static tFblFsmGuard FblBmState_PowerOn_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +static tFblFsmGuard FblBmState_Init_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) || defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) +static tFblFsmGuard FblBmState_CallFailsafeUpdater_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY) +static tFblFsmGuard FblBmState_CallFblInitKey_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY */ +#if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) +static tFblFsmGuard FblBmState_CallTarget_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBLBM_BOOTTARGETLIST_SIZE > 0u */ +static tFblFsmGuard FblBmState_CallFbl_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) +static tFblFsmGuard FblBmState_CallFblStayInBoot_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +static tFblFsmGuard FblBmState_CheckEarlyFblSegments (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBLBM_ENABLE_SECURE_BOOT */ +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) +static tFblFsmGuard FblBmState_CallFblInitCmac_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ +static tFblFsmGuard FblBmState_Fail_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +/* Guards */ +static tFblFsmGuard FblBmState_CheckFblValidity (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) +static tFblFsmGuard FblBmState_FailsafeUpdaterSearchInit (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +static tFblFsmGuard FblBmState_FailsafeUpdaterCheck (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +static tFblFsmGuard FblBmState_FailsafeUpdaterSearchNext (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#elif defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) +static tFblFsmGuard FblBmState_FailsafeUpdaterUserCheck (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) +static tFblFsmGuard FblBmState_CheckSignedPresPattKeyAvailability (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +static tFblFsmGuard FblBmState_CallFblInitKeySignedPresPatt (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +static tFblFsmGuard FblBmState_CheckSignedPresPattValidity (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + +static tFblFsmGuard FblBmState_CheckKeyAvailability (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) +static tFblFsmGuard FblBmState_CheckFblMacErased (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ +#if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) +static tFblFsmGuard FblBmState_CheckApplStartFlag (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ +static tFblFsmGuard FblBmState_CheckReprogFlag (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +static tFblFsmGuard FblBmState_CheckFblLbt (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) +static tFblFsmGuard FblBmState_CheckReprogLbt (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ +#if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) +static tFblFsmGuard FblBmState_TargetListInit (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +static tFblFsmGuard FblBmState_TargetCheck (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +static tFblFsmGuard FblBmState_TargetListNext (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); +#endif /* FBLBM_BOOTTARGETLIST_SIZE > 0u */ +static tFblFsmGuard FblBmState_CheckLateFblSegments (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); + +#define FBLBM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBLBM_HEADER_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/** BM header data for access from application software */ +V_MEMROM0 V_MEMROM1 tFblBmHeader V_MEMROM2 FblBmHeader = /* PRQA S 1514 */ /* MD_FblBmMain_1514_BmHeader */ +{ + FBLBM_HEADER_MAGIC_VALUE, + FBLBM_HEADER_MAJOR_VERSION, + FBLBM_HEADER_MINOR_VERSION, + FBL_HEADER_ADDRESS, +#if defined( FBLBM_MAIN_ENABLE_FBL_START ) + (tFblStrtFct)&FblStart, +#else + (tFblStrtFct)V_NULL, +#endif +#if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) + (tApplStrtFct)&ApplStart, +#else + (tApplStrtFct)V_NULL, +#endif + 0u, /* Checksum is not yet used */ + FBLBM_HEADER_END_MAGIC_VALUE +}; +#define FBLBM_HEADER_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +#define FBLBM_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/** Block Info for the FBL block */ +V_MEMRAM0 static V_MEMRAM1 tFblBmBlockInfo V_MEMRAM2 fblBmBlockInfo; + +#if defined( FBLBM_ENABLE_STANDALONE_MODE ) +/** Local copy of FBL header structure */ +V_MEMRAM0 static V_MEMRAM1 tFblHeader V_MEMRAM2 fblBmFblHeader; /* PRQA S 3218 */ /* MD_FBL_3218_FileScopeStatic */ +#endif /* FBLBM_ENABLE_STANDALONE_MODE */ + +/** Context Structure of the Finite State Machine (FSM) */ +V_MEMRAM0 static V_MEMRAM1 tFblFsmContext V_MEMRAM2 g_BmFsmContext; /* PRQA S 3218 */ /* MD_FBL_3218_FileScopeStatic */ + +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) || defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) +/** Entry Point for Failsafe Updater */ +V_MEMRAM0 static V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 g_BmFailsafeUpdaterBmHeader; +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + +#if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) +/** Counter for search for valid target */ +V_MEMRAM0 static V_MEMRAM1 vuintx V_MEMRAM2 g_BmTargetListIndex; +/** Entry Point for target */ +V_MEMRAM0 static V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 g_BmTargetBmHeader; +#endif /* FBLBM_BOOTTARGETLIST_SIZE > 0u */ + +/** Error Code */ +V_MEMRAM0 static V_MEMRAM1 tFblBmError V_MEMRAM2 g_BmError; + +#define FBLBM_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/***** State machine *****/ + +#define FBLBM_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/** State PowerOn (0) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_PowerOn[] = { + /* Initialize Memory and go directly to next step: Init + */ + FBL_FSM_TRIGGER_ENTRY(FblBmState_PowerOn_Entry), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_INIT) +}; + +/** State Init (1) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_Init[] = { + /* Call Init Routines + * GOTO next step on continue-event + */ + FBL_FSM_TRIGGER_ENTRY(FblBmState_Init_Entry), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CHECK_FBL_VALIDITY) +}; + +/** State CheckFblValidity (2) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckFblValidity[] = { + /* Configuration switch: + * IF Extended PP is enabled goto state CheckKeyPPAvailability + * ELSEIF FBL is valid goto state CheckSecureBootEnabled + * ELSE GOTO UpdaterEnabled + */ +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckFblValidity, FBLBM_STATE_CHECK_PP_KEY_AVAILABILITY), +#else + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckFblValidity, FBLBM_STATE_SECURE_BOOT_ENABLED), +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAILSAFE_UPDATER_ENABLED) +}; + +/** State FailsafeUpdaterEnabled (3) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_FailsafeUpdaterEnabled[] = { + /* Configuration switch: If Updater support is enabled search for updater. + * This state is reached when no valid FBL is available. This can only happen + * if a FBL-update process is interrupted. + */ +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAILSAFE_UPDATER_SEARCH_INIT) +#elif defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAILSAFE_UPDATER_USER_CHECK) +#else /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ +}; + +/** State FailsafeUpdaterSearchInit (4) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_FailsafeUpdaterSearchInit[] = { +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_FailsafeUpdaterSearchInit, FBLBM_STATE_FAILSAFE_UPDATER_CHECK), /* */ +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State FailsafeUpdaterCheck (5) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_FailsafeUpdaterCheck[] = { + /* If a update is aborted e.g. due to power loss, the FBL may be already erased. + * In this case: Search for a valid Updater and call it + */ +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_FailsafeUpdaterCheck, FBLBM_STATE_CALL_FAILSAFE_UPDATER), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAILSAFE_UPDATER_SEARCH_NEXT), +#else /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ +}; + +/** State FailsafeUpdaterSearchNext (6) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_FailsafeUpdaterSearchNext[] = { +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_FailsafeUpdaterSearchNext, FBLBM_STATE_FAILSAFE_UPDATER_CHECK), +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State FailsafeUpdaterUserCheck (7) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_FailsafeUpdaterUserCheck[] = { +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_FailsafeUpdaterUserCheck, FBLBM_STATE_CALL_FAILSAFE_UPDATER), +#endif + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State CallFailsafeUpdater (8) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFailsafeUpdater[] = { + /* Start the Updater + */ +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) || defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) + FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFailsafeUpdater_Entry), +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + + +/** State CheckSignedPresPattKeyAvailability (9) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckSignedPresPattKeyAvailability[] = { + /* Check if a Key is already available. If not, FBL shall be called to initialize the key. + */ +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckSignedPresPattKeyAvailability, FBLBM_STATE_CHECK_SIGNED_PP_VALIDITY), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CALL_FBL_PP_INIT_KEY) +#else /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ +}; + +/** State CallFblInitKeySignedPresPatt (10) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFblInitKeySignedPresPatt[] = { + /* Call FBL to initialize key */ +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) + FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFblInitKeySignedPresPatt), +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State CheckSignedPresPattValidity with MAC (11) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckSignedPresPattValidity[] = { +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckSignedPresPattValidity, FBLBM_STATE_SECURE_BOOT_ENABLED), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAILSAFE_UPDATER_ENABLED) +#else /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ +}; + +/** State SecureBootEnabled (12) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_SecureBootEnabled[] = { + /* Configuration switch: + * IF Secure Boot is enabled GOTO CheckKeyAvailability + * ELSE skip this step + */ +#if defined( FBLBM_ENABLE_SECURE_BOOT ) + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_KEY_AVAILABILITY) +#else + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_EARLY_FBL_SEGMENTS) +#endif +}; + +/** State CheckKeyAvailability (13) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckKeyAvailability[] = { + /* Check if a Key is already available. If not, FBL shall be called to initialize the key. + */ + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckKeyAvailability, FBLBM_STATE_INIT_FBL_MAC_ENABLED), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CALL_FBL_INIT_KEY) +}; + +/** State CallFblInitKey (14) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFblInitKey[] = { + /* Call FBL to initialize key */ +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY) + FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFblInitKey_Entry), +#endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY */ + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State InitFblCmacEnabled (15) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_InitFblMacEnabled[] = { + /* Configuration switch: + * IF Secure Boot is enabled GOTO CheckFblMacErased + * ELSE skip this step + */ +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_FBL_MAC_ERASED) +#else /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_EARLY_FBL_SEGMENTS) +#endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ +}; + +/** State CheckFblMacErased (16) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckFblMacErased[] = { + /* Check if a CMAC is available. If not, the FBL is probably written with a debugger and the CMAC area is in erased state. FBL shall be called to initialize the CMAC. + */ +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckFblMacErased, FBLBM_STATE_CALL_FBL_INIT_CMAC), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CHECK_EARLY_FBL_SEGMENTS) +#else /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) +#endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ +}; + +/** State CallFblInitCmac (17) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFblInitCmac[] = { + /* Call FBL and set Magicflag to make it init its CMAC. Shall be used only for debugging. + */ +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) + FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFblInitCmac_Entry), +#endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State StayInBootEnabled (18) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_StayInBootEnabled[] = { + /* Configuration Switch: If Stay in Boot is enabled, ApplStartMagicFlag must be evaluated to decide + * if the application shall be started. Otherwise this can be skipped. + */ +#if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT) + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_APPL_START_FLAG) +#else /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_FBL_LBT) +#endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ + }; + +/** State CheckApplStartFlag (19) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckApplStartFlag[] = { + /* Evaluate ApplStartMagicFlag to decide if the application shall be started. + */ +#if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckApplStartFlag, FBLBM_STATE_CHECK_FBL_LBT), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CHECK_FBL_VERIFICATION_STAY_IN_BOOT) +#else /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) +#endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ +}; + +/** State CheckFblLbt (20) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckFblLbt[] = { + /* Check validity and verification of FBL-LBT + * If it can't be verified/validated, something went wrong: The FBL (which contains the FBL-LBT) is valid but + * the LBT is not verified/valid => Fail + */ + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckFblLbt, FBLBM_STATE_REPROG_LBT_ENABLED), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State CheckReprogFlag (21) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckReprogFlag[] = { + /* Check if Reprogramming Flag is set. If so, check if FBL is valid. + */ + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckReprogFlag, FBLBM_STATE_CHECK_LATE_FBL_SEGMENTS), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_STAY_IN_BOOT_ENABLED) +}; + +/** State ReprogLbtEnable (22) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_ReprogLbtEnabled[] = { + /* Configuration Switch: If a reprogrammable LBT is used... + */ +#if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) + FBL_FSM_TRIGGER_UNCONDITIONAL( FBLBM_STATE_CHECK_REPROG_LBT), +#else /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ + FBL_FSM_TRIGGER_UNCONDITIONAL( FBLBM_STATE_TARGET_LIST_INIT) +#endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ +}; + +/** State CheckReprogLbt (23) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckReprogLbt[] = { + /* Check validity/verification of the reprogrammable LBT. If it is not usable, the application can not be found. + * Therefore the FBL is called as a fallback. + */ +#if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckReprogLbt, FBLBM_STATE_TARGET_LIST_INIT), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CHECK_LATE_FBL_SEGMENTS) +#else /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) +#endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ +}; + +/** State TargetListInit (24) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_TargetListInit[] = { + /* Prepare searching the target list + */ +#if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_TargetListInit, FBLBM_STATE_TARGET_CHECK), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +#else /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_LATE_FBL_SEGMENTS) +#endif /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ +}; + +/** State TargetCheck (25) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_TargetCheck[] = { + /* Check one entry of the target list. If all conditions match, call the target. + * Otherwise go to "Next" + */ +#if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_TargetCheck, FBLBM_STATE_CALL_TARGET), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_TARGET_LIST_NEXT) +#else /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) +#endif /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ +}; + +/** State TargetListNext (26) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_TargetListNext[] = { + /* Get next element form target list + */ +#if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_TargetListNext, FBLBM_STATE_TARGET_CHECK), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CHECK_LATE_FBL_SEGMENTS) +#else /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) +#endif /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ +}; + +/** State CallTarget (27) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallTarget[] = { + /* Start the application/updater + */ +#if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) + FBL_FSM_TRIGGER_ENTRY(FblBmState_CallTarget_Entry), +#endif /* FBLBM_BOOTTARGETLIST_SIZE > 0u */ + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State CheckLateFblSegments (28) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckLateFblSegments[] = { + /* If verification (CMAC) of FBL is successful, call it. Otherwise go to Fail state + */ + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckLateFblSegments, FBLBM_STATE_CALL_FBL), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State CheckFblVerificationStayInBoot (29) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckFblVerificationStayInBoot[] = { + /* If verification (CMAC) of FBL is successful, call it. Otherwise go to Fail state + */ + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckLateFblSegments, FBLBM_STATE_CALL_FBL_STAY_IN_BOOT), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State CallFbl (30) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFbl[] = { + /* Start FBL */ + FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFbl_Entry), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State CallFblStayInBoot (31) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFblStayInBoot[] = { + /* Start FBL (StayInBoot)*/ +#if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT) + FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFblStayInBoot_Entry), +#endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +}; + +/** State CheckEarlyFblSegments (32) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckEarlyFblSegments[] = { + /* Check if FBL-Segments are valid. + */ +#if defined( FBLBM_ENABLE_SECURE_BOOT ) + FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckEarlyFblSegments, FBLBM_STATE_CHECK_REPROG_FLAG), + FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) +#else /* FBLBM_ENABLE_SECURE_BOOT */ + FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_REPROG_FLAG) +#endif /* FBLBM_ENABLE_SECURE_BOOT */ +}; + +/** State Fail (33) */ +V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_Fail[] = { + /* Fail State + */ + FBL_FSM_TRIGGER_ENTRY(FblBmState_Fail_Entry) +}; + +/** List of all States */ +V_MEMROM0 static V_MEMROM1 tFblFsmStateDefinition V_MEMROM2 bmFsmStates[] = /* PRQA S 3218 */ /* MD_FBL_3218_FileScopeStatic */ +{ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_PowerOn) }, /* 0 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_Init) }, /* 1 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckFblValidity) }, /* 2 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_FailsafeUpdaterEnabled) }, /* 3 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_FailsafeUpdaterSearchInit) }, /* 4 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_FailsafeUpdaterCheck) }, /* 5 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_FailsafeUpdaterSearchNext) }, /* 6 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_FailsafeUpdaterUserCheck ) }, /* 7 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFailsafeUpdater) }, /* 8 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckSignedPresPattKeyAvailability) }, /* 9 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFblInitKeySignedPresPatt) }, /* 10 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckSignedPresPattValidity) }, /* 11 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_SecureBootEnabled) }, /* 12 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckKeyAvailability) }, /* 13 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFblInitKey) }, /* 14 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_InitFblMacEnabled) }, /* 15 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckFblMacErased) }, /* 16 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFblInitCmac) }, /* 17 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_StayInBootEnabled) }, /* 18 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckApplStartFlag) }, /* 19 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckFblLbt) }, /* 20 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckReprogFlag) }, /* 21 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_ReprogLbtEnabled) }, /* 22 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckReprogLbt) }, /* 23 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_TargetListInit) }, /* 24 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_TargetCheck) }, /* 25 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_TargetListNext) }, /* 26 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallTarget) }, /* 27 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckLateFblSegments) }, /* 28 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckFblVerificationStayInBoot) }, /* 29 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFbl) }, /* 30 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFblStayInBoot) }, /* 31 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckEarlyFblSegments) }, /* 32 */ + { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_Fail) } /* 33 */ +}; +#define FBLBM_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +#define FBLBM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * FblBmState_PowerOn_Entry + *********************************************************************************************************************/ +/*! \brief Called directly on PowerOn + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_PowerOn_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + g_BmError = FBLBM_ERROR_NO_ERROR; + + FBLBM_CALLOUT_POWER_ON_PRE_HW(); + FBLBM_CALLOUT_POWER_ON_PRE_OEM(); + FBLBM_CALLOUT_POWER_ON_PRE(); + +#if !defined( FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON ) + /* Disable global interrupt handling */ + FblInterruptDisable(); /* PRQA S 1006 */ /* MD_FblBmMain_1006 */ +#endif /* FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON */ + +#if defined( FBLBM_MAIN_ENABLE_VTT_USECASE ) +#else + /* Check if bootmanager header address is correctly configured in generation tool */ + /* PRQA S 0306 1 */ /* MD_FblBmMain_0306_FblBmHeader */ + assertFblGen(FblBmHeaderLocal == FblBmHeaderTable, kFblSysAssertParameterOutOfRange); +#endif /* FBL_MAIN_ENABLE_VTT_USECASE */ + + /* Power on initialization of core modules */ + ClrWDInit(); + + MemDriver_InitPowerOn(); + +#if !defined( FBLBM_ENABLE_STANDALONE_MODE ) + /* Initialize states of diagnostic layer */ + FblDiagInitPowerOn(); +#endif + + /* Initialize intermediate access layer for LBT */ + FblLbtInitPowerOn(); + +#if defined( FBLBM_MAIN_ENABLE_HARDWARE_SWAP ) + /* Initialize hardware swap module */ + FblSwapInitPowerOn(); +#endif + + /* Initialization callout */ + FBLBM_CALLOUT_POWER_ON_POST_HW(); + FBLBM_CALLOUT_POWER_ON_POST_OEM(); + FBLBM_CALLOUT_POWER_ON_POST(); + + return kFblFsmGuard_True; +} + +/********************************************************************************************************************** + * FblBmState_Init_Entry + *********************************************************************************************************************/ +/*! \brief Called as a 2nd step after PowerOn + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_Init_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + /* Early initialization callout */ + FBLBM_CALLOUT_INIT_PRE_HW(); + FBLBM_CALLOUT_INIT_PRE_OEM(); + FBLBM_CALLOUT_INIT_PRE(); + + /* Initialize and activate watchdog */ + FblInitWatchdog(); + /* Initialize Timer */ + FblTimerInit(); + +#if defined( FBLBM_ENABLE_STANDALONE_MODE ) + EcuM_StartupTwo(); +#else + /* EcuM_StartupTwo is called by Bootloader + * Modules which should be already available in the Bootmanager should be placed in INIT_ZERO or INIT_ONE phase + */ +#endif + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) + /* Initializes SecureBoot */ + FblSb_Init(); +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + +#if defined( FBLBM_MAIN_ENABLE_HARDWARE_SWAP ) + /* Execute the flash partition swap */ + (void)FblSwapActivate(); +#endif /* FBLBM_MAIN_ENABLE_HARDWARE_SWAP */ + + /* Late initialization callout */ + FBLBM_CALLOUT_INIT_POST_HW(); + FBLBM_CALLOUT_INIT_POST_OEM(); + FBLBM_CALLOUT_INIT_POST(); + + return kFblFsmGuard_True; +} + +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) || defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) +/********************************************************************************************************************** + * FblBmState_CallFailsafeUpdater_Entry + *********************************************************************************************************************/ +/*! \brief Call a failsafe updater + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CallFailsafeUpdater_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + /* Disable Timer etc. */ + FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ + + /* Call Failsafe Updater */ + FBLBM_CALLOUT_CALL_FAILSAFE_UPDATER(&g_BmFailsafeUpdaterBmHeader); + + /* This code is never reached */ + return kFblFsmGuard_True; +} +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY ) +/********************************************************************************************************************** + * FblBmState_CallFblInitKey_Entry + *********************************************************************************************************************/ +/*! \brief Call the FBL and set a magic flag to direct him to init the missing key + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + * \config FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CallFblInitKey_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + /* Disable Timer etc. */ + FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ + + FblBmSetInitKeysMagicFlag(); + + /* Call Fbl */ + FBLBM_CALLOUT_CALL_FBL_INIT_KEYS(&fblBmBlockInfo.bmHeader); + + /* This code is never reached */ + return kFblFsmGuard_True; +} +#endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY */ + +#if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) +/********************************************************************************************************************** + * FblBmState_CallTarget_Entry + *********************************************************************************************************************/ +/*! \brief Call a target (Application, Updater) + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CallTarget_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +# endif + + /* Disable Timer etc. */ + FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ + + /* Call Appl */ + FBLBM_CALLOUT_CALL_TARGET(&g_BmTargetBmHeader); + + /* This code is never reached */ + return kFblFsmGuard_True; +} +#endif/* FBLBM_BOOTTARGETLIST_SIZE > 0u */ + +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) +/********************************************************************************************************************** + * FblBmState_CallFblInitCmac_Entry + *********************************************************************************************************************/ +/*! \brief Call the FBL to initialize the FBL-CMAC(s) + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + * \config FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CallFblInitCmac_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + /* Disable Timer etc. */ + FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ + + FblBmSetInitCmacMagicFlag(); + + /* Call Fbl */ + FBLBM_CALLOUT_CALL_FBL_INIT_CMAC(&fblBmBlockInfo.bmHeader); + + /* This code is never reached */ + return kFblFsmGuard_True; +} +#endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ + +/********************************************************************************************************************** + * FblBmState_CallFbl_Entry + *********************************************************************************************************************/ +/*! \brief Start the FBL + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CallFbl_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + /* Disable Timer etc. */ + FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ + + /* Call Fbl */ + FBLBM_CALLOUT_CALL_FBL(&fblBmBlockInfo.bmHeader); + + /* This code is never reached */ + return kFblFsmGuard_True; +} + +# if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) +/********************************************************************************************************************** + * FblBmState_CallFblStayInBoot_Entry + *********************************************************************************************************************/ +/*! \brief Start the FBL and set the magic flag that to check for a stay in boot message + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CallFblStayInBoot_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + /* Disable Timer etc. */ + FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ + + FblBmSetStayInBootMagicFlag(); + + /* Call Fbl */ + FBLBM_CALLOUT_CALL_FBL(&fblBmBlockInfo.bmHeader); + + /* This code is never reached */ + return kFblFsmGuard_True; +} +#endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +/********************************************************************************************************************** + * FblBmState_CheckEarlyFblSegments + *********************************************************************************************************************/ +/*! \brief Start Early check of FBL segments. + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CheckEarlyFblSegments(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result = kFblFsmGuard_True; + +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +# endif + +# if defined( FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK ) + if (kFblOk != FblSb_VerifySegments(&fblBmBlockInfo.bmHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_FBL_VERIFICATION_FAILED; + } +# endif /* FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK */ + + return result; +} +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + +/********************************************************************************************************************** + * FblBmState_Fail_Entry + *********************************************************************************************************************/ +/*! \brief An error has happened. + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_Fail_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + + FBLBM_CALLOUT_FATAL_ERROR(g_BmError); + + return kFblFsmGuard_False; +} + +/********************************************************************************************************************** + * FblBmCheckFblValidity + *********************************************************************************************************************/ +/*! \brief Checks the Header and the validity (e.g.: Presence Pattern) of the FBL + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CheckFblValidity(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + result = kFblFsmGuard_True; + +#if defined( FBLBM_ENABLE_STANDALONE_MODE ) + /* Read FBL header from configured memory location */ + + if (FblReadProm(FblBmHeader.fblHeaderAddress, (vuint8*) &fblBmFblHeader, sizeof(tFblHeader)) != sizeof(tFblHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_HEADER_READ_FAILED; + } + + /* Check magic flag of the FBL header */ + if (kFblFsmGuard_True == result) + { + if (fblBmFblHeader.magicFlag != FBL_MAIN_HEADER_MAGIC_FLAG) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_HEADER_MAGIC_FAILED; + } + } + + if (kFblFsmGuard_True == result) + { + /* Fill out the block descriptor for the FBL */ + fblBmBlockInfo.logicalBlock.blockStartAddress = fblBmFblHeader.fblStartAddress; + fblBmBlockInfo.logicalBlock.blockLength = fblBmFblHeader.fblLength; + fblBmBlockInfo.logicalBlock.bmHeaderAddress = (tFblAddress) fblBmFblHeader.bmHeader; /* PRQA S 0306 */ /* MD_FblBmMain_0306 */ + fblBmBlockInfo.logicalBlock.mandatoryType = TRUE; + fblBmBlockInfo.logicalBlock.blockNr = 0x00u; +# if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) + /* Check if Presence Pattern is valid */ + if (kFblOk != FBLBM_CALLOUT_IS_VALIDPATTERN(FBLBMHDR_TARGET_FBL, &fblBmBlockInfo.logicalBlock)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_VALIDITY_FAILED; + } +# else + /* Check if FBL is valid (e.g.: evaluate Presence Pattern) */ + if (kFblOk != FBLBM_CALLOUT_IS_VALIDBLOCK(FBLBMHDR_TARGET_FBL, &fblBmBlockInfo.logicalBlock)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_VALIDITY_FAILED; + } +# endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + } + +#else + + /* Fill out the block descriptor for the FBL */ + fblBmBlockInfo.logicalBlock.blockStartAddress = FblHeader.fblStartAddress; + fblBmBlockInfo.logicalBlock.blockLength = FblHeader.fblLength; + fblBmBlockInfo.logicalBlock.bmHeaderAddress = (tFblAddress) FblHeader.bmHeader; /* PRQA S 0306 */ /* MD_FblBmMain_0306 */ + fblBmBlockInfo.logicalBlock.mandatoryType = TRUE; + fblBmBlockInfo.logicalBlock.blockNr = 0x00u; + + +#endif /* FBLBM_ENABLE_STANDALONE_MODE */ + + if (kFblFsmGuard_True == result) /* PRQA S 2991, 2995 */ /* MD_FblBmMain_2991_2995 */ + { + if (FBLBMHDR_CHKHDR_OK != FblBmHdrGetBmHeader(FBLBMHDR_TARGET_FBL, fblBmBlockInfo.logicalBlock.bmHeaderAddress, &fblBmBlockInfo.bmHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_FBL_BMHEADER_INCORRECT; + } + } + + return result; +} + +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) +/********************************************************************************************************************** + * FblBmState_FailsafeUpdaterSearchInit + *********************************************************************************************************************/ +/*! \brief Prepare the search for an failsafe Updater. + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + * \config FBLBM_ENABLE_UPDATER_FAILSAFE + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_FailsafeUpdaterSearchInit(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + /* Get BmHeader address from callout. In case FBLBM_ENABLE_UPDATER_FAILSAFE is enabled, callout + * FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT is requested to return the next possible location + */ + if (kFblOk == FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT()) + { + result = kFblFsmGuard_True; + } + else + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_UPDATER_SEARCH_INIT_FAILED; + } + return result; +} + +/********************************************************************************************************************** + * FblBmState_CheckFailsafeUpdater + *********************************************************************************************************************/ +/*! \brief Check if failsafe updater is valid and can be verified. + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + * \config FBLBM_ENABLE_UPDATER_FAILSAFE + *********************************************************************************************************************/ +/* PRQA S 3673, 6010, 6030 1 */ /* MD_FBL_3673_PointerToConstParameter, MD_MSR_STPTH, MD_MSR_STCYC */ +static tFblFsmGuard FblBmState_FailsafeUpdaterCheck(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + tFblBmBlockInfo blockInfo = { 0 }; + vuint32 headerAddress; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + result = kFblFsmGuard_True; + if (kFblOk != FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS(&headerAddress)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_UPDATER_HEADER_ADDRESS; + } + + /* Hint: The order of checks is different than checking an application because the FBL-LBT can not be used here */ + if (kFblFsmGuard_True == result) + { + blockInfo.bmHeader.bmTargetHandle = FBLBMHDR_TARGET_FBLUPDATER; + blockInfo.bmHeader.bmBlockStartAddress = 0u; + blockInfo.bmHeader.bmBlockLength = 1u; + blockInfo.bmHeader.bmEntryAddress = 0u; + + /* Read BM header from flash */ + if (FblReadProm(headerAddress, (vuint8 *)&blockInfo.bmHeader, sizeof(tFblBmHdrHeader)) != sizeof(tFblBmHdrHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_UPDATER_HEADER_READ_ERROR; + } + } + + /* Check for correct target handle */ + if (kFblFsmGuard_True == result) + { + if (blockInfo.bmHeader.bmTargetHandle != FBLBMHDR_TARGET_FBLUPDATER) /* PRQA S 2992,2996 */ /* MD_FblBmMain_2880_2992_2996_FlashRead */ + { + result = kFblFsmGuard_False; /* PRQA S 2880 */ /* MD_FblBmMain_2880_2992_2996_FlashRead */ + g_BmError = FBLBM_ERROR_UPDATER_HEADER_TYPE; + } + } + + /* Check for consistency errors */ + if (kFblFsmGuard_True == result) + { + if ( kFblOk != FblBmHdrCheckConsistency(&blockInfo.bmHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_UPDATER_HEADER_CONSISTENCY; + } + } + + /* Header seems to be OK, check if block is valid */ + if (kFblFsmGuard_True == result) + { + /* Initialize the logical block structure */ + blockInfo.logicalBlock.blockStartAddress = blockInfo.bmHeader.bmBlockStartAddress; + blockInfo.logicalBlock.blockLength = blockInfo.bmHeader.bmBlockLength; + + if (kFblOk != FBLBM_CALLOUT_IS_VALIDBLOCK(blockInfo.bmHeader.bmTargetHandle, &blockInfo.logicalBlock)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_UPDATER_BLOCK_VALIDITY; + } + } + +# if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) + if (kFblFsmGuard_True == result) + { +# if defined( FBLBM_ENABLE_USE_VERIFY_HEADER_ROM ) + if (kFblOk != FblSb_VerifyHeaderRom(headerAddress, &blockInfo.bmHeader)) +# else + if (kFblOk != FblSb_VerifyHeader(&blockInfo.bmHeader)) +# endif /* FBLBM_ENABLE_USE_VERIFY_HEADER_ROM */ + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_UPDATER_HEADER_CMAC_VERIFY; + } + } +# endif /* FBLBM_ENABLE_HEADER_VERIFICATION */ + + if (kFblFsmGuard_True == result) + { + if (kFblOk != FblSb_VerifySegments(&blockInfo.bmHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_UPDATER_VERIFY; + } + } +# endif /* FBLBM_ENABLE_SECURE_BOOT */ + + if (kFblFsmGuard_True == result) + { + g_BmFailsafeUpdaterBmHeader = blockInfo.bmHeader; + } + + return result; +} + +/********************************************************************************************************************** + * FblBmState_FailsafeUpdaterSearchNext + *********************************************************************************************************************/ +/*! \brief Get next possible location for a Failsafe Updater BmHeader + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + * \config FBLBM_ENABLE_UPDATER_FAILSAFE + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_FailsafeUpdaterSearchNext(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + if (kFblOk == FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT()) + { + result = kFblFsmGuard_True; + } + else + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_UPDATER_SEARCH_NEXT_FINISHED; + } + + return result; +} +#elif defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) +/********************************************************************************************************************** + * FblBmState_FailsafeUpdaterUserCheck + *********************************************************************************************************************/ +/*! \brief Prepare the search for an failsafe Updater. + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + * \config FBLBM_ENABLE_UPDATER_FAILSAFE_USER + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_FailsafeUpdaterUserCheck(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result = kFblFsmGuard_False; +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + if (FBLBM_CALLOUT_FAILSAFE_UPDATER_USER_CHECK(&g_BmFailsafeUpdaterBmHeader) == kFblOk) + { + result = kFblFsmGuard_True; + } + + return result; +} +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) +/********************************************************************************************************************** + * FblBmState_CheckSignedPresPattKeyAvailability + *********************************************************************************************************************/ +/*! \brief Check if Key is available for MAC verification. If not, the FBL is called to initialize PP the key. + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CheckSignedPresPattKeyAvailability(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + if (FBLBM_KEY_IS_NOT_AVAILABLE == FBLBM_CALLOUT_GET_PP_SIGN_KEYEMPTY()) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_KEY_NOT_AVAILABLE; + } + else + { + result = kFblFsmGuard_True; + } + return result; +} + +/********************************************************************************************************************** + * FblBmState_CallFblInitKeySignedPresPatt + *********************************************************************************************************************/ +/*! \brief Call the FBL and set a magic flag to direct him to init the missing signed presence pattern key + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CallFblInitKeySignedPresPatt(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + /* Disable Timer etc. */ + FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ + + FblBmSetSignedPPMagicFlag(); + + /* Call Fbl */ + FBLBM_CALLOUT_CALL_FBL_INIT_SIGNED_PRESENCEPATTERN(&fblBmBlockInfo.bmHeader); + + /* This code is never reached */ + return kFblFsmGuard_True; +} + +/********************************************************************************************************************** + * FblBmState_CheckSignedPresPattValidity + *********************************************************************************************************************/ +/*! \brief Checks the Header and the validity (e.g.: signed Presence Pattern) of the FBL + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CheckSignedPresPattValidity(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + result = kFblFsmGuard_True; + +#if defined( FBLBM_ENABLE_STANDALONE_MODE ) + /* Read FBL header from configured memory location */ + + if (FblReadProm(FblBmHeader.fblHeaderAddress, (vuint8*) &fblBmFblHeader, sizeof(tFblHeader)) != sizeof(tFblHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_HEADER_READ_FAILED; + } + + /* Check magic flag of the FBL header */ + if (kFblFsmGuard_True == result) + { + if (fblBmFblHeader.magicFlag != FBL_MAIN_HEADER_MAGIC_FLAG) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_HEADER_MAGIC_FAILED; + } + } + + if (kFblFsmGuard_True == result) + { + /* Fill out the block descriptor for the FBL */ + fblBmBlockInfo.logicalBlock.blockStartAddress = fblBmFblHeader.fblStartAddress; + fblBmBlockInfo.logicalBlock.blockLength = fblBmFblHeader.fblLength; + fblBmBlockInfo.logicalBlock.bmHeaderAddress = (tFblAddress) fblBmFblHeader.bmHeader; /* PRQA S 0306 */ /* MD_FblBmMain_0306 */ + fblBmBlockInfo.logicalBlock.mandatoryType = TRUE; + fblBmBlockInfo.logicalBlock.blockNr = 0x00u; + + /* Check if FBL is valid (e.g.: evaluate Presence Pattern) */ + if (kFblOk != FBLBM_CALLOUT_IS_VALIDBLOCK(FBLBMHDR_TARGET_FBL, &fblBmBlockInfo.logicalBlock)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_VALIDITY_FAILED; + } + } + +#else + + /* Fill out the block descriptor for the FBL */ + fblBmBlockInfo.logicalBlock.blockStartAddress = FblHeader.fblStartAddress; + fblBmBlockInfo.logicalBlock.blockLength = FblHeader.fblLength; + fblBmBlockInfo.logicalBlock.bmHeaderAddress = (tFblAddress) FblHeader.bmHeader; /* PRQA S 0306 */ /* MD_FblBmMain_0306 */ + fblBmBlockInfo.logicalBlock.mandatoryType = TRUE; + fblBmBlockInfo.logicalBlock.blockNr = 0x00u; + + +#endif /* FBLBM_ENABLE_STANDALONE_MODE */ + + if (kFblFsmGuard_True == result) /* PRQA S 2991, 2995 */ /* MD_FblBmMain_2991_2995 */ + { + if (FBLBMHDR_CHKHDR_OK != FblBmHdrGetBmHeader(FBLBMHDR_TARGET_FBL, fblBmBlockInfo.logicalBlock.bmHeaderAddress, &fblBmBlockInfo.bmHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_FBL_BMHEADER_INCORRECT; + } + } + + return result; +} +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ +/********************************************************************************************************************** + * FblBmState_CheckKeyAvailability + *********************************************************************************************************************/ +/*! \brief Check if Key is available for MAC verification. If not, the FBL is called to initialize the key. + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CheckKeyAvailability(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) && \ + defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY ) + if (FBLBM_KEY_IS_NOT_AVAILABLE == FBLBM_CALLOUT_GET_KEYEMPTY()) + { + /* Key is not available */ + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_KEY_NOT_AVAILABLE; + } + else + { + result = kFblFsmGuard_True; + } +#else + /* No key needed or not configured to be checked, return OK to proceed */ + result = kFblFsmGuard_True; +#endif + return result; +} + +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) +/********************************************************************************************************************** + * FblBmState_CheckFblMacErased + *********************************************************************************************************************/ +/*! \brief Check if a CMAC (even an invalid one) is written for the FBL - if not call FBL to write a CMAC. + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + * \config FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CheckFblMacErased(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + if (FBLBM_MAC_IS_AVAILABLE == FBLBM_CALLOUT_GET_FBL_CMACERASED(&fblBmBlockInfo)) + { + /* FBL-CMAC is already written */ + result = kFblFsmGuard_False; + } + else + { + /* FBL-CMAC is not yet written */ + result = kFblFsmGuard_True; + } + return result; +} +#endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ + +#if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) +/********************************************************************************************************************** + * FblBmState_CheckApplStartFlag + *********************************************************************************************************************/ +/*! \brief Check if the ApplStart flag is set + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + * \config FBLBM_MAIN_ENABLE_STAY_IN_BOOT + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CheckApplStartFlag( tFblFsmContextPtr const pFsmContext, tFblFsmEvent event ) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + if (FblBmChkApplStartMagicFlag()) + { + FblBmClrMagicFlag(); + result = kFblFsmGuard_True; + } + else + { + result = kFblFsmGuard_False; + } + + return result; +} +#endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ + +/********************************************************************************************************************** + * FblBmState_CheckReprogFlag + *********************************************************************************************************************/ +/*! \brief Check if Reprogramming Flag is set + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + * \config FBL_DISABLE_STAY_IN_BOOT + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CheckReprogFlag(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + /* Check if there is a reprogramming request (e.g. UDS, XCP, MCMP, OTA) */ + if (FBLBM_CALLOUT_CHECKREPROGFLAG() == kFblOk) + { + /* Do not clear flag, as the Bootloader requires it as well */ + + result = kFblFsmGuard_True; + } + else + { + result = kFblFsmGuard_False; + } + + return result; +} + +/********************************************************************************************************************** + * FblBmState_CheckFblLbt + *********************************************************************************************************************/ +/*! \brief Check the validity and verification of the FBL-LBT and / or FblBmHeader + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673, 6010 1 */ /* MD_FBL_3673_PointerToConstParameter, MD_MSR_STPTH */ +static tFblFsmGuard FblBmState_CheckFblLbt(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +#if defined( FBLBM_ENABLE_STANDALONE_MODE ) + tFblFsmGuard result = kFblFsmGuard_True; + +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +# endif + +# if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) +# if defined( FBLBM_ENABLE_USE_VERIFY_HEADER_ROM ) + if (kFblOk != FblSb_VerifyHeaderRom(fblBmBlockInfo.logicalBlock.bmHeaderAddress, &fblBmBlockInfo.bmHeader)) +# else + if (kFblOk != FblSb_VerifyHeader(&fblBmBlockInfo.bmHeader)) +# endif /* FBLBM_ENABLE_USE_VERIFY_HEADER_ROM */ + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_FBL_BMHEADER_VERIFICATION_FAILED; + } + + if (kFblFsmGuard_False != result) +# endif /* FBLBM_ENABLE_HEADER_VERIFICATION */ + { +# if defined( FBLBM_ENABLE_FBLLBT_VERIFICATION ) + if (kFblOk != FblSb_VerifyFblLbt(&fblBmFblHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_LBT_VERIFY; + } + else +# endif /* FBLBM_ENABLE_FBLLBT_VERIFICATION */ +# else /* FBLBM_ENABLE_SECURE_BOOT */ + { +# endif /* FBLBM_ENABLE_SECURE_BOOT */ + { + /* Validation of FBL-LBT successful: Use Fbl-LBT */ + FblLbtActivateLbtBlockByAddress((tFblAddress)fblBmFblHeader.pLogicalBlockTable); /* PRQA S 0306 */ /* MD_FblBmMain_0306 */ + + /* Consistency check (BM-LBT <-> FBL-LBT) */ + /* Check if block count exceeds built-in maximum value */ + if (FblLbtGetBlockCount() > FBL_LBT_BLOCK_COUNT) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_LBT_TOO_LARGE; + } + else + { + result = kFblFsmGuard_True; + } + } + } + + if (kFblFsmGuard_True != result) + { + /* Failure - switch back to internal LBT */ + FblLbtInitPowerOn(); + } + + return result; +#else +# if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +# endif + + return kFblFsmGuard_True; +#endif /* FBLBM_ENABLE_STANDALONE_MODE */ +} + +#if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) +/********************************************************************************************************************** + * FblBmState_CheckReprogLbt + *********************************************************************************************************************/ +/*! \brief Check if a Reprogrammable LBT is available. If so, use it. + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + * \config FBL_LBT_ENABLE_REPROGRAMMABLE_LBT + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CheckReprogLbt( tFblFsmContextPtr const pFsmContext, tFblFsmEvent event ) +{ + tFblFsmGuard result; + tFblBmBlockInfo blockInfo; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + result = kFblFsmGuard_True; + + /* Get Reprog-LBT from FBL-LBT */ + if (kFblOk != FblLbtGetBlockDescriptorByNr(FBL_LBT_LBT_BLOCK_NUMBER, &blockInfo.logicalBlock)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_REPROG_LBT_DESCR; + } + + if (kFblFsmGuard_True == result) + { + if (kFblOk != FBLBM_CALLOUT_IS_VALIDBLOCK(FBLBMHDR_TARGET_REPROGLBT, &blockInfo.logicalBlock)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_REPROG_LBT_INVALID; + } + } + + if (kFblFsmGuard_True == result) + { + if (FBLBMHDR_CHKHDR_OK != FblBmHdrGetBmHeader(FBLBMHDR_TARGET_REPROGLBT, blockInfo.logicalBlock.bmHeaderAddress, &blockInfo.bmHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_REPROG_LBT_BMHEADER_INCORRECT; + } + } + +# if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) + if (kFblFsmGuard_True == result) + { +# if defined( FBLBM_ENABLE_USE_VERIFY_HEADER_ROM ) + if (kFblOk != FblSb_VerifyHeaderRom(blockInfo.logicalBlock.bmHeaderAddress, &blockInfo.bmHeader)) +# else + if (kFblOk != FblSb_VerifyHeader(&blockInfo.bmHeader)) +# endif /* FBLBM_ENABLE_USE_VERIFY_HEADER_ROM */ + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_REPROG_LBT_VERIFY_HEADER; + } + } +# endif/* FBLBM_ENABLE_HEADER_VERIFICATION */ + + if (kFblFsmGuard_True == result) + { + if (kFblOk != FblSb_VerifySegments(&blockInfo.bmHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_REPROG_LBT_VERIFY_SEGMENTS; + } + } +# endif /* FBLBM_ENABLE_SECURE_BOOT */ + + if (kFblFsmGuard_True == result) + { + tFblLbtMagicFlag originalMagicFlag = FblLbtGetMagicFlag(); + + FblLbtActivateLbtBlockByAddress(blockInfo.logicalBlock.blockStartAddress); + + if (originalMagicFlag != FblLbtGetMagicFlag()) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_REPROG_LBT_MAGIC_FLAG; + } + else if (FblLbtGetBlockCount() > FBL_LBT_BLOCK_COUNT) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_REPROG_LBT_BLOCK_COUNT; + } + else + { + /* Nothing to do */ + } + + if (kFblFsmGuard_True != result) + { +# if defined( FBLBM_ENABLE_STANDALONE_MODE ) + /* Use LBT from FblHeader, if this point is reached it was already verified and checked for consistency */ + FblLbtActivateLbtBlockByAddress((tFblAddress)fblBmFblHeader.pLogicalBlockTable); +# else /* FBLBM_ENABLE_STANDALONE_MODE */ + FblLbtInitPowerOn(); +# endif /* FBLBM_ENABLE_STANDALONE_MODE */ + } + } + + return result; +} +#endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ + +#if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) +/********************************************************************************************************************** + * FblBmState_TargetListInit + *********************************************************************************************************************/ +/*! \brief Prepare target list search. Get target list via callout + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_TargetListInit(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + g_BmTargetListIndex = 0u; + result = kFblFsmGuard_True; + + return result; +} + +/********************************************************************************************************************** + * FblBmState_TargetCheck + *********************************************************************************************************************/ +/*! \brief Check validity and verification of a target and all its dependencies + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673, 6010, 6030, 6080 1 */ /* MD_FBL_3673_PointerToConstParameter, MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STMIF */ +static tFblFsmGuard FblBmState_TargetCheck(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ +#if defined( FBLBM_ENABLE_SECURE_BOOT ) + tFblResult fblSbResult; +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + tFblFsmGuard result; + tFblBmHdrTargetListEntry target; + tFblBmHdrTargetHandle targetHandle; + tFblBmBlockInfo blockInfoTarget = { 0 }; + tFblBmBlockInfo blockInfoDep; + vuintx index; + tFblBmHdrCheckBmHeaderResult findHeaderResult; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + target = FblBm_BootTargetList[g_BmTargetListIndex]; + targetHandle = target.target; + result = kFblFsmGuard_True; + + /* Check Application validity */ + if (kFblOk != FBLBM_CALLOUT_CHECK_TARGET_VALIDITY(targetHandle)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_TARGET_INVALID; + } + + if (kFblFsmGuard_True == result) + { + if (FBLBMHDR_CHKHDR_OK != FblBmHdrFindValidHeader(targetHandle, &blockInfoTarget)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_TARGET_NO_VALID_HEADER; + } + } + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) + if (kFblFsmGuard_True == result) + { +# if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) +# if defined( FBLBM_ENABLE_USE_VERIFY_HEADER_ROM ) + fblSbResult = FblSb_VerifyHeaderRom(blockInfoTarget.logicalBlock.bmHeaderAddress, &blockInfoTarget.bmHeader); +# else + fblSbResult = FblSb_VerifyHeader(&blockInfoTarget.bmHeader); +# endif /* FBLBM_ENABLE_USE_VERIFY_HEADER_ROM */ + + if (kFblOk == fblSbResult) +# endif /* FBLBM_ENABLE_HEADER_VERIFICATION */ + { + fblSbResult = FblSb_VerifySegments(&blockInfoTarget.bmHeader); + } + if (kFblOk != fblSbResult) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_TARGET_VERIFICATION_FAILED; + } + } +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + + if (kFblFsmGuard_True == result) + { + /* Check all Mandatory dependencies */ + for (index = 0u; index < target.dependenciesSize; index++) + { + targetHandle = target.dependencies[index].target; + + findHeaderResult = FblBmHdrFindValidHeader(targetHandle, &blockInfoDep); + + if (FBLBMHDR_CHKHDR_OK == findHeaderResult) + { +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) +# if defined( FBLBM_ENABLE_USE_VERIFY_HEADER_ROM ) + fblSbResult = FblSb_VerifyHeaderRom(blockInfoDep.logicalBlock.bmHeaderAddress, &blockInfoDep.bmHeader); +# else + fblSbResult = FblSb_VerifyHeader(&blockInfoDep.bmHeader); +# endif /* FBLBM_ENABLE_USE_VERIFY_HEADER_ROM */ + + if (kFblOk == fblSbResult) +# endif/* FBLBM_ENABLE_HEADER_VERIFICATION */ + { + fblSbResult = FblSb_VerifySegments(&blockInfoDep.bmHeader); + } + if (kFblOk != fblSbResult) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_TARGET_DEP_VERIFY_FAILED; + } +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + } + else + { + if (FBLBM_TARGET_TYPE_MANDATORY == target.dependencies[index].type) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_TARGET_DEP_MANDATORY_MISSING; + } + else + { + /* Ignore this block, it is optional */ + FBLBM_CALLOUT_IS_OPTIONALBLOCK(targetHandle, &blockInfoDep.logicalBlock); + } + } + if (kFblFsmGuard_False == result) + { + break; + } + } /* END FOR */ + } + + /* Check if the target address is valid */ + if (kFblFsmGuard_True == result) + { + if (blockInfoTarget.bmHeader.bmEntryAddress == FBLBMHDR_ENTRY_ADDRESS_INVALID) /* PRQA S 2962 */ /* MD_FBL_2962_UninitializedVariable */ + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_TARGET_INVALID_ADDRESS; + assertFbl(0u, kFblSysAssertParameterOutOfRange); /* PRQA S 2741, 4558 */ /* MD_FBL_2741_4558_Assert */ + } + } + + if (kFblFsmGuard_True == result) + { + /* Store BmHeader of target */ + g_BmTargetBmHeader = blockInfoTarget.bmHeader; + } + + return result; +} + +/********************************************************************************************************************** + * FblBmState_TargetListNext + *********************************************************************************************************************/ +/*! \brief Get next target entry from target list. + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_TargetListNext(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + + g_BmTargetListIndex++; + if (FBLBM_BOOTTARGETLIST_SIZE > g_BmTargetListIndex) + { + result = kFblFsmGuard_True; + } + else + { + /* End of list reached */ + result = kFblFsmGuard_False; + } + + return result; +} +#endif /* FBLBM_BOOTTARGETLIST_SIZE > 0u */ + +/********************************************************************************************************************** + * FblBmState_CheckLateFblSegments + *********************************************************************************************************************/ +/*! \brief Verify the whole FBL segments. + * \param[in] pFsmContext Pointer to context of state machine + * \param[in] event Event that caused handler execution + * \return - kFblFsmGuard_True if transition to next configured state is allowed, + * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) + *********************************************************************************************************************/ +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +static tFblFsmGuard FblBmState_CheckLateFblSegments(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) +{ + tFblFsmGuard result; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ + (void)pFsmContext; + (void)event; +#endif + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined( FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK ) + /* Segments are already verified during the Check Early Fbl Segments state */ +# else /* FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK */ + if (kFblOk != FblSb_VerifySegments(&fblBmBlockInfo.bmHeader)) + { + result = kFblFsmGuard_False; + g_BmError = FBLBM_ERROR_FBL_VERIFICATION_FAILED; + } + else +# endif /* FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK */ +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + { + result = kFblFsmGuard_True; + } + + return result; +} + +/********************************************************************************************************************** + * FblBmDeinit + *********************************************************************************************************************/ +/*! \brief Deinitialize e.g. stop the timer before calling a target. + *********************************************************************************************************************/ +static void FblBmDeinit(void) +{ + FBLBM_CALLOUT_DEINIT_PRE_OEM(); + FBLBM_CALLOUT_DEINIT_PRE_HW(); + FBLBM_CALLOUT_DEINIT_PRE(); + +#if defined( FBL_WATCHDOG_ON ) + /* Synchronize watchdog before application start */ + ApplFblWDLong(); +#endif /* FBL_WATCHDOG_ON */ + /* Stop timer to avoid a timer interrupt after application start */ + FblTimerStopp(); + + FBLBM_CALLOUT_DEINIT_POST_OEM(); + FBLBM_CALLOUT_DEINIT_POST_HW(); + FBLBM_CALLOUT_DEINIT_POST(); +} + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +/*-- Bootmanager helper functions ----------------------------------------------------------------------------------------*/ + +#if defined( FBLBM_ENABLE_STANDALONE_MODE ) +/*********************************************************************************************************************** + * FblMemSetInteger + **********************************************************************************************************************/ +/*! \brief Convert given integer value to big-endian byte array + * \param[in] count Number of relevant bytes + * \param[in] input Input value + * \param[out] buffer Pointer to output buffer + **********************************************************************************************************************/ +void FblMemSetInteger( vuintx count, vuint32 input, tFblMemRamData buffer) +{ + vuint32 localInput = input; + vuintx localCount = count; + + /* Integer to array conversion only supported for up to 32-bit values */ + assertFblInternal(count <= sizeof(vuint32), kFblSysAssertParameterOutOfRange); + + /* Loop relevant bytes */ + while (localCount > 0u) + { + localCount--; + /* Store most significant byte first */ + buffer[localCount] = (vuint8) (localInput & 0xFFu); + /* Shift in next byte */ + localInput >>= 8u; + } +} + +/*********************************************************************************************************************** + * FblMemGetInteger + **********************************************************************************************************************/ +/*! \brief Convert given big-endian byte array to integer value + * \param[in] count Number of relevant bytes + * \param[in] buffer Pointer to input buffer + * \return Integer value + **********************************************************************************************************************/ +vuint32 FblMemGetInteger( vuintx count, tFblMemConstRamData buffer) +{ + vuint32 output = 0u; + vuintx idx = 0u; + vuintx localCount = count; + + /* Array to integer conversion only supported for up to 32-bit values */ + assertFblInternal(count <= sizeof(vuint32), kFblSysAssertParameterOutOfRange); + + /* Loop relevant bytes */ + while (localCount > 0u) + { + /* Most significant byte first */ + output <<= 8u; + /* Add current byte */ + output |= (vuint32)buffer[idx]; + + idx++; + localCount--; + } + + return output; +} +#endif /* FBLBM_ENABLE_STANDALONE_MODE */ + +/*-- Main functions --------------------------------------------------------------------------------------------------*/ + +/*********************************************************************************************************************** + * FblMain + **********************************************************************************************************************/ +/*! \brief Initializes the system and runs the bootmanager. + **********************************************************************************************************************/ +/* PRQA S 5209 1 */ /* MD_FblBmMain_5209_Main */ +void V_API_NEAR FblMain(void) +{ + /* Initialize state machine */ + FblFsmInitPowerOn(); + + /* Start State Machine */ + g_BmFsmContext.stateDefinitions = bmFsmStates; + g_BmFsmContext.stateCount = FBLBM_ARRAY_SIZE(bmFsmStates); + FblFsmInit(&g_BmFsmContext, (tFblFsmState) FBLBM_STATE_POWER_ON); + + while (g_BmFsmContext.state != (tFblFsmState) FBLBM_STATE_FAIL) + { + /* Request next step */ + FblFsmTriggerEvent(&g_BmFsmContext, (tFblFsmEvent) FBLBM_EVENT_CONTINUE); + FblFsmStateTask(&g_BmFsmContext); + } + + FBLBM_CALLOUT_FATAL_ERROR(FBLBM_ERROR_END_OF_MAIN_REACHED); +} + +#define FBLBM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBLBM_MAIN_ENABLE_FBL_START ) +# define FBLBM_FBLSTART_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * FblStart + **********************************************************************************************************************/ +/*! \brief Transition from application into flash boot loader + * \pre Valid application program running + * \param[in] channel Specify the channel of the reprogramming request (e.g. UDS, XCP, MCMP, OTA) + * \param[in] pFblStartParam Pointer to OEM specific parameter structure + * \param[in] length Length of OEM specific parameter structure [Bytes] + **********************************************************************************************************************/ +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) +/* PRQA S 3673 2 */ /* MD_FBL_3673_PointerToConstParameter */ +void FblStart( FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_FIRST + V_MEMRAM1 void V_MEMRAM2 V_MEMRAM3 * pFblStartParam, vuint8 length ) +# else +void FblStart( FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_ONLY ) +# endif /* FBL_MAIN_ENABLE_FBLSTART_PARAM */ +{ +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) + vuintx i; +# endif + +# if !defined( FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON ) + FblInterruptDisable(); /* PRQA S 1006 */ /* MD_FblBmMain_1006 */ +# endif /* FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON */ + + /* Restore bootmanager context - e.g. small data area base registers */ + FblHwRestoreFblContext(); /* PRQA S 1006 */ /* MD_FblBmMain_1006 */ + +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) + /* Copy parameter to reset safe variable */ + for (i = 0u; i < length; i++) + { + /* PRQA S 0316 1 */ /* MD_FblBmMain_0316 */ + ((volatile vuint8*)&fblBmFblStartParameter)[i] = ((vuint8*)pFblStartParam)[i]; + } +# endif /* FBLBM_MAIN_ENABLE_FBLSTART_PARAM */ + +#if defined( FBLBM_MAIN_ENABLE_FBLSTART_CHANNEL ) + fblBmFblStartChannel = FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE; +#endif /* FBLBM_MAIN_ENABLE_FBLSTART_CHANNEL */ + + /* Set FblStart magic flag + Please pay attention: The FblStart magic flag does not use a shared memory area so that the buffer may overlap + with the application stack. */ + FblBmSetFblStartMagicFlag(); + + /* Generate reset */ + FBLBM_CALLOUT_RESET(); +} +# define FBLBM_FBLSTART_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBLBM_MAIN_ENABLE_FBL_START */ + +#if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) +# define FBLBM_APPLSTART_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * ApplStart + **********************************************************************************************************************/ +/*! \brief Transition from flash boot loader into application + * \pre Valid FBL program running + * \param[in] pApplStartParam Pointer to OEM specific parameter structure + * \param[in] length Length of OEM specific parameter structure [Bytes] + **********************************************************************************************************************/ +# if defined( FBLBM_MAIN_ENABLE_APPLSTART_PARAM ) +/* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ +void ApplStart( V_MEMRAM1 void V_MEMRAM2 V_MEMRAM3 * pApplStartParam, vuint8 length ) +# else +void ApplStart( void ) +# endif /* FBLBM_MAIN_ENABLE_APPLSTART_PARAM */ +{ +# if defined( FBLBM_MAIN_ENABLE_APPLSTART_PARAM ) + vuintx i; +# endif + +# if !defined( FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON ) + FblInterruptDisable(); /* PRQA S 1006 */ /* MD_FblBmMain_1006 */ +# endif /* FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON */ + + /* Restore bootmanager context - e.g. small data area base registers */ + FblHwRestoreFblContext(); /* PRQA S 1006 */ /* MD_FblBmMain_1006 */ +# if defined( FBLBM_MAIN_ENABLE_APPLSTART_PARAM ) + /* Copy parameter to reset safe variable */ + for (i = 0u; i < length; i++) + { + /* PRQA S 0316 1 */ /* MD_FblBmMain_0316 */ + ((volatile vuint8*)&fblBmApplStartParameter)[i] = ((vuint8*)pApplStartParam)[i]; + } +# endif /* FBLBM_MAIN_ENABLE_APPLSTART_PARAM */ + + /* Set ApplStart magic flag + Please pay attention: The ApplStart magic flag does not use a shared memory area so that the buffer may overlap + with the application stack. */ + FblBmSetApplStartMagicFlag(); + + /* Generate reset */ + FBLBM_CALLOUT_RESET(); +} +# define FBLBM_APPLSTART_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ + +/*********************************************************************************************************************** + * CONFIGURATION CHECKS + **********************************************************************************************************************/ + +#if ( defined( FBLBM_ENABLE_HEADER_VERIFICATION ) && !defined( FBLBM_ENABLE_FBLLBT_VERIFICATION ) ) +# error "Configuration not supported" +#endif + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_FblBmMain_0306: + Reason: Address conversion between integer values and pointers is required to allow for hardware independent + configuration and address range checks. + Risk: The size of integer required to hold the result of a pointer cast is implementation defined. + Prevention: The size of the respective integer data type which holds the address value is adapted on a hardware + specific basis. + + MD_FblBmMain_0306_FblBmHeader: + Reason: A memory address is compared to a configured value. The configured value is interpreted as an integer. + Risk: The comparison may fail due to different data types. + Prevention: If this check fails, the configuration checks done by assertions have to verified manually. + + MD_FblBmMain_0316: + Reason: API is defined with pointer to void parameter, so pointer has to be casted to or from void. + Risk: Wrong data access or undefiend behavior for platforms where the byte alignment is not arbitrary. + Prevention: Code inspection. + + MD_FblBmMain_1006: + Reason: Interrupts are enabled/disabled using assembler code. + Risk: The code is not portable for different compilers. + Prevention: The assembler code provided by each FblHw module has to be tested. + + MD_FblBmMain_1514_BmHeader: + Reason: MISRA: The object FblBmHeader is only referenced by function ..., in the translation unit where it is defined + This object is exported globally to other modules. + Risk: Name space pollution + Prevention: No Prevention necessary + + MD_FBL_2962_UninitializedVariable: + Reason: The variable is actually initialzed at runtime. The successive code will never be executed over not initialzed data. + Risk: Some potential case not detected during development can lead to read a content which is not valid. + Prevention: Write robust code which doesn't allow to read a non initialzed content. + + MD_FBL_2987_RedundantCode: + Reason: QAC misinterprets the code which actually has side effects (i.e. hardware registers are written and read). + Risk: No identifiable risk + Prevention: No prevention required. + + MD_FblBmMain_2991_2995: + Reason: The value of the if-controlling expression depends on the configuration. + Risk: No risk. + Prevention: No prevention necessary. + + MD_FblBmMain_2880_2992_2996_FlashRead: + Reason: QAC does not interpret this correctly. The compared data is read from flash (and may therefore contain deviating values). + Risk: No risk. + Prevention: No prevention required. + + MD_FblBmMain_3205_UnusedIdentifiers + Reason: Depending on the configuration some values of the enum definition are not referenced by the code. + For clarity theses values are not omitted but kept as a place holder. + Risk: No identifiable risk. + Prevention: No prevention required. + + MD_FBL_3218_FileScopeStatic: + Reason: Configuration constants/tables are kept at a central location for a better overview and maintenance. + Risk: Unintended use of object in wrong scope. + Prevention: Architectural pattern supports prevention of incorrect use of objects in wrong context. + Code inspection focus on correct use of objects. + + MD_FBL_3673_PointerToConstParameter: + Reason: Many standards like AUTOSAR, ISO, but also OEM specifications specify the function prototypes without + const statement. We have to comply to this standards. + Risk: Unintended read or write access into memory location. + Prevention: Code inspection focus on correct access to expected memory location + + MD_FBL_2741_4558_Assert: + Reason: The assertion macro has been designed to have an invariant condition and not using bool variable. + Risk: No identifiable risk. Assertion macro are disable in production code. + Prevention: No prevention required. + + MD_FblBmMain_5209_Main: + Reason: The Vector standard API for main function follows ANSI C typical definition of main function returning int. + Risk: No identifiable risk. + Prevention: No prevention required. + + */ + +/*********************************************************************************************************************** + * END OF FILE: BM_MAIN.C + **********************************************************************************************************************/ diff --git a/Source/bsw/FblBm/bm_main.h b/Source/bsw/FblBm/bm_main.h new file mode 100644 index 0000000..2ada6cb --- /dev/null +++ b/Source/bsw/FblBm/bm_main.h @@ -0,0 +1,200 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Main module of BM + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 04.00.00 2019-10-10 vistmo FBL-390 Adapt main function interface for vBaseEnv + * 04.00.01 2019-11-05 visrie ESCAN00104616 No changes + * ESCAN00104790 No changes + * 05.00.00 2019-12-04 visrie FBL-456 No changes + * ESCAN00104644 No changes + * ESCAN00105176 No changes + * 05.01.00 2020-01-13 visrie ESCAN00104481 Fixed redeclaration issue + * FBL-953 Reworked handling of AP include files + * 05.02.00 2020-02-28 vistbe FBL-949 No changes + * 06.00.00 2020-04-08 visrie FBL-1016 No changes + * 06.00.01 2020-04-08 visrie ESCAN00106837 No changes + * 06.00.02 2020-10-28 visrcn ESCAN00107189 Compiler error: Wrong definition for FblMain function + * 06.01.00 2021-08-11 visrie FBL-3394 Added/adapted MemMap sections + * 06.02.00 2022-02-04 visrie FBL-4602 No changes + * 06.02.01 2022-04-06 fmenke ESCAN00111029 No changes + * 06.03.00 2022-04-08 visrie FBL-4126 No changes + * 06.04.00 2022-04-11 lhopfhauer FBL-4822 Changed external switches to internal switches + * 06.04.01 2022-04-28 fmenke ESCAN00111741 No changes + * 06.05.00 2022-05-06 lhopfhauer FBL-5148 No changes + * 06.06.00 2022-07-13 fmenke FBL-5391 No changes + * 06.06.01 2022-08-04 jschmitding ESCAN00112070 No changes + * 06.07.00 2022-11-07 lhopfhauer FBL-4932 No changes + * 06.08.00 2022-11-30 visrie FBL-6065 Encapsulate FblMain declaration + * 06.08.01 2024-03-04 visrie ESCAN00116460 No changes + * 06.09.00 2024-05-16 lhopfhauer FBL-8602 No changes + * 06.10.00 2024-11-15 erizk FBL-9652 No changes + * 06.11.00 2025-05-23 dganesh FBL-9715 No changes + * 06.12.00 2025-09-23 pharring FBL-10124 Add support for FblLib_Logger + **********************************************************************************************************************/ + +#ifndef BM_MAIN_H +#define BM_MAIN_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblBm_Main CQComponent : Implementation */ +#define FBLBM_MAIN_VERSION 0x0612u +#define FBLBM_MAIN_RELEASE_VERSION 0x00u + +/* Interface version */ +/** Major interface version identifies incompatible changes */ +#define FBLBM_API_VERSION_MAJOR 0x03u +/** Minor interface version identifies backward compatible changes */ +#define FBLBM_API_VERSION_MINOR 0x00u +/** Release interface version identifies cosmetic changes */ +#define FBLBM_API_VERSION_RELEASE 0x00u + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "bm_types.h" +#if defined( FBLBM_ENABLE_HARDWARE_CONFIGURATION ) +# include "bm_hw_ap.h" +#endif +#if defined( FBLBM_ENABLE_OEM_CONFIGURATION ) +# include "bm_oem_ap.h" +#endif +#if defined( FBLBM_ENABLE_GENERIC_CONFIGURATION ) +# include "bm_ap.h" +#endif +#include "bm_hdr.h" + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/** Helper macro to get number of array entries */ /* PRQA S 3453 1 */ /* MD_MSR_FctLikeMacro */ +#define FBLBM_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0u])) + +/** Undefined hook function */ +#define FBLBM_HOOK_NONE (tFblBmFunc)0 + +#if defined( FBLBM_ENABLE_STANDALONE_MODE ) && \ + defined( FBLBM_INSTANCE_BOOTMANAGER ) +/** Pointer type to byte data in RAM */ +typedef V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tFblMemRamData; +/** Pointer type to constant byte data in RAM */ +typedef const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * tFblMemConstRamData; + +/** Response pending state (never active) */ +# define GetRcrRpInProgress() ((vuint8)0x00u) + +# if defined( FBL_CW_LOCKS_TASKS ) || \ + defined( FBLCW_LOCKS_TASKS ) +/*********************************************************************************************************************** +* COM WRAPPER COMPATIBILITY DEFINITIONS +**********************************************************************************************************************/ +/* Define interface version for classic FblWrapperCom modules */ +# if !defined( FBL_CW_API_REFERENCE_VERSION_MAJOR ) +/** Major interface version identifies incompatible changes */ +# define FBL_CW_API_REFERENCE_VERSION_MAJOR 0x01u +/** Minor interface version identifies backward compatible changes */ +# define FBL_CW_API_REFERENCE_VERSION_MINOR 0x00u +/** Release interface version identifies cosmetic changes */ +# define FBL_CW_API_REFERENCE_VERSION_RELEASE 0x00u +# endif +# if !defined( FBL_CW_CFG_PTR ) +# define FBL_CW_CFG_PTR V_NULL +# endif +# else +# define FBL_CW_LOCKS_TASKS +# define FBLCW_LOCKS_TASKS +# define FblCwIsTimerTaskAllowed() ((vuint8)0x00u) +# define FblCwIsStateTaskAllowed() ((vuint8)0x00u) +# define FblCwRetransmitRP() +# define FblCwClrInit() +# define FblCwTimerTask() +# define FblCwStateTask() +# endif /* FBL_CW_LOCKS_TASKS || FBLCW_LOCKS_TASKS */ +#endif /* FBLBM_ENABLE_STANDALONE_MODE && FBLBM_INSTANCE_BOOTMANAGER */ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#define FBLBM_HEADER_START_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +V_MEMROM0 extern V_MEMROM1 tFblBmHeader V_MEMROM2 FblBmHeader; +#define FBLBM_HEADER_STOP_SEC_CONST +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLBM_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* Helper functions */ +#if defined( FBLBM_ENABLE_STANDALONE_MODE ) && \ + defined( FBLBM_INSTANCE_BOOTMANAGER ) +void FblMemSetInteger( vuintx count, vuint32 input, tFblMemRamData buffer ); +vuint32 FblMemGetInteger( vuintx count, tFblMemConstRamData buffer ); +#endif /* FBLBM_ENABLE_STANDALONE_MODE && FBLBM_INSTANCE_BOOTMANAGER */ + +#if defined( FBLBM_INSTANCE_BOOTMANAGER ) +void V_API_NEAR FblMain(void); /* PRQA S 5209 */ /* MD_FblBmMain_5209_Main */ +#endif /* FBLBM_INSTANCE_BOOTMANAGER */ + +#define FBLBM_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBLBM_MAIN_ENABLE_FBL_START ) +# define FBLBM_FBLSTART_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) +void V_CALLBACK_NEAR FblStart( FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_FIRST + V_MEMRAM1 void V_MEMRAM2 V_MEMRAM3 * pFblStartParam, vuint8 length ); +# else +void V_CALLBACK_NEAR FblStart( FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_ONLY ); +# endif /* FBL_MAIN_ENABLE_FBLSTART_PARAM */ +# define FBLBM_FBLSTART_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBLBM_MAIN_ENABLE_FBL_START */ + +#if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) +# define FBLBM_APPLSTART_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +# if defined( FBLBM_MAIN_ENABLE_APPLSTART_PARAM ) +void ApplStart( V_MEMRAM1 void V_MEMRAM2 V_MEMRAM3 * pApplStartParam, vuint8 length ); +# else +void ApplStart( void ); +# endif /* FBLBM_MAIN_ENABLE_FBLSTART_PARAM */ +# define FBLBM_APPLSTART_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ + +#endif /* BM_MAIN_H */ + +/*********************************************************************************************************************** + * END OF FILE: BM_MAIN.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblBm/bm_shared.c b/Source/bsw/FblBm/bm_shared.c new file mode 100644 index 0000000..248c8fc --- /dev/null +++ b/Source/bsw/FblBm/bm_shared.c @@ -0,0 +1,93 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Main module of BM + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 04.00.00 2019-10-10 vistmo FBL-390 No changes + * 04.00.01 2019-11-05 visrie ESCAN00104616 Fixed include structure + * ESCAN00104790 Fixed variable types + * 05.00.00 2019-12-04 visrie FBL-456 No changes + * ESCAN00104644 No changes + * ESCAN00105176 No changes + * 05.01.00 2020-01-13 visrie ESCAN00104481 No changes + * FBL-953 No changes + * 05.02.00 2020-02-28 vistbe FBL-949 No changes + * 06.00.00 2020-04-08 visrie FBL-1016 No changes + * 06.00.01 2020-04-08 visrie ESCAN00106837 No changes + * 06.00.02 2020-10-28 visrcn ESCAN00107189 No changes + * 06.01.00 2021-08-11 visrie FBL-3394 No changes + * 06.02.00 2022-02-04 visrie FBL-4602 No changes + * 06.02.01 2022-04-06 fmenke ESCAN00111029 No changes + * 06.03.00 2022-04-08 visrie FBL-4126 No changes + * 06.04.00 2022-04-11 lhopfhauer FBL-4822 No changes + * 06.04.01 2022-04-28 fmenke ESCAN00111741 No changes + * 06.05.00 2022-05-06 lhopfhauer FBL-5148 No changes + * 06.06.00 2022-07-13 fmenke FBL-5391 No changes + * 06.06.01 2022-08-04 jschmitding ESCAN00112070 No changes + * 06.07.00 2022-11-07 lhopfhauer FBL-4932 No changes + * 06.08.00 2022-11-30 visrie FBL-6065 No changes + * 06.08.01 2024-03-04 visrie ESCAN00116460 No changes + * 06.09.00 2024-05-16 lhopfhauer FBL-8602 No changes + * 06.10.00 2024-11-15 erizk FBL-9652 No changes + * 06.11.00 2025-05-23 dganesh FBL-9715 No changes + * 06.12.00 2025-09-23 pharring FBL-10124 No changes + **********************************************************************************************************************/ + +#define BM_SHARED_SOURCE + +/*********************************************************************************************************************** +* INCLUDES +**********************************************************************************************************************/ + +#include "fbl_inc.h" +#include "bm_shared.h" + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#if defined( FBLBM_MAIN_ENABLE_MAGICFLAG ) +# define FBLBM_MAIN_MAGICFLAG_START_SEC_VAR_NOINIT +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/** Reprogramming request storage variable */ +V_MEMRAM0 volatile V_MEMRAM1 vuint8 V_MEMRAM2 fblBmMagicFlag[kFblBmNoOfMagicBytes]; +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_CHANNEL ) +V_MEMRAM0 volatile V_MEMRAM1 vuint8 V_MEMRAM2 fblBmFblStartChannel; +# endif /* FBLBM_MAIN_ENABLE_FBLSTART_PARAM */ +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) +V_MEMRAM0 volatile V_MEMRAM1 tFblBmFblStartParameter V_MEMRAM2 fblBmFblStartParameter; +# endif /* FBLBM_MAIN_ENABLE_FBLSTART_PARAM */ +# if defined( FBLBM_MAIN_ENABLE_APPLSTART_PARAM ) +V_MEMRAM0 volatile V_MEMRAM1 tFblBmApplStartParameter V_MEMRAM2 fblBmApplStartParameter; +# endif /* FBLBM_MAIN_ENABLE_APPLSTART_PARAM */ +# define FBLBM_MAIN_MAGICFLAG_STOP_SEC_VAR_NOINIT +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBLBM_MAIN_ENABLE_MAGICFLAG */ + +/*********************************************************************************************************************** + * END OF FILE: BM_SHARED.C + **********************************************************************************************************************/ diff --git a/Source/bsw/FblBm/bm_shared.h b/Source/bsw/FblBm/bm_shared.h new file mode 100644 index 0000000..eaab7fb --- /dev/null +++ b/Source/bsw/FblBm/bm_shared.h @@ -0,0 +1,272 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Main module of BM + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 04.00.00 2019-10-10 vistmo FBL-390 No changes + * 04.00.01 2019-11-05 visrie ESCAN00104616 No changes + * ESCAN00104790 No changes + * 05.00.00 2019-12-04 visrie FBL-456 No changes + * ESCAN00104644 No changes + * ESCAN00105176 No changes + * 05.01.00 2020-01-13 visrie ESCAN00104481 No changes + * FBL-953 No changes + * 05.02.00 2020-02-28 vistbe FBL-949 No changes + * 06.00.00 2020-04-08 visrie FBL-1016 No changes + * 06.00.01 2020-04-08 visrie ESCAN00106837 No changes + * 06.00.02 2020-10-28 visrcn ESCAN00107189 No changes + * 06.01.00 2021-08-11 visrie FBL-3394 No changes + * 06.02.00 2022-02-04 visrie FBL-4602 No changes + * 06.02.01 2022-04-06 fmenke ESCAN00111029 No changes + * 06.03.00 2022-04-08 visrie FBL-4126 No changes + * 06.04.00 2022-04-11 lhopfhauer FBL-4822 Add support for new MagicFlag value and Swap API + * 06.04.01 2022-04-28 fmenke ESCAN00111741 No changes + * 06.05.00 2022-05-06 lhopfhauer FBL-5148 Encapsulate call of FblInterruptDisable + * 06.06.00 2022-07-13 fmenke FBL-5391 No changes + * 06.06.01 2022-08-04 jschmitding ESCAN00112070 No changes + * 06.07.00 2022-11-07 lhopfhauer FBL-4932 No changes + * 06.08.00 2022-11-30 visrie FBL-6065 No changes + * 06.08.01 2024-03-04 visrie ESCAN00116460 No changes + * 06.09.00 2024-05-16 lhopfhauer FBL-8602 No changes + * 06.10.00 2024-11-15 erizk FBL-9652 No changes + * 06.11.00 2025-05-23 dganesh FBL-9715 Extend presence pattern to connect validity information + * 06.12.00 2025-09-23 pharring FBL-10124 No changes + **********************************************************************************************************************/ + +#ifndef BM_SHARED_H +#define BM_SHARED_H + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* Remap of FBL specific switch to BM switch */ +#if !defined( FBLBM_MAIN_ENABLE_FBL_START ) && \ + !defined( FBLBM_MAIN_DISABLE_FBL_START ) +# if defined( FBL_ENABLE_FBL_START ) +# define FBLBM_MAIN_ENABLE_FBL_START +# endif +#endif + +#if !defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) && \ + !defined( FBLBM_MAIN_DISABLE_STAY_IN_BOOT ) +# if defined( FBL_ENABLE_STAY_IN_BOOT ) +# define FBLBM_MAIN_ENABLE_STAY_IN_BOOT +# endif +#endif + +#if !defined( FBLBM_MAIN_ENABLE_HARDWARE_SWAP ) && \ + !defined( FBLBM_MAIN_DISABLE_HARDWARE_SWAP ) +# if defined( FBL_ENABLE_HARDWARE_SWAP ) +# define FBLBM_MAIN_ENABLE_HARDWARE_SWAP +# endif +#endif + +#if !defined( FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON ) && \ + !defined( FBLBM_MAIN_DISABLE_INTERRUPT_DISABLE_AT_POWER_ON ) +# if defined( FBL_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON ) +# define FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON +# endif +#endif + +#if !defined( FBLBM_MAIN_ENABLE_MAGICFLAG ) && \ + !defined( FBLBM_MAIN_DISABLE_MAGICFLAG ) +# if defined( FBLBM_MAIN_ENABLE_FBL_START ) || \ + defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) || \ + (defined( FBLBM_ENABLE_SECURE_BOOT ) && \ + (defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY ) || \ + defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) || \ + defined( FBLBM_MAIN_ENABLE_HARDWARE_SWAP )) \ + ) +/** Enable magic flag in case of known magic flag configuration */ +# define FBLBM_MAIN_ENABLE_MAGICFLAG +# endif +#endif + +/*********************************************************************************************************************** + * DEFINES (MAGIC FLAG) + **********************************************************************************************************************/ + +#if defined( FBLBM_MAIN_ENABLE_MAGICFLAG ) +# define kFblBmNoOfMagicBytes 8u +# define kFblBmClearMagicByte 0x00u +# define FblBmClrMagicFlag() \ +{ \ + fblBmMagicFlag[0u] = kFblBmClearMagicByte; \ + fblBmMagicFlag[1u] = kFblBmClearMagicByte; \ + fblBmMagicFlag[2u] = kFblBmClearMagicByte; \ + fblBmMagicFlag[3u] = kFblBmClearMagicByte; \ + fblBmMagicFlag[4u] = kFblBmClearMagicByte; \ + fblBmMagicFlag[5u] = kFblBmClearMagicByte; \ + fblBmMagicFlag[6u] = kFblBmClearMagicByte; \ + fblBmMagicFlag[7u] = kFblBmClearMagicByte; \ +} +/* PRQA S 0342 11 */ /* MD_MSR_Rule20.10_0342 */ +# define FblBmSetMagicFlag(infix) \ +{ \ + fblBmMagicFlag[0u] = kFblBm ## infix ## MagicByte0; \ + fblBmMagicFlag[1u] = kFblBm ## infix ## MagicByte1; \ + fblBmMagicFlag[2u] = kFblBm ## infix ## MagicByte2; \ + fblBmMagicFlag[3u] = kFblBm ## infix ## MagicByte3; \ + fblBmMagicFlag[4u] = kFblBm ## infix ## MagicByte4; \ + fblBmMagicFlag[5u] = kFblBm ## infix ## MagicByte5; \ + fblBmMagicFlag[6u] = kFblBm ## infix ## MagicByte6; \ + fblBmMagicFlag[7u] = kFblBm ## infix ## MagicByte7; \ +} +/* PRQA S 0342 9 */ /* MD_MSR_Rule20.10_0342 */ +# define FblBmChkMagicFlag(infix) \ + (( (fblBmMagicFlag[0u] == kFblBm ## infix ## MagicByte0) \ + && (fblBmMagicFlag[1u] == kFblBm ## infix ## MagicByte1) \ + && (fblBmMagicFlag[2u] == kFblBm ## infix ## MagicByte2) \ + && (fblBmMagicFlag[3u] == kFblBm ## infix ## MagicByte3) \ + && (fblBmMagicFlag[4u] == kFblBm ## infix ## MagicByte4) \ + && (fblBmMagicFlag[5u] == kFblBm ## infix ## MagicByte5) \ + && (fblBmMagicFlag[6u] == kFblBm ## infix ## MagicByte6) \ + && (fblBmMagicFlag[7u] == kFblBm ## infix ## MagicByte7)) ? 1u : 0u) + +# if defined( FBLBM_MAIN_ENABLE_FBL_START ) +/* Define pattern for magic flags used for UDS reprogramming indication */ +# define kFblBmFblStartMagicByte0 0x50u /* 'P' */ +# define kFblBmFblStartMagicByte1 0x72u /* 'r' */ +# define kFblBmFblStartMagicByte2 0x6Fu /* 'o' */ +# define kFblBmFblStartMagicByte3 0x67u /* 'g' */ +# define kFblBmFblStartMagicByte4 0x53u /* 'S' */ +# define kFblBmFblStartMagicByte5 0x69u /* 'i' */ +# define kFblBmFblStartMagicByte6 0x67u /* 'g' */ +# define kFblBmFblStartMagicByte7 0x6Eu /* 'n' */ +# define FblBmSetFblStartMagicFlag() FblBmSetMagicFlag(FblStart) +# define FblBmChkFblStartMagicFlag() FblBmChkMagicFlag(FblStart) +# endif /* FBLBM_MAIN_ENABLE_FBL_START */ + +# if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) +/* Define pattern for magic flags used if Bootloader should initialize the PP keys and generate/write CMAC */ +# define kFblBmSignedPPMagicByte0 0x53u /* 'S' */ +# define kFblBmSignedPPMagicByte1 0x69u /* 'i' */ +# define kFblBmSignedPPMagicByte2 0x67u /* 'g' */ +# define kFblBmSignedPPMagicByte3 0x70u /* 'p' */ +# define kFblBmSignedPPMagicByte4 0x70u /* 'p' */ +# define kFblBmSignedPPMagicByte5 0x4Bu /* 'k' */ +# define kFblBmSignedPPMagicByte6 0x65u /* 'e' */ +# define kFblBmSignedPPMagicByte7 0x79u /* 'y' */ +# define FblBmSetSignedPPMagicFlag() FblBmSetMagicFlag(SignedPP) +# define FblBmChkSignedPPMagicFlag() FblBmChkMagicFlag(SignedPP) +# endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + +# if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) +/* Define pattern for magic flags used for application start */ +# define kFblBmApplStartMagicByte0 0x41u /* 'A' */ +# define kFblBmApplStartMagicByte1 0x70u /* 'p' */ +# define kFblBmApplStartMagicByte2 0x70u /* 'p' */ +# define kFblBmApplStartMagicByte3 0x6Cu /* 'l' */ +# define kFblBmApplStartMagicByte4 0x53u /* 'S' */ +# define kFblBmApplStartMagicByte5 0x69u /* 'i' */ +# define kFblBmApplStartMagicByte6 0x67u /* 'g' */ +# define kFblBmApplStartMagicByte7 0x6Eu /* 'n' */ +# define FblBmSetApplStartMagicFlag() FblBmSetMagicFlag(ApplStart) +# define FblBmChkApplStartMagicFlag() FblBmChkMagicFlag(ApplStart) + +/* Define pattern for magic flags used if Bootloader should check for stay in boot message */ +# define kFblBmStayInBootMagicByte0 0x53u /* 'S' */ +# define kFblBmStayInBootMagicByte1 0x74u /* 't' */ +# define kFblBmStayInBootMagicByte2 0x61u /* 'a' */ +# define kFblBmStayInBootMagicByte3 0x79u /* 'y' */ +# define kFblBmStayInBootMagicByte4 0x42u /* 'B' */ +# define kFblBmStayInBootMagicByte5 0x6Fu /* 'o' */ +# define kFblBmStayInBootMagicByte6 0x6Fu /* 'o' */ +# define kFblBmStayInBootMagicByte7 0x74u /* 't' */ +# define FblBmSetStayInBootMagicFlag() FblBmSetMagicFlag(StayInBoot) +# define FblBmChkStayInBootMagicFlag() FblBmChkMagicFlag(StayInBoot) +# endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ + +# if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY ) +/* Define pattern for magic flags used if Bootloader should initialize the keys and generate/write CMAC */ +# define kFblBmInitKeysMagicByte0 0x49u /* 'I' */ +# define kFblBmInitKeysMagicByte1 0x6Eu /* 'n' */ +# define kFblBmInitKeysMagicByte2 0x69u /* 'i' */ +# define kFblBmInitKeysMagicByte3 0x74u /* 't' */ +# define kFblBmInitKeysMagicByte4 0x4Bu /* 'K' */ +# define kFblBmInitKeysMagicByte5 0x65u /* 'e' */ +# define kFblBmInitKeysMagicByte6 0x79u /* 'y' */ +# define kFblBmInitKeysMagicByte7 0x73u /* 's' */ +# define FblBmSetInitKeysMagicFlag() FblBmSetMagicFlag(InitKeys) +# define FblBmChkInitKeysMagicFlag() FblBmChkMagicFlag(InitKeys) +# endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY */ + +# if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY ) || \ + defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) +/* Define pattern for magic flags used if Bootloader should initialize the keys and generate/write CMAC */ +# define kFblBmInitCmacMagicByte0 0x49u /* 'I' */ +# define kFblBmInitCmacMagicByte1 0x6Eu /* 'n' */ +# define kFblBmInitCmacMagicByte2 0x69u /* 'i' */ +# define kFblBmInitCmacMagicByte3 0x74u /* 't' */ +# define kFblBmInitCmacMagicByte4 0x43u /* 'C' */ +# define kFblBmInitCmacMagicByte5 0x6Du /* 'm' */ +# define kFblBmInitCmacMagicByte6 0x61u /* 'a' */ +# define kFblBmInitCmacMagicByte7 0x63u /* 'c' */ +# define FblBmSetInitCmacMagicFlag() FblBmSetMagicFlag(InitCmac) +# define FblBmChkInitCmacMagicFlag() FblBmChkMagicFlag(InitCmac) +# endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY || FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ + +# if defined( FBLBM_MAIN_ENABLE_HARDWARE_SWAP ) +/* Define pattern for magic flags used if Bootloader should perform a secure boot update */ +# define kFblBmSBUpdateMagicByte0 0x53u /* 'S' */ +# define kFblBmSBUpdateMagicByte1 0x42u /* 'B' */ +# define kFblBmSBUpdateMagicByte2 0x55u /* 'U' */ +# define kFblBmSBUpdateMagicByte3 0x70u /* 'p' */ +# define kFblBmSBUpdateMagicByte4 0x64u /* 'd' */ +# define kFblBmSBUpdateMagicByte5 0x61u /* 'a' */ +# define kFblBmSBUpdateMagicByte6 0x74u /* 't' */ +# define kFblBmSBUpdateMagicByte7 0x65u /* 'e' */ +# define FblBmSetSBUpdateMagicFlag() FblBmSetMagicFlag(SBUpdate) +# define FblBmChkSBUpdateMagicFlag() FblBmChkMagicFlag(SBUpdate) +# endif /* FBLBM_MAIN_ENABLE_HARDWARE_SWAP */ +# endif /* FBLBM_ENABLE_SECURE_BOOT */ +#endif /* FBLBM_MAIN_ENABLE_MAGICFLAG */ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +#if defined( FBLBM_MAIN_ENABLE_MAGICFLAG ) +# define FBLBM_MAIN_MAGICFLAG_START_SEC_VAR_NOINIT +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +V_MEMRAM0 extern volatile V_MEMRAM1 vuint8 V_MEMRAM2 fblBmMagicFlag[kFblBmNoOfMagicBytes]; +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_CHANNEL ) +V_MEMRAM0 extern volatile V_MEMRAM1 vuint8 V_MEMRAM2 fblBmFblStartChannel; +# endif /* FBLBM_MAIN_ENABLE_FBLSTART_PARAM */ +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) +V_MEMRAM0 extern volatile V_MEMRAM1 tFblBmFblStartParameter V_MEMRAM2 fblBmFblStartParameter; +# endif /* FBLBM_MAIN_ENABLE_FBLSTART_PARAM */ +# if defined( FBLBM_MAIN_ENABLE_APPLSTART_PARAM ) +V_MEMRAM0 extern volatile V_MEMRAM1 tFblBmApplStartParameter V_MEMRAM2 fblBmApplStartParameter; +# endif /* FBLBM_MAIN_ENABLE_APPLSTART_PARAM */ +# define FBLBM_MAIN_MAGICFLAG_STOP_SEC_VAR_NOINIT +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* FBLBM_MAIN_ENABLE_MAGICFLAG */ + +#endif /* BM_SHARED_H */ + +/*********************************************************************************************************************** + * END OF FILE: BM_SHARED.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblBm/bm_types.h b/Source/bsw/FblBm/bm_types.h new file mode 100644 index 0000000..3df4ca4 --- /dev/null +++ b/Source/bsw/FblBm/bm_types.h @@ -0,0 +1,166 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Main module of BM + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 04.00.00 2019-10-10 vistmo FBL-390 No changes + * 04.00.01 2019-11-05 visrie ESCAN00104616 No changes + * ESCAN00104790 No changes + * 05.00.00 2019-12-04 visrie FBL-456 Added support for new FblLibSecBoot interface + * ESCAN00104644 No changes + * ESCAN00105176 No changes + * 05.01.00 2020-01-13 visrie ESCAN00104481 No changes + * FBL-953 Reworked handling of AP include files + * 05.02.00 2020-02-28 vistbe FBL-949 Split configuration files + * 06.00.00 2020-04-08 visrie FBL-1016 No changes + * 06.00.01 2020-04-08 visrie ESCAN00106837 No changes + * 06.00.02 2020-10-28 visrcn ESCAN00107189 No changes + * 06.01.00 2021-08-11 visrie FBL-3394 No changes + * 06.02.00 2022-02-04 visrie FBL-4602 No changes + * 06.02.01 2022-04-06 fmenke ESCAN00111029 No changes + * 06.03.00 2022-04-08 visrie FBL-4126 Improve usage for application + * 06.04.00 2022-04-11 lhopfhauer FBL-4822 No changes + * 06.04.01 2022-04-28 fmenke ESCAN00111741 No changes + * 06.05.00 2022-05-06 lhopfhauer FBL-5148 No changes + * 06.06.00 2022-07-13 fmenke FBL-5391 No changes + * 06.06.01 2022-08-04 jschmitding ESCAN00112070 No changes + * 06.07.00 2022-11-07 lhopfhauer FBL-4932 No changes + * 06.08.00 2022-11-30 visrie FBL-6065 No changes + * 06.08.01 2024-03-04 visrie ESCAN00116460 No changes + * 06.09.00 2024-05-16 lhopfhauer FBL-8602 No changes + * 06.10.00 2024-11-15 erizk FBL-9652 Optimize startup times for secure boot + * 06.11.00 2025-05-23 dganesh FBL-9715 No changes + * 06.12.00 2025-09-23 pharring FBL-10124 No changes + **********************************************************************************************************************/ + +#ifndef BM_TYPES_H +#define BM_TYPES_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +/* Required for FBL base types */ +#include "fbl_def.h" +#include "Fbl_Lbt.h" +#include "bm_hdr_types.h" +#include "FblBm_Lcfg.h" +#if defined( FBLBM_ENABLE_HARDWARE_CONFIGURATION ) +# include "bm_hw_cfg.h" +#endif +#if defined( FBLBM_ENABLE_OEM_CONFIGURATION ) +# include "bm_oem_cfg.h" +#endif +#if defined( FBLBM_ENABLE_GENERIC_CONFIGURATION ) +# include "bm_ap_cfg.h" +#endif + +#include "bm_shared.h" +#include "bm_types_header.h" + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/** Values for BmHeader */ +#define FBLBM_HEADER_MAGIC_VALUE 0x05ECB007u /* Magic word */ +#define FBLBM_HEADER_MAJOR_VERSION 0x0001u /* Major version of BmHeader format */ +#define FBLBM_HEADER_MINOR_VERSION 0x0000u /* Minor Version of BmHeader format */ +#define FBLBM_HEADER_END_MAGIC_VALUE 0xCEC41160u /* Magic word to check for correct padding */ + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +/** Mandatory blocks information */ +typedef struct +{ + tBlockDescriptor logicalBlock; /**< Pointer to logical block */ + tFblBmHdrHeader bmHeader; /**< pointer to bootmanager header structure */ +} tFblBmBlockInfo; + +/** Error codes */ +typedef enum +{ + FBLBM_ERROR_NO_ERROR = 0u, /* 0 */ + FBLBM_ERROR_HEADER_READ_FAILED, /* 1 */ + FBLBM_ERROR_HEADER_MAGIC_FAILED, /* 2 */ + FBLBM_ERROR_HEADER_VERSION_FAILED, /* 3 */ + FBLBM_ERROR_HEADER_LENGTH_FAILED, /* 4 */ + FBLBM_ERROR_VALIDITY_FAILED, /* 5 */ + FBLBM_ERROR_FBL_BMHEADER_INCORRECT, /* 6 */ + FBLBM_ERROR_FBL_BMHEADER_VERIFICATION_FAILED, /* 7 */ + FBLBM_ERROR_FBL_VERIFICATION_FAILED, /* 8 */ + FBLBM_ERROR_FBL_FBLHEADER_FAILED, /* 9 */ + FBLBM_ERROR_KEY_NOT_AVAILABLE, /* 10 */ + FBLBM_ERROR_UPDATER_SEARCH_INIT_FAILED, /* 11 */ + FBLBM_ERROR_UPDATER_SEARCH_NEXT_FINISHED, /* 12 */ + FBLBM_ERROR_UPDATER_HEADER_ADDRESS, /* 13 */ + FBLBM_ERROR_UPDATER_HEADER_READ_ERROR, /* 14 */ + FBLBM_ERROR_UPDATER_HEADER_CONSISTENCY, /* 15 */ + FBLBM_ERROR_UPDATER_HEADER_TYPE, /* 16 */ + FBLBM_ERROR_UPDATER_BLOCK_VALIDITY, /* 17 */ + FBLBM_ERROR_UPDATER_HEADER_CMAC_VERIFY, /* 18 */ + FBLBM_ERROR_UPDATER_VERIFY, /* 19 */ + FBLBM_ERROR_LBT_POINTER_NULL, /* 20 */ + FBLBM_ERROR_LBT_TOO_LARGE, /* 21 */ + FBLBM_ERROR_LBT_SIZE, /* 22 */ + FBLBM_ERROR_LBT_VERIFY, /* 23 */ + FBLBM_ERROR_REPROG_LBT_DESCR, /* 24 */ + FBLBM_ERROR_REPROG_LBT_INVALID, /* 25 */ + FBLBM_ERROR_REPROG_LBT_BMHEADER_INCORRECT, /* 26 */ + FBLBM_ERROR_REPROG_LBT_VERIFY_HEADER, /* 27 */ + FBLBM_ERROR_REPROG_LBT_VERIFY_SEGMENTS, /* 28 */ + FBLBM_ERROR_REPROG_LBT_MAGIC_FLAG, /* 29 */ + FBLBM_ERROR_REPROG_LBT_BLOCK_COUNT, /* 30 */ + FBLBM_ERROR_TARGET_LIST_INIT, /* 31 */ + FBLBM_ERROR_TARGET_INVALID, /* 32 */ + FBLBM_ERROR_TARGET_NO_VALID_HEADER, /* 33 */ + FBLBM_ERROR_TARGET_VERIFICATION_FAILED, /* 34 */ + FBLBM_ERROR_TARGET_INVALID_ADDRESS, /* 35 */ + FBLBM_ERROR_TARGET_DEP_MANDATORY_MISSING, /* 36 */ + FBLBM_ERROR_TARGET_DEP_NO_VALID_HEADER, /* 37 */ + FBLBM_ERROR_TARGET_DEP_VERIFY_FAILED, /* 38 */ + FBLBM_ERROR_END_OF_MAIN_REACHED, /* 39 */ + FBLBM_ERROR_AP_CHECK_MAC_READ_FAIL, /* 40 */ + FBLBM_ERROR_AP_CHECK_MAC_BUF_LENGTH, /* 41 */ + FBLBM_ERROR_AP_CHECK_MAC_READ_FAIL_LENGTH /* 42 */ +} tFblBmError; + +typedef enum +{ + FBLBM_KEY_IS_NOT_AVAILABLE, + FBLBM_KEY_IS_AVAILABLE +} tFblBmKeyEmptyResult; + +typedef enum +{ + FBLBM_MAC_IS_NOT_AVAILABLE, + FBLBM_MAC_IS_AVAILABLE +} tFblBmMacEmptyResult; + +#endif /* __BM_TYPES_H__ */ + +/*********************************************************************************************************************** + * END OF FILE: BM_TYPES.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblBm/bm_types_header.h b/Source/bsw/FblBm/bm_types_header.h new file mode 100644 index 0000000..fd98415 --- /dev/null +++ b/Source/bsw/FblBm/bm_types_header.h @@ -0,0 +1,143 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Main module of BM + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 06.03.00 2022-04-08 visrie FBL-4126 Improve usage for application + * 06.04.00 2022-04-11 lhopfhauer FBL-4822 No changes + * 06.04.01 2022-04-28 fmenke ESCAN00111741 No changes + * 06.05.00 2022-05-06 lhopfhauer FBL-5148 No changes + * 06.06.00 2022-07-13 fmenke FBL-5391 No changes + * 06.06.01 2022-08-04 jschmitding ESCAN00112070 No changes + * 06.07.00 2022-11-07 lhopfhauer FBL-4932 No changes + * 06.08.00 2022-11-30 visrie FBL-6065 No changes + * 06.08.01 2024-03-04 visrie ESCAN00116460 No changes + * 06.09.00 2024-05-16 lhopfhauer FBL-8602 No changes + * 06.10.00 2024-11-15 erizk FBL-9652 No changes + * 06.11.00 2025-05-23 dganesh FBL-9715 No changes + * 06.12.00 2025-09-23 pharring FBL-10124 No changes + **********************************************************************************************************************/ + +#ifndef BM_TYPES_HEADER_H +#define BM_TYPES_HEADER_H + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#if !defined( FBLBM_HEADER_ADDRESS ) +# error "Set the define FBLBM_HEADER_ADDRESS to the address of the BmHeader." +#endif +#if !defined( FBL_CALL_TYPE ) +# define FBL_CALL_TYPE +#endif + +#if defined( FBLBM_MAIN_ENABLE_FBLSTART_CHANNEL ) +# define FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_ONLY uint8 channel +# define FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_FIRST uint8 channel, +# define FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE channel +#else +# define FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_ONLY void +# define FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_FIRST /* Not used */ +# define FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE 0u +#endif /* FBLBM_MAIN_ENABLE_FBLSTART_CHANNEL */ + +/*********************************************************************************************************************** + * BmHeader access + **********************************************************************************************************************/ + + +/* Define to access the FBL header structure */ +#if defined( V_MEMROM1_FAR ) +/* File is included in FBL context */ +# define FblBmHeaderTable ((V_MEMROM1_FAR tFblBmHeader V_MEMROM2_FAR V_MEMROM3 *)(FBLBM_HEADER_ADDRESS)) +# define FblBmHeaderLocal ((V_MEMROM1_FAR tFblBmHeader V_MEMROM2_FAR V_MEMROM3 *)(&FblBmHeader)) +#else +/* File is included in Application context */ +# define FblBmHeaderTable ((P2CONST(tFblBmHeader, AUTOMATIC, FBLBM_HEADER_CONST))(FBLBM_HEADER_ADDRESS)) +# define FblBmHeaderLocal ((P2CONST(tFblBmHeader, AUTOMATIC, FBLBM_HEADER_CONST))(&FblBmHeader)) +#endif + +/* PRQA S 3453 19 */ /* MD_MSR_FctLikeMacro */ +#if defined( FBL_ENABLE_FBL_START ) +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_CHANNEL ) +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) +# define CallFblStart(channel, pParam, length) (FblBmHeaderTable->pFblStartFct)((channel), (pParam), (length)) +# else +# define CallFblStart(channel) (FblBmHeaderTable->pFblStartFct)(channel) +# endif /* FBLBM_MAIN_ENABLE_FBLSTART_PARAM */ +# else +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) +# define CallFblStart(pParam, length) (FblBmHeaderTable->pFblStartFct)((pParam), (length)) +# else +# define CallFblStart() (FblBmHeaderTable->pFblStartFct)() +# endif /* FBLBM_MAIN_ENABLE_FBLSTART_PARAM */ +# endif /* FBLBM_MAIN_ENABLE_FBLSTART_CHANNEL */ +#endif /* FBL_ENABLE_FBL_START */ + +#if defined( FBL_ENABLE_STAY_IN_BOOT ) +# if defined( FBLBM_MAIN_ENABLE_APPLSTART_PARAM ) +# define CallApplStart(pParam, length) (FblBmHeaderTable->pApplStartFct)((pParam), (length)) +# else +# define CallApplStart() (FblBmHeaderTable->pApplStartFct)() +# endif +#endif /* FBL_ENABLE_STAY_IN_BOOT */ + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +# if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) +/** Pointer to call FblStart() function */ +typedef FBL_CALL_TYPE void (*tFblStrtFct)(FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_FIRST void* pParam, uint8 length); +# else +/** Pointer to call FblStart() function */ +typedef FBL_CALL_TYPE void (*tFblStrtFct)(FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_ONLY); +# endif /* FBL_MAIN_ENABLE_FBLSTART_PARAM */ + +# if defined( FBLBM_MAIN_ENABLE_APPLSTART_PARAM ) +/** Pointer to call FblStart() function */ +typedef FBL_CALL_TYPE void (*tApplStrtFct)(void* pParam, uint8 length); +# else +/** Pointer to call FblStart() function */ +typedef FBL_CALL_TYPE void (*tApplStrtFct)(void); +# endif /* FBL_MAIN_ENABLE_FBLSTART_PARAM */ + +/** BM header structure */ +typedef struct +{ + uint32 magic; /**< Magic Word */ + uint16 majorVersion; /**< Major version of BmHeader format */ + uint16 minorVersion; /**< Minor version of BmHeader format */ + uint32 fblHeaderAddress; /**< Pointer to Fbl Header */ + tFblStrtFct pFblStartFct; /**< Pointer to FblStart-function */ + tApplStrtFct pApplStartFct; /**< Pointer to ApplStart-function */ + uint32 checksum; /**< Checksum on BmHeader */ + uint32 end_magic; /**< End of structure in memory */ +} tFblBmHeader; + +#endif /* BM_TYPES_HEADER_H */ + +/*********************************************************************************************************************** + * END OF FILE: BM_TYPES_HEADER.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblBmHdr/bm_hdr.c b/Source/bsw/FblBmHdr/bm_hdr.c new file mode 100644 index 0000000..f087b5e --- /dev/null +++ b/Source/bsw/FblBmHdr/bm_hdr.c @@ -0,0 +1,234 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief BM Header module + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2019-31-01 visrie - Initial release + * 01.01.00 2019-02-18 vismvi - No changes + * visrie ESCAN00102184 Maximum number of verification entries are not correctly evaluated + * 01.02.00 2019-07-22 visrie ESCAN00103790 Support invalid entry address configuration + * ESCAN00103791 Support of custom verification + * ESCAN00103803 No changes + * 02.00.00 2019-12-03 visrie FBL-456 Added support for new FblLibSecBoot interface + * 02.00.01 2020-01-15 visrie ESCAN00105368 Added missing encapsulation + * 02.01.00 2022-02-25 vistbe FBL-4128 Added/adapted MemMap sections + * 02.02.00 2024-08-29 viswmo FBL-9163 Add target-based BmHdrHeader search for updater + **********************************************************************************************************************/ + +#define BM_HDR_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" +#include "bm_main.h" +#include "fbl_lbt_access.h" + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# include "fbl_secboot.h" +#endif + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLBM_HDR_VERSION != 0x0202u ) || \ + ( FBLBM_HDR_RELEASE_VERSION != 0x00u ) +# error "Error in bm_hdr.c: Source and Header file are inconsistent!" +#endif + +#if ( FBLBM_HDR_VERSION != _FBLBM_HDR_VERSION ) || ( FBLBM_HDR_RELEASE_VERSION != _FBLBM_HDR_RELEASE_VERSION ) +# error "Error in bm_hdr.c: Source and v_ver.h are inconsistent!" +#endif + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ +#define FBLBMHDR_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * FblBmHdrGetBmHeader + **********************************************************************************************************************/ +/*! \brief Validate a specific bootmanager header of a logical block + * \param[in] targetHandle Target handle (e.g. Bootloader, Application) + * \param[in] bmHeaderAddress Location of the BmHeader structure. + * \param[out] bmHeader Buffer for the BmHeader + * \return Result of operation + * FBLBMHDR_CHKHDR_OK when operation succeeded + * FBLBMHDR_CHKHDR_READ_FAIL when reading the BmHeader failed + * FBLBMHDR_CHKHDR_HEADER_INCONSISTENT when the BmHeader is inconsistent + * FBLBMHDR_CHKHDR_WRONG_TARGET when the BmHeader is for another target + **********************************************************************************************************************/ +tFblBmHdrCheckBmHeaderResult FblBmHdrGetBmHeader(tFblBmHdrTargetHandle targetHandle, tFblAddress bmHeaderAddress, + V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader) +{ + tFblBmHdrCheckBmHeaderResult result; + + result = FBLBMHDR_CHKHDR_OK; + + if (FblReadProm(bmHeaderAddress, (vuint8 *)bmHeader, sizeof(tFblBmHdrHeader)) != sizeof(tFblBmHdrHeader)) + { + result = FBLBMHDR_CHKHDR_READ_FAIL; + } + + /* Check for correct target handle */ + if (result == FBLBMHDR_CHKHDR_OK) + { + if (bmHeader->bmTargetHandle != targetHandle) + { + result = FBLBMHDR_CHKHDR_WRONG_TARGET; + } + } + + /* Check for consistency errors */ + if (result == FBLBMHDR_CHKHDR_OK) + { + if (kFblOk != FblBmHdrCheckConsistency(bmHeader)) + { + result = FBLBMHDR_CHKHDR_HEADER_INCONSISTENT; + } + } + + return result; +} /* PRQA S 6010 */ /* MD_MSR_STPTH */ + +/*********************************************************************************************************************** + * FblBmHdrCheckConsistency + **********************************************************************************************************************/ +/*! \brief Checks the consistency of the BM header structure + * \param[in] bmHeader: Pointer to the BM Header structure + * \return Result of operation + **********************************************************************************************************************/ +tFblResult FblBmHdrCheckConsistency( const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * pBmHeader ) +{ + tFblResult result; +#if defined( FBLBMHDR_ENABLE_HEADER_VERIFICATION_LIST ) + vuintx i; +#endif /* FBLBMHDR_ENABLE_HEADER_VERIFICATION_LIST */ + + /* Initialize variables */ + result = kFblOk; + + /* Check magic value */ + if (pBmHeader->bmMagicFlag != FBLBMHDR_MAGIC_FLAG) + { + result = kFblFailed; + } + +#if defined( FBLBMHDR_ENABLE_HEADER_VERIFICATION_LIST ) + /* Check number of verification regions */ + if (result == kFblOk) + { + if (pBmHeader->bmVerificationListEntries > FBLBMHDR_NUM_OF_VERIFICATION_ENTRIES) + { + result = kFblFailed; + } + } + + /* Check if a verification region contains the entry address */ + if ( (result == kFblOk) + && (pBmHeader->bmEntryAddress != FBLBMHDR_ENTRY_ADDRESS_INVALID)) + { + /* Change result to failed, it will be set back to OK if a valid region was found */ + result = kFblFailed; + + for (i = 0u; i < pBmHeader->bmVerificationListEntries; i++) + { + if ( (pBmHeader->bmEntryAddress >= pBmHeader->bmVerificationList[i].address) + && (pBmHeader->bmEntryAddress < (pBmHeader->bmVerificationList[i].address + pBmHeader->bmVerificationList[i].length))) + { + /* Entry address is in a verification range */ + result = kFblOk; + break; + } + } + } +#endif /* FBLBMHDR_ENABLE_HEADER_VERIFICATION_LIST */ + + return result; +} + +#if defined( FBLBM_CALLOUT_IS_VALIDBLOCK ) +/*********************************************************************************************************************** + * FblBmHdrFindValidHeader + **********************************************************************************************************************/ +/*! \brief Find a valid bootmanager header structure for the given target + * \param[in] targetHandle Target handle (e.g. Bootloader, Application) + * \param[in,out] pBlockInfo Pointer to a structure which holds a pointer to the BM header and the corresponding + * logical block. + * \return Result of operation + * FBLBMHDR_CHKHDR_OK A valid BmHeader is found + * FBLBMHDR_CHKHDR_NOT_FOUND No BmHeader found + * FBLBMHDR_CHKHDR_BLOCK_INVALID Logical block is not valid + * see FblBmHdrCheckBmHeader for further return values. + * see FblBmHdrVerifyBmHeader for further return values. + **********************************************************************************************************************/ +tFblBmHdrCheckBmHeaderResult FblBmHdrFindValidHeader(tFblBmHdrTargetHandle targetHandle, + V_MEMRAM1 tFblBmBlockInfo V_MEMRAM2 V_MEMRAM3 * pBlockInfo) +{ + tFblBmHdrCheckBmHeaderResult result; + tFblLbtBlockFilter blockFilter; + + /* Initialize variables */ + result = FBLBMHDR_CHKHDR_NOT_FOUND; + + /* Iterate over all mandatory blocks */ + FblLbtBlockFilterInit(&blockFilter); + pBlockInfo->logicalBlock = FblLbtBlockFirst(&blockFilter); + while (FblLbtBlockDone() == FALSE) + { + + if (kFblOk == FBLBM_CALLOUT_IS_VALIDBLOCK(targetHandle, &pBlockInfo->logicalBlock)) + { + result = FblBmHdrGetBmHeader(targetHandle, pBlockInfo->logicalBlock.bmHeaderAddress, &pBlockInfo->bmHeader); + } + else + { + result = FBLBMHDR_CHKHDR_BLOCK_INVALID; + } + + if (result == FBLBMHDR_CHKHDR_OK) + { + /* Leave loop after first hit */ + break; + } + + /* Prepare next cycle */ + pBlockInfo->logicalBlock = FblLbtBlockNext(); + } + + return result; +} +#endif /* FBLBM_CALLOUT_IS_VALIDBLOCK */ + +#define FBLBMHDR_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * END OF FILE: BM_HDR.C + **********************************************************************************************************************/ diff --git a/Source/bsw/FblBmHdr/bm_hdr.h b/Source/bsw/FblBmHdr/bm_hdr.h new file mode 100644 index 0000000..1217bb0 --- /dev/null +++ b/Source/bsw/FblBmHdr/bm_hdr.h @@ -0,0 +1,75 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief BM Header module + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2019-31-01 visrie - Initial release + * 01.01.00 2019-02-18 vismvi - No changes + * visrie ESCAN00102184 No changes + * 01.02.00 2019-07-22 visrie ESCAN00103790 No changes + * ESCAN00103791 No changes + * ESCAN00103803 No changes + * 02.00.00 2019-12-03 visrie FBL-456 Added support for new FblLibSecBoot interface + * 02.00.01 2020-01-15 visrie ESCAN00105368 Added missing encapsulation + * 02.01.00 2022-02-25 vistbe FBL-4128 Added/adapted MemMap sections + * 02.02.00 2024-08-29 viswmo FBL-9163 Add target-based BmHdrHeader search for updater + **********************************************************************************************************************/ + +#ifndef BM_HDR_H +#define BM_HDR_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblBm_Hdr CQComponent : Implementation */ +#define FBLBM_HDR_VERSION 0x0202u +#define FBLBM_HDR_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "FblBmHdr_Cfg.h" + +/*********************************************************************************************************************** + * FUNCTION PROTOTYPES + **********************************************************************************************************************/ +#define FBLBMHDR_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +tFblResult FblBmHdrCheckConsistency( const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * pBmHeader ); +tFblBmHdrCheckBmHeaderResult FblBmHdrGetBmHeader(tFblBmHdrTargetHandle targetHandle, tFblAddress bmHeaderAddress, + V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader); +#if defined( FBLBM_CALLOUT_IS_VALIDBLOCK ) +tFblBmHdrCheckBmHeaderResult FblBmHdrFindValidHeader(tFblBmHdrTargetHandle targetHandle, + V_MEMRAM1 tFblBmBlockInfo V_MEMRAM2 V_MEMRAM3 * pBlockInfo); +#endif /* FBLBM_CALLOUT_IS_VALIDBLOCK */ + +#define FBLBMHDR_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* BM_HDR_H */ + +/*********************************************************************************************************************** + * END OF FILE: BM_HDR.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblBmHdr/bm_hdr_types.h b/Source/bsw/FblBmHdr/bm_hdr_types.h new file mode 100644 index 0000000..52a3548 --- /dev/null +++ b/Source/bsw/FblBmHdr/bm_hdr_types.h @@ -0,0 +1,67 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief BM Header module + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2019-31-01 visrie - Initial release + * 01.01.00 2019-02-18 vismvi - No changes + * visrie ESCAN00102184 No changes + * 01.02.00 2019-07-22 visrie ESCAN00103790 Support invalid entry address configuration + * ESCAN00103791 No changes + * ESCAN00103803 No changes + * 02.00.00 2019-12-03 visrie FBL-456 No changes + * 02.00.01 2020-01-15 visrie ESCAN00105368 No changes + * 02.01.00 2022-02-25 vistbe FBL-4128 No changes + * 02.02.00 2024-08-29 viswmo FBL-9163 No changes + **********************************************************************************************************************/ + +#ifndef BM_HDR_TYPES_H +#define BM_HDR_TYPES_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "FblBmHdr_Cfg.h" + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +typedef enum +{ + FBLBMHDR_CHKHDR_OK, + FBLBMHDR_CHKHDR_BLOCK_INVALID, + FBLBMHDR_CHKHDR_READ_FAIL, + FBLBMHDR_CHKHDR_HEADER_INCONSISTENT, + FBLBMHDR_CHKHDR_WRONG_TARGET, + FBLBMHDR_CHKHDR_GET_MAC_FAIL, + FBLBMHDR_CHKHDR_VERIFICATION_FAIL, + FBLBMHDR_CHKHDR_NOT_FOUND +}tFblBmHdrCheckBmHeaderResult; + +#endif /* BM_HDR_TYPES_H */ + +/*********************************************************************************************************************** + * END OF FILE: BM_HDR_TYPES.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblNvPattern/Make/FblNvPattern_cfg.mak b/Source/bsw/FblNvPattern/Make/FblNvPattern_cfg.mak new file mode 100644 index 0000000..0f18e05 --- /dev/null +++ b/Source/bsw/FblNvPattern/Make/FblNvPattern_cfg.mak @@ -0,0 +1,12 @@ +############################################################################### +# File Name : FblNvPattern_cfg.mak +# Description: Configuration makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the FblNvPattern_rules.mak file. +############################################################################### \ No newline at end of file diff --git a/Source/bsw/FblNvPattern/Make/FblNvPattern_check.mak b/Source/bsw/FblNvPattern/Make/FblNvPattern_check.mak new file mode 100644 index 0000000..c6629b9 --- /dev/null +++ b/Source/bsw/FblNvPattern/Make/FblNvPattern_check.mak @@ -0,0 +1,12 @@ +############################################################################### +# File Name : FblNvPattern_check.mak +# Description: Configuration check makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the FblNvPattern_rules.mak file. +############################################################################### diff --git a/Source/bsw/FblNvPattern/Make/FblNvPattern_defs.mak b/Source/bsw/FblNvPattern/Make/FblNvPattern_defs.mak new file mode 100644 index 0000000..5cfe78d --- /dev/null +++ b/Source/bsw/FblNvPattern/Make/FblNvPattern_defs.mak @@ -0,0 +1,12 @@ +############################################################################### +# File Name : FblNvPattern_defs.mak +# Description: Public makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the FblNvPattern_rules.mak file. +############################################################################### diff --git a/Source/bsw/FblNvPattern/Make/FblNvPattern_rules.mak b/Source/bsw/FblNvPattern/Make/FblNvPattern_rules.mak new file mode 100644 index 0000000..84947ea --- /dev/null +++ b/Source/bsw/FblNvPattern/Make/FblNvPattern_rules.mak @@ -0,0 +1,24 @@ +############################################################################### +# File Name : FblNvPattern_rules.mak +# Description: Rules makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Version Date Author Description +#------------------------------------------------------------------------------ +# 1.00.00 2025-04-25 virjjn Initial commit +#------------------------------------------------------------------------------ +# TemplateVersion = 1.02 +############################################################################### + +# Component Files +CC_FILES_TO_BUILD += FblNvPattern$(BSW_SRC_DIR)\fbl_nvpattern.c +GENERATED_SOURCE_FILES += $(GENDATA_DIR)\..\Source\FblNvPattern_Callout_Stubs.c + +# Library Settings +LIBRARIES_TO_BUILD += FblNvPattern +FblNvPattern_FILES += FblNvPattern$(BSW_SRC_DIR)\fbl_nvpattern.c \ No newline at end of file diff --git a/Source/bsw/FblNvPattern/fbl_nvpattern.c b/Source/bsw/FblNvPattern/fbl_nvpattern.c new file mode 100644 index 0000000..8e5ed6e --- /dev/null +++ b/Source/bsw/FblNvPattern/fbl_nvpattern.c @@ -0,0 +1,1306 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Implementation of pattern/mask based non-volatile information storage + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 02.00.00 2025-03-11 virjjn FBL-9704 Initial version + * 02.01.00 2025-06-19 dganesh FBL-11034 Improvements in extended presence pattern + **********************************************************************************************************************/ + +#define FBL_NVPATTERN_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" +#include "fbl_nvpattern.h" + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLLIB_NVPATTERN_VERSION != 0x0201u ) || \ + ( FBLLIB_NVPATTERN_RELEASE_VERSION != 0x00u ) +# error "Error in fbl_nvpattern.c: Source and header file are inconsistent!" +#endif + +#if ( FBLLIB_NVPATTERN_VERSION != _FBLLIB_NVPATTERN_VERSION ) || \ + ( FBLLIB_NVPATTERN_RELEASE_VERSION != _FBLLIB_NVPATTERN_RELEASE_VERSION ) +# error "Error in fbl_nvpattern.c: Source and v_ver.h are inconsistent!" +#endif + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* Definition of marker/mask values and their size */ +#if !defined( kFblNvMarkerValue ) +# define kFblNvMarkerValue {0x73u, 0x6Au, 0x29u, 0x3Eu} +#endif /* kFblNvMarkerValue */ +#if !defined( kFblNvMaskValue ) +# define kFblNvMaskValue {0x8Cu, 0x95u, 0xD6u, 0xC1u} +#endif /* kFblNvMaskValue */ +#if !defined( kFblNvPatternSize ) +# define kFblNvPatternSize 4u +#endif /* kFblNvPatternSize */ + +/* Macro to calculate the page aligned size to hold a value of size len */ +#define PAGE_ALIGN(len, align) (((len) + ((align) - 1u)) & ~((align) - 1u)) + +/* Macro to check if val is a power of two */ +#define IS_POWOFTWO(val) (((val) & ~((val) - 1u)) == (val)) + +/* Size of write buffer with enough space to hold one marker/mask value */ +#if ( FBL_MAX_SEGMENT_SIZE < kFblNvPatternSize ) +# define kFblNvPatternSegmentSize PAGE_ALIGN(kFblNvPatternSize, FBL_MAX_SEGMENT_SIZE) +#else +# define kFblNvPatternSegmentSize FBL_MAX_SEGMENT_SIZE +#endif + +/* Checks if tFblNvPatternId belongs to a block property or a pattern */ +#define IS_VALID_PATTERN_ID(id) (((id) > kFblNvPatternId_Invalid) && ((id) < kFblNvPatternId_Separator)) +#define IS_VALID_PROPERTY_ID(id) (((id) > kFblNvPatternId_Separator) && ((id) < kFblNvPatternId_Last)) + +/* Parameter value to skip comparison for function FblNvPatternGetPatternItemState */ +#define DONT_COMPARE (vuint8*)0u + +/* Enable the unexpected value check by default */ +#if !defined( FBL_NVPATTERN_DISABLE_CHECK_UNEXPECTEDVALUE ) +# define FBL_NVPATTERN_ENABLE_CHECK_UNEXPECTEDVALUE +#endif /* !FBL_NVPATTERN_DISABLE_CHECK_UNEXPECTEDVALUE && !FBL_NVPATTERN_ENABLE_CHECK_UNEXPECTEDVALUE */ + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +/** Buffer with alignment to platform requirements */ +typedef struct +{ + vuint32 alignDummy; /**< Used to force 4Byte alignment */ + vuint8 data[kFblNvPatternSegmentSize]; +} tFblNvPatternAlignedBuffer; + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +#define FBLNVPATTERN_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +V_MEMRAM0 static V_MEMRAM1 tFblNvPatternAlignedBuffer V_MEMRAM2 pageBuffer; +#define FBLNVPATTERN_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLNVPATTERN_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +static tFblResult FblNvPatternWritePageAligned( const vuint8* pSrcBuffer, IO_PositionType address, IO_SizeType length ); +static tFblNvPatternItemState FblNvPatternGetPatternItemState( IO_PositionType patternAddress, IO_SizeType length, const vuint8* compareValue ); +static tFblResult FblNvPatternGetPatternBlockDescriptorByStartAddress( IO_PositionType patternStartAddress, + V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor ); +static IO_SizeType FblNvPatternGetPatternOffset( tFblNvPatternId patternId, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * patternLength ); + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FblNvPatternWritePageAligned + **********************************************************************************************************************/ +/*! \brief Writes data respecting the page size of the memory device + * \pre GetBaseAddr function has been called first + * \param[in] pSrcBuffer pointer to source data + * \param[in] address target address + * \param[in] length length of data + **********************************************************************************************************************/ +static tFblResult FblNvPatternWritePageAligned( const vuint8* pSrcBuffer, IO_PositionType address, IO_SizeType length ) +{ + tFblResult result; + IO_SizeType i; + IO_SizeType writeGranularity; + IO_SizeType actualWriteLength; + IO_SizeType localLength; + IO_PositionType offset; + + /* Initialize variables */ + result = kFblOk; + localLength = length; + offset = 0u; + + while (localLength > 0u) + { + (void)FblRealTimeSupport(); + + /* Determine page aligned write length, limit to buffer length */ + if (localLength > kFblNvPatternSegmentSize) + { + writeGranularity = kFblNvPatternSegmentSize; + actualWriteLength = kFblNvPatternSegmentSize; + } + else + { + writeGranularity = PAGE_ALIGN(localLength, (IO_SizeType)MemDriver_SegmentSize); + actualWriteLength = localLength; + } + + /* Fill buffer with payload data */ + for (i = 0u; i < actualWriteLength; i++) + { + pageBuffer.data[i] = pSrcBuffer[i + offset]; + } + /* Pad remaining buffer if necessary */ + if (actualWriteLength < kFblNvPatternSegmentSize) + { + for (i = actualWriteLength; i < writeGranularity; i++) + { + pageBuffer.data[i] = 0u; + } + } + + /* Call MIO to write data */ + if (MemDriver_RWriteSync(pageBuffer.data, writeGranularity, address + offset) != IO_E_OK) + { + result = kFblFailed; + break; + } + + /* Update variables */ + localLength -= actualWriteLength; + offset += actualWriteLength; + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternGetPatternItemState + **********************************************************************************************************************/ +/*! \brief Reads one marker/mask and returns the state of it + * \pre Global variable memSegment is set to the block where the pattern is stored + * \param[in] patternAddress address of pattern item + * \param[in] length the length of the pattern item to read + * \param[in] compareValue pointer to expected pattern value (return ExpectedValue), 0 if no comparison is needed + * \return The state of the pattern item + **********************************************************************************************************************/ +/* PRQA S 6010, 6030, 6080 1 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STMIF */ +static tFblNvPatternItemState FblNvPatternGetPatternItemState( IO_PositionType patternAddress, IO_SizeType length, const vuint8* compareValue) +{ + tFblNvPatternItemState itemState = FBL_NVPATTERN_STATE_READERROR; + vuint8 memErasedValue; + IO_SizeType currentReadLength; + IO_SizeType localLength = length; + IO_PositionType readOffset = 0u; + vuint32 i; + vuint32 countExpectedValue = 0u; + vuint32 countErasedValue = 0u; + + /* Determine memory erased value of used device */ +#if defined( FBL_ENABLE_MULTIPLE_MEM_DEVICES ) + memErasedValue = memDrvLst[FlashBlock[memSegment].device].erasedValue; +#else + memErasedValue = FBL_FLASH_DELETED; +#endif + + while (localLength > 0u) + { + /* Limit read length to buffer size */ + if (localLength > kFblNvPatternSegmentSize) + { + currentReadLength = kFblNvPatternSegmentSize; + } + else + { + currentReadLength = localLength; + } + + /* Read marker/mask */ + switch (MemDriver_RReadSync(pageBuffer.data, currentReadLength, patternAddress + readOffset)) + { + case IO_E_OK: + case IO_E_ERASED: + { + /* Read successful. Because some drivers don't return IO_E_ERASED, + * we have to assume that memory is erased if all bytes show the erased value + * and compare against the erased value later. */ + itemState = FBL_NVPATTERN_STATE_ERASED; + break; + } + default: + { + /* Read error */ + itemState = FBL_NVPATTERN_STATE_READERROR; + assertFbl(0u, kFblSysAssertParameterOutOfRange); /* PRQA S 2741, 4558 */ /* MD_FblNvPattern_Assertion */ + break; + } + } + + if (itemState == FBL_NVPATTERN_STATE_ERASED) + { + /* Check all bytes of marker/mask */ + for (i = 0u; i < currentReadLength; i++) + { + /* Compare one byte of pattern against the expected value/erased value */ + if ((compareValue != DONT_COMPARE) && (pageBuffer.data[i] == compareValue[readOffset + i])) + { + countExpectedValue++; + } + else if (pageBuffer.data[i] == memErasedValue) + { + countErasedValue++; + } + else /* (pageBuffer.data[i] != memErasedValue) */ + { + /* This might happen in case of unintended writes to pattern area */ + itemState = FBL_NVPATTERN_STATE_UNEXPECTEDVALUE; + } + + /* In case of an unexpected value break out of the for loop */ + if (itemState == FBL_NVPATTERN_STATE_UNEXPECTEDVALUE) + { + break; + } + } + + /* Check if there were expected and erased bytes included */ + if ( (countErasedValue != 0u) + && (countExpectedValue != 0u)) + { + itemState = FBL_NVPATTERN_STATE_UNEXPECTEDVALUE; + } + } + + /* Abort in case of error */ + if ((itemState == FBL_NVPATTERN_STATE_UNEXPECTEDVALUE) || (itemState == FBL_NVPATTERN_STATE_READERROR)) + { + break; + } + + /* Update variables */ + localLength -= currentReadLength; + readOffset += currentReadLength; + } + + /* Set itemState according to the counts */ + if (length == 0u) + { + itemState = FBL_NVPATTERN_STATE_NOMEMSEGMENT; + } + else if (countErasedValue == length) + { + itemState = FBL_NVPATTERN_STATE_ERASED; + } + else if (countExpectedValue == length) + { + itemState = FBL_NVPATTERN_STATE_EXPECTEDVALUE; + } + else + { + /* itemState already set correctly */ + } + + return itemState; +} + + +/*********************************************************************************************************************** + * FblNvPatternGetPatternBlockDescriptorByStartAddress + **********************************************************************************************************************/ +/*! \brief Prepares a dummy block descriptor spaning only the pattern region + * \param[in] patternStartAddress Start address of pattern region + * \param[out] blockDescriptor Pointer to RAM buffer in which the dummy block descriptor can be stored + * \return kFblOk: block descriptor created successfully , kFblFailed: Else + **********************************************************************************************************************/ +static tFblResult FblNvPatternGetPatternBlockDescriptorByStartAddress( IO_PositionType patternStartAddress, + V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor ) +{ + tFblResult result = kFblFailed; + IO_SizeType patternLength; + IO_SizeType patternRegionLength = 0u; + + /* Get memory segment index */ + memSegment = FblMemSegmentNrGet(patternStartAddress); + + /* Check if a valid memory segment in flash block table was found */ + if (memSegment >= 0) + { + /* Get offset for last pattern/property as this offset equals size of the complete pattern region */ + /* PRQA S 4342 1 */ /* MD_FblNvPattern_4342 */ + patternRegionLength = FblNvPatternGetPatternOffset((tFblNvPatternId)((vuintx)kFblNvPatternId_Last - 1u), &patternLength); + + blockDescriptor->blockStartAddress = patternStartAddress; + blockDescriptor->blockLength = patternRegionLength; + result = kFblOk; + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternGetPatternOffset + **********************************************************************************************************************/ +/*! \brief Returns the offset for a certain pattern/property + * \details The returned offset is calculated from the end of the pattern region. Therefore a lower offset has + * the meaning that the respective pattern is located closer to the end of the pattern region. + * \pre Global variable memSegment is set to the block where the pattern region is stored + * \param[in] patternId ID of pattern/property for which the offset shall be calculated + * \param[out] patternOffset Pointer to RAM buffer to store the offset to the requested pattern + * \param[out] pPatternLength Pointer to RAM buffer to store the actual write address of the NvPattern or property + * \return Offset to the requested pattern + **********************************************************************************************************************/ +static IO_SizeType FblNvPatternGetPatternOffset( tFblNvPatternId patternId, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * patternLength ) +{ + IO_SizeType patternOffset = 0u; + IO_SizeType localPatternLength = 0u; + vuintx i; + vuintx upperBound; + + /* Segment size must be a power of two */ + assertFbl(IS_POWOFTWO(MemDriver_SegmentSize), kFblSysAssertParameterOutOfRange); + + /* Adjust patternLength to write segment size of device */ + localPatternLength = PAGE_ALIGN(kFblNvPatternSize, (IO_SizeType)MemDriver_SegmentSize); + + /* Add size of NvPatterns to offset... + * Upper bound for loop is either the last NvPattern element if base address of block property has been requested + * or patternId in case the requested element is a NvPattern */ + upperBound = (patternId > kFblNvPatternId_Separator) ? ((vuintx)kFblNvPatternId_Separator - 1u) : (vuintx)patternId; + + for (i = 0u; i < upperBound; i++) + { +#if defined( FBL_NVPATTERN_ENABLE_MULTIPLE_VALIDATION ) + patternOffset += (localPatternLength * ((IO_SizeType)fblNvPatternMultiplicity[i] * 2u)); +#else + patternOffset += (localPatternLength * 2u); +#endif /* FBL_NVPATTERN_ENABLE_MULTIPLE_VALIDATION */ + } + + /* ... then add sizes of block property elements */ +#if defined( FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES ) + /* Skip this loop (set upperBound to 0) if the requested Id is not a block property, + * otherwise subtract kFblNvPatternId_Separator from pattern id to get the index into fblNvPatternElementLength */ + upperBound = (patternId > kFblNvPatternId_Separator) ? ((vuintx)patternId - (vuintx)kFblNvPatternId_Separator) : 0u; + + for (i = 0u; i < upperBound; i++) + { + patternOffset += PAGE_ALIGN(fblNvBlockProperties[i].length, (IO_SizeType)MemDriver_SegmentSize); + localPatternLength = PAGE_ALIGN(fblNvBlockProperties[i].length, (IO_SizeType)MemDriver_SegmentSize); + } +#endif /* FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES */ + + /* Put results into arguments */ + *patternLength = localPatternLength; + + return patternOffset; +} +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * FblNvPatternGetPatternState + **********************************************************************************************************************/ +/*! \brief Determines the state of one or a set of marker/mask pairs. + * \details Iterates through all sub-patterns in case of multiple validation. + * Returns address and length of pattern which stores the currently relevant state. + * \param[in] pBlockDescriptor descriptor of the logical block which contains the NvPattern + * \param[in] patternId Id of pattern to read + * \param[out] pPatternAddress Pointer to RAM buffer which keeps the pattern base address + * \param[out] pPatternLength Pointer to RAM buffer which keeps the actual write length of the pattern + * \return The state of the (sub) pattern which holds the current state of the pattern + **********************************************************************************************************************/ +tFblNvPatternState FblNvPatternGetPatternState( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * pBlockDescriptor, + tFblNvPatternId patternId, + V_MEMRAM1 IO_PositionType V_MEMRAM2 V_MEMRAM3 * pPatternAddress, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * pPatternLength ) +{ + vuint32 multiplicity; + tFblNvPatternState patternState; + IO_PositionType patternAddress; + vuint8 fblMarkerValue[] = kFblNvMarkerValue; /* PRQA S 3678 */ /* MD_FblNvPattern_3678_LocalVariable */ + vuint8 fblMaskValue[] = kFblNvMaskValue; /* PRQA S 3678 */ /* MD_FblNvPattern_3678_LocalVariable */ + + /* PRQA S 2742, 2880 2 */ /* MD_FblNvPattern_Assertion */ + assertFblUser(sizeof(fblMarkerValue) == kFblNvPatternSize, kFblSysAssertParameterOutOfRange); + assertFblUser(sizeof(fblMaskValue) == kFblNvPatternSize, kFblSysAssertParameterOutOfRange); + + /* Initialize variables */ + patternAddress = *pPatternAddress; + patternState.markerState = FBL_NVPATTERN_STATE_NOMEMSEGMENT; + patternState.maskState = FBL_NVPATTERN_STATE_NOMEMSEGMENT; + memSegment = -1; + + /* Get Base Address of pattern if id is valid */ + if (IS_VALID_PATTERN_ID(patternId)) + { + memSegment = FblNvPatternGetBaseAddrByBlockDescriptor(pBlockDescriptor, patternId, &patternAddress, pPatternLength); + } + + if (memSegment >= 0) + { + /* Determine number of sub-patterns */ +#if defined( FBL_NVPATTERN_ENABLE_MULTIPLE_VALIDATION ) + multiplicity = (vuint32)fblNvPatternMultiplicity[((vuintx)patternId - 1u)]; +#else + multiplicity = 1u; +#endif + } + else + { + /* No memory segment found, abort */ + multiplicity = 0u; + } + + /* Go through all configured sub-patterns until we have found the sub-pattern which holds the most recent state */ + while (multiplicity >= 1u) + { + /* Poll watchdog function */ + (void)FblRealTimeSupport(); + + /* Read marker and mask area */ + patternState.markerState = FblNvPatternGetPatternItemState(patternAddress, kFblNvPatternSize, fblMarkerValue); + patternState.maskState = FblNvPatternGetPatternItemState((patternAddress + *pPatternLength), kFblNvPatternSize, fblMaskValue); + + if ( ((patternState.markerState == FBL_NVPATTERN_STATE_EXPECTEDVALUE) && (patternState.maskState == FBL_NVPATTERN_STATE_ERASED)) + || ((patternState.markerState == FBL_NVPATTERN_STATE_ERASED) && (patternState.maskState == FBL_NVPATTERN_STATE_ERASED))) + { + /* One pattern item is in erased state, this is the most recent state of the pattern */ + break; + } + + /* Get base address of next sub-pattern */ + patternAddress += (*pPatternLength * 2u); + + /* Decrement number of sub-patterns to process */ + multiplicity--; + } + + /* Write current address to passed argument pointer */ + *pPatternAddress = patternAddress; + + return patternState; +} + + +/*********************************************************************************************************************** + * FblNvPatternGetPatternStateByStartAddress + **********************************************************************************************************************/ +/*! \brief Determines the state of one or a set of marker/mask pairs. + * \details Iterates through all sub-patterns in case of multiple validation. + * Returns address and length of pattern which stores the currently relevant state. + * \param[in] patternStartAddress Start address of pattern region + * \param[in] patternId Id of pattern to read + * \param[out] pPatternAddress Pointer to RAM buffer which keeps the address of the pattern + * \param[out] pPatternLength Pointer to RAM buffer which keeps the actual write length of the pattern + * \return The state of the (sub) pattern which holds the current state of the pattern + **********************************************************************************************************************/ +tFblNvPatternState FblNvPatternGetPatternStateByStartAddress( IO_PositionType patternStartAddress, + tFblNvPatternId patternId, + V_MEMRAM1 IO_PositionType V_MEMRAM2 V_MEMRAM3 * patternAddress, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * patternLength ) +{ + tBlockDescriptor dummyBlockDescriptor = { 0u }; + tFblNvPatternState patternState = { 0u }; + + if(FblNvPatternGetPatternBlockDescriptorByStartAddress(patternStartAddress, &dummyBlockDescriptor) == kFblOk) + { + patternState = FblNvPatternGetPatternState(&dummyBlockDescriptor, patternId, patternAddress, patternLength); + } + + return patternState; +} + +/*********************************************************************************************************************** + * FblNvPatternGetBaseAddr + **********************************************************************************************************************/ +/*! \brief Calculates base address and actual (write) length of pattern and mask + * \pre LBT is present + * \param[in] blockNr Logical block number + * \param[in] patternId ID of the pattern which shall be checked + * \param[out] pPatternAddress Pointer to RAM buffer which keeps the pattern base address + * \param[out] pPatternLength Pointer to RAM buffer which keeps the actual write length of the pattern + * \return memSegment of the pattern location or -1 in case of an error + **********************************************************************************************************************/ +vsint16 FblNvPatternGetBaseAddr( vuint8 blockNr, + tFblNvPatternId patternId, + V_MEMRAM1 IO_PositionType V_MEMRAM2 V_MEMRAM3 * pPatternAddress, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * pPatternLength ) +{ + tBlockDescriptor blockDescriptor; + tFblResult result; + + result = FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor); + + if (result == kFblOk) + { + memSegment = FblNvPatternGetBaseAddrByBlockDescriptor(&blockDescriptor, patternId, pPatternAddress, pPatternLength); + } + else + { + /* Invalid block number passed, signal failure via return value */ + memSegment = -1; + } + + return memSegment; +} + +/*********************************************************************************************************************** + * FblNvPatternGetBaseAddrByBlockDescriptor + **********************************************************************************************************************/ +/*! \brief Calculates base address and actual (write) length of an NvPattern or block property element + * \param[in] blockDescriptor Logical block descriptor + * \param[in] patternId ID of the NvPattern or block property for which the base address is requested + * \param[out] pPatternAddress Pointer to RAM buffer to store the base address + * \param[out] pPatternLength Pointer to RAM buffer to store the actual write address of the NvPattern or property + * \return memSegment of the pattern location or -1 in case of an error + **********************************************************************************************************************/ +vsint16 FblNvPatternGetBaseAddrByBlockDescriptor( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId patternId, + V_MEMRAM1 IO_PositionType V_MEMRAM2 V_MEMRAM3 * patternAddress, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * patternLength ) +{ + IO_PositionType lastBlockAddress; + + /* Get address of last byte in block */ + lastBlockAddress = blockDescriptor->blockStartAddress + (blockDescriptor->blockLength - 1u); + + /* Get corresponding memory segment index */ + memSegment = FblMemSegmentNrGet(lastBlockAddress); + + /* Check if a valid memory segment in flash block table was found */ + if (memSegment >= 0) + { + IO_SizeType offsetLength = FblNvPatternGetPatternOffset(patternId, patternLength); + + /* Calculate pattern address */ + *patternAddress = (lastBlockAddress - offsetLength) + 1u; + + /* Check for range overflow */ + assertFbl(*patternAddress >= blockDescriptor->blockStartAddress, kFblSysAssertParameterOutOfRange); + + /* All NvPattern data must be stored in the same memSegment */ + assertFbl(FblMemSegmentNrGet(*patternAddress) == memSegment, kFblSysAssertParameterOutOfRange); + } + else + { + /* No memory segment found, this is a configuration error. */ + assertFbl(0u, kFblSysAssertParameterOutOfRange); /* PRQA S 2741, 4558 */ /* MD_FblNvPattern_Assertion */ + } + + return memSegment; +} + +/*********************************************************************************************************************** + * FblNvPatternGetPatternRegionSizeByStartAddress + **********************************************************************************************************************/ +/*! \brief Calculates length of complete region containing NvPattern or block property elements + * \param[in] patternStartAddress Start address of pattern region + * \param[out] patternLength Pointer to RAM buffer to store the region size + * \return kFblOk: Pattern region size calculated successfully , kFblFailed: Else + **********************************************************************************************************************/ +tFblResult FblNvPatternGetPatternRegionSizeByStartAddress( IO_PositionType patternStartAddress, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * patternRegionLength) +{ + tBlockDescriptor blockDescriptor; + tFblResult result = FblNvPatternGetPatternBlockDescriptorByStartAddress(patternStartAddress, &blockDescriptor); + + if (result == kFblOk) + { + *patternRegionLength = (IO_SizeType)blockDescriptor.blockLength; + } + + return result; +} +/*********************************************************************************************************************** + * FblNvPatternSet + **********************************************************************************************************************/ +/*! \brief Writes the pattern into the flash memory. + * \details The location of the pattern will be taken from the logical block table + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] patternId ID of the pattern which shall be set + * \return kFblOk: pattern successfully written, kFblFailed: Error writing pattern + **********************************************************************************************************************/ +tFblResult FblNvPatternSet( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, tFblNvPatternId patternId ) +{ + tBlockDescriptor localBlockDescriptor; + tFblResult result; + + result = FblLbtGetBlockDescriptorByNr(blockDescriptor->blockNr, &localBlockDescriptor); + + if (result == kFblOk) + { + result = FblNvPatternSetByBlockDescriptor(&localBlockDescriptor, patternId); + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternSetByBlockDescriptor + **********************************************************************************************************************/ +/*! \brief Writes the pattern into the flash memory. + * \details The location of the pattern will be taken from the logical block descriptor. + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] patternId ID of the pattern which shall be set + * \return kFblOk: pattern successfully written or already set, kFblFailed: Error writing pattern + **********************************************************************************************************************/ +tFblResult FblNvPatternSetByBlockDescriptor( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId patternId ) +{ + IO_PositionType patternAddress; + IO_SizeType patternLength; + tFblResult result; + tFblNvPatternState patternState; + vuint8 fblMarkerValue[] = kFblNvMarkerValue; /* PRQA S 3678 */ /* MD_FblNvPattern_3678_LocalVariable */ + + /* PRQA S 2742, 2880 1 */ /* MD_FblNvPattern_Assertion */ + assertFblUser(sizeof(fblMarkerValue) == kFblNvPatternSize, kFblSysAssertParameterOutOfRange); + + /* Initialize variables */ + result = kFblFailed; + + /* Check state of pattern */ + patternState = FblNvPatternGetPatternState(blockDescriptor, patternId, &patternAddress, &patternLength); + + /* Proceed if marker is blank */ + if (patternState.markerState == FBL_NVPATTERN_STATE_ERASED) + { + /* Write pattern */ + if (kFblOk == FblNvPatternWritePageAligned(fblMarkerValue, patternAddress, kFblNvPatternSize)) + { + /* Verify that pattern is valid now */ + patternState = FblNvPatternGetPatternState(blockDescriptor, patternId, &patternAddress, &patternLength); + + if (patternState.markerState == FBL_NVPATTERN_STATE_EXPECTEDVALUE) + { +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) + result = FblNvPatternUpdateCmacByBlockDescriptor(blockDescriptor, patternId); +#else + result = kFblOk; +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + } + } + } + else if ((patternState.markerState == FBL_NVPATTERN_STATE_EXPECTEDVALUE) && (patternState.maskState == FBL_NVPATTERN_STATE_ERASED)) + { + /* Pattern already has expected state */ + result = kFblOk; + } + else + { + /* For the sake of completeness */ + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternSetByStartAddress + **********************************************************************************************************************/ +/*! \brief Writes the pattern into the flash memory. + * \param[in] patternStartAddress Start address of pattern region + * \param[in] patternId ID of the pattern which shall be set + * \return kFblOk: pattern successfully written or already set, kFblFailed: Error writing pattern + **********************************************************************************************************************/ +tFblResult FblNvPatternSetByStartAddress( IO_PositionType patternStartAddress, + tFblNvPatternId patternId) +{ + tBlockDescriptor dummyBlockDescriptor = { 0u }; + tFblResult result = FblNvPatternGetPatternBlockDescriptorByStartAddress(patternStartAddress, &dummyBlockDescriptor); + + if (result == kFblOk) + { + result = FblNvPatternSetByBlockDescriptor(&dummyBlockDescriptor, patternId); + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternClr + **********************************************************************************************************************/ +/*! \brief Writes the mask to invalidate the pattern + * \details The location of the pattern will be taken from the logical block table + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] patternId ID of the pattern which shall be set + * \return kFblOk: Mask for invalidation successfully written, kFblFailed: Error writing invalidation mask + **********************************************************************************************************************/ +tFblResult FblNvPatternClr( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, tFblNvPatternId patternId ) +{ + tBlockDescriptor localBlockDescriptor; + tFblResult result; + + result = FblLbtGetBlockDescriptorByNr(blockDescriptor->blockNr, &localBlockDescriptor); + + if (result == kFblOk) + { + result = FblNvPatternClrByBlockDescriptor(&localBlockDescriptor, patternId); + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternClrByBlockDescriptor + **********************************************************************************************************************/ +/*! \brief Writes the mask to invalidate the pattern + * \details The location of the pattern will be taken from the passed logical block descriptor + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] patternId ID of the pattern which shall be set + * \return kFblOk: Mask for invalidation successfully written, kFblFailed: Error writing invalidation mask + **********************************************************************************************************************/ +tFblResult FblNvPatternClrByBlockDescriptor( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId patternId ) +{ + tFblResult result; + IO_PositionType patternAddress; + IO_SizeType patternLength; + tFblNvPatternState patternState; + vuint8 fblMaskValue[] = kFblNvMaskValue; /* PRQA S 3678 */ /* MD_FblNvPattern_3678_LocalVariable */ + + /* PRQA S 2742, 2880 1 */ /* MD_FblNvPattern_Assertion */ + assertFblUser(sizeof(fblMaskValue) == kFblNvPatternSize, kFblSysAssertParameterOutOfRange); + + /* Check state of pattern */ + patternState = FblNvPatternGetPatternState(blockDescriptor, patternId, &patternAddress, &patternLength); + + /* Only set mask if pattern is set to valid */ + if ((patternState.markerState == FBL_NVPATTERN_STATE_EXPECTEDVALUE) && (patternState.maskState == FBL_NVPATTERN_STATE_ERASED)) + { + /* Write mask value to flash */ + result = FblNvPatternWritePageAligned(fblMaskValue, (patternAddress + patternLength), kFblNvPatternSize); + } + else + { + /* Pattern is already in invalid state, do nothing. Illegal states are detected with assertions only. */ + result = kFblOk; + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternClrByStartAddress + **********************************************************************************************************************/ +/*! \brief Writes the mask to invalidate the pattern + * \param[in] patternStartAddress Start address of pattern region + * \param[in] patternId ID of the pattern which shall be cleared + * \return kFblOk: Mask for invalidation successfully written, kFblFailed: Error writing invalidation mask + **********************************************************************************************************************/ +tFblResult FblNvPatternClrByStartAddress( IO_PositionType patternStartAddress, tFblNvPatternId patternId ) +{ + tBlockDescriptor dummyBlockDescriptor = { 0u }; + tFblResult result = FblNvPatternGetPatternBlockDescriptorByStartAddress(patternStartAddress, &dummyBlockDescriptor); + + if (result == kFblOk) + { + result = FblNvPatternClrByBlockDescriptor(&dummyBlockDescriptor, patternId); + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternGet + **********************************************************************************************************************/ +/*! \brief Checks if the pattern state is 'valid' (correct pattern value is set/mask is erased) + * \details The location of the pattern and mask is taken from the logical block table + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] patternId ID of the pattern which shall be checked + * \return kFblOk: Pattern is set and mask is erased, + * kFblFailed: Pattern is not set or mask not erased + **********************************************************************************************************************/ +tFblResult FblNvPatternGet( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, tFblNvPatternId patternId ) +{ + tBlockDescriptor localBlockDescriptor; + tFblResult result; + + result = FblLbtGetBlockDescriptorByNr(blockDescriptor->blockNr, &localBlockDescriptor); + + if (result == kFblOk) + { + result = FblNvPatternGetByBlockDescriptor(&localBlockDescriptor, patternId); + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternGetByBlockDescriptor + **********************************************************************************************************************/ +/*! \brief Checks if the pattern state is 'valid' (correct pattern value is set/mask is erased) + * \details The location of the pattern and mask is taken from the passed logical block descriptor + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] patternId ID of the pattern which shall be checked + * \return kFblOk: Pattern is set and mask is erased, + * kFblFailed: Pattern is not set or mask not erased + **********************************************************************************************************************/ +tFblResult FblNvPatternGetByBlockDescriptor( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId patternId ) +{ + IO_PositionType patternAddress; + IO_SizeType patternLength; + tFblNvPatternState patternState; + tFblResult result; + + /* Initialize result */ + result = kFblFailed; + + /* Check state of pattern */ + patternState = FblNvPatternGetPatternState(blockDescriptor, patternId, &patternAddress, &patternLength); + if ((patternState.markerState == FBL_NVPATTERN_STATE_EXPECTEDVALUE) && (patternState.maskState == FBL_NVPATTERN_STATE_ERASED)) + { +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) + result = FblNvPatternVerifyCmacByBlockDescriptor(blockDescriptor, patternId); +#else + result = kFblOk; +#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternGetByStartAddress + **********************************************************************************************************************/ +/*! \brief Checks if the pattern state is 'valid' (correct pattern value is set/mask is erased) + * \param[in] patternStartAddress Start address of pattern region + * \param[in] patternId ID of the pattern which shall be checked + * \return kFblOk: Pattern is set and mask is erased, + * kFblFailed: Pattern is not set or mask not erased + **********************************************************************************************************************/ +tFblResult FblNvPatternGetByStartAddress( IO_PositionType patternStartAddress, tFblNvPatternId patternId ) +{ + tBlockDescriptor dummyBlockDescriptor = { 0u }; + tFblResult result = FblNvPatternGetPatternBlockDescriptorByStartAddress(patternStartAddress, &dummyBlockDescriptor); + + if (result == kFblOk) + { + result = FblNvPatternGetByBlockDescriptor(&dummyBlockDescriptor, patternId); + } + + return result; +} + +#if defined( FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES ) +# if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) +/*********************************************************************************************************************** + * FblNvPatternGetPropertyStateAndAddrByBlockDescriptor + **********************************************************************************************************************/ +/*! \brief Retrieve the property state and address + * \details The location of the property is taken from the passed logical block descriptor + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] propertyId Id of the property to check the erase state + * \param[out] address Pointer to the property address + * \param[out] state Pointer to the property state + * \return kFblOk: Property state and address are read, + * kFblFailed: Property state and address are not read + **********************************************************************************************************************/ +tFblResult FblNvPatternGetPropertyStateAndAddrByBlockDescriptor(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId propertyId, + V_MEMRAM1 IO_PositionType V_MEMRAM2 V_MEMRAM3 * address, + V_MEMRAM1 tFblNvPatternItemState V_MEMRAM2 V_MEMRAM3 * state) +{ + IO_PositionType propertyAddress = 0u; + IO_SizeType propertyLength; + IO_SizeType actualPropertyLength; + tFblResult result = kFblFailed; + + /* Init variables */ + *state = FBL_NVPATTERN_STATE_UNEXPECTEDVALUE; + *address = 0u; + + /* Check if requested Id is valid */ + if (IS_VALID_PROPERTY_ID(propertyId)) + { + /* Get address of element. Length is not used. */ + if (FblNvPatternGetBaseAddrByBlockDescriptor(blockDescriptor, propertyId, &propertyAddress, &propertyLength) >= 0) + { + /* Get the property length */ + actualPropertyLength = fblNvBlockProperties[(vuintx)propertyId - (vuintx)kFblNvPatternId_Separator - 1u].length; + *state = FblNvPatternGetPatternItemState(propertyAddress, actualPropertyLength, DONT_COMPARE); + *address = propertyAddress; + result = kFblOk; + } + } + + return result; +} +# endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ + +/*********************************************************************************************************************** + * FblNvPatternGetProperty + **********************************************************************************************************************/ +/*! \brief Reads value of a block property element + * \details Location of the property is taken from the logical block table + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] propertyId Id of property to read + * \param[in] bufferLength Length of destination buffer + * \param[out] pDestBuffer Pointer to RAM where read property value will be stored + * \return kFblOk: Property successfully read, kFblFailed: Error reading property + **********************************************************************************************************************/ +tFblResult FblNvPatternGetProperty( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId propertyId, + IO_SizeType bufferLength, + vuint8* pDestBuffer ) +{ + tBlockDescriptor localBlockDescriptor; + tFblResult result; + + result = FblLbtGetBlockDescriptorByNr(blockDescriptor->blockNr, &localBlockDescriptor); + + if (result == kFblOk) + { + result = FblNvPatternGetPropertyByBlockDescriptor(&localBlockDescriptor, propertyId, bufferLength, pDestBuffer); + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternGetPropertyByBlockDescriptor + **********************************************************************************************************************/ +/*! \brief Reads value of an block property element + * \details The location of the block property is taken from the passed logical block descriptor + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] propertyId Id of the property to read + * \param[in] bufferLength Length of destination buffer + * \param[out] pDestBuffer Pointer to RAM where the read property value will be stored + * \return kFblOk: Property successfully read, kFblFailed: Error reading property + **********************************************************************************************************************/ +tFblResult FblNvPatternGetPropertyByBlockDescriptor( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId propertyId, + IO_SizeType bufferLength, + vuint8* pDestBuffer ) +{ + IO_PositionType propertyAddress; + IO_SizeType propertyLength; + IO_SizeType sizeToRead = 0u; + tFblNvPatternId depPattern; + tFblResult result; + + result = kFblFailed; + propertyAddress = 0u; + + /* Check if requested Id is valid */ + if (IS_VALID_PROPERTY_ID(propertyId)) + { + sizeToRead = fblNvBlockProperties[(vuintx)propertyId - (vuintx)kFblNvPatternId_Separator - 1u].length; + depPattern = fblNvBlockProperties[(vuintx)propertyId - (vuintx)kFblNvPatternId_Separator - 1u].dependentPattern; + + /* Check if buffer length is sufficient for storing requested data */ + if (sizeToRead <= bufferLength) + { + /* If dependent pattern configured, check its validity */ + if (depPattern != kFblNvPatternId_Invalid) + { + result = FblNvPatternGetByBlockDescriptor(blockDescriptor, depPattern); + } + else + { + result = kFblOk; + } + } + } + + if (result == kFblOk) + { + /* Get address of property (length is not needed) */ + if (FblNvPatternGetBaseAddrByBlockDescriptor(blockDescriptor, propertyId, &propertyAddress, &propertyLength) >= 0) + { + if (MemDriver_RReadSync(pDestBuffer, sizeToRead, propertyAddress) == IO_E_OK) + { + result = kFblOk; + } + } + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternGetPropertyByStartAddress + **********************************************************************************************************************/ +/*! \brief Reads value of an block property element + * \param[in] patternStartAddress Start address of pattern region + * \param[in] propertyId Id of the property to read + * \param[in] bufferLength Length of destination buffer + * \param[out] pDestBuffer Pointer to RAM where the read property value will be stored + * \return kFblOk: Property successfully read, kFblFailed: Error reading property + **********************************************************************************************************************/ +tFblResult FblNvPatternGetPropertyByStartAddress( IO_PositionType patternStartAddress, + tFblNvPatternId propertyId, + IO_SizeType bufferLength, + vuint8 * destBuffer ) +{ + tBlockDescriptor dummyBlockDescriptor = { 0u }; + tFblResult result = FblNvPatternGetPatternBlockDescriptorByStartAddress(patternStartAddress, &dummyBlockDescriptor); + + if (result == kFblOk) + { + result = FblNvPatternGetPropertyByBlockDescriptor(&dummyBlockDescriptor, propertyId, bufferLength, destBuffer); + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternSetProperty + **********************************************************************************************************************/ +/*! \brief Writes value of a block property + * \details The location of the property is taken from the logical block table + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] pSrcBuffer Pointer to RAM with the data to write + * \param[in] propertyId Id of the block property to write + * \return kFblOk: Property successfully written, kFblFailed: Error writing property + **********************************************************************************************************************/ +tFblResult FblNvPatternSetProperty( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + const vuint8* pSrcBuffer, + tFblNvPatternId propertyId ) +{ + tBlockDescriptor localBlockDescriptor; + tFblResult result; + + result = FblLbtGetBlockDescriptorByNr(blockDescriptor->blockNr, &localBlockDescriptor); + + if (result == kFblOk) + { + result = FblNvPatternSetPropertyByBlockDescriptor(&localBlockDescriptor, pSrcBuffer, propertyId); + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternSetPropertyByBlockDescriptor + **********************************************************************************************************************/ +/*! \brief Writes value of a block property + * \details The location of the property is taken from the passed logical block descriptor + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] pSrcBuffer Pointer to RAM with the data to write + * \param[in] propertyId Id of the property to write + * \return kFblOk: Property successfully written, kFblFailed: Error writing property + **********************************************************************************************************************/ +tFblResult FblNvPatternSetPropertyByBlockDescriptor( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + const vuint8* pSrcBuffer, + tFblNvPatternId propertyId ) +{ + IO_PositionType propertyAddress; + IO_SizeType propertyLength; + IO_SizeType actualPropertyLength; + tFblResult result; + + /* Initialize variables */ + result = kFblFailed; + propertyAddress = 0u; + + /* Check if requested Id is valid */ + if (IS_VALID_PROPERTY_ID(propertyId)) + { + /* Get address and length of element */ + if (FblNvPatternGetBaseAddrByBlockDescriptor(blockDescriptor, propertyId, &propertyAddress, &propertyLength) >= 0) + { + /* Only write block property to memory if it has not been set before */ + actualPropertyLength = fblNvBlockProperties[(vuintx)propertyId - (vuintx)kFblNvPatternId_Separator - 1u].length; + if (FblNvPatternGetPatternItemState(propertyAddress, actualPropertyLength, DONT_COMPARE) == FBL_NVPATTERN_STATE_ERASED) + { + result = FblNvPatternWritePageAligned(pSrcBuffer, propertyAddress, actualPropertyLength); + } + } + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternSetPropertyByStartAddress + **********************************************************************************************************************/ +/*! \brief Writes value of a block property + * \param[in] patternStartAddress Start address of pattern region + * \param[in] pSrcBuffer Pointer to RAM with the data to write + * \param[in] propertyId Id of the property to write + * \return kFblOk: Property successfully written, kFblFailed: Error writing property + **********************************************************************************************************************/ +tFblResult FblNvPatternSetPropertyByStartAddress( IO_PositionType patternStartAddress, + const vuint8* srcBuffer, + tFblNvPatternId propertyId ) +{ + tBlockDescriptor dummyBlockDescriptor = { 0u }; + tFblResult result = FblNvPatternGetPatternBlockDescriptorByStartAddress(patternStartAddress, &dummyBlockDescriptor); + + if (result == kFblOk) + { + result = FblNvPatternSetPropertyByBlockDescriptor(&dummyBlockDescriptor, srcBuffer, propertyId); + } + + return result; +} + +# if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) +/*********************************************************************************************************************** + * FblNvPatternSignedPresencePatternInit + **********************************************************************************************************************/ +/*! \brief Init the AES key and update the CMAC for all valid logical block during the first startup of ECU + **********************************************************************************************************************/ +void FblNvPatternSignedPresencePatternInit(void) +{ + ApplFblNvPatternSignedPresencePatternInit(); +} + +/*********************************************************************************************************************** + * FblNvPatternUpdateCmacByBlockDescriptor + **********************************************************************************************************************/ +/*! \brief Calculate the CMAC for the received patternId and update it in the respective property + * \details The address of the property will be fetched from the logical block descriptor + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] patternId Id of the pattern for which the CMAC needs to be calculated and written + * \return kFblOk: CMAC updated + * kFblFailed: CMAC not updated + **********************************************************************************************************************/ +tFblResult FblNvPatternUpdateCmacByBlockDescriptor(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId patternId) +{ + tFblResult result = kFblFailed; + IO_PositionType propertyAddress = 0u; + tFblNvPatternItemState propertyState; + vuint8 signatureBuffer[FBL_NVPATTERN_PP_CMAC_SIZE]; + + if (fblNvPatternProperties[patternId] != kFblNvPatternId_Invalid) + { + assertFblUser(fblNvBlockProperties[(vuintx)fblNvPatternProperties[patternId] - (vuintx)kFblNvPatternId_Separator - 1u].dependentPattern + == kFblNvPatternId_Invalid, kFblSysAssertParameterOutOfRange); + + if (FblNvPatternGetPropertyStateAndAddrByBlockDescriptor(blockDescriptor, fblNvPatternProperties[patternId], + &propertyAddress, &propertyState) == kFblOk) + { + if (propertyState == FBL_NVPATTERN_STATE_ERASED) + { + if (ApplFblNvPatternGenerateCMAC(fblNvPatternProperties[patternId], blockDescriptor, signatureBuffer) == kFblOk) + { + result = FblNvPatternSetPropertyByBlockDescriptor(blockDescriptor, signatureBuffer, fblNvPatternProperties[patternId]); + } + } + } + } + else + { + result = kFblOk; + } + + return result; +} + +/*********************************************************************************************************************** + * FblNvPatternVerifyCmacByBlockDescriptor + **********************************************************************************************************************/ +/*! \brief Verify the CMAC for the received patternId + * \details The address of the property will be fetched from the logical block descriptor + * \param[in] blockDescriptor Pointer to the logical block descriptor + * \param[in] patternId Id of the pattern for which the CMAC needs to be verified + * \return kFblOk: CMAC verified successfully + * kFblFailed: CMAC not verified or verification failed + **********************************************************************************************************************/ +tFblResult FblNvPatternVerifyCmacByBlockDescriptor(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId patternId) +{ + vuint8 signatureBuffer[FBL_NVPATTERN_PP_CMAC_SIZE]; + IO_PositionType propertyAddress = 0u; + IO_SizeType actualPropertyLength; + tFblNvPatternItemState propertyState; + tFblResult result = kFblFailed; + + if (fblNvPatternProperties[patternId] != kFblNvPatternId_Invalid) + { + assertFblUser(fblNvBlockProperties[(vuintx)fblNvPatternProperties[patternId] - (vuintx)kFblNvPatternId_Separator - 1u].dependentPattern + == kFblNvPatternId_Invalid, kFblSysAssertParameterOutOfRange); + + if (FblNvPatternGetPropertyStateAndAddrByBlockDescriptor(blockDescriptor, fblNvPatternProperties[patternId], + &propertyAddress, &propertyState) == kFblOk) + { + if (propertyState != FBL_NVPATTERN_STATE_ERASED) + { + actualPropertyLength = fblNvBlockProperties[(vuintx)fblNvPatternProperties[patternId] - + (vuintx)kFblNvPatternId_Separator - 1u].length; + + if (MemDriver_RReadSync(signatureBuffer, actualPropertyLength, propertyAddress) == IO_E_OK) + { + result = ApplFblNvPatternVerifyCMAC(fblNvPatternProperties[patternId], blockDescriptor, signatureBuffer); + } + } + } + } + else + { + result = kFblOk; + } + + return result; +} +# endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ +#endif /* FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES */ + +#define FBLNVPATTERN_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * ERROR CHECKS + **********************************************************************************************************************/ + +#if (!IS_POWOFTWO(FBL_MAX_SEGMENT_SIZE)) +# error "FBL_MAX_SEGMENT_SIZE must be a power of two." +#endif + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_FblNvPattern_Assertion: + Reason: Assertion macros have to be disabled in production code and are used only for development. + Risk: Assertion code may be enabled in production code unintentionally. If a assertion condition is unexpectedly + false, the code is active. A problem may occur if the Macro is additionally changed from single statement + to multiple statement. + Prevention: Macro is not allowed to be changed without review. Development code is automatically disabled via + configuration of project state "Production". + + MD_FblNvPattern_3678_LocalVariable: + Reason: Local variable/array is not declared as const as some compiler/platforms have issues with that. + Risk: Content of the variable/array could be modified within the function. + Prevention: Code is checked for unintended write accesses by code inspection. + + MD_FblNvPattern_4342: + Reason: An expression of essential type has been cast to an enum type. + Risk: The essential type is not in range of enum type. + Prevention: Code must be reviewed to ensure cast is only applied on values in valid range + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_NVPATTERN.C + **********************************************************************************************************************/ diff --git a/Source/bsw/FblNvPattern/fbl_nvpattern.h b/Source/bsw/FblNvPattern/fbl_nvpattern.h new file mode 100644 index 0000000..f8c672c --- /dev/null +++ b/Source/bsw/FblNvPattern/fbl_nvpattern.h @@ -0,0 +1,167 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Implementation of pattern/mask based non-volatile information storage + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 02.00.00 2025-03-11 virjjn FBL-9704 Initial version + * 02.01.00 2025-06-19 dganesh FBL-11034 No changes + **********************************************************************************************************************/ + +#ifndef FBLLIB_NVPATTERN_H +#define FBLLIB_NVPATTERN_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblLib_NvPattern CQComponent : Implementation */ +#define FBLLIB_NVPATTERN_VERSION 0x0201u +#define FBLLIB_NVPATTERN_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "FblNvPattern_Cfg.h" +#include "fbl_nvpattern_oem.h" + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* Set Id of separator item to last item if storing arbitrary values is not enabled */ +#if !defined( FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES ) +# define kFblNvPatternId_Separator kFblNvPatternId_Last +#endif /* FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES */ + +/*********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + **********************************************************************************************************************/ + +/** Representation of status of marker/mask */ +typedef enum +{ + FBL_NVPATTERN_STATE_NOMEMSEGMENT = 0u, /**< No matching memory segment has been found */ + FBL_NVPATTERN_STATE_READERROR, /**< Memory area could not be read */ + FBL_NVPATTERN_STATE_ERASED, /**< Marker/mask area is erased */ + FBL_NVPATTERN_STATE_UNEXPECTEDVALUE, /**< Unexpected marker/mask value */ + FBL_NVPATTERN_STATE_EXPECTEDVALUE /**< Expected marker/mask value is set */ +} tFblNvPatternItemState; + +/** Status of pattern */ +typedef struct +{ + tFblNvPatternItemState markerState; + tFblNvPatternItemState maskState; +} tFblNvPatternState; + +/*********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLNVPATTERN_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + + +tFblNvPatternState FblNvPatternGetPatternState( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * pBlockDescriptor, + tFblNvPatternId patternId, + V_MEMRAM1 IO_PositionType V_MEMRAM2 V_MEMRAM3 * pPatternAddress, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * pPatternLength ); +tFblNvPatternState FblNvPatternGetPatternStateByStartAddress( IO_PositionType patternStartAddress, + tFblNvPatternId patternId, + V_MEMRAM1 IO_PositionType V_MEMRAM2 V_MEMRAM3 * patternAddress, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * patternLength ); +vsint16 FblNvPatternGetBaseAddr( vuint8 blockNr, + tFblNvPatternId patternId, + V_MEMRAM1 IO_PositionType V_MEMRAM2 V_MEMRAM3 * pPatternAddress, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * pPatternLength ); +vsint16 FblNvPatternGetBaseAddrByBlockDescriptor( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId patternId, + V_MEMRAM1 IO_PositionType V_MEMRAM2 V_MEMRAM3 * patternAddress, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * patternLength ); +tFblResult FblNvPatternGetPatternRegionSizeByStartAddress( IO_PositionType patternStartAddress, + V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * patternRegionLength ); +tFblResult FblNvPatternSet( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, tFblNvPatternId patternId ); +tFblResult FblNvPatternSetByBlockDescriptor( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId patternId ); +tFblResult FblNvPatternSetByStartAddress( IO_PositionType patternStartAddress, tFblNvPatternId patternId ); +tFblResult FblNvPatternClr( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, tFblNvPatternId patternId ); +tFblResult FblNvPatternClrByBlockDescriptor( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId patternId ); +tFblResult FblNvPatternClrByStartAddress( IO_PositionType patternStartAddress, tFblNvPatternId patternId ); +tFblResult FblNvPatternGet( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, tFblNvPatternId patternId ); +tFblResult FblNvPatternGetByBlockDescriptor( const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId patternId ); +tFblResult FblNvPatternGetByStartAddress( IO_PositionType patternStartAddress, tFblNvPatternId patternId ); + +#if defined( FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES ) +tFblResult FblNvPatternGetProperty(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId propertyId, + IO_SizeType bufferLength, + vuint8* pDestBuffer ); +tFblResult FblNvPatternGetPropertyByBlockDescriptor(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + tFblNvPatternId propertyId, + IO_SizeType bufferLength, + vuint8* pDestBuffer ); +tFblResult FblNvPatternGetPropertyByStartAddress( IO_PositionType patternStartAddress, + tFblNvPatternId propertyId, + IO_SizeType bufferLength, + vuint8 * destBuffer ); +tFblResult FblNvPatternSetProperty(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + const vuint8* pSrcBuffer, + tFblNvPatternId propertyId); +tFblResult FblNvPatternSetPropertyByBlockDescriptor(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + const vuint8* pSrcBuffer, + tFblNvPatternId propertyId); +tFblResult FblNvPatternSetPropertyByStartAddress( IO_PositionType patternStartAddress, + const vuint8* srcBuffer, + tFblNvPatternId propertyId ); +# if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) +tFblResult FblNvPatternGetPropertyStateAndAddrByBlockDescriptor(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 *blockDescriptor, + tFblNvPatternId propertyId, + V_MEMRAM1 IO_PositionType V_MEMRAM2 V_MEMRAM3 *address, + V_MEMRAM1 tFblNvPatternItemState V_MEMRAM2 V_MEMRAM3 *state); + +tFblResult FblNvPatternUpdateCmacByBlockDescriptor(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 *blockDescriptor, + tFblNvPatternId patternId); +tFblResult FblNvPatternVerifyCmacByBlockDescriptor(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 *blockDescriptor, + tFblNvPatternId patternId); +void FblNvPatternSignedPresencePatternInit(void); +void ApplFblNvPatternSignedPresencePatternInit(void); +tFblResult ApplFblNvPatternVerifyCMAC(tFblNvPatternId patternId, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * signatureBuffer); + +tFblResult ApplFblNvPatternGenerateCMAC(tFblNvPatternId patternId, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * signatureBuffer); +# endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ +#endif /* FBL_NVPATTERN_ENABLE_BLOCK_PROPERTIES */ +#define FBLNVPATTERN_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* FBLLIB_NVPATTERN_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_NVPATTERN.H + **********************************************************************************************************************/ diff --git a/Source/bsw/FblSecBoot/fbl_secboot.c b/Source/bsw/FblSecBoot/fbl_secboot.c new file mode 100644 index 0000000..31c6e8c --- /dev/null +++ b/Source/bsw/FblSecBoot/fbl_secboot.c @@ -0,0 +1,606 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief SecureBoot implementation + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2020-01-07 visrie FBL-524 Initial release + * 01.00.01 2020-04-27 visrie FBL-1773 No changes + * 02.00.00 2020-05-19 vistbe FBL-1016 Support EcuM_Init() mechanism + * 02.01.00 2021-01-19 visrie FBL-2648 Added support of new SecureBoot verify variant + * FBL-2641 Updated to new API version + * 02.02.00 2021-09-03 visjdn FBL-3352 No changes + * 02.03.00 2023-06-21 vistbe FBL-4814 Add support for OTA + * 02.03.01 2024-05-16 viswmo ESCAN00117059 Signature failure is not reported + * 02.04.00 2024-11-18 vismix FBL-9654 Optimize startup times for secure boot + * 02.05.00 2025-01-24 vikatya PIO-1340 SecureBoot for selected blocks + * 02.06.00 2025-02-19 visrie FBL-10209 Support total length for confirmation mode + **********************************************************************************************************************/ + +#define FBL_SECBOOT_SOURCE + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "fbl_inc.h" +#include "Std_Types.h" +#include "Csm.h" +#include "bm_types.h" +#include "bm_hdr.h" +#include "fbl_secboot.h" + +#if defined( FBLSB_ENABLE_COPY_FLASH_DRIVER ) +# include "FlashRom.h" +#endif /* FBLSB_ENABLE_COPY_FLASH_DRIVER */ + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( FBLLIB_SECBOOT_VHSM_VERSION != 0x0206u ) || \ + ( FBLLIB_SECBOOT_VHSM_RELEASE_VERSION != 0x00u ) +# error "Error in FBL_SECBOOT.C: Source and Header file are inconsistent!" +#endif + +#if ( FBLLIB_SECBOOT_VHSM_VERSION != _FBLLIB_SECBOOT_VHSM_VERSION ) || \ + ( FBLLIB_SECBOOT_VHSM_RELEASE_VERSION != _FBLLIB_SECBOOT_VHSM_RELEASE_VERSION ) +# error "Error in FBL_SECBOOT.C: Source and v_ver.h are inconsistent!" +#endif + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/** Watchdog triggered every n-th cycle (has to power of two) */ +#if !defined( FBLSB_WATCHDOG_CYCLE_COUNT ) +# define FBLSB_WATCHDOG_CYCLE_COUNT 0x20u +#endif +/** Trigger watchdog every n-th cycle */ +#define FBLSB_TRIGGER_WATCHDOG(cycle) \ +{ \ + if (((cycle) & (FBLSB_WATCHDOG_CYCLE_COUNT - 1u)) == 0x00u) \ + { \ + (void)FblLookForWatchdog(); \ + } \ +} + +#define FBLSB_VHSM_AUTHENTICATION_HEADER_HEADER 20u /* Magic Pattern (16) + Revision (4) */ +#define FBLSB_VHSM_AUTHENTICATION_HEADER_GROUPID 4u /* GroupId */ +#define FBLSB_VHSM_AUTHENTICATION_HEADER_NO_SEGMENTS 2u /* Nr of Segments */ +#define FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_BASE (FBLSB_VHSM_AUTHENTICATION_HEADER_GROUPID + FBLSB_VHSM_AUTHENTICATION_HEADER_NO_SEGMENTS) +#define FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_SEGMENT 42u /* Address (4) + Length (4) + Mode (2) + Hash (32) */ +#define FBLSB_VHSM_AUTHENTICATION_HEADER_SIGNATURE_LENGTH 4u /* Length field containing the actual length of the signature */ +#define FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_SEGMENTS(noOfSegments) \ + ((noOfSegments) * FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_SEGMENT) +#define FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH(noOfSegments) \ + (FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_BASE + FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_SEGMENTS(noOfSegments)) + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * GLOBAL DATA + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ +#define FBLSB_START_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +V_MEMRAM0 static V_MEMRAM1 tFblSbExtErrCode V_MEMRAM2 sbExtErrCode; + +#define FBLSB_STOP_SEC_VAR +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ +#define FBLSB_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBLSB_ENABLE_GENERATE_CMAC ) +static tFblLength FblSb_GetAuthenticationHeaderLength(const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * dataPtr); +static tFblResult FblSb_UpdateCommonMac(V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader, vuint32 macId); +#endif /* FBLSB_ENABLE_GENERATE_CMAC */ + +/*********************************************************************************************************************** + * EXTERNAL DATA + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +#if defined( FBLSB_ENABLE_GENERATE_CMAC ) +/*********************************************************************************************************************** + * FblSb_GetAuthenticationHeaderLength +**********************************************************************************************************************/ +/*! \brief Calculates the length of the vHsm authentication header + * \param[in] dataPtr Pointer to the groupId of the vHsm authentication header + * \return Length of the authentication header + **********************************************************************************************************************/ +static tFblLength FblSb_GetAuthenticationHeaderLength(const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * dataPtr) +{ + tFblLength authHeaderLength; + vuint32 noOfSegments; + + noOfSegments = FblMemGetInteger(FBLSB_VHSM_AUTHENTICATION_HEADER_NO_SEGMENTS, &dataPtr[FBLSB_VHSM_AUTHENTICATION_HEADER_GROUPID]); + authHeaderLength = FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH(noOfSegments); + + return authHeaderLength; +} + +/*********************************************************************************************************************** + * FblSb_UpdateCommonMac + **********************************************************************************************************************/ +/*! \brief Generate and write the common MACs + * \param[in] bmHeader Pointer to the bmHdrHeader structure + * \param[in] macId MAC operation identifier + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise + **********************************************************************************************************************/ +/* PRQA S 3673, 6010, 6030, 6080 1 */ /* MD_MSR_Rule8.13, MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STMIF */ +static tFblResult FblSb_UpdateCommonMac(V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader, vuint32 macId) +{ + tFblResult result = kFblOk; + Crypto_VerifyResultType verifyResult = CRYPTO_E_VER_NOT_OK; + uint32 jobId = 0u; + const uint8 * dataPtr; + uint32 dataLength = 0u; + uint32 signatureAddress = 0u; + uint32 signatureLength = 0u; + + /* Check if mac operation is configured. */ + if (macId != FBLBMHDR_MAC_OP_REF_NOT_USED) + { + /* Check if the SecureBootGroup can be updated */ + if (macId < FBLSB_NUM_OF_MAC_OPERATIONS) + { + /* Check if SecureBootUpdate is actually required */ + if ((FblSb_GetVerificationMethodOfMacOperation(macId) == FBLSB_VERIFICATIONMETHOD_INTERNAL) +# if defined( FBL_ENABLE_OTA ) + && (vOtaM_IsOpenedPartitionOfRoleActive() == E_OK) +# endif /* FBL_ENABLE_OTA */ + ) + { + jobId = FblSb_GetCsmJobIdOfMacUpdate(); + dataPtr = (const uint8 *)bmHeader->bmAuthenticationHeaderAddress; /* PRQA S 0306 */ /* MD_FblLibSecBoot_0306 */ + dataLength = FblSb_GetAuthenticationHeaderLength(dataPtr); + result = ApplFblSbGetSignatureInfo(bmHeader, macId, &signatureAddress, &signatureLength); + + assertFblGen((result == kFblOk), kFblSysAssertParameterOutOfRange); + + if (result == kFblOk) + { + /* PRQA S 0306 2 */ /* MD_FblLibSecBoot_0306 */ + if (E_OK == Csm_SignatureVerify(jobId, CRYPTO_OPERATIONMODE_SINGLECALL, dataPtr, dataLength, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))signatureAddress, signatureLength, &verifyResult)) + { + if (verifyResult != CRYPTO_E_VER_OK) + { + sbExtErrCode = FBLSB_EXT_ERR_CODE_SIGNATURE; + result = kFblFailed; + } + } + else + { + result = kFblFailed; + } + } + } + else if (FblSb_IsConfirmationModeOfMacOperation(macId)) + { + boolean inactivePartition = FALSE; + + jobId = FblSb_GetCsmJobIdOfMacConfirmationMode(); + dataPtr = (const uint8 *)bmHeader->bmAuthenticationHeaderAddress; /* PRQA S 0306 */ /* MD_FblLibSecBoot_0306 */ + dataLength = FBLSB_VHSM_AUTHENTICATION_HEADER_HEADER; + dataLength += FblSb_GetAuthenticationHeaderLength(&dataPtr[FBLSB_VHSM_AUTHENTICATION_HEADER_HEADER]); + signatureLength = FblMemGetInteger(FBLSB_VHSM_AUTHENTICATION_HEADER_SIGNATURE_LENGTH, &dataPtr[dataLength]); /* Extract actual signature length */ + dataLength += FBLSB_VHSM_AUTHENTICATION_HEADER_SIGNATURE_LENGTH; + dataLength += signatureLength; + +# if defined( FBL_ENABLE_OTA ) + if (vOtaM_IsOpenedPartitionOfRoleInactive() == E_OK) + { + inactivePartition = TRUE; + } +# endif /* FBL_ENABLE_OTA */ + + if (E_OK == Csm_SignatureVerify(jobId, CRYPTO_OPERATIONMODE_SINGLECALL, dataPtr, dataLength, + (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))&inactivePartition, sizeof(inactivePartition), &verifyResult)) + { + if (verifyResult != CRYPTO_E_VER_OK) + { + sbExtErrCode = FBLSB_EXT_ERR_CODE_SIGNATURE; + result = kFblFailed; + } + } + else + { + result = kFblFailed; + } + } + else + { + result = kFblFailed; + } + } + else + { + /* This block has no SecureBootGroup and therefore can not be updated */ + result = kFblFailed; + } + + if ( (result != kFblOk) + && (sbExtErrCode == FBLSB_EXT_ERR_CODE_NONE) ) + { + sbExtErrCode = FBLSB_EXT_ERR_CODE_GENERAL; + } + } + + return result; +} +#endif /* FBLSB_ENABLE_GENERATE_CMAC */ + +/*********************************************************************************************************************** + * GLOBAL FUNCTIONS + **********************************************************************************************************************/ + +#if defined( FBLSB_ENABLE_COPY_FLASH_DRIVER ) +/*********************************************************************************************************************** + * FblUpdCopyFlashDriver + ***********************************************************************************************************************/ +/*! \brief Copies the flashdriver from the ROM table into flashCode buffer + ***********************************************************************************************************************/ +void FblSb_CopyFlashDriver( void ) +{ + vuint16 index; + + /* flashCode buffer location must match the flashdriver start address */ +# if defined( FLASH_DRIVER_RELOCATABLE ) +# else + if ( (flashCode == (IO_U8 *)FLASHDRV_BLOCK0_ADDRESS) ) +# endif /* FLASH_DRIVER_RELOCATABLE */ + { + /* Copy all flash driver code from ROM into the flashCode buffer */ + for (index = 0u; index < FLASHDRV_BLOCK0_LENGTH; index++) + { + FBLSB_TRIGGER_WATCHDOG(index); + flashCode[index] = FLASHDRV_DECRYPTDATA(flashDrvBlk0[index]); + } + } +} +#endif /* FBLSB_ENABLE_COPY_FLASH_DRIVER */ + +/*********************************************************************************************************************** + * FblSb_Init + ***********************************************************************************************************************/ +/*! \brief Initializes the SecureBoot module + * \details Initializes the complete crypto stack + ***********************************************************************************************************************/ +void FblSb_Init(void) +{ + /* Crypto stack is initialized via EcuM_Init */ + + sbExtErrCode = FBLSB_EXT_ERR_CODE_NONE; +} + +/*********************************************************************************************************************** + * FblSb_VerifyFblLbt + **********************************************************************************************************************/ +/*! \brief Verifies the BmHdrHeader and the LogicalBlockTable of the bootloader + * \param[in] fblHeader Pointer to the FBL Header + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise or when the feature is disabled + **********************************************************************************************************************/ +tFblResult FblSb_VerifyFblLbt(const V_MEMRAM1 tFblHeader V_MEMRAM2 V_MEMRAM3 * fblHeader) +{ + tFblResult result = kFblFailed; +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined( FBLBM_ENABLE_FBLLBT_VERIFICATION ) + Crypto_VerifyResultType verifyResult = CRYPTO_E_VER_NOT_OK; + uint32 jobId = 0u; + uint32 groupId = 0u; +# endif /* FBLBM_ENABLE_FBLLBT_VERIFICATION */ +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */ + (void)fblHeader; +#endif + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined( FBLBM_ENABLE_FBLLBT_VERIFICATION ) + jobId = FblSb_GetCsmJobIdOfMacVerify(); + groupId = FblSb_GetGroupIdOfMacOperation(FBLSB_SECOND_AUTH_MAC_OPERATION_ID); + + /* Verify the FBL-Header and the LBT */ + if (Csm_MacVerify(jobId, CRYPTO_OPERATIONMODE_SINGLECALL, (uint8 *)&groupId, sizeof(groupId), NULL_PTR, 0u, &verifyResult) == E_OK) + { + result = kFblOk; + } + + if ((result == kFblOk) && (verifyResult != CRYPTO_E_VER_OK)) + { + result = kFblFailed; + } +# endif /* FBLBM_ENABLE_FBLLBT_VERIFICATION */ +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + + return result; +} + +/*********************************************************************************************************************** + * FblSb_VerifyHeader + **********************************************************************************************************************/ +/*! \brief Verifies the header + * \param[in] bmHdrHeader Pointer to the FblBmHdrHeader structure + * \return Result of operation + * kFblFailed always (unsupported feature) + **********************************************************************************************************************/ +tFblResult FblSb_VerifyHeader(const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHdrHeader) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */ + (void)bmHdrHeader; +#endif + + return kFblFailed; +} + +/*********************************************************************************************************************** + * FblSb_VerifyHeaderRom + **********************************************************************************************************************/ +/*! \brief Verifies the MAC of the BmHdrHeader structure at a specific address + * \param[in] bmHeaderAddress Address of the bmHdrHeader structure + * \param[in] bmHdrHeader Pointer to the FblBmHdrHeader structure + * \return kFblFailed always (unsupported feature) + **********************************************************************************************************************/ +tFblResult FblSb_VerifyHeaderRom(tFblAddress bmHeaderAddress, const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHdrHeader) +{ +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */ + (void)bmHeaderAddress; + (void)bmHdrHeader; +#endif + + return kFblFailed; +} + +/*********************************************************************************************************************** + * FblSb_UpdateInitialSegments + **********************************************************************************************************************/ +/*! \brief Updates the SecureBootSegments based on the initial values. + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblSb_UpdateInitialSegments(void) +{ + tFblResult result = kFblOk; + Crypto_VerifyResultType verifyResult; + uint32 jobId; + vuint32 macOperationIdx; + uint32 groupId; + + /* Iterrate over the configuration */ + for (macOperationIdx = 0u; ((macOperationIdx < FBLSB_NUM_OF_MAC_OPERATIONS) && (result == kFblOk)); macOperationIdx++) + { + jobId = FblSb_GetCsmJobIdOfMacVerifyForceSequential(); + + if (FblSb_IsVerifyForceSequentialOfMacOperation(macOperationIdx)) + { + result = kFblFailed; + verifyResult = CRYPTO_E_VER_NOT_OK; + groupId = FblSb_GetGroupIdOfMacOperation(macOperationIdx); + if (Csm_MacVerify(jobId, CRYPTO_OPERATIONMODE_SINGLECALL, (uint8 *)&groupId, sizeof(groupId), NULL_PTR, 0u, &verifyResult) == E_OK) + { + if (verifyResult == CRYPTO_E_VER_OK) + { + result = kFblOk; + } + } + } + } + + return result; +} + +/*********************************************************************************************************************** + * FblSb_VerifySegments + **********************************************************************************************************************/ +/*! \brief Verifies the segments + * \details Triggers a verification of the configured SecureBootGroup. + * \param[in] bmHdrHeader Pointer to the FblBmHdrHeader structure + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblSb_VerifySegments(const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHdrHeader) +{ + tFblResult result = kFblFailed; + Crypto_VerifyResultType verifyResult = CRYPTO_E_VER_NOT_OK; + uint32 macId = FblBmHdr_GetFblSbMacId(bmHdrHeader->bmTargetHandle); + uint32 jobId; + uint32 groupId; + + /* Check if mac operation is configured. */ + if (macId != FBLBMHDR_MAC_OP_REF_NOT_USED) + { + if (macId < FBLSB_NUM_OF_MAC_OPERATIONS) + { + jobId = FblSb_GetCsmJobIdOfMacVerify(); + groupId = FblSb_GetGroupIdOfMacOperation(macId); + if (E_OK == Csm_MacVerify(jobId, CRYPTO_OPERATIONMODE_SINGLECALL, (uint8 *)&groupId, sizeof(groupId), NULL_PTR, 0u, &verifyResult)) + { + result = kFblOk; + } + } + + if( (result == kFblOk) + && (verifyResult != CRYPTO_E_VER_OK)) + { + result = kFblFailed; + } + } + else + { + result = kFblOk; + } + + return result; +} + +#if defined( FBLSB_ENABLE_GENERATE_CMAC ) +/*********************************************************************************************************************** + * FblSb_UpdateFblMac + **********************************************************************************************************************/ +/*! \brief Generate and write the necessary MACs for the FBL + * \param[in] fblHeader Pointer to the FBL Header + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise + **********************************************************************************************************************/ +tFblResult FblSb_UpdateFblMac(V_MEMROM1 tFblHeader V_MEMROM2 V_MEMROM3 * fblHeader) +{ + tFblResult result = kFblFailed; + tFblBmHdrHeader bmHeader = { 0u }; + vuint32 macId = 0u; + + /* Clear any previous errors */ + sbExtErrCode = FBLSB_EXT_ERR_CODE_NONE; + + /* Read BM Header */ + /* PRQA S 0306 1 */ /* MD_FblLibSecBoot_0306 */ + if (FblReadProm((tFblAddress)fblHeader->bmHeader, (vuint8 *)&bmHeader, sizeof(bmHeader)) == sizeof(bmHeader)) + { + result = FblBmHdrCheckConsistency(&bmHeader); + } + else + { + sbExtErrCode = FBLSB_EXT_ERR_CODE_MEMORY; + } + + if (result == kFblOk) + { + /* Update the MAC for the first validation structure, used for all FBL segments */ + macId = FblBmHdr_GetFblSbMacId(bmHeader.bmTargetHandle); + result = FblSb_UpdateCommonMac(&bmHeader, macId); + } + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined( FBLBM_ENABLE_FBLLBT_VERIFICATION ) + if (result == kFblOk) + { + /* Now update the MAC of the second validation structure */ + bmHeader.bmAuthenticationHeaderAddress = FBLSB_SECOND_AUTH_HEADER_ADDRESS; + result = FblSb_UpdateCommonMac(&bmHeader, FBLSB_SECOND_AUTH_MAC_OPERATION_ID); + } +# endif /* FBLBM_ENABLE_FBLLBT_VERIFICATION */ +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + + return result; +} + +/*********************************************************************************************************************** + * FblSb_UpdateBlockMac + **********************************************************************************************************************/ +/*! \brief Generate and write the necessary MACs for a logical block + * \param[in] blockDescriptor Pointer to the logical block + * \param[in] segmentList Pointer to the segments + * \return Result of operation + * kFblOk when operation succeeded + * kFblFailed otherwise + **********************************************************************************************************************/ +/* PRQA S 3673 2 */ /* MD_MSR_Rule8.13 */ +tFblResult FblSb_UpdateBlockMac(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + V_MEMRAM1 FL_SegmentListType V_MEMRAM2 V_MEMRAM3 * segmentList) +{ + tFblResult result = kFblFailed; + tFblBmHdrHeader bmHeader = { 0u }; + vuint32 macId = 0u; + +#if defined( V_ENABLE_USE_DUMMY_STATEMENT ) + /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */ + (void)segmentList; +#endif + + /* Clear any previous errors */ + sbExtErrCode = FBLSB_EXT_ERR_CODE_NONE; + + /* Read BM Header */ + if (FblReadProm(blockDescriptor->bmHeaderAddress, (vuint8 *)&bmHeader, sizeof(bmHeader)) == sizeof(bmHeader)) + { + result = FblBmHdrCheckConsistency(&bmHeader); + } + else + { + sbExtErrCode = FBLSB_EXT_ERR_CODE_MEMORY; + } + + if (result == kFblOk) + { + macId = FblBmHdr_GetFblSbMacId(bmHeader.bmTargetHandle); + result = FblSb_UpdateCommonMac(&bmHeader, macId); + } + + return result; +} +#endif /* FBLSB_ENABLE_GENERATE_CMAC */ + +/*********************************************************************************************************************** + * FblSb_GetExtendedErrorCode + **********************************************************************************************************************/ +/*! \brief Returns an extended error information from previous call to FblSb_UpdateBlockMac/FblSb_UpdateFblMac + * \return Extended error code + **********************************************************************************************************************/ +tFblSbExtErrCode FblSb_GetExtendedErrorCode(void) +{ + return sbExtErrCode; +} + +#define FBLSB_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * MISRA + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_FblLibSecBoot_0306: + Reason: Address conversion between integer values and pointers is required to allow for hardware independent + configuration and address range checks. + Risk: The size of integer required to hold the result of a pointer cast is implementation-defined. + Prevention: The size of the respective integer data type which holds the address value is adapted on a hardware + specific basis. The correctness of the respective implementation is verified by runtime tests. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: FBL_SECBOOT.C + **********************************************************************************************************************/ diff --git a/Source/bsw/FblSecBoot/fbl_secboot.h b/Source/bsw/FblSecBoot/fbl_secboot.h new file mode 100644 index 0000000..d123e97 --- /dev/null +++ b/Source/bsw/FblSecBoot/fbl_secboot.h @@ -0,0 +1,121 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief SecureBoot implementation + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2020-01-07 visrie FBL-524 Initial release + * 01.00.01 2020-04-27 visrie FBL-1773 Added API reference version define + * 02.00.00 2020-05-19 vistbe FBL-1016 No changes + * 02.01.00 2021-01-19 visrie FBL-2648 No changes + * FBL-2641 Updated to new API version + * 02.02.00 2021-09-08 visjdn FBL-3352 No changes + * 02.03.00 2023-06-21 vistbe FBL-4814 Add support for OTA + * 02.03.01 2024-05-16 viswmo ESCAN00117059 No changes + * 02.04.00 2024-11-18 vismix FBL-9654 No changes + * 02.05.00 2025-01-24 vikatya PIO-1340 No changes + * 02.06.00 2025-02-19 visrie FBL-10209 No changes + **********************************************************************************************************************/ + +#ifndef FBL_SECBOOT_H +#define FBL_SECBOOT_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblLib_SecBoot_vHsm CQComponent : Implementation */ +#define FBLLIB_SECBOOT_VHSM_VERSION 0x0206u +#define FBLLIB_SECBOOT_VHSM_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "FblSb_Cfg.h" +#include "FblBm_Cfg.h" +#include "fbl_secboot_ap.h" +#include "fbl_main_types.h" + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* Reference interface version */ +/** Major interface version identifies incompatible changes */ +#define FBLSB_API_REFERENCE_VERSION_MAJOR 0x02u +/** Minor interface version identifies backward compatible changes */ +#define FBLSB_API_REFERENCE_VERSION_MINOR 0x03u +/** Release interface version identifies cosmetic changes */ +#define FBLSB_API_REFERENCE_VERSION_RELEASE 0x00u + +#if defined( FBL_ENABLE_OTA ) +# define FblSb_UpdateBlockMacSwap(blockDescriptor, segmentList) FblSb_UpdateBlockMac(blockDescriptor, segmentList) +#endif + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +typedef enum +{ + FBLSB_EXT_ERR_CODE_NONE = 0u, + FBLSB_EXT_ERR_CODE_GENERAL, + FBLSB_EXT_ERR_CODE_CRC, + FBLSB_EXT_ERR_CODE_SIGNATURE, + FBLSB_EXT_ERR_CODE_MEMORY +} tFblSbExtErrCode; + +/*********************************************************************************************************************** + * FUNCTION PROTOTYPES + **********************************************************************************************************************/ +#define FBLSB_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( FBLSB_ENABLE_COPY_FLASH_DRIVER ) +void FblSb_CopyFlashDriver( void ); +#endif /* FBLSB_ENABLE_COPY_FLASH_DRIVER */ + +void FblSb_Init(void); +tFblResult FblSb_VerifyFblLbt(const V_MEMRAM1 tFblHeader V_MEMRAM2 V_MEMRAM3 * fblHeader); +tFblResult FblSb_VerifyHeader(const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHdrHeader); +tFblResult FblSb_VerifyHeaderRom(tFblAddress bmHeaderAddress, const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHdrHeader); +tFblResult FblSb_VerifySegments(const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 *bmHdrHeader); + +tFblResult FblSb_UpdateInitialSegments(void); + +#if defined( FBLSB_ENABLE_GENERATE_CMAC ) +tFblResult FblSb_UpdateFblMac(V_MEMROM1 tFblHeader V_MEMROM2 V_MEMROM3 * fblHeader); +tFblResult FblSb_UpdateBlockMac(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor, + V_MEMRAM1 FL_SegmentListType V_MEMRAM2 V_MEMRAM3 * segmentList); +#endif /* FBLSB_ENABLE_GENERATE_CMAC */ + +tFblSbExtErrCode FblSb_GetExtendedErrorCode(void); + +#define FBLSB_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* FBL_SECBOOT_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_SECBOOT.H + **********************************************************************************************************************/ diff --git a/Source/bsw/VStdLib/Make/VStdLib_cfg.mak b/Source/bsw/VStdLib/Make/VStdLib_cfg.mak new file mode 100644 index 0000000..2160b93 --- /dev/null +++ b/Source/bsw/VStdLib/Make/VStdLib_cfg.mak @@ -0,0 +1,79 @@ +############################################################################### +# File Name : VStdLib_cfg.mak +# Description: Configuration makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the VStdLib_rules.mak file. +############################################################################### + +############################################################## +# CAN_CONFIG_PATH: (not used for Vector) +# The Variable CAN_CONFIG_PATH is optional. It allows the +# configuration of the directory, where you can also find the +# generated source files. Generally they should be in the +# directory $(PROJECT_ROOT)\source\networks. +# But if the application should run on several hardware +# targets, then different CAN configurations of different +# directories will be necessary. Therefor the variable +# CAN_CONFIG_PATH should be used. +# +# For example: +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\st10 +# CAN_CONFIG_PATH = $(PROJECT_ROOT)\source\network\v850 +# + +#VSTDLIB_CONFIG_PATH = + + +############################################################## +# CAN_DRIVER_MODE: (not used for Vector) +# This Variable contains the name of the can driver module. At +# the moment the Standard Software Core Supports the two driver +# can_drv.c (single CAN) and can_drvm.c (multi CAN). Other +# values are not allowed. +# +# For example: +# CAN_DRIVER_MODE = singlechannel/multichannel +# + + +############################################################### +# REQUIRED +# +# No Other resources are required to write a Configuration +# Makefile. +# +############################################################### + + +############################################################### +# PROVIDE +# +# A Configuration Makefile does not provide resources for other +# basic software bundles or the base_make package +# +############################################################### + + +############################################################### +# REGISTRY +# +# Like the Provide-Section this block is empty. +# +############################################################### + + +############################################################### +# SPECIFIC +# +# All variables in the _cfg makefile are "Specific" variables, +# because they should only be used in the *_check.mak, +# *_defs.mak and *_rules.mak Makefiles of the same basic +# software bundle. +############################################################### diff --git a/Source/bsw/VStdLib/Make/VStdLib_check.mak b/Source/bsw/VStdLib/Make/VStdLib_check.mak new file mode 100644 index 0000000..5ebb4e4 --- /dev/null +++ b/Source/bsw/VStdLib/Make/VStdLib_check.mak @@ -0,0 +1,79 @@ +############################################################################### +# File Name : VStdLib_check.mak +# Description: Configuration check makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the VStdLib_rules.mak file. +############################################################################### + +############################################################### +# REGISTRY +# + +#e.g.: PREPARE_CONFIGURATION_INTERFACE += CAN_MODULES +PREPARE_CONFIGURATION_INTERFACE += + +CHECK_VARS_WHICH_ARE_REQUIRED += + +CHECK_VARS_WHICH_ARE_OPTIONAL += + +CHECK_VARS_WHICH_ARE_OBSOLETE += + +CHECK_VARS_WITH_ONE_CC_FILE += +CHECK_VARS_WITH_MORE_CC_FILES += + +CHECK_VARS_WITH_ONE_CPP_FILE += +CHECK_VARS_WITH_MORE_CPP_FILES += + +CHECK_VARS_WITH_ONE_ASM_FILE += +CHECK_VARS_WITH_MORE_ASM_FILES += + +CHECK_VARS_WITH_ONE_LIB_FILE += +CHECK_VARS_WITH_MORE_LIB_FILES += + +CHECK_VARS_WITH_ONE_OBJ_FILE += +CHECK_VARS_WITH_MORE_OBJ_FILES += + +#e.g: CHECK_VARS_WITH_ONE_DIRECTORY += $(DIRECTORIES_TO_CREATE) +# $(DIRECTORIES_TO_CREATE) = C:\demo\drv (this var is defined in _rules.mak) +CHECK_VARS_WITH_ONE_DIRECTORY += +CHECK_VARS_WITH_MORE_DIRECTORIES += + +CHECK_VARS_WITH_ONE_FILE += +CHECK_VARS_WITH_MORE_FILES += + +CHECK_VARS_WITH_MAX_LENGTH_ONE += + +############################################################### +# SPECIFIC +# +#ifneq ($(CAN_DRIVER_MODE),singlechannel) +#ifneq ($(CAN_DRIVER_MODE),multichannel) +#$(error The value of the variable CAN_DRIVER_MODE is not valid. \ +# Please use singlechannel or multichannel) +#endif +#endif + + +############################################################### +# REQUIRED +# +# No other resources are required for a Configuration Check +# Makefile +# +############################################################### + + +############################################################### +# PROVIDE +# +# A configuration Makefile does not provide resources for other +# basic software bundles or the base-make package. +# +############################################################### + diff --git a/Source/bsw/VStdLib/Make/VStdLib_defs.mak b/Source/bsw/VStdLib/Make/VStdLib_defs.mak new file mode 100644 index 0000000..209074a --- /dev/null +++ b/Source/bsw/VStdLib/Make/VStdLib_defs.mak @@ -0,0 +1,85 @@ +############################################################################### +# File Name : VStdLib_defs.mak +# Description: Public makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the VStdLib_rules.mak file. +############################################################################### + +############################################################### +# INTERNAL REQUIRED CONFIGURATION (in can_cfg.mak) +# +# CAN_MODULES (required) (not necessary for Vector) +# CAN_DRIVER_MODE (required) (not necessary for Vector) +# CAN_PROJECT_PATH (optional) +# CAN_BUILD_LIBRARY (required) + + +############################################################### +# REQUIRED (defined in base_make) +# +# PROJECT_ROOT +# SSC_ROOT +############################################################### + + +############################################################### +# SPECIFIC +# Specific variables which were defined here are only for local use in this Makefile +# if for example additional includes are necessary, these vars can be defined and used in the REGISTRY-Part. +# e.g.: $(CAN_CORE_PATH) = $(SSC_ROOT)\Can could be used for CPP_INCLUDE_PATH += $(CAN_CORE_PATH)\CPP_FILES\... + +VSTDLIB_CORE_PATH = + +# e.g.: CAN_OUTPUT_PATH = $(GENDATA_DIR) +VSTDLIB_OUTPUT_PATH = + + + +#CAN_TOOL_PATH = $(PROJECT_ROOT)\core\com\can\gentool + +# it is also possible to generate own configurations with some checks like the following example +# ifneq ( $(CAN_CONFIG_PATH),) +# CAN_PROJECT_PATH = $(CAN_CONFIG_PATH) +# else +# CAN_PROJECT_PATH = $(PROJECT_ROOT)\source\network\can +# endif + + +############################################################### +# REGISTRY +# +# $(SSC_PLUGINS) is a list of the components. Here can is added (not necessary for Vector, whole component-list also exists in Global.makefile.target.make...) +# e.g.: SSC_PLUGINS += can +SSC_PLUGINS += +#e.g.: CAN_DEPENDENT_PLUGINS = +VSTDLIB_DEPENDENT_PLUGINS = + +#----------------------------------------------------------------------------------------- +# MakeSupport usually includes all header-files which were in the same +# directory as the source-files automatically, but to ensure that the +# Asr-Makefiles will also work with other Basic-Make-Packages, +# it is necessary to define all include directories for this Module +# e.g.: CC_INCLUDE_PATH += $(CAN_CORE_PATH) +#------------------------------------------------------------------------------------------ +CC_INCLUDE_PATH += VStdLib$(BSW_SRC_DIR) +CPP_INCLUDE_PATH += +ASM_INCLUDE_PATH += + +#PREPROCESSOR_DEFINES+= drivermode + +#drivermode_KEY = CAN_MODE +#drivermode_VALUE = $(CAN_DRIVER_MODE) + + +############################################################### +# PROVIDE +# +# A Public Makefile does not provide resources for other basic +# software bundles or the base_make package. +############################################################### diff --git a/Source/bsw/VStdLib/Make/VStdLib_rules.mak b/Source/bsw/VStdLib/Make/VStdLib_rules.mak new file mode 100644 index 0000000..e72c2b7 --- /dev/null +++ b/Source/bsw/VStdLib/Make/VStdLib_rules.mak @@ -0,0 +1,100 @@ +############################################################################### +# File Name : VStdLib_rules.mak +# Description: Rules makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2019 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Version Date Author Description +#------------------------------------------------------------------------------ +# 1.00.00 2018-10-23 vistkr Initial Version for VStdLib_GenericAsr +# 1.01.00 2019-02-06 vircbl Added support of component-based SIP structure +#------------------------------------------------------------------------------ +# TemplateVersion = 1.02 +############################################################################### + + +############################################################### +# REGISTRY +# + +#e.g.: LIBRARIES_TO_BUILD += +#e.g.: _FILES = \.c +LIBRARIES_TO_BUILD += + +# e.g.: CC_FILES_TO_BUILD += \.c \_Irq.c +CC_FILES_TO_BUILD += VStdLib$(BSW_SRC_DIR)\vstdlib.c +CPP_FILES_TO_BUILD += +ASM_FILES_TO_BUILD += + +#LIBRARIES_LINK_ONLY += (not yet supported) +#OBJECTS_LINK_ONLY += (not yet supported) + +#------------------------------------------------------------------------------------------------- +#only define new dirs, OBJ, LIB, LOG were created automaticly +#------------------------------------------------------------------------------------------------- +DIRECTORIES_TO_CREATE += + +#DEPEND_GCC_OPTS += (not yet supported) + +# e.g.: GENERATED_SOURCE_FILES += $(GENDATA_DIR)\drv_par.c +GENERATED_SOURCE_FILES += + +#e.g.: COMMON_SOURCE_FILES += $(GENDATA_DIR)\v_par.c +COMMON_SOURCE_FILES += + +#------------------------------------------------------------------------------------------------- +# .dep & .lnk & .bin and..... +# all in err\ & obj\ & lst\ & lib\ & log\ will be deleted by clean-rule automaticly +# so in this clean-rule it is only necessary to define additional files which +# were not delete automaticly. +# e.g.: $()\can_test.c +#------------------------------------------------------------------------------------------------- +MAKE_CLEAN_RULES += +#MAKE_GENERATE_RULES += +#MAKE_COMPILER_RULES += +#MAKE_DEBUG_RULES += +#MAKE_CONFIG_RULES += +#MAKE_ADD_RULES += + + +############################################################### +# REQUIRED (defined in BaseMake (global.Makefile.target.make...)) +# +# SSC_ROOT (required) +# PROJECT_ROOT (required) +# +# LIB_OUTPUT_PATH (optional) +# OBJ_OUTPUT_PATH (optional) +# +# OBJ_FILE_SUFFIX +# LIB_FILE_SUFFIX +# +############################################################### + + +############################################################### +# PROVIDE this Section can be used to define own additional rules +# +# In vendorx_can_cfg.mak: +# Please configure the project file: +#CAN_CONFIG_FILE = $(PROJECT_ROOT)\source\network\can\my_can_config.cfg + +#In vendorx_can_config : +#generate_can_config: +#$(SSC_ROOT)\core\com\can\tools\canconfiggen.exe -o $(CAN_CONFIG_FILE) + + +############################################################### +# SPECIFIC +# +# There are no rules defined for the Specific part of the +# Rules-Makefile. Each author is free to create temporary +# variables or to use other resources of GNU-MAKE +# +############################################################### + + diff --git a/Source/bsw/VStdLib/_VStdLib_Cfg.h b/Source/bsw/VStdLib/_VStdLib_Cfg.h new file mode 100644 index 0000000..581a769 --- /dev/null +++ b/Source/bsw/VStdLib/_VStdLib_Cfg.h @@ -0,0 +1,1006 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file VStdLib_Cfg.h + * \brief Configuration of the generic Vector Standard Library (VStdLib_GenericAsr) + * \details Template file that can be adapted by the user. + * This file contains the project specific configuration of the VStdLib. It also provides the possibility + * of overwriting the public APIs with project specific optimized implementations. + * + *********************************************************************************************************************/ + +#if !defined (VSTDLIB_CFG_H) +# define VSTDLIB_CFG_H + +/** + * Additional include files + * + * If necessary include additional files below (e.g. if VSTDLIB_USE_LIBRARY_FUNCTIONS is defined to STD_ON). + */ +/* # include ... */ + +/********************************************************************************************************************** + * General configuration + *********************************************************************************************************************/ + +/** + * VSTDLIB_USE_LIBRARY_FUNCTIONS + * + * If set to STD_ON the memory initialization, memory copy and memory comparison APIs are mapped to external functions + * (e.g. compiler libraries or other implementations that are optimized for the target platform). + * As the generic VStdLib implementation provides optimized routines only for 32bit platforms, this is recommended when + * using MCUs with other architectures. + * + * Values: + * STD_ON - Use external memory functions - requires additional configuration, see below. + * STD_OFF - Use generic memory functions provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION + * + * If set to STD_ON the memory copy with endianness swap API is mapped to an external function + * (e.g. compiler libraries or other implementations that are optimized for the target platform). + * As the generic VStdLib implementation provides optimized routines only for 32bit platforms, this is recommended when + * using MCUs with other architectures. + * + * Values: + * STD_ON - Use external memory copy with endianness swap function - requires additional configuration, see below. + * STD_OFF - Use generic memory copy with endianness swap function provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION STD_OFF + +/** + * VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION + * + * If set to STD_ON, the memory check API is mapped to an external function (e.g. compiler libraries + * or other implementations that are optimized for the target platform). + * As the generic VStdLib implementation provides optimized routines only for 32bit platforms, this is recommended when + * using MCUs with other architectures. + * + * Values: + * STD_ON - Use external memory check function - requires additional configuration, see below. + * STD_OFF - Use generic memory check function provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION STD_OFF + +/** + * VSTDLIB_RUNTIME_OPTIMIZATION + * + * If set to STD_ON optimized routines are used to increase the performance of the memory initialization, memory copy + * and memory comparison APIs. + * The setting of this define is only relevant if VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_OFF or + * VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION == STD_OFF. + * + * Values: + * STD_ON - Use optimized routines for memory operations (runtime efficient, but increases code size) + * STD_OFF - Use simple routines for memory operations (code efficient, but significantly increases runtime) + * + * Default: + * STD_ON + */ +# define VSTDLIB_RUNTIME_OPTIMIZATION STD_ON + +/** + * VSTDLIB_USE_JUMPTABLES + * + * If set to STD_ON jump tables are used to increase the performance of the memory initialization and memory copy APIs. + * The setting of this define is only relevant if VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON and + * VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_OFF or + * VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION == STD_OFF. + * + * Values: + * STD_ON - Use jump tables for memory operations (runtime efficient in general, but may depend on compiler) + * STD_OFF - Use loops for memory operations (code efficient, also use this if the compiler generates no efficient + * code for the jump tables) + * + * Default: + * STD_ON + */ +# define VSTDLIB_USE_JUMPTABLES STD_ON + +/** + * VSTDLIB_DEV_ERROR_DETECT + * + * If set to STD_ON the development error detection is enabled. In this case the pointer arguments of all global + * module functions are checked. If any NULL_PTR is passed, these functions return without performing any action. + * Please note that this setting has no influence on MICROSAR SafeBSW. + * + * Values: + * STD_ON - Check function arguments + * STD_OFF - Disable development error detection + * + * Default: + * STD_OFF + */ +# define VSTDLIB_DEV_ERROR_DETECT STD_OFF + +/** + * VSTDLIB_DEV_ERROR_REPORT + * + * If set to STD_ON the development error reporting is enabled. In this case Det_ReportError() is called if any + * development error is detected. + * + * Values: + * STD_ON - Enable calls of Det_ReportError() - requires VSTDLIB_DEV_ERROR_DETECT also to be defined to STD_ON + * STD_OFF - Disable development error reporting + * + * Default: + * STD_OFF + */ +# define VSTDLIB_DEV_ERROR_REPORT STD_OFF + +/** + * VSTDLIB_VERSION_INFO_API + * + * If set to STD_ON the API VStdLib_GetVersionInfo() is provided. + * + * Values: + * STD_ON - Provide the version info API + * STD_OFF - Do not provide the version info API + * + * Default: + * STD_OFF + */ +# define VSTDLIB_VERSION_INFO_API STD_OFF + +/** + * VSTDLIB_DUMMY_STATEMENT + * + * Expression that is used for dummy statements to avoid compile warnings about unused identifiers. + * + * Example values: + * (void)(v) + * (v)=(v) + * or leave the definition empty to disable the usage of dummy statements + * + * Default: + * (void)(v) + */ +# define VSTDLIB_DUMMY_STATEMENT(v) (void)(v) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ + +/** + * VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS + * + * If set to STD_ON all 8-bit bit search APIs are mapped to external functions (e.g. compiler libraries or + * other implementations that are optimized for the target platform). + * + * Values: + * STD_ON - Use external bit search functions - requires additional configuration, see below. + * STD_OFF - Use generic 8-bit bit search functions provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS + * + * If set to STD_ON all 16-bit bit search APIs are mapped to external functions (e.g. compiler libraries or + * other implementations that are optimized for the target platform). + * + * Values: + * STD_ON - Use external bit search functions - requires additional configuration, see below. + * STD_OFF - Use generic 16-bit bit search functions provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS + * + * If set to STD_ON all 32-bit bit search APIs are mapped to external functions (e.g. compiler libraries or + * other implementations that are optimized for the target platform). + * + * Values: + * STD_ON - Use external bit search functions - requires additional configuration, see below. + * STD_OFF - Use generic 32-bit bit search functions provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS + * + * If set to STD_ON all 64-bit bit search APIs are mapped to external functions (e.g. compiler libraries or + * other implementations that are optimized for the target platform). + * The setting of this define is only allowed if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * + * Values: + * STD_ON - Use external bit search functions - requires additional configuration, see below. + * STD_OFF - Use generic 64-bit bit search functions provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS + * + * If set to STD_ON all 16-bit deserialization and serialization APIs are mapped to external functions + * (e.g. compiler libraries or other implementations that are optimized for the target platform). + * + * Values: + * STD_ON - Use external (de-)serialization functions - requires additional configuration, see below. + * STD_OFF - Use generic 16-bit (de-)serialization functions provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS + * + * If set to STD_ON all 32-bit deserialization and serialization APIs are mapped to external functions + * (e.g. compiler libraries or other implementations that are optimized for the target platform). + * + * Values: + * STD_ON - Use external (de-)serialization functions - requires additional configuration, see below. + * STD_OFF - Use generic 32-bit (de-)serialization functions provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS + * + * If set to STD_ON all 64-bit deserialization and serialization APIs are mapped to external functions + * (e.g. compiler libraries or other implementations that are optimized for the target platform). + * The setting of this define is only allowed if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * + * Values: + * STD_ON - Use external (de-)serialization functions - requires additional configuration, see below. + * STD_OFF - Use generic 64-bit (de-)serialization functions provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS + * + * If set to STD_ON all 16-bit endianness swap APIs are mapped to external functions (e.g. compiler libraries + * or other implementations that are optimized for the target platform). + * + * Values: + * STD_ON - Use external endianness swap functions - requires additional configuration, see below. + * STD_OFF - Use generic 16-bit endianness swap functions provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS + * + * If set to STD_ON all 32-bit endianness swap APIs are mapped to external functions (e.g. compiler libraries + * or other implementations that are optimized for the target platform). + * + * Values: + * STD_ON - Use external endianness swap functions - requires additional configuration, see below. + * STD_OFF - Use generic 32-bit endianness swap functions provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS + * + * If set to STD_ON all 64-bit endianness swap APIs are mapped to external functions (e.g. compiler libraries + * or other implementations that are optimized for the target platform). + * The setting of this define is only allowed if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * + * Values: + * STD_ON - Use external endianness swap functions - requires additional configuration, see below. + * STD_OFF - Use generic 64-bit endianness swap functions provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS + * + * If set to STD_ON all bit copy sawtooth APIs are mapped to external functions (e.g. compiler libraries + * or other implementations that are optimized for the target platform). + * + * Values: + * STD_ON - Use external bit copy functions with sawtooth bit numbering + * STD_OFF - Use generic bit copy functions with sawtooth bit numbering provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS STD_OFF + +/** + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS + * + * If set to STD_ON all bit copy monotone APIs are mapped to external functions (e.g. compiler libraries + * or other implementations that are optimized for the target platform). + * + * Values: + * STD_ON - Use external bit copy functions with monotone bit numbering + * STD_OFF - Use generic bit copy functions with monotone bit numbering provided by VStdLib + * + * Default: + * STD_OFF + */ +# define VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS STD_OFF + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_ON) +/** + * Memory library functions. + * + * If VSTDLIB_USE_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify the memory initialization, memory + * copy and memory comparison APIs by overwriting the definitions below. The error directive has to be removed. + * + * NOTE: + * - If the external functionality is not able to handle more than 65535 bytes it is necessary to define + * VSTDLIB_SUPPORT_LARGE_DATA to STD_OFF. + * - The specified functions must behave synchronously. + * - It has to be ensured that the specified memory initialization and memory copy functions are able to copy from + * and to all memory locations independently of the pointer length. + */ +# error "Verify the setting for VSTDLIB_SUPPORT_LARGE_DATA and fill the macros in this section with correct values!" + +# define VSTDLIB_SUPPORT_LARGE_DATA STD_ON + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Set nCnt bytes to zero at pDst (any alignment) */ +# define VStdLib_MemClr(pDst, nCnt) memset((pDst), 0, (nCnt)) + +/* Set nCnt bytes to the character nPattern at pDst (any alignment) */ +# define VStdLib_MemSet(pDst, nPattern, nCnt) memset((pDst), (nPattern), (nCnt)) + +/* Copy nCnt bytes from pSrc to pDst (any alignment) */ +# define VStdLib_MemCpy(pDst, pSrc, nCnt) memcpy((pDst), (pSrc), (nCnt)) + +/* Copy nCnt 16bit blocks from pSrc to pDst (both pointers 16-bit aligned) */ +# define VStdLib_MemCpy16(pDst, pSrc, nCnt) memcpy((pDst), (pSrc), ((nCnt)<<1)) + +/* Copy nCnt 32bit blocks from pSrc to pDst (both pointers 32-bit aligned) */ +# define VStdLib_MemCpy32(pDst, pSrc, nCnt) memcpy((pDst), (pSrc), ((nCnt)<<2)) + +/* + * Compares the two buffers for the specified number of bytes and returns whether they are equal or not. + * + * The memory comparison API has to return the datatype sint8 with the following values + * < 0, if buffer1 contains a smaller value than buffer2. + * = 0, if buffer1 and buffer2 are equal for the number of compared bytes. + * > 0, if buffer1 contains a greater value than buffer2. + * + * Attention: The shown example is only possible, if memcmp() returns values which are in the range of datatype sint8! + * +*/ +# define VStdLib_MemCmp(pBuf1, pBuf2, nCnt) ((sint8)memcmp((pBuf1), (pBuf2), (nCnt))) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_ON */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION == STD_ON) +/** + * Memory copy with endianness swap API library function. + * + * If VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION is set to STD_ON it is necessary to specify the + * memory copy with endianness swap API by overwriting the definition below. The error directive has to be removed. + * + * NOTE: + * - If the external functionality is not able to handle more than 65535 bytes it is necessary to define + * VSTDLIB_SUPPORT_LARGE_DATA to STD_OFF. + * - The specified function must behave synchronously. + * - It has to be ensured that the specified function is able to copy from and to all memory locations independently + * of the pointer length. + */ +# error "Verify the setting for VSTDLIB_SUPPORT_LARGE_DATA and fill the macro in this section with the correct value!" + +# if !defined (VSTDLIB_SUPPORT_LARGE_DATA) +# define VSTDLIB_SUPPORT_LARGE_DATA STD_ON +# endif + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* + * Copies nCnt bytes from pSrc (any alignment) to pDst (integer type alignment) with swapped endianness according to + * the integer type intType. + * + * Possible values for parameter inType are: + * - 1 for integer type uint8/sint8 + * - 2 for integer type uint16/sint16 + * - 4 for integer type uint32/sint32 + * - 8 for integer type uint64/sint64 + */ +# define VStdLib_MemCpySwapEndian(pDst, pSrc, nCnt, intType) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION == STD_ON */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION == STD_ON) +/** + * Memory check library function. + * + * If VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION is set to STD_ON it is necessary to define the memory check function by overwriting the definition below. + * The error directive has to be removed. + * + * NOTE: + * - If the external functionality is not able to handle more than 65535 bytes it is necessary to define + * VSTDLIB_SUPPORT_LARGE_DATA to STD_OFF. + * - The specified function must behave synchronously. + */ +# error "Verify the setting for VSTDLIB_SUPPORT_LARGE_DATA and fill the macro in this section with the correct value!" + +# if !defined (VSTDLIB_SUPPORT_LARGE_DATA) +# define VSTDLIB_SUPPORT_LARGE_DATA STD_ON +# endif + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Compares nCnt bytes of memory starting at pBuf to the specified 8-bit nPattern. If the content at pBuf is equal to the nPattern, E_OK is returned. + Otherwise, the errorCode passed as argument is returned. */ +# define VStdLib_MemCheck(pBuf, nPattern, nCnt, errorCode) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION == STD_ON */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON) +/** + * Bit search library functions. + * + * If VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify 8-bit bit search APIs by + * overwriting the definitions below. The error directive has to be removed. + * + * The 8-bit search APIs to get the highest/lowest bit position of a set/unset bit have to use the return value + * VSTDLIB_BITPOS_NA, if the value contains no set/unset bit. + * + * The 8-bit search APIs to get the bit count of leading/trailing ones/zeros have to use the return value + * VSTDLIB_BITCNT_NA, if the value contains no unset/set bit. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Returns the highest bit position of a set bit in the specified 8-bit value */ +# define VStdLib_GetHighestBitPosOne8(value) + +/* Returns the highest bit position of an unset bit in the specified 8-bit value */ +# define VStdLib_GetHighestBitPosZero8(value) + +/* Returns the lowest bit position of a set bit in the specified 8-bit value */ +# define VStdLib_GetLowestBitPosOne8(value) + +/* Returns the lowest bit position of an unset bit in the specified 8-bit value */ +# define VStdLib_GetLowestBitPosZero8(value) + +/* Returns the count of set bits preceding the highest unset bit in the specified 8-bit value */ +# define VStdLib_GetCountLeadingOnes8(value) + +/* Returns the count of unset bits preceding the highest set bit in the specified 8-bit value */ +# define VStdLib_GetCountLeadingZeros8(value) + +/* Returns the count of set bits following the lowest unset bit in the specified 8-bit value */ +# define VStdLib_GetCountTrailingOnes8(value) + +/* Returns the count of unset bits following the lowest set bit in the specified 8-bit value */ +# define VStdLib_GetCountTrailingZeros8(value) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON) +/** + * Bit search library functions. + * + * If VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify 16-bit bit search APIs by + * overwriting the definitions below. The error directive has to be removed. + * + * The 16-bit search APIs to get the highest/lowest bit position of a set/unset bit have to use the return value + * VSTDLIB_BITPOS_NA, if the value contains no set/unset bit. + * + * The 16-bit search APIs to get the bit count of leading/trailing ones/zeros have to use the return value + * VSTDLIB_BITCNT_NA, if the value contains no unset/set bit. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Returns the highest bit position of a set bit in the specified 16-bit value */ +# define VStdLib_GetHighestBitPosOne16(value) + +/* Returns the highest bit position of an unset bit in the specified 16-bit value */ +# define VStdLib_GetHighestBitPosZero16(value) + +/* Returns the lowest bit position of a set bit in the specified 16-bit value */ +# define VStdLib_GetLowestBitPosOne16(value) + +/* Returns the lowest bit position of an unset bit in the specified 16-bit value */ +# define VStdLib_GetLowestBitPosZero16(value) + +/* Returns the count of set bits preceding the highest unset bit in the specified 16-bit value */ +# define VStdLib_GetCountLeadingOnes16(value) + +/* Returns the count of unset bits preceding the highest set bit in the specified 16-bit value */ +# define VStdLib_GetCountLeadingZeros16(value) + +/* Returns the count of set bits following the lowest unset bit in the specified 16-bit value */ +# define VStdLib_GetCountTrailingOnes16(value) + +/* Returns the count of unset bits following the lowest set bit in the specified 16-bit value */ +# define VStdLib_GetCountTrailingZeros16(value) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON) +/** + * Bit search library functions. + * + * If VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify 32-bit bit search APIs by + * overwriting the definitions below. The error directive has to be removed. + * + * The 32-bit search APIs to get the highest/lowest bit position of a set/unset bit have to use the return value + * VSTDLIB_BITPOS_NA, if the value contains no set/unset bit. + * + * The 32-bit search APIs to get the bit count of leading/trailing ones/zeros have to use the return value + * VSTDLIB_BITCNT_NA, if the value contains no unset/set bit. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Returns the highest bit position of a set bit in the specified 32-bit value */ +# define VStdLib_GetHighestBitPosOne32(value) + +/* Returns the highest bit position of an unset bit in the specified 32-bit value */ +# define VStdLib_GetHighestBitPosZero32(value) + +/* Returns the lowest bit position of a set bit in the specified 32-bit value */ +# define VStdLib_GetLowestBitPosOne32(value) + +/* Returns the lowest bit position of an unset bit in the specified 32-bit value */ +# define VStdLib_GetLowestBitPosZero32(value) + +/* Returns the count of set bits preceding the highest unset bit in the specified 32-bit value */ +# define VStdLib_GetCountLeadingOnes32(value) + +/* Returns the count of unset bits preceding the highest set bit in the specified 32-bit value */ +# define VStdLib_GetCountLeadingZeros32(value) + +/* Returns the count of set bits following the lowest unset bit in the specified 32-bit value */ +# define VStdLib_GetCountTrailingOnes32(value) + +/* Returns the count of unset bits following the lowest set bit in the specified 32-bit value */ +# define VStdLib_GetCountTrailingZeros32(value) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if ((defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON)) +/** + * Bit search library functions. + * + * If VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify 64-bit bit search APIs by + * overwriting the definitions below. The error directive has to be removed. + * + * The 64-bit search APIs to get the highest/lowest bit position of a set/unset bit have to use the return value + * VSTDLIB_BITPOS_NA, if the value contains no set/unset bit. + * + * The 64-bit search APIs to get the bit count of leading/trailing ones/zeros have to use the return value + * VSTDLIB_BITCNT_NA, if the value contains no unset/set bit. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Returns the highest bit position of a set bit in the specified 64-bit value */ +# define VStdLib_GetHighestBitPosOne64(value) + +/* Returns the highest bit position of an unset bit in the specified 64-bit value */ +# define VStdLib_GetHighestBitPosZero64(value) + +/* Returns the lowest bit position of a set bit in the specified 64-bit value */ +# define VStdLib_GetLowestBitPosOne64(value) + +/* Returns the lowest bit position of an unset bit in the specified 64-bit value */ +# define VStdLib_GetLowestBitPosZero64(value) + +/* Returns the count of set bits preceding the highest unset bit in the specified 64-bit value */ +# define VStdLib_GetCountLeadingOnes64(value) + +/* Returns the count of unset bits preceding the highest set bit in the specified 64-bit value */ +# define VStdLib_GetCountLeadingZeros64(value) + +/* Returns the count of set bits following the lowest unset bit in the specified 64-bit value */ +# define VStdLib_GetCountTrailingOnes64(value) + +/* Returns the count of unset bits following the lowest set bit in the specified 64-bit value */ +# define VStdLib_GetCountTrailingZeros64(value) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* (defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON) */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON) +/** + * (De-)serialization library functions. + * + * If VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify the 16-bit + * deserialization and serialization APIs by overwriting the definitions below. The error directive has to be removed. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Converts the specified unsigned 16-bit value to an unsigned 8-bit array according to big endian */ +# define VStdLib_ConvertUint16ToUint8ArrayBigEndian(src, dst) + +/* Converts the specified unsigned 16-bit value to an unsigned 8-bit array according to little endian */ +# define VStdLib_ConvertUint16ToUint8ArrayLittleEndian(src, dst) + +/* Converts the specified signed 16-bit value to an unsigned 8-bit array according to big endian */ +# define VStdLib_ConvertSint16ToUint8ArrayBigEndian(src, dst) + +/* Converts the specified signed 16-bit value to an unsigned 8-bit array according to little endian */ +# define VStdLib_ConvertSint16ToUint8ArrayLittleEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an unsigned 16-bit value according to big endian */ +# define VStdLib_ConvertUint8ArrayToUint16BigEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an unsigned 16-bit value according to little endian */ +# define VStdLib_ConvertUint8ArrayToUint16LittleEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an signed 16-bit value according to big endian */ +# define VStdLib_ConvertUint8ArrayToSint16BigEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an signed 16-bit value according to little endian */ +# define VStdLib_ConvertUint8ArrayToSint16LittleEndian(src, dst) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON) +/** + * (De-)serialization library functions. + * + * If VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify the 32-bit + * deserialization and serialization APIs by overwriting the definitions below. The error directive has to be removed. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Converts the specified unsigned 32-bit value to an unsigned 8-bit array according to big endian */ +# define VStdLib_ConvertUint32ToUint8ArrayBigEndian(src, dst) + +/* Converts the specified unsigned 32-bit value to an unsigned 8-bit array according to little endian */ +# define VStdLib_ConvertUint32ToUint8ArrayLittleEndian(src, dst) + +/* Converts the specified signed 32-bit value to an unsigned 8-bit array according to big endian */ +# define VStdLib_ConvertSint32ToUint8ArrayBigEndian(src, dst) + +/* Converts the specified signed 32-bit value to an unsigned 8-bit array according to little endian */ +# define VStdLib_ConvertSint32ToUint8ArrayLittleEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an unsigned 32-bit value according to big endian */ +# define VStdLib_ConvertUint8ArrayToUint32BigEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an unsigned 32-bit value according to little endian */ +# define VStdLib_ConvertUint8ArrayToUint32LittleEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an signed 32-bit value according to big endian */ +# define VStdLib_ConvertUint8ArrayToSint32BigEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an signed 32-bit value according to little endian */ +# define VStdLib_ConvertUint8ArrayToSint32LittleEndian(src, dst) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if ((defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON)) +/** + * (De-)serialization library functions. + * + * If VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify the 64-bit + * deserialization and serialization APIs by overwriting the definitions below. The error directive has to be removed. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Converts the specified unsigned 64-bit value to an unsigned 8-bit array according to big endian */ +# define VStdLib_ConvertUint64ToUint8ArrayBigEndian(src, dst) + +/* Converts the specified unsigned 64-bit value to an unsigned 8-bit array according to little endian */ +# define VStdLib_ConvertUint64ToUint8ArrayLittleEndian(src, dst) + +/* Converts the specified signed 64-bit value to an unsigned 8-bit array according to big endian */ +# define VStdLib_ConvertSint64ToUint8ArrayBigEndian(src, dst) + +/* Converts the specified signed 64-bit value to an unsigned 8-bit array according to little endian */ +# define VStdLib_ConvertSint64ToUint8ArrayLittleEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an unsigned 64-bit value according to big endian */ +# define VStdLib_ConvertUint8ArrayToUint64BigEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an unsigned 64-bit value according to little endian */ +# define VStdLib_ConvertUint8ArrayToUint64LittleEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an signed 64-bit value according to big endian */ +# define VStdLib_ConvertUint8ArrayToSint64BigEndian(src, dst) + +/* Converts the specified unsigned 8-bit array to an signed 64-bit value according to little endian */ +# define VStdLib_ConvertUint8ArrayToSint64LittleEndian(src, dst) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* (defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON) */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON) +/** + * Endianness swap library functions. + * + * If VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify the 16-bit + * endianness swap APIs by overwriting the definitions below. The error directive has to be removed. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Swaps the endianness of the specified unsigned 16-bit value */ +# define VStdLib_SwapEndianUint16(value) + +/* Swaps the endianness of the specified signed 16-bit value */ +# define VStdLib_SwapEndianSint16(value) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON) +/** + * Endianness swap library functions. + * + * If VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify the 32-bit + * endianness swap APIs by overwriting the definitions below. The error directive has to be removed. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Swaps the endianness of the specified unsigned 32-bit value */ +# define VStdLib_SwapEndianUint32(value) + +/* Swaps the endianness of the specified signed 32-bit value */ +# define VStdLib_SwapEndianSint32(value) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if ((defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON)) +/** + * Endianness swap library functions. + * + * If VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify the 64-bit + * endianness swap APIs by overwriting the definitions below. The error directive has to be removed. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Swaps the endianness of the specified unsigned 64-bit value */ +# define VStdLib_SwapEndianUint64(value) + +/* Swaps the endianness of the specified signed 64-bit value */ +# define VStdLib_SwapEndianSint64(value) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* (defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON) */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS == STD_ON) +/** + * Bitcopy sawtooth library functions. + * + * If VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify the Bitcopy + * sawtooth APIs by overwriting the definitions below. The error directive has to be removed. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Copy nCnt bits from pSrc to pDst (any offset) with big data endianness + * Bit numbering of source and destination is sawtooth */ +# define VStdLib_BitCpySawBigToBigEndian(pDst, nDstBitOffsetSaw, pSrc, nSrcBitOffsetSaw, nCnt) + +/* Copy nCnt bits from pSrc to pDst (any offset) with swapped data endianness (big to little) + * Bit numbering of source and destination is sawtooth */ +# define VStdLib_BitCpySawBigToLittleEndian(pDst, nDstBitOffsetSaw, pSrc, nSrcBitOffsetSaw, nCnt) + +/* Copy nCnt bits from pSrc to pDst (any offset) with swapped data endianness (little to big) + * Bit numbering of source and destination is sawtooth */ +# define VStdLib_BitCpySawLittleToBigEndian(pDst, nDstBitOffsetSaw, pSrc, nSrcBitOffsetSaw, nCnt) + +/* Copy nCnt bits from pSrc to pDst (any offset) with little data endianness + * Bit numbering of source and destination is sawtooth */ +# define VStdLib_BitCpySawLittleToLittleEndian(pDst, nDstBitOffsetSaw, pSrc, nSrcBitOffsetSaw, nCnt) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* (VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS == STD_ON) */ + +/********************************************************************************************************************** + * Additional configuration if VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS == STD_ON + *********************************************************************************************************************/ + +# if (VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS == STD_ON) +/** + * Bitcopy sawtooth library functions. + * + * If VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS is set to STD_ON it is necessary to specify the Bitcopy + * sawtooth APIs by overwriting the definitions below. The error directive has to be removed. + * + */ +# error "Fill the macros in this section with correct values!" + +/* PRQA S 3453 FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +/* Copy nCnt bits from pSrc to pDst (any offset) with big data endianness + * Bit numbering of source and destination is monotone */ +# define VStdLib_BitCpyMonBigToBigEndian(pDst, nDstBitOffsetMon, pSrc, nSrcBitOffsetMon, nCnt) + +/* Copy nCnt bits from pSrc to pDst (any offset) with swapped data endianness (big to little) + * Bit numbering of source and destination is monotone */ +# define VStdLib_BitCpyMonBigToLittleEndian(pDst, nDstBitOffsetMon, pSrc, nSrcBitOffsetMon, nCnt) + +/* Copy nCnt bits from pSrc to pDst (any offset) with swapped data endianness (little to big) + * Bit numbering of source and destination is monotone */ +# define VStdLib_BitCpyMonLittleToBigEndian(pDst, nDstBitOffsetMon, pSrc, nSrcBitOffsetMon, nCnt) + +/* Copy nCnt bits from pSrc to pDst (any offset) with little data endianness + * Bit numbering of source and destination is monotone */ +# define VStdLib_BitCpyMonLittleToLittleEndian(pDst, nDstBitOffsetMon, pSrc, nSrcBitOffsetMon, nCnt) + +/* PRQA L:FUNCTION_LIKE_MACRO */ + +# endif /* (VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS == STD_ON) */ + +/********************************************************************************************************************** + * Compatibility for legacy Vector modules + *********************************************************************************************************************/ + +# if defined(VSTD_ENABLE_INTCTRL_HANDLING) || defined(VSTD_ENABLE_DEFAULT_INTCTRL) || \ + defined(VSTD_ENABLE_OSEK_INTCTRL) || defined(VSTD_ENABLE_APPL_INTCTRL) +/** + * Compatibility for legacy Vector modules. + * + * Legacy Vector modules that are used in a MICROSAR stack might rely on interrupt handling functionalities that are + * no longer supported by VStdLib. Map relevant calls to functionalities that are provided by the MICROSAR stack or + * application and remove the error directive. VStdSuspendAllInterrupts() and VStdResumeAllInterrupts() can be mapped + * to OS services or an exclusive area that is provided by the BSW scheduler for example. + */ +# error "VStdLib_GenericAsr does not support interrupt control handling, provide a mapping in this section!" + +# endif + +/********************************************************************************************************************** + * Do not modify anything below + *********************************************************************************************************************/ + +# define VSTDLIB_CFG_MAJOR_VERSION (3u) +# define VSTDLIB_CFG_MINOR_VERSION (4u) + +#endif /* VSTDLIB_CFG_H */ + +/********************************************************************************************************************** + * END OF FILE: VStdLib_Cfg.h + *********************************************************************************************************************/ diff --git a/Source/bsw/VStdLib/vstdlib.c b/Source/bsw/VStdLib/vstdlib.c new file mode 100644 index 0000000..80ce911 --- /dev/null +++ b/Source/bsw/VStdLib/vstdlib.c @@ -0,0 +1,7811 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file vstdlib.c + * \brief Implementation of the generic Vector Standard Library (VStdLib_GenericAsr) + * \details This is the source file of the VStdLib. It contains the hardware independent implementation of the + * public APIs. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the header file. + * + * FILE VERSION + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the VERSION CHECK below. + *********************************************************************************************************************/ + +#define VSTDLIB_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +#include "vstdlib.h" + +/********************************************************************************************************************** + * VERSION CHECK + *********************************************************************************************************************/ + +/* Checks the version of the interface header file */ +#if ( (VSTDLIB_SW_MAJOR_VERSION != (3u)) \ + || (VSTDLIB_SW_MINOR_VERSION != (9u)) \ + || (VSTDLIB_SW_PATCH_VERSION != (0u)) ) +# error "Version numbers of vstdlib.c and vstdlib.h are inconsistent!" +#endif + +/* Checks the version of the configuration header file */ +#if ( (VSTDLIB_CFG_MAJOR_VERSION != (3u)) \ + || (VSTDLIB_CFG_MINOR_VERSION != (4u)) ) +# error "Version numbers of vstdlib.c and VStdLib_Cfg.h are inconsistent!" +#endif + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ + +#if !defined (VSTDLIB_USE_LIBRARY_FUNCTIONS) +# error "VSTDLIB_USE_LIBRARY_FUNCTIONS has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION) +# error "VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION) +# error "VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_RUNTIME_OPTIMIZATION) +# error "VSTDLIB_RUNTIME_OPTIMIZATION has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_JUMPTABLES) +# error "VSTDLIB_USE_JUMPTABLES has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_DEV_ERROR_DETECT) +# error "VSTDLIB_DEV_ERROR_DETECT has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_DEV_ERROR_REPORT) +# error "VSTDLIB_DEV_ERROR_REPORT has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_VERSION_INFO_API) +# error "VSTDLIB_VERSION_INFO_API has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_DUMMY_STATEMENT) +# error "VSTDLIB_DUMMY_STATEMENT has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS) +# error "VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS) +# error "VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS) +# error "VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS) +# error "VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS) +# error "VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS) +# error "VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS) +# error "VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS) +# error "VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS) +# error "VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if !defined (VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS) +# error "VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS has to be defined.. check VStdLib_Cfg.h!" +#endif + +#if (!defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON)) +# error "The 64-bit bit search functions can only be overwritten, if PLATFORM_SUPPORT_SINT64_UINT64 is defined!" +#endif + +#if (!defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON)) +# error "The 64-bit (De-)serialization functions can only be overwritten, if PLATFORM_SUPPORT_SINT64_UINT64 is defined!" +#endif + +#if (!defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON)) +# error "The 64-bit endianness conversion functions can only be overwritten, if PLATFORM_SUPPORT_SINT64_UINT64 is defined!" +#endif + +#if ((VSTDLIB_DEV_ERROR_REPORT == STD_ON) && (VSTDLIB_DEV_ERROR_DETECT != STD_ON)) +# error "VSTDLIB_DEV_ERROR_REPORT defined to STD_ON requires VSTDLIB_DEV_ERROR_DETECT also to be defined to STD_ON!" +#endif + +#if (VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_ON) +# if (!defined (VStdLib_MemClr) || !defined (VStdLib_MemSet) || !defined (VStdLib_MemCpy) || \ + !defined (VStdLib_MemCpy16) || !defined (VStdLib_MemCpy32) || !defined (VStdLib_MemCmp)) +# error "Memory function API mapping has to be defined!" +# endif +#endif + +#if (VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION == STD_ON) +# if (!defined (VStdLib_MemCpySwapEndian)) +# error "Memory copy with endianness swap API mapping has to be defined" +# endif +#endif + +#if (VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION == STD_ON) +# if (!defined (VStdLib_MemCheck)) +# error "Memory check API mapping has to be defined" +# endif +#endif + +#if (((VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON)) && \ + (VSTDLIB_SUPPORT_LARGE_DATA != STD_ON) && (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON)) +# error "VSTDLIB_RUNTIME_OPTIMIZATION must not be enabled if large data support is not given!" +#endif + +#if (VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON) +# if (!defined (VStdLib_GetHighestBitPosOne8) || !defined (VStdLib_GetHighestBitPosZero8) || \ + !defined (VStdLib_GetLowestBitPosOne8) || !defined (VStdLib_GetLowestBitPosZero8) || \ + !defined (VStdLib_GetCountLeadingOnes8) || !defined (VStdLib_GetCountLeadingZeros8) || \ + !defined (VStdLib_GetCountTrailingOnes8) || !defined (VStdLib_GetCountTrailingZeros8)) +# error "Bit search API mapping for 8-bit values has to be defined!" +# endif +#endif + +#if (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON) +# if (!defined (VStdLib_GetHighestBitPosOne16) || !defined (VStdLib_GetHighestBitPosZero16) || \ + !defined (VStdLib_GetLowestBitPosOne16) || !defined (VStdLib_GetLowestBitPosZero16) || \ + !defined (VStdLib_GetCountLeadingOnes16) || !defined (VStdLib_GetCountLeadingZeros16) || \ + !defined (VStdLib_GetCountTrailingOnes16) || !defined (VStdLib_GetCountTrailingZeros16)) +# error "Bit search API mapping for 16-bit values has to be defined!" +# endif +#endif + +#if (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON) +# if (!defined (VStdLib_GetHighestBitPosOne32) || !defined (VStdLib_GetHighestBitPosZero32) || \ + !defined (VStdLib_GetLowestBitPosOne32) || !defined (VStdLib_GetLowestBitPosZero32) || \ + !defined (VStdLib_GetCountLeadingOnes32) || !defined (VStdLib_GetCountLeadingZeros32) || \ + !defined (VStdLib_GetCountTrailingOnes32) || !defined (VStdLib_GetCountTrailingZeros32)) +# error "Bit search API mapping for 32-bit values has to be defined!" +# endif +#endif + +#if (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON) +# if (!defined (VStdLib_GetHighestBitPosOne64) || !defined (VStdLib_GetHighestBitPosZero64) || \ + !defined (VStdLib_GetLowestBitPosOne64) || !defined (VStdLib_GetLowestBitPosZero64) || \ + !defined (VStdLib_GetCountLeadingOnes64) || !defined (VStdLib_GetCountLeadingZeros64) || \ + !defined (VStdLib_GetCountTrailingOnes64) || !defined (VStdLib_GetCountTrailingZeros64)) +# error "Bit search API mapping for 64-bit values has to be defined!" +# endif +#endif + +#if (VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON) +# if (!defined (VStdLib_ConvertUint16ToUint8ArrayBigEndian) || !defined (VStdLib_ConvertUint16ToUint8ArrayLittleEndian) || \ + !defined (VStdLib_ConvertSint16ToUint8ArrayBigEndian) || !defined (VStdLib_ConvertSint16ToUint8ArrayLittleEndian) || \ + !defined (VStdLib_ConvertUint8ArrayToUint16BigEndian) || !defined (VStdLib_ConvertUint8ArrayToUint16LittleEndian) || \ + !defined (VStdLib_ConvertUint8ArrayToSint16BigEndian) || !defined (VStdLib_ConvertUint8ArrayToSint16LittleEndian)) +# error "(De-)serialization API mapping for 16-bit values has to be defined!" +# endif +#endif + +#if (VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON) +# if (!defined (VStdLib_ConvertUint32ToUint8ArrayBigEndian) || !defined (VStdLib_ConvertUint32ToUint8ArrayLittleEndian) || \ + !defined (VStdLib_ConvertSint32ToUint8ArrayBigEndian) || !defined (VStdLib_ConvertSint32ToUint8ArrayLittleEndian) || \ + !defined (VStdLib_ConvertUint8ArrayToUint32BigEndian) || !defined (VStdLib_ConvertUint8ArrayToUint32LittleEndian) || \ + !defined (VStdLib_ConvertUint8ArrayToSint32BigEndian) || !defined (VStdLib_ConvertUint8ArrayToSint32LittleEndian)) +# error "(De-)serialization API mapping for 32-bit values has to be defined!" +# endif +#endif + +#if (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON) +# if (!defined (VStdLib_ConvertUint64ToUint8ArrayBigEndian) || !defined (VStdLib_ConvertUint64ToUint8ArrayLittleEndian) || \ + !defined (VStdLib_ConvertSint64ToUint8ArrayBigEndian) || !defined (VStdLib_ConvertSint64ToUint8ArrayLittleEndian) || \ + !defined (VStdLib_ConvertUint8ArrayToUint64BigEndian) || !defined (VStdLib_ConvertUint8ArrayToUint64LittleEndian) || \ + !defined (VStdLib_ConvertUint8ArrayToSint64BigEndian) || !defined (VStdLib_ConvertUint8ArrayToSint64LittleEndian)) +# error "(De-)serialization API mapping for 64-bit values has to be defined!" +# endif +#endif + +#if (VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON) +# if (!defined (VStdLib_SwapEndianUint16) || !defined (VStdLib_SwapEndianSint16)) +# error "Endianness swap API mapping for 16-bit values has to be defined" +# endif +#endif + +#if (VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON) +# if (!defined (VStdLib_SwapEndianUint32) || !defined (VStdLib_SwapEndianSint32)) +# error "Endianness swap API mapping for 32-bit values has to be defined" +# endif +#endif + +#if (VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON) +# if (!defined (VStdLib_SwapEndianUint64) || !defined (VStdLib_SwapEndianSint64)) +# error "Endianness swap API mapping for 64-bit values has to be defined" +# endif +#endif + +/********************************************************************************************************************** + * LOCAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* Masks internal parameters to ensure an upper limit of 3, respectively 31 */ +#define VSTDLIB_MASK_3 (0x03u) +#define VSTDLIB_MASK_31 (0x1Fu) + +/* Bitmask for lower three bits */ +#define VSTDLIB_MASK_7 (0x07u) + +/* Bitmasks for search and endianness swap algorithms */ +#define VSTDLIB_MASK_UPPER_NIBBLE (0xF0u) +#define VSTDLIB_MASK_LOWER_NIBBLE (0x0Fu) +#define VSTDLIB_MASK_UPPER_BYTE (0xFF00u) +#define VSTDLIB_MASK_LOWER_BYTE (0x00FFu) +#define VSTDLIB_MASK_UPPER_TWO_BYTES (0xFFFF0000u) +#define VSTDLIB_MASK_LOWER_TWO_BYTES (0x0000FFFFu) +#define VSTDLIB_MASK_UPPER_FOUR_BYTES (0xFFFFFFFF00000000uLL) +#define VSTDLIB_MASK_LOWER_FOUR_BYTES (0x00000000FFFFFFFFuLL) +#define VSTDLIB_MASK_ALLBITS_IN_ONE_BYTE (0xFFu) +#define VSTDLIB_MASK_ALLBITS_IN_TWO_BYTES (0xFFFFu) +#define VSTDLIB_MASK_ALLBITS_IN_FOUR_BYTES (0xFFFFFFFFu) +#define VSTDLIB_MASK_ALLBITS_IN_EIGHT_BYTES (0xFFFFFFFFFFFFFFFFuLL) + +/* Return values for VStdLib_Loc_GetMemCmpNeqResult(), VStdLib_MemCmp(), VStdLib_Loc_MemCmp_8(), + VStdLib_Loc_MemCmp_32_Aligned(), VStdLib_Loc_MemCmp_32_Unaligned() */ +#define VSTDLIB_MEM_CMP_RES_EQ (0) +#define VSTDLIB_MEM_CMP_RES_G (1) +#define VSTDLIB_MEM_CMP_RES_L (-1) + +/* Not each Platform_Types.h defines CPU_TYPE_64 */ +#if !defined (CPU_TYPE_64) +# define CPU_TYPE_64 (64u) +#endif + +/********************************************************************************************************************** + * LOCAL FUNCTION MACROS + *********************************************************************************************************************/ + +/* Returns the number of bytes (0 - 3) that are missing to the next 32-bit boundary + Note: VSTDLIB_MASK_7 required to mask lower three bits, which ensures that macro returns 0 for 32-bit aligned pointer. +*/ +#if (CPU_TYPE == CPU_TYPE_64) +/* ESCAN00108975: Compiler warning: 'type cast': pointer truncation from 'uint8 *' to 'uint32_least' + ESCAN00109680: Compiler warning: Conversion from 'uint8 *' to 'uint64' is sign-extended +*/ +# define VSTDLIB_ALIGN_OFFSET(ptr) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ \ + (uint8_least)((4u - ((uint64)(ptr) & VSTDLIB_MASK_7)) & VSTDLIB_MASK_3) +#else +# define VSTDLIB_ALIGN_OFFSET(ptr) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ \ + (uint8_least)((4u - ((uint32_least)(ptr) & VSTDLIB_MASK_7)) & VSTDLIB_MASK_3) +#endif + +#if ((VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || \ + (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) + +/* Returns the bit position of a set bit in the specified nibble by using a lookup table */ +# define VStdLib_Loc_GetHighestBitPosOneInNibble(value) VStdLib_HighestBitPosOneInNibble[(value)] +# define VStdLib_Loc_GetLowestBitPosOneInNibble(value) VStdLib_LowestBitPosOneInNibble[(value)] + +#endif /* (VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || + (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) */ + +/* Converts a byte array (src) to the integer type value (dst) in the swapped endianness. + The endianness swap is implemented by using the opposite service function to the current platform endianness. +*/ +#if (VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON) +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) +# define VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(src, dst) VStdLib_ConvertUint8ArrayToUint16LittleEndian((src), (dst)) +# define VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian(src, dst) VStdLib_ConvertUint8ArrayToUint32LittleEndian((src), (dst)) +# if defined (PLATFORM_SUPPORT_SINT64_UINT64) +# define VStdLib_Loc_ConvertUint8ArrayToUint64SwapEndian(src, dst) VStdLib_ConvertUint8ArrayToUint64LittleEndian((src), (dst)) +# endif +# else /* (CPU_BYTE_ORDER == LOW_BYTE_FIRST */ +# define VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(src, dst) VStdLib_ConvertUint8ArrayToUint16BigEndian((src), (dst)) +# define VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian(src, dst) VStdLib_ConvertUint8ArrayToUint32BigEndian((src), (dst)) +# if defined (PLATFORM_SUPPORT_SINT64_UINT64) +# define VStdLib_Loc_ConvertUint8ArrayToUint64SwapEndian(src, dst) VStdLib_ConvertUint8ArrayToUint64BigEndian((src), (dst)) +# endif +# endif /* CPU_BYTE_ORDER */ +#endif /* VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON */ + +/********************************************************************************************************************** + * LOCAL TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/* Module specific definition of LOCAL */ +#if !defined (VSTDLIB_LOCAL) +# define VSTDLIB_LOCAL static +#endif + +#if ((VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON) || \ + (VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON)) + +/* Struct for iterations in source and destination for bit copy algorithm */ +typedef struct +{ + VStdLib_CntType startByte; + VStdLib_CntType lastByte; + uint8 bitOffsetStartByte; + uint8 bitOffsetEndByte; +} VStdLib_BitCpyIterType; + +#endif /* (VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON) || + (VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON) */ + +/********************************************************************************************************************** + * LOCAL DATA PROTOTYPES + *********************************************************************************************************************/ +#if ((VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || \ + (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) + +# define VSTDLIB_START_SEC_CONST_8BIT +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/* Lookup table of nibble to bit position of highest set bit in nibble */ +VSTDLIB_LOCAL CONST(uint8, VSTDLIB_CONST) VStdLib_HighestBitPosOneInNibble[16u] = /* PRQA S 3218 */ /* MD_VStdLib_FileScope */ +{ + /* Bit position / Nibble value */ + VSTDLIB_BITPOS_NA, /* 0000 */ /* not possible, is catched directly via API */ + 0u, /* 0001 */ + 1u, /* 0010 */ + 1u, /* 0011 */ + 2u, /* 0100 */ + 2u, /* 0101 */ + 2u, /* 0110 */ + 2u, /* 0111 */ + 3u, /* 1000 */ + 3u, /* 1001 */ + 3u, /* 1010 */ + 3u, /* 1011 */ + 3u, /* 1100 */ + 3u, /* 1101 */ + 3u, /* 1110 */ + 3u /* 1111 */ +}; + +/* Lookup table of nibble to bit position of lowest set bit in nibble */ +VSTDLIB_LOCAL CONST(uint8, VSTDLIB_CONST) VStdLib_LowestBitPosOneInNibble[16u] = /* PRQA S 3218 */ /* MD_VStdLib_FileScope */ +{ + /* Bit position / Nibble value */ + VSTDLIB_BITPOS_NA, /* 0000 */ /* not possible, is catched directly via API */ + 0u, /* 0001 */ + 1u, /* 0010 */ + 0u, /* 0011 */ + 2u, /* 0100 */ + 0u, /* 0101 */ + 1u, /* 0110 */ + 0u, /* 0111 */ + 3u, /* 1000 */ + 0u, /* 1001 */ + 1u, /* 1010 */ + 0u, /* 1011 */ + 2u, /* 1100 */ + 0u, /* 1101 */ + 1u, /* 1110 */ + 0u /* 1111 */ +}; + +# define VSTDLIB_STOP_SEC_CONST_8BIT +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /*(VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || + (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#define VSTDLIB_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if (VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_Loc_GetMemCmpNeqResult() + *********************************************************************************************************************/ +/*! \brief Returns whether the specified buffer1 value is greater or smaller than the specified buffer2 value. + * \details - + * \param[in] buf1Value Buffer1 value for comparison. + * \param[in] buf2Value Buffer2 value for comparison. + * \return < 0 Buffer1 value is greater than buffer2 value. + * \return > 0 Buffer1 value is smaller than buffer2 value. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON + * \pre The parameters 'buf1Value' and 'buf2Value' have to contain unequal values. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(sint8, VSTDLIB_CODE) VStdLib_Loc_GetMemCmpNeqResult(uint32 buf1Value, uint32 buf2Value); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCmp_8() + *********************************************************************************************************************/ +/*! \brief Compares two buffers byte-wise for the specified number of bytes and returns whether they are equal + * or not (any alignment). + * \details - + * \param[in] pBuf1_8 8-bit pointer to first buffer for comparison. + * \param[in] pBuf2_8 8-bit pointer to second buffer for comparison. + * \param[in] nCnt Number of bytes to compare, pBuf1_8 and pBuf2_8 must be valid for this amount. + * \return < 0 The first buffer contains a smaller value than the second buffer. + * \return 0 The two buffers are equal for the number of compared bytes. + * \return > 0 The first buffer contains a greater value than the second buffer. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON + * \pre The parameters 'pBuf1_8' and 'pBuf2_8' have to point to valid memory areas. Each memory area has to + * be valid for at least the byte count defined in parameter 'nCnt'. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(sint8, VSTDLIB_CODE) VStdLib_Loc_MemCmp_8( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf1_8, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf2_8, + uint32_least nCnt); + +# if (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON) + +/********************************************************************************************************************** + * VStdLib_Loc_MemSet_8_3() + *********************************************************************************************************************/ +/*! \brief Initializes up to 3 bytes at pDst to the character nPattern (any alignment). + * \details Depending on VSTDLIB_USE_JUMPTABLES either with a jumptable or a for loop. + * \param[out] pDst8 8-bit pointer to the memory location to be initialized. + * \param[in] nPattern The character to be used to initialize the memory. + * \param[in] nCnt Number of bytes to initialize, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst8' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemSet_8_3( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + uint8 nPattern, + uint8_least nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_MemSet_8_31() + *********************************************************************************************************************/ +/*! \brief Initializes up to 31 bytes at pDst to the character nPattern (any alignment). + * \details Depending on VSTDLIB_USE_JUMPTABLES either with a jumptable or a for loop. + * \param[out] pDst8 8-bit pointer to the memory location to be initialized. + * \param[in] nPattern The character to be used to initialize the memory. + * \param[in] nCnt Number of bytes to initialize, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst8' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemSet_8_31( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + uint8 nPattern, + uint8_least nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_MemSet_32_Aligned() + *********************************************************************************************************************/ +/*! \brief Initializes memory at pDst to the character nPattern (32-bit aligned). + * \details With a for loop, the tail depending on VSTDLIB_USE_JUMPTABLES either with a jumptable or a for loop. + * \param[out] pDst32 32-bit pointer to the memory location to be initialized. + * \param[in] nPattern The character to be used to initialize the memory. + * \param[in] nCnt Number of bytes to initialize, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst32' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemSet_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + uint8 nPattern, + uint32_least nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpy_8_3() + *********************************************************************************************************************/ +/*! \brief Copies up to 3 bytes from pSrc to pDst (any alignment). + * \details Depending on VSTDLIB_USE_JUMPTABLES either with a jumptable or a for loop. + * \param[out] pDst8 8-bit pointer to the memory location to copy to. + * \param[in] pSrc8 8-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst8' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpy_8_3( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpy_8_31() + *********************************************************************************************************************/ +/*! \brief Copies up to 31 bytes from pSrc to pDst (any alignment). + * \details Depending on VSTDLIB_USE_JUMPTABLES either with a jumptable or a for loop. + * \param[out] pDst8 8-bit pointer to the memory location to copy to. + * \param[in] pSrc8 8-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst8' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpy_8_31( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpy_32_Aligned() + *********************************************************************************************************************/ +/*! \brief Copies 32-bit aligned data from pSrc to pDst. + * \details With a for loop, the tail depending on VSTDLIB_USE_JUMPTABLES either with a jumptable or a for loop. + * \param[out] pDst32 32-bit pointer to the memory location to copy to. + * \param[in] pSrc32 32-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst32' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpy_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpy_8_PartialWord() + *********************************************************************************************************************/ +/*! \brief Copies a partial word of 1 to 3 bytes from pSrc to pDst to reach a 32-bit boundary (any alignment). + * \details Depending on VSTDLIB_USE_JUMPTABLES either with a jumptable or a for loop. + * \param[out] pDst8 8-bit pointer to the memory location to copy to. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in,out] pPrev Word to copy from (is modified and used by caller afterwards). + * \param[in,out] pDPos Index for pDst8 to copy to (is modified and used by caller afterwards). + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst8' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpy_8_PartialWord( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + uint8_least nCnt, + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pPrev, + P2VAR(uint32_least, AUTOMATIC, VSTDLIB_VAR_FAR) pDPos); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpy_32_Unaligned() + *********************************************************************************************************************/ +/*! \brief Copies data from 32-bit aligned pSrc to unaligned pDst. + * \details With a for loop using 32-bit accesses, the head and tail depending on VSTDLIB_USE_JUMPTABLES either + with a jumptable or a for loop. + * \param[out] pDst8 8-bit pointer to the memory location to copy to. + * \param[in] pSrc32 32-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] nDstOffset pDst offset to the next 32-bit boundary. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst8' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpy_32_Unaligned( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt, + uint8_least nDstOffset); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCmp_32_Aligned() + *********************************************************************************************************************/ +/*! \brief Compares two 32-bit aligned buffers for the specified number of bytes and returns whether they are + * equal or not. + * \details The buffer values are compared 4-bytes-wise until the number of not compared bytes is smaller than 4. + * The remaining bytes are compared byte-wise using VStdLib_Loc_MemCmp_8(). + * \param[in] pBuf1_32 32-bit pointer to first buffer for comparison. + * \param[in] pBuf2_32 32-bit pointer to second buffer for comparison. + * \param[in] nCnt Number of bytes to compare, pBuf1_32 and pBuf2_32 must be valid for this amount. + * \return < 0 The first buffer contains a smaller value than the second buffer. + * \return 0 The two buffers are equal for the number of compared bytes. + * \return > 0 The first buffer contains a greater value than the second buffer. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pBuf1_32' and 'pBuf2_32' have to point to valid memory areas. Each memory area has + * to be valid for at least the byte count defined in parameter 'nCnt'. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(sint8, VSTDLIB_CODE) VStdLib_Loc_MemCmp_32_Aligned( + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf1_32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf2_32, + uint32_least nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCmp_32_Unaligned() + *********************************************************************************************************************/ +/*! \brief Compares a 32-bit aligned buffer with an unaligned buffer for the specified number of bytes and + * returns whether they are equal or not. + * \details The buffer values are compared 4-bytes-wise by correcting the byte displacement until the number of + * not compared bytes is smaller than 4. The remaining bytes are compared byte-wise using + * VStdLib_Loc_MemCmp_8(). + * \param[in] pBuf1_32 32-bit pointer to first buffer for comparison. + * \param[in] pBuf2_8 8-bit pointer to second buffer for comparison. + * \param[in] nCnt Number of bytes to compare, pBuf1_32 and pBuf2_8 must be valid for this amount. + * \param[in] nBuf2Offset pBuf2_8 offset to the next 32-bit boundary. + * \return < 0 The first buffer contains a smaller value than the second buffer. + * \return 0 The two buffers are equal for the number of compared bytes. + * \return > 0 The first buffer contains a greater value than the second buffer. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pBuf1_32' and 'pBuf2_8' have to point to valid memory areas. Each memory area has + * to be valid for at least the byte count defined in parameter 'nCnt'. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(sint8, VSTDLIB_CODE) VStdLib_Loc_MemCmp_32_Unaligned( + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf1_32, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf2_8, + uint32_least nCnt, + uint8_least nBuf2Offset); + +# endif /* VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON */ +#endif /* VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON */ + +#if (VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON) +# if (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON) + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian_IntType_32() + *********************************************************************************************************************/ +/*! \brief Copies and swaps up to 32 bytes from pSrc8 (any alignment) to pDst (intType alignment) according to + * the integer type intType. + * \details Depending on VSTDLIB_USE_JUMPTABLES either with a jumptable or a for loop. + * \param[out] pDst Pointer to the memory location to copy to. + * \param[in] pSrc8 8-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[16, 32, 64]). + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst' is aligned according to the integer type 'intType'. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian_IntType_32( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt, + uint8 intType); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian_Int16_32() + *********************************************************************************************************************/ +/*! \brief Copies and swaps up to 32 bytes from pSrc8 (any alignment) to pDst16 (16-bit alignment) according to + * the integer type VSTDLIB_INTTYPE_16. + * \details Depending on VSTDLIB_USE_JUMPTABLES either with a jumptable or a for loop. + * \param[out] pDst16 16-bit pointer to the memory location to copy to. + * \param[in] pSrc8 8-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst16' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type VSTDLIB_INTTYPE_16 size. + * The parameter 'pDst16' is 16-bit aligned. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian_Int16_32( + P2VAR(uint16, AUTOMATIC, VSTDLIB_VAR_FAR) pDst16, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian_Int32_32() + *********************************************************************************************************************/ +/*! \brief Copies and swaps up to 32 bytes from pSrc8 (any alignment) to pDst32 (32-bit alignment) according to + * the integer type VSTDLIB_INTTYPE_32. + * \details Depending on VSTDLIB_USE_JUMPTABLES either with a jumptable or a for loop. + * \param[out] pDst32 32-bit pointer to the memory location to copy to. + * \param[in] pSrc8 8-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst32' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type VSTDLIB_INTTYPE_32 size. + * The parameter 'pDst32' is 32-bit aligned. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian_Int32_32( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt); + +# if defined (PLATFORM_SUPPORT_SINT64_UINT64) + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian_Int64_32() + *********************************************************************************************************************/ +/*! \brief Copies and swaps up to 32 bytes from pSrc8 (any alignment) to pDst64 (64-bit alignment) according to + * the integer type VSTDLIB_INTTYPE_64. + * \details Depending on VSTDLIB_USE_JUMPTABLES either with a jumptable or a for loop. + * \param[out] pDst64 64-bit pointer to the memory location to copy to. + * \param[in] pSrc8 8-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * && defined PLATFORM_SUPPORT_SINT64_UINT64 + * \pre The parameters 'pDst64' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type VSTDLIB_INTTYPE_64 size. + * The parameter 'pDst64' is 64-bit aligned. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian_Int64_32( + P2VAR(uint64, AUTOMATIC, VSTDLIB_VAR_FAR) pDst64, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt); + +# endif /* defined PLATFORM_SUPPORT_SINT64_UINT64 */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian_32_Aligned() + *********************************************************************************************************************/ +/*! \brief Copies and swaps 32-bit aligned data from pSrc32 to pDst32 according to the integer type intType. + * \details With a for loop. The tail depending on VSTDLIB_USE_JUMPTABLES either with a jumptable (32-bit access) + * or a for loop (integer type dependent access). + * \param[out] pDst32 32-bit pointer to the memory location to copy to. + * \param[in] pSrc32 32-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[16, 32, 64]). + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst32' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst32' is 32-bit aligned and aligned according to the integer type 'intType'. + * The parameter 'pSrc32' is 32-bit aligned. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt, + uint8 intType); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndianInt16_32_Aligned() + *********************************************************************************************************************/ +/*! \brief Copies and swaps 32-bit aligned data from pSrc32 to pDst32 according to the integer type + * VSTDLIB_INTTYPE_16. + * \details With a for loop. The tail depending on VSTDLIB_USE_JUMPTABLES either with a jumptable (32-bit access) + * or a for loop (16-bit access). + * \param[out] pDst32 32-bit pointer to the memory location to copy to. + * \param[in] pSrc32 32-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst32' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type VSTDLIB_INTTYPE_16 size. + * The parameter 'pDst32' is 16-bit and 32-bit aligned. + * The parameter 'pSrc32' is 32-bit aligned. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndianInt16_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_SwapEndianInt16_32() + *********************************************************************************************************************/ +/*! \brief Returns two 16-bit values with a swapped endianness in a 32-bit value. + * \details - + * \param[in] src32 32-bit value containing two 16-bit values. + * \return 32-bit value containing the two 16-bit values with a swapped endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint32, VSTDLIB_CODE) VStdLib_Loc_SwapEndianInt16_32(uint32 src32); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndianInt32_32_Aligned() + *********************************************************************************************************************/ +/*! \brief Copies and swaps 32-bit aligned data from pSrc32 to pDst32 according to the integer type + * VSTDLIB_INTTYPE_32. + * \details With a for loop. The tail depending on VSTDLIB_USE_JUMPTABLES either with a jumptable (32-bit access) + * or a for loop (32-bit access). + * \param[out] pDst32 32-bit pointer to the memory location to copy to. + * \param[in] pSrc32 32-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pDst32' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type VSTDLIB_INTTYPE_32 size. + * The parameter 'pDst32' is 32-bit aligned. + * The parameter 'pSrc32' is 32-bit aligned. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndianInt32_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt); + +# if defined (PLATFORM_SUPPORT_SINT64_UINT64) + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndianInt64_32_Aligned() + *********************************************************************************************************************/ +/*! \brief Copies and swaps 32-bit aligned data from pSrc32 to pDst32 according to the integer type + * VSTDLIB_INTTYPE_64. + * \details With a for loop. The tail depending on VSTDLIB_USE_JUMPTABLES either with a jumptable (32-bit access) + * or a for loop (64-bit access). + * \param[out] pDst32 32-bit pointer to the memory location to copy to. + * \param[in] pSrc32 32-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * && defined PLATFORM_SUPPORT_SINT64_UINT64 + * \pre The parameters 'pDst32' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type VSTDLIB_INTTYPE_64 size. + * The parameter 'pDst32' is 32-bit and 64-bit aligned. + * The parameter 'pSrc32' is 32-bit aligned. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndianInt64_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt); + +# endif /* defined PLATFORM_SUPPORT_SINT64_UINT64 */ +# endif /* VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian() + *********************************************************************************************************************/ +/*! \brief Copies and swaps nCnt bytes from pSrc8 (any alignment) to pDst (intType alignment) according to + * the integer type intType. + * \details - + * \param[out] pDst Pointer to the memory location to copy to. + * \param[in] pSrc8 8-bit pointer to the memory location to copy from. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[16, 32, 64]). + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst' is aligned according to the integer type 'intType'. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint32_least nCnt, + uint8 intType); + +#endif /* VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyConvertBitCounting() + *********************************************************************************************************************/ +/*! \brief Converts sawtooth to monotone bit position numbering and vice versa. + * \details Is used by _s BitCpy and normal BitCpy APIs. The conversion from sawtooth to monotone bit position + * numbering in case of big endian data simplifies the calculation of the last byte to copy to or + * from and the calculation of its bit offset. Same applies for the conversion of monotone to sawtooth + * bit position numbering in case of little endian data. + * \param[in] bitPos Bit position numbered as sawtooth or monotone. + * \return Bit position with converted bit position numbering. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(VStdLib_CntType, VSTDLIB_CODE) VStdLib_Loc_BitCpyConvertBitCounting(VStdLib_CntType bitPos); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyGetLastIterByte() + *********************************************************************************************************************/ +/*! \brief Returns last iteration byte. + * \details Is used by _s BitCpy and normal BitCpy APIs to get the last iteration byte. + * \param[in] lengthInBits Sum of bits to be copied plus the offset. + * \return Last iteration byte. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(VStdLib_CntType, VSTDLIB_CODE) VStdLib_Loc_BitCpyGetLastIterByte( + VStdLib_CntType lengthInBits); + +#if ((VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON) || \ + (VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON)) + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyIter() + *********************************************************************************************************************/ +/*! \brief Sets all relevant interation parameters to iterate over a memory location. + * \details - + * \param[in] pIter Pointer to the iteration structure of a memory location. + * \param[in] nBitOffset Bit offset numbered as sawtooth or monotone. + * \param[in] nCnt Number of bits to copy. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyIter( + P2VAR(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pIter, + VStdLib_CntType nBitOffset, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyGetOffsetInBitsEndByte() + *********************************************************************************************************************/ +/*! \brief Returns bit offset in the last byte. + * \details Converts bit numbering from sawtooth to monotone and vice versa. It is used to shift the bit mask + * for the last destination byte and to determine the source byte shift if the memory locations have + * different data endianness. + * \param[in] lengthInBits Sum of bits to be copied plus the bit offset. + * \return 0-7 Bit offset in last byte. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_BitCpyGetOffsetInBitsEndByte( + VStdLib_CntType lengthInBits); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyBigEndianSrc_7() + *********************************************************************************************************************/ +/*! \brief Copies big endian data from one memory location into another memory location. + * \details Uses VStdLib_Loc_BitCpyBigEndianSrc() and a bit mask to copy 1 to 7 bits starting at pSrc8 + * to another memory location starting at pDst8. + * \param[out] pDst8 Pointer to the memory location to copy to, must not be NULL. + * \param[in] dstByteIdx Index to iterate over all bytes in the memory location to copy to. + * \param[in] pSrc8 Pointer to the memory location to copy from, must not be NULL. + * \param[in] srcByteIdx Index to iterate over all bytes in the memory location to copy from. + * \param[in] pSrcIter Pointer to the iteration structure of the memory location to copy from. + * \param[in] srcShift Variable to indicate if right/left or no shift is needed for the relevant source byte. + * \param[in] dstBitMask Mask to be able to copy number of bits < 8. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyBigEndianSrc_7( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + VStdLib_CntType dstByteIdx, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift, + uint8 dstBitMask); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyLittleEndianSrc_7() + *********************************************************************************************************************/ +/*! \brief Copies little endian data from one memory location into another memory location. + * \details Uses VStdLib_Loc_BitCpyLittleEndianSrc() and a bit mask to copy 1 to 7 bits starting at pSrc8 + * to another memory location starting at pDst8. + * \param[out] pDst8 Pointer to the memory location to copy to. + * \param[in] dstByteIdx Index to iterate over all dstBytes. + * \param[in] pSrc8 Pointer to the memory location to copy from. + * \param[in] srcByteIdx Index to iterate over all bytes in the memory location to copy from. + * \param[in] pSrcIter Pointer to the iteration structure of the memory location to copy from. + * \param[in] srcShift Variable to indicate if right/left or no shift is needed for the relevant source byte. + * \param[in] dstBitMask Mask to be able to copy number of bits < 8. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyLittleEndianSrc_7( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + VStdLib_CntType dstByteIdx, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift, + uint8 dstBitMask); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyBigEndianSrc() + *********************************************************************************************************************/ +/*! \brief Returns byte (big endian data) with relevant bits to copy to a memory location. + * \details Uses VStdLib_Loc_BitCpyShiftRight_BigEndianSrc() or VStdLib_Loc_BitCpyShiftLeft_BigEndianSrc() to + * get source byte with relevant bits. + * \param[in] pSrc8 Pointer to the memory location to copy from, must not be NULL. + * \param[in] srcByteIdx Index to indicate which source byte to use. + * \param[in] pSrcIter Pointer to the iteration structure of the memory location to copy from. + * \param[in] srcShift Variable to indicate if right/left or no shift is needed for the relevant source byte. + * \return Source byte to copy. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_BitCpyBigEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyLittleEndianSrc() + *********************************************************************************************************************/ +/*! \brief Returns byte (little endian data) with relevant bits to copy to a memory location. + * \details Uses VStdLib_Loc_BitCpyShiftRight_LittleEndianSrc() or VStdLib_Loc_BitCpyShiftLeft_LittleEndianSrc() + * to get source byte with relevant bits. + * \param[in] pSrc8 Pointer to the memory location to copy from, must not be NULL. + * \param[in] srcByteIdx Index to indicate which source byte to use. + * \param[in] pSrcIter Pointer to the iteration structure of the memory location to copy from. + * \param[in] srcShift Variable to indicate if right/left or no shift is needed for the relevant source byte. + * \return Source byte to copy. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_BitCpyLittleEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyShiftRight_BigEndianSrc() + *********************************************************************************************************************/ +/*! \brief Prepares byte (big endian data) with relevant bits to copy to a memory location. + * \details To align the offsets of the memory locations the relevant byte in the source is shifted + * and merged with the missing bits of the previous relevant source byte. + * \param[in] pSrc8 Pointer to the memory location to copy from, must not be NULL. + * \param[out] pSrcByte Pointer to byte to be modified. + * \param[in] srcByteIdx Index to indicate which source byte to use. + * \param[in] pSrcIter Pointer to the iteration structure of the memory location to copy from. + * \param[in] srcShift Variable that indicates that right shift is needed for the relevant source byte. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyShiftRight_BigEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcByte, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyShiftLeft_BigEndianSrc() + *********************************************************************************************************************/ +/*! \brief Prepares byte (big endian data) with relevant bits to copy to a memory location. + * \details To align the offsets of the memory locations the relevant byte in the source is shifted + * and merged with the missing bits of the next relevant source byte. + * \param[in] pSrc8 Pointer to the memory location to copy from, must not be NULL. + * \param[out] pSrcByte Pointer to byte to be modified. + * \param[in] srcByteIdx Index to indicate which source byte to use. + * \param[in] pSrcIter Pointer to the iteration structure of the memory location to copy from. + * \param[in] srcShift Variable that indicates that left shift is needed for the relevant source byte. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyShiftLeft_BigEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcByte, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyShiftRight_LittleEndianSrc() + *********************************************************************************************************************/ +/*! \brief Prepares byte (big endian data) with relevant bits to copy to a memory location. + * \details To align the offsets of the memory locations the relevant byte in the source is shifted + * and merged with the missing bits of the next relevant source byte. + * \param[in] pSrc8 Pointer to the memory location to copy from, must not be NULL. + * \param[out] pSrcByte Pointer to byte to be modified. + * \param[in] srcByteIdx Index to indicate which source byte to use. + * \param[in] pSrcIter Pointer to the iteration structure of the memory location to copy from. + * \param[in] srcShift Variable that indicates that right shift is needed for the relevant source byte. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyShiftRight_LittleEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcByte, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyShiftLeft_LittleEndianSrc() + *********************************************************************************************************************/ +/*! \brief Prepares byte (big endian data) with relevant bits to copy to a memory location. + * \details To align the offsets of the memory locations the relevant byte in the source is shifted + * and merged with the missing bits of the previous relevant source byte. + * \param[in] pSrc8 Pointer to the memory location to copy from, must not be NULL. + * \param[out] pSrcByte Pointer to byte to be modified. + * \param[in] srcByteIdx Index to indicate which source byte to use. + * \param[in] pSrcIter Pointer to the iteration structure of the memory location to copy from. + * \param[in] srcShift Variable that indicates that left shift is needed for the relevant source byte. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyShiftLeft_LittleEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcByte, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpySwapEndian() + *********************************************************************************************************************/ +/*! \brief Copies and swaps nCnt bits from one memory location into another memory location. + * \details Copies bits byte-wise starting at pSrc8 to another memory location starting at pDst8. + * \param[out] pDst8 Pointer to the memory location to copy to, must not be NULL. + * \param[in] pDstIter Pointer to the iteration structure of the memory location to copy to. + * \param[in] pSrc8 Pointer to the memory location to copy from, must not be NULL. + * \param[in] pSrcIter Pointer to the iteration structure of the memory location to copy from. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpySwapEndian( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pDstIter, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyBigToBigEndian() + *********************************************************************************************************************/ +/*! \brief Copies big endian data from one memory location to another memory location with big endian data. + * \details Copies nCnt bits starting at pSrc to another memory location starting at pDst. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to the + * destination-byte-pointer. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to the + * source-byte-pointer. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyBigToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyBigToLittleEndian() + *********************************************************************************************************************/ +/*! \brief Copies big endian data from one memory location to another memory location with little endian data. + * \details Copies nCnt bits starting at pSrc to another memory location starting at pDst. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to the + * destination-byte-pointer. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to the + * source-byte-pointer. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyBigToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyLittleToBigEndian() + *********************************************************************************************************************/ +/*! \brief Copies little endian data from one memory location to another memory location with big endian data. + * \details Copies nCnt bits starting at pSrc to another memory location starting at pDst. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to the + * destination-byte-pointer. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to the + * source-byte-pointer. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyLittleToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyLittleToLittleEndian() + *********************************************************************************************************************/ +/*! \brief Copies little endian data from one memory location to another memory location with little endian data. + * \details Copies nCnt bits starting at pSrc to another memory location starting at pDst. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to the + * destination-byte-pointer. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to the + * source-byte-pointer. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area. + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyLittleToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt); + +#endif /* (VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON) || + (VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON) */ + +#if (VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION != STD_ON) + +/********************************************************************************************************************** + * VStdLib_Loc_GetMemCheckResult() + *********************************************************************************************************************/ +/*! \brief Checks if a buffer value is equal to a pattern. + * \details Assigns a passed errorCode to the retVal in case of mismatch. + * \param[in] nBufValue Value to be checked. + * \param[in] nPattern The character to be checked against. + * \param[in] pRetVal Pointer to the result. + * \param[in] errorCode Value to be assigned as the result, if bufValue is not equal to pattern. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION != STD_ON + * \pre errorCode != E_OK + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_GetMemCheckResult( + uint32 nBufValue, + uint32 nPattern, + P2VAR(Std_ReturnType, AUTOMATIC, VSTDLIB_VAR_FAR) pRetVal, + Std_ReturnType errorCode); + +/********************************************************************************************************************** + * VStdLib_Loc_MemCheck_8() + *********************************************************************************************************************/ +/*! \brief Checks byte-wise if the data at pBuf8 matches the nPattern (any alignment). + * \details - + * \param[out] pBuf8 8-bit pointer to the memory location to be checked. + * \param[in] nPattern The character to be checked for in the memory. + * \param[in] nCnt Number of bytes to check, pBuf8 must be valid for this amount. + * \param[in] errorCode Value to be returned, if content of pBuf8 is not equal to pattern. + * \return E_OK pBuf8 consists only of the pattern. + * \return errorCode pBuf8 contains atleast one value that is not equal to pattern. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pBuf8' and 'nCnt' have to define a valid memory area and (errorCode != E_OK). + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_Loc_MemCheck_8( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf8, + uint8 nPattern, + uint32_least nCnt, + Std_ReturnType errorCode); + +# if (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON) + +/********************************************************************************************************************** + * VStdLib_Loc_MemCheck_32_Aligned() + *********************************************************************************************************************/ +/*! \brief Checks data at pBuf(32-bit aligned) for the nPattern. + * \details The buffer data is checked 4-bytes-wise until less than 4 bytes are left to be checked. + * The remaining bytes are compared byte-wise using VStdLib_Loc_MemCheck_8() + * \param[out] pBuf32 32-bit pointer to the memory location to be checked. + * \param[in] nPattern The character to checked for in the memory. + * \param[in] nCnt Number of bytes to check, pBuf must be valid for this amount. + * \param[in] errorCode Value to be returned, if content of pBuf is not equal to pattern. + * \return E_OK pBuf consists only of the pattern. + * \return errorCode pBuf contains atleast one value that is not equal to pattern. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION != STD_ON && VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON + * \pre The parameters 'pBuf32' and 'nCnt' have to define a valid memory area and (errorCode != E_OK). + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_Loc_MemCheck_32_Aligned( + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf32, + uint8 nPattern, + uint32_least nCnt, + Std_ReturnType errorCode); + +# endif /* VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON */ +#endif /* VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION != STD_ON */ + +#if ((VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || \ + (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || ((defined PLATFORM_SUPPORT_SINT64_UINT64) && \ + (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON))) + +/********************************************************************************************************************** + * VStdLib_Loc_GetHighestBitPosOneInByte() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of a set bit in the specified byte value. + * \details - + * \param[in] value The byte value in which the highest set bit shall be found. + * \return 0-7 Bit position of the highest set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * (defined PLATFORM_SUPPORT_SINT64_UINT64 && VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + * \pre The parameters 'value' has to be greater than zero (contains at least one set bit). + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetHighestBitPosOneInByte(uint8 value); + +/********************************************************************************************************************** + * VStdLib_Loc_GetLowestBitPosOneInByte() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of a set bit in the specified byte value. + * \details - + * \param[in] value The byte value in which the lowest set bit shall be found. + * \return 0-7 Bit position of the lowest set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * (defined PLATFORM_SUPPORT_SINT64_UINT64 && VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + * \pre The parameters 'value' has to be smaller than its maximum value (contains at least one unset bit). + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetLowestBitPosOneInByte(uint8 value); + +#endif /* (VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || + (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || ((defined PLATFORM_SUPPORT_SINT64_UINT64) && \ + (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) */ + +#if ((VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || \ + ((defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON))) + +/********************************************************************************************************************** + * VStdLib_Loc_GetHighestBitPosOneInTwoBytes() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of a set bit in the specified two byte value. + * \details - + * \param[in] value The two byte value in which the highest set bit shall be found. + * \return 0-15 Bit position of the highest set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * (defined PLATFORM_SUPPORT_SINT64_UINT64 && VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + * \pre The parameters 'value' has to be greater than zero (contains at least one set bit). + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetHighestBitPosOneInTwoBytes(uint16 value); + +/********************************************************************************************************************** + * VStdLib_Loc_GetLowestBitPosOneInTwoBytes() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of a set bit in the specified two byte value. + * \details - + * \param[in] value The two byte value in which the lowest set bit shall be found. + * \return 0-15 Bit position of the lowest set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * (defined PLATFORM_SUPPORT_SINT64_UINT64 && VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + * \pre The parameters 'value' has to be smaller than its maximum value (contains at least one unset bit). + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetLowestBitPosOneInTwoBytes(uint16 value); + +#endif /* (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || + ((defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) */ + +#if ((VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || ((defined PLATFORM_SUPPORT_SINT64_UINT64) && \ + (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON))) + +/********************************************************************************************************************** + * VStdLib_Loc_GetHighestBitPosOneInFourBytes() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of a set bit in the specified four byte value. + * \details - + * \param[in] value The four byte value in which the highest set bit shall be found. + * \return 0-31 Bit position of the highest set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * (defined PLATFORM_SUPPORT_SINT64_UINT64 && VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + * \pre The parameters 'value' has to be greater than zero (contains at least one set bit). + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetHighestBitPosOneInFourBytes(uint32 value); + +/********************************************************************************************************************** + * VStdLib_Loc_GetLowestBitPosOneInFourBytes() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of a set bit in the specified four byte value. + * \details - + * \param[in] value The four byte value in which the lowest set bit shall be found. + * \return 0-31 Bit position of the lowest set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON || + * (defined PLATFORM_SUPPORT_SINT64_UINT64 && VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + * \pre The parameters 'value' has to be smaller than its maximum value (contains at least one unset bit). + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetLowestBitPosOneInFourBytes(uint32 value); + +#endif /* (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || ((defined PLATFORM_SUPPORT_SINT64_UINT64) && + (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) */ + +#if ((defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) + +/********************************************************************************************************************** + * VStdLib_Loc_GetHighestBitPosOneInEightBytes() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of a set bit in the specified eight byte value. + * \details - + * \param[in] value The eight byte value in which the highest set bit shall be found. + * \return 0-63 Bit position of the highest set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config defined PLATFORM_SUPPORT_SINT64_UINT64 && VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON + * \pre The parameters 'value' has to be greater than zero (contains at least one set bit). + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetHighestBitPosOneInEightBytes(uint64 value); + +/********************************************************************************************************************** + * VStdLib_Loc_GetLowestBitPosOneInEightBytes() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of a set bit in the specified eight byte value. + * \details - + * \param[in] value The eight byte value in which the lowest set bit shall be found. + * \return 0-63 Bit position of the lowest set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config defined PLATFORM_SUPPORT_SINT64_UINT64 && VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON + * \pre The parameters 'value' has to be smaller than its maximum value (contains at least one unset bit). + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetLowestBitPosOneInEightBytes(uint64 value); + +#endif /* (defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) */ + +/********************************************************************************************************************** + * LOCAL FUNCTIONS + *********************************************************************************************************************/ + +#if (VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_Loc_GetMemCmpNeqResult() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(sint8, VSTDLIB_CODE) VStdLib_Loc_GetMemCmpNeqResult(uint32 buf1Value, uint32 buf2Value) +{ + /* ----- Local Variables ---------------------------------------------- */ + sint8 result; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Set result depending, if buffer1 value is greater or smaller than buffer2 value */ + if (buf1Value > buf2Value) + { + result = VSTDLIB_MEM_CMP_RES_G; + } + else /* (buf1Value < buf2Value) */ + { + result = VSTDLIB_MEM_CMP_RES_L; + } + + return result; +} + +/********************************************************************************************************************** + * VStdLib_Loc_MemCmp_8() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(sint8, VSTDLIB_CODE) VStdLib_Loc_MemCmp_8( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf1_8, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf2_8, + uint32_least nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32_least pos; + sint8 result = VSTDLIB_MEM_CMP_RES_EQ; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Linearly compare buffers byte-wise in a loop */ + for (pos = 0u; pos < nCnt; pos++) /* FETA_VSTDLIB_LOC_MEMCMP_X_X */ + { + /* #110 If current buffer values are unequal */ + if (pBuf1_8[pos] != pBuf2_8[pos]) + { + /* #120 Set corresponding result value and break the comparison */ + result = VStdLib_Loc_GetMemCmpNeqResult((uint32)pBuf1_8[pos], (uint32)pBuf2_8[pos]); + break; + } + } + + return result; +} + +# if (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON) + +/********************************************************************************************************************** + * VStdLib_Loc_MemSet_8_3() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemSet_8_3( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + uint8 nPattern, + uint8_least nCnt) +{ + /* ----- Implementation ----------------------------------------------- */ +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #10 Initialize up to 3 bytes using a jump table */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (nCnt) + { + case 3: + pDst8[2] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 2: + pDst8[1] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 1: + pDst8[0] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + default: + /* nothing to do */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + uint8_least idx; + + /* #20 Linearly initialize the bytes using a loop */ + for (idx = 0u; idx < nCnt; idx++) /* FETA_VSTDLIB_LOC_MEMSET_X_X */ + { + pDst8[idx] = nPattern; /* SBSW_VSTDLIB_ACCESS_LOOP */ + } + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} /* VStdLib_Loc_MemSet_8_3() */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemSet_8_31() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6030 1 */ /* MD_VStdLib_Metrics */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemSet_8_31( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + uint8 nPattern, + uint8_least nCnt) +{ + /* ----- Implementation ----------------------------------------------- */ +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #10 Initialize up to 31 bytes using a jump table */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (nCnt) + { + case 31: + pDst8[30] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 30: + pDst8[29] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 29: + pDst8[28] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 28: + pDst8[27] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 27: + pDst8[26] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 26: + pDst8[25] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 25: + pDst8[24] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 24: + pDst8[23] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 23: + pDst8[22] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 22: + pDst8[21] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 21: + pDst8[20] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 20: + pDst8[19] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 19: + pDst8[18] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 18: + pDst8[17] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 17: + pDst8[16] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 16: + pDst8[15] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 15: + pDst8[14] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 14: + pDst8[13] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 13: + pDst8[12] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 12: + pDst8[11] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 11: + pDst8[10] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 10: + pDst8[9] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 9: + pDst8[8] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 8: + pDst8[7] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 7: + pDst8[6] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 6: + pDst8[5] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 5: + pDst8[4] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 4: + pDst8[3] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 3: + pDst8[2] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 2: + pDst8[1] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 1: + pDst8[0] = nPattern; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + default: + /* nothing to do */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + uint8_least idx; + + /* #20 Linearly initialize the bytes using a loop */ + for (idx = 0u; idx < nCnt; idx++) /* FETA_VSTDLIB_LOC_MEMSET_X_X */ + { + pDst8[idx] = nPattern; /* SBSW_VSTDLIB_ACCESS_LOOP */ + } + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} /* VStdLib_Loc_MemSet_8_31() */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemSet_32_Aligned() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemSet_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + uint8 nPattern, + uint32_least nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32_least dPos = 0u; + uint32_least remaining; + uint32 nPattern32 = + (uint32)(((uint32)nPattern << 24u) | ((uint32)nPattern << 16u) | ((uint32)nPattern << 8u) | nPattern); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Linearly initialize 16-byte blocks using 32-bit accesses in a loop */ + for (remaining = nCnt; remaining >= 16u; remaining -= 16u) /* FETA_VSTDLIB_LOC_MEMSET_X_X */ + { + pDst32[dPos] = nPattern32; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 1u] = nPattern32; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 2u] = nPattern32; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 3u] = nPattern32; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + dPos += 4u; + } + +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #20 Initialize the remaining block using a jump table */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (remaining) + { + /* #30 Use 32-bit access for remaining four byte tuples */ + case 15: + case 14: + case 13: + case 12: + pDst32[dPos] = nPattern32; /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + dPos++; + /* intentionally no break */ + case 11: + case 10: + case 9: + case 8: + pDst32[dPos] = nPattern32; /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + dPos++; + /* intentionally no break */ + case 7: + case 6: + case 5: + case 4: + pDst32[dPos] = nPattern32; /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + dPos++; + /* intentionally no break */ + case 3: + case 2: + case 1: + /* #40 Use 8-bit access for remaining three bytes */ + VStdLib_Loc_MemSet_8_3( /* SBSW_VSTDLIB_CALL_REMAINING_JUMPTABLE */ /* FETA_VSTDLIB_CALL_LOC_MEMSET_8_X_REMAINING */ + (P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pDst32[dPos], + nPattern, + (uint8_least) (remaining & VSTDLIB_MASK_3)); + /* intentionally no break */ + default: + /* nothing to do */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + /* #50 Initialize the remaining block using a byte-wise algorithm */ + VStdLib_Loc_MemSet_8_31( /* SBSW_VSTDLIB_CALL_REMAINING */ /* FETA_VSTDLIB_CALL_LOC_MEMSET_8_X_REMAINING */ + (P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pDst32[dPos], + nPattern, + (uint8_least) remaining); + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} /* VStdLib_Loc_MemSet_32_Aligned() */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpy_8_3() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpy_8_3( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt) +{ + /* ----- Implementation ----------------------------------------------- */ +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #10 Copy up to 3 bytes using a jump table */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (nCnt) + { + case 3: + pDst8[2] = pSrc8[2]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 2: + pDst8[1] = pSrc8[1]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 1: + pDst8[0] = pSrc8[0]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + default: + /* nothing to do */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + uint8_least idx; + + /* #20 Linearly copy the bytes using a loop */ + for (idx = 0u; idx < nCnt; idx++) /* FETA_VSTDLIB_LOC_MEMCPY_X_X */ + { + pDst8[idx] = pSrc8[idx]; /* SBSW_VSTDLIB_ACCESS_LOOP */ + } + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} /* VStdLib_Loc_MemCpy_8_3() */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpy_8_31() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6030 1 */ /* MD_VStdLib_Metrics */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpy_8_31( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt) +{ + /* ----- Implementation ----------------------------------------------- */ +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #10 Copy up to 31 bytes using a jump table */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (nCnt) + { + case 31: + pDst8[30] = pSrc8[30]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 30: + pDst8[29] = pSrc8[29]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 29: + pDst8[28] = pSrc8[28]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 28: + pDst8[27] = pSrc8[27]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 27: + pDst8[26] = pSrc8[26]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 26: + pDst8[25] = pSrc8[25]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 25: + pDst8[24] = pSrc8[24]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 24: + pDst8[23] = pSrc8[23]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 23: + pDst8[22] = pSrc8[22]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 22: + pDst8[21] = pSrc8[21]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 21: + pDst8[20] = pSrc8[20]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 20: + pDst8[19] = pSrc8[19]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 19: + pDst8[18] = pSrc8[18]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 18: + pDst8[17] = pSrc8[17]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 17: + pDst8[16] = pSrc8[16]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 16: + pDst8[15] = pSrc8[15]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 15: + pDst8[14] = pSrc8[14]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 14: + pDst8[13] = pSrc8[13]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 13: + pDst8[12] = pSrc8[12]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 12: + pDst8[11] = pSrc8[11]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 11: + pDst8[10] = pSrc8[10]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 10: + pDst8[9] = pSrc8[9]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 9: + pDst8[8] = pSrc8[8]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 8: + pDst8[7] = pSrc8[7]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 7: + pDst8[6] = pSrc8[6]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 6: + pDst8[5] = pSrc8[5]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 5: + pDst8[4] = pSrc8[4]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 4: + pDst8[3] = pSrc8[3]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 3: + pDst8[2] = pSrc8[2]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 2: + pDst8[1] = pSrc8[1]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + case 1: + pDst8[0] = pSrc8[0]; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + /* intentionally no break */ + default: + /* nothing to do */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + uint8_least idx; + + /* #20 Linearly copy the bytes using a loop */ + for (idx = 0u; idx < nCnt; idx++) /* FETA_VSTDLIB_LOC_MEMCPY_X_X */ + { + pDst8[idx] = pSrc8[idx]; /* SBSW_VSTDLIB_ACCESS_LOOP */ + } + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} /* VStdLib_Loc_MemCpy_8_31() */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpy_32_Aligned() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpy_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32_least dPos = 0u; /* == sPos */ + uint32_least remaining; + uint32 x0, x1, x2, x3; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Linearly copy 16-byte blocks using 32-bit accesses in a loop */ + for (remaining = nCnt; remaining >= 16u; remaining -= 16u) /* FETA_VSTDLIB_LOC_MEMCPY_X_X */ + { + x0 = pSrc32[dPos]; + x1 = pSrc32[dPos + 1u]; + x2 = pSrc32[dPos + 2u]; + x3 = pSrc32[dPos + 3u]; + pDst32[dPos] = x0; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 1u] = x1; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 2u] = x2; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 3u] = x3; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + dPos += 4u; + } + +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #20 Copy the remaining block using a jump table */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (remaining) + { + /* #30 Use 32-bit access for remaining four byte tuples */ + case 15: + case 14: + case 13: + case 12: + pDst32[dPos] = pSrc32[dPos]; /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + dPos++; + /* intentionally no break */ + case 11: + case 10: + case 9: + case 8: + pDst32[dPos] = pSrc32[dPos]; /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + dPos++; + /* intentionally no break */ + case 7: + case 6: + case 5: + case 4: + pDst32[dPos] = pSrc32[dPos]; /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + dPos++; + /* intentionally no break */ + case 3: + case 2: + case 1: + /* #40 Use 8-bit access for remaining three bytes */ + VStdLib_Loc_MemCpy_8_3( /* SBSW_VSTDLIB_CALL_REMAINING_JUMPTABLE */ /* FETA_VSTDLIB_CALL_LOC_MEMCPY_8_X_REMAINING */ + (P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pDst32[dPos], + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pSrc32[dPos], + (uint8_least) (remaining & VSTDLIB_MASK_3)); + /* intentionally no break */ + default: + /* nothing to do */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + /* #50 Copy the remaining block using a byte-wise algorithm */ + VStdLib_Loc_MemCpy_8_31( /* SBSW_VSTDLIB_CALL_REMAINING */ /* FETA_VSTDLIB_CALL_LOC_MEMCPY_8_X_REMAINING */ + (P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pDst32[dPos], + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pSrc32[dPos], + (uint8_least) remaining); + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} /* VStdLib_Loc_MemCpy_32_Aligned() */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpy_8_PartialWord() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpy_8_PartialWord( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + uint8_least nCnt, + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pPrev, + P2VAR(uint32_least, AUTOMATIC, VSTDLIB_VAR_FAR) pDPos) +{ + /* ----- Implementation ----------------------------------------------- */ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #10 Copy 1 to 3 bytes using a jump table and adapt '*pDPos' and '*pPrev' for little endian byte order */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (nCnt) + { + case 3: + pDst8[*pDPos] = (uint8) *pPrev; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + (*pDPos)++; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + (*pPrev) >>= 8u; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + /* intentionally no break */ + case 2: + pDst8[*pDPos] = (uint8) *pPrev; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + (*pDPos)++; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + (*pPrev) >>= 8u; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + /* intentionally no break */ + default: /* case 1 - nCnt is always in range [1..3] */ + pDst8[*pDPos] = (uint8) *pPrev; /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + (*pDPos)++; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + (*pPrev) >>= 8u; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + uint8_least idx; + + /* #20 Linearly copy the bytes using a loop and adapt '*pDPos' and '*pPrev' for little endian byte order */ + for (idx = 0u; idx < nCnt; idx++) /* FETA_VSTDLIB_LOC_MEMCPY_X_X */ + { + pDst8[*pDPos] = (uint8) (uint8) *pPrev; /* SBSW_VSTDLIB_ACCESS_LOOP */ + (*pDPos)++; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + (*pPrev) >>= 8u; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + } + +# endif /* VSTDLIB_USE_JUMPTABLES */ +# else /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #30 Copy 1 to 3 bytes using a jump table and adapt '*pDPos' and '*pPrev' for big endian byte order */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (nCnt) + { + case 3: + pDst8[*pDPos] = (uint8) ((*pPrev) >> 24u); /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + (*pDPos)++; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + (*pPrev) <<= 8u; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + /* intentionally no break */ + case 2: + pDst8[*pDPos] = (uint8) ((*pPrev) >> 24u); /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + (*pDPos)++; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + (*pPrev) <<= 8u; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + /* intentionally no break */ + default: /* case 1 - nCnt is always in range [1..3] */ + pDst8[*pDPos] = (uint8) ((*pPrev) >> 24u); /* SBSW_VSTDLIB_ACCESS_8_JUMPTABLE */ + (*pDPos)++; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + (*pPrev) <<= 8u; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + uint8_least idx; + + /* #40 Linearly copy the bytes using a loop and adapt '*pDPos' and '*pPrev' for big endian byte order */ + for (idx = 0u; idx < nCnt; idx++) /* FETA_VSTDLIB_LOC_MEMCPY_X_X */ + { + pDst8[*pDPos] = (uint8) ((*pPrev) >> 24u); /* SBSW_VSTDLIB_ACCESS_LOOP */ + (*pDPos)++; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + (*pPrev) <<= 8u; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + } + +# endif /* VSTDLIB_USE_JUMPTABLES */ +# endif /* CPU_BYTE_ORDER */ +} /* VStdLib_Loc_MemCpy_8_PartialWord() */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpy_32_Unaligned() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpy_32_Unaligned( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt, + uint8_least nDstOffset) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32_least dPos = 0u; + uint32_least sPos = 0u; + uint32_least remaining = nCnt; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 If more than 32 bytes have to be copied */ + if (remaining >= 32u) + { + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32; + uint32 prev; + + /* #20 Copy the first partial word to reach the 32-bit boundary and adjust the destination pointer */ + prev = pSrc32[sPos]; + remaining -= 4u; + VStdLib_Loc_MemCpy_8_PartialWord( /* SBSW_VSTDLIB_CALL_MODIFIED_CNT */ /* FETA_VSTDLIB_CALL_LOC_MEMCPY_8_PARTIALWORD */ + pDst8, + nDstOffset, + &prev, + &dPos); + + /* At this point 'pDst8[dPos]' is aligned to a 32-bit boundary */ + pDst32 = (P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) &pDst8[dPos]; /* PRQA S 0310, 3305 */ /* MD_VStdLib_PtrCast */ + dPos = 0u; + sPos++; + + /* #30 Linearly copy 16-byte blocks using 32-bit accesses by correcting the byte displacement of dst and src */ + if (nDstOffset == 3u) /* 24-bit displacement */ + { + for (; remaining >= 16u; remaining -= 16u) /* FETA_VSTDLIB_LOC_MEMCPY_32_UNALIGNED */ + { + uint32 x0, x1, x2, x3, x4; + x1 = pSrc32[sPos]; + x2 = pSrc32[sPos + 1u]; + x3 = pSrc32[sPos + 2u]; + x4 = pSrc32[sPos + 3u]; +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + x0 = prev | (x1 << 8u); + x1 = (x1 >> 24u) | (x2 << 8u); + x2 = (x2 >> 24u) | (x3 << 8u); + x3 = (x3 >> 24u) | (x4 << 8u); + prev = x4 >> 24u; +# else /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + x0 = prev | (x1 >> 8u); + x1 = (x1 << 24u) | (x2 >> 8u); + x2 = (x2 << 24u) | (x3 >> 8u); + x3 = (x3 << 24u) | (x4 >> 8u); + prev = x4 << 24; +# endif /* CPU_BYTE_ORDER */ + pDst32[dPos] = x0; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 1u] = x1; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 2u] = x2; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 3u] = x3; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + dPos += 4u; + sPos += 4u; + } + } + else if (nDstOffset == 2u) /* 16-bit displacement */ + { + for (; remaining >= 16u; remaining -= 16u) /* FETA_VSTDLIB_LOC_MEMCPY_32_UNALIGNED */ + { + uint32 x0, x1, x2, x3, x4; + x1 = pSrc32[sPos]; + x2 = pSrc32[sPos + 1u]; + x3 = pSrc32[sPos + 2u]; + x4 = pSrc32[sPos + 3u]; +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + x0 = prev | (x1 << 16u); + x1 = (x1 >> 16u) | (x2 << 16u); + x2 = (x2 >> 16u) | (x3 << 16u); + x3 = (x3 >> 16u) | (x4 << 16u); + prev = x4 >> 16u; +# else /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + x0 = prev | (x1 >> 16); + x1 = (x1 << 16u) | (x2 >> 16u); + x2 = (x2 << 16u) | (x3 >> 16u); + x3 = (x3 << 16u) | (x4 >> 16u); + prev = x4 << 16; +# endif /* CPU_BYTE_ORDER */ + pDst32[dPos] = x0; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 1u] = x1; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 2u] = x2; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 3u] = x3; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + dPos += 4u; + sPos += 4u; + } + + } + else /* nDstOffset == 1 - 8-bit displacement */ + { + for (; remaining >= 16u; remaining -= 16u) /* FETA_VSTDLIB_LOC_MEMCPY_32_UNALIGNED */ + { + uint32 x0, x1, x2, x3, x4; + x1 = pSrc32[sPos]; + x2 = pSrc32[sPos + 1u]; + x3 = pSrc32[sPos + 2u]; + x4 = pSrc32[sPos + 3u]; +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + x0 = prev | (x1 << 24u); + x1 = (x1 >> 8u) | (x2 << 24u); + x2 = (x2 >> 8u) | (x3 << 24u); + x3 = (x3 >> 8u) | (x4 << 24u); + prev = x4 >> 8u; +# else /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + x0 = prev | (x1 >> 24u); + x1 = (x1 << 8u) | (x2 >> 24u); + x2 = (x2 << 8u) | (x3 >> 24u); + x3 = (x3 << 8u) | (x4 >> 24u); + prev = x4 << 8u; +# endif /* CPU_BYTE_ORDER */ + pDst32[dPos] = x0; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 1u] = x1; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 2u] = x2; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 3u] = x3; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + dPos += 4u; + sPos += 4u; + } + } + + /* #40 Linearly copy the remaining words using a loop */ + { + uint8_least prevShift = (uint8_least) ((nDstOffset << 3u) & VSTDLIB_MASK_31); + uint8_least xShift = 32u - prevShift; + /* At this point remaining is < 16 byte */ + for (; remaining >= 4u; remaining -= 4u) /* FETA_VSTDLIB_LOC_MEMCPY_32_UNALIGNED */ + { + uint32 x0, x1; + x1 = pSrc32[sPos]; +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + x0 = prev | (x1 << xShift); + prev = x1 >> prevShift; +# else /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + x0 = prev | (x1 >> xShift); + prev = x1 << prevShift; +# endif /* CPU_BYTE_ORDER */ + pDst32[dPos] = x0; /* SBSW_VSTDLIB_ACCESS_32_LOOP_REMAINING */ + dPos++; + sPos++; + } + } + + /* #50 Copy the remaining partial word using a byte-wise algorithm */ + pDst8 = (P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pDst32[dPos]; /* PRQA S 1338 */ /* MD_VStdLib_ParamMod */ + dPos = 0u; + VStdLib_Loc_MemCpy_8_PartialWord( /* SBSW_VSTDLIB_CALL_REMAINING_PARTIAL */ /* FETA_VSTDLIB_CALL_LOC_MEMCPY_8_PARTIALWORD_CALC */ + pDst8, + (4u - nDstOffset), + &prev, + &dPos); + } + + /* #60 Copy the remaining bytes using a byte-wise algorithm */ + VStdLib_Loc_MemCpy_8_31( /* SBSW_VSTDLIB_CALL_REMAINING */ /* FETA_VSTDLIB_CALL_LOC_MEMCPY_8_31_REMAINING */ + &pDst8[dPos], + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pSrc32[sPos], + (uint8_least) remaining); +} /* VStdLib_Loc_MemCpy_32_Unaligned() */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCmp_32_Aligned() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(sint8, VSTDLIB_CODE) VStdLib_Loc_MemCmp_32_Aligned( + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf1_32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf2_32, + uint32_least nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32_least pos = 0u; + uint32_least remaining = nCnt; + sint8 result = VSTDLIB_MEM_CMP_RES_EQ; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Linearly compare buffers 4-bytes-wise using 32-bit accesses in a loop */ + for (; remaining >= 4u; remaining -= 4u) /* FETA_VSTDLIB_LOC_MEMCMP_X_X */ + { + /* #110 If current buffer values are unequal */ + if (pBuf1_32[pos] != pBuf2_32[pos]) + { + /* #120 Set corresponding result value and break the comparison */ + result = VStdLib_Loc_GetMemCmpNeqResult(pBuf1_32[pos], pBuf2_32[pos]); + break; + } + pos++; + } + + /* #130 If the buffers are still equal */ + if (result == VSTDLIB_MEM_CMP_RES_EQ) + { + /* #140 Compare the remaining bytes using byte-wise memcmp */ + result = VStdLib_Loc_MemCmp_8( /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCMP_8_ALIGNED_REMAINING */ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pBuf1_32[pos], + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pBuf2_32[pos], + remaining); + } + + return result; +} + +/********************************************************************************************************************** + * VStdLib_Loc_MemCmp_32_Unaligned() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(sint8, VSTDLIB_CODE) VStdLib_Loc_MemCmp_32_Unaligned( + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf1_32, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf2_8, + uint32_least nCnt, + uint8_least nBuf2Offset) +{ + /* ----- Local Variables ---------------------------------------------- */ + sint8 result; + + /* ----- Implementation ----------------------------------------------- */ + + /* #100 Compare the first bytes to reach the 32-bit boundary for buffer2 */ + result = VStdLib_Loc_MemCmp_8((P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR))&pBuf1_32[0u], /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCMP_8_NBUF2OFFSET */ + pBuf2_8, nBuf2Offset); + + /* #110 If buffers are still equal */ + if (result == VSTDLIB_MEM_CMP_RES_EQ) + { + /* #120 Adjust pointer for buffer2 */ + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf2_32 = \ + (P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR))&pBuf2_8[nBuf2Offset]; /* PRQA S 0310, 3305 */ /* MD_VStdLib_PtrCast */ + uint32_least buf1Pos = 1u; /* 32-bit value at position 0 was already used in comparison above */ + uint32_least buf2Pos = 0u; /* First 32-bit value in 32 bit aligned buffer2 */ + uint32_least remaining = nCnt - 4u; /* 4 bytes were already used in comparison above (not compared bytes will be stored in 'prev') */ + + /* #130 Determine byte displacement properties for the 4-byte-wise comparison */ + + /* Calculate byte displacement dependent shift values */ + uint8_least prevShift = (uint8_least) ((nBuf2Offset << 3u) & VSTDLIB_MASK_31); + uint8_least xShift = 32u - prevShift; + + /* Save the not compared bytes, because of byte displacement */ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + uint32 prev = pBuf1_32[0u] >> prevShift; +# else /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + uint32 prev = pBuf1_32[0u] << prevShift; +# endif + + /* #140 Linearly compare buffers 4-byte-wise using 32-bit accesses in a loop by correcting the byte displacement of buffer1 and buffer2 */ + for (; remaining >= 4u; remaining -= 4u) /* FETA_VSTDLIB_LOC_MEMCMP_32_UNALIGNED */ + { + uint32 x0, x1; + x1 = pBuf1_32[buf1Pos]; /* Save current 32-bit value */ + + /* Compare value: not compared bytes from previous comparison 'prev' plus bytes from current 32-bit value */ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + x0 = prev | (x1 << xShift); +# else /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + x0 = prev | (x1 >> xShift); +# endif + + /* #150 If current buffer values are unequal */ + if (x0 != pBuf2_32[buf2Pos]) + { + /* #160 Set corresponding result value and break the comparison */ + result = VStdLib_Loc_GetMemCmpNeqResult(x0, pBuf2_32[buf2Pos]); + break; + } + else + { + buf1Pos++; + buf2Pos++; + + /* Save the not compared bytes, because of byte displacement */ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + prev = x1 >> prevShift; +# else /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + prev = x1 << prevShift; +# endif + } + } + + /* #170 If the buffers are still equal */ + if (result == VSTDLIB_MEM_CMP_RES_EQ) + { + /* #180 Compare the remaining bytes from the byte displacement correction using byte-wise memcmp */ + /* At this point (4 - nBuf2Offset) bytes of buffer2 are not compared, which are contained in 'prev' from buffer1 */ + pBuf2_8 = (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR))&pBuf2_32[buf2Pos]; /* PRQA S 1338 */ /* MD_VStdLib_ParamMod */ + result = VStdLib_Loc_MemCmp_8((P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR))&prev, /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCMP_8_CALC */ + pBuf2_8, (4u - (uint32_least)nBuf2Offset)); + } + + /* #190 If the buffers are still equal */ + /* After the last 32-bit alignment of buffer1, there may be 0 to 3 bytes that were not compared by the 4-byte-wise comparison */ + if (result == VSTDLIB_MEM_CMP_RES_EQ) + { + /* #200 Compare the remaining bytes using byte-wise memcmp */ + result = VStdLib_Loc_MemCmp_8( /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCMP_8_UNALIGNED_REMAINING */ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pBuf1_32[buf1Pos], /* First byte after last 32-bit alignment */ + &pBuf2_8[(4u - nBuf2Offset)], /* First byte after 'prev' comparison */ + remaining); + } + } + + return result; +} + +# endif /* VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON */ +#endif /* VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON */ + + +#if (VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON) +# if (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON) + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian_IntType_32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian_IntType_32( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt, + uint8 intType) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Execute integer type dependent copying and swapping */ + switch (intType) + { + case VSTDLIB_INTTYPE_16: + VStdLib_Loc_MemCpySwapEndian_Int16_32( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INTX_X */ + (P2VAR(uint16, AUTOMATIC, VSTDLIB_VAR_FAR))pDst, /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + pSrc8, + nCnt); + break; + + case VSTDLIB_INTTYPE_32: + VStdLib_Loc_MemCpySwapEndian_Int32_32( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INTX_X */ + (P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR))pDst, /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + pSrc8, + nCnt); + break; + +# if defined (PLATFORM_SUPPORT_SINT64_UINT64) + case VSTDLIB_INTTYPE_64: + VStdLib_Loc_MemCpySwapEndian_Int64_32( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INTX_X */ + (P2VAR(uint64, AUTOMATIC, VSTDLIB_VAR_FAR))pDst, /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + pSrc8, + nCnt); + break; +# endif + + default: + /* #20 Do not copy and swap for any unsupported intType */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + errorId = VSTDLIB_E_PARAM_INTTYPE; +# endif + break; + } + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_COPY_SWAP_ENDIAN, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} /* VStdLib_Loc_MemCpySwapEndian_8_32() */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian_Int16_32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +/* PRQA S 6030 1 */ /* MD_VStdLib_Metrics */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian_Int16_32( + P2VAR(uint16, AUTOMATIC, VSTDLIB_VAR_FAR) pDst16, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt) +{ + /* ----- Implementation ----------------------------------------------- */ +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #10 Copy and swap up to 32 bytes using a jump table */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (nCnt) + { + case 32: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[30], &pDst16[15]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 30: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[28], &pDst16[14]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 28: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[26], &pDst16[13]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 26: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[24], &pDst16[12]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 24: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[22], &pDst16[11]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 22: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[20], &pDst16[10]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 20: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[18], &pDst16[9]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 18: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[16], &pDst16[8]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 16: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[14], &pDst16[7]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 14: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[12], &pDst16[6]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 12: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[10], &pDst16[5]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 10: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[8], &pDst16[4]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 8: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[6], &pDst16[3]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 6: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[4], &pDst16[2]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 4: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[2], &pDst16[1]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 2: + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[0], &pDst16[0]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + default: + /* nothing to do */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + uint8_least idxSrc, idxDst = 0u; + + /* #20 Linearly copy and swap the bytes using a loop */ + for (idxSrc = 0u; idxSrc < nCnt; idxSrc += 2u) /* FETA_VSTDLIB_LOC_MEMCPYSWAPENDIAN_X_X */ + { + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian(&pSrc8[idxSrc], &pDst16[idxDst]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + idxDst++; + } + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} /* VStdLib_Loc_MemCpySwapEndian_Int16_32() */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian_Int32_32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian_Int32_32( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt) +{ + /* ----- Implementation ----------------------------------------------- */ +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #10 Copy and swap up to 32 bytes using a jump table */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (nCnt) + { + case 32: + VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian(&pSrc8[28], &pDst32[7]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 28: + VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian(&pSrc8[24], &pDst32[6]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 24: + VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian(&pSrc8[20], &pDst32[5]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 20: + VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian(&pSrc8[16], &pDst32[4]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 16: + VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian(&pSrc8[12], &pDst32[3]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 12: + VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian(&pSrc8[8], &pDst32[2]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 8: + VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian(&pSrc8[4], &pDst32[1]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 4: + VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian(&pSrc8[0], &pDst32[0]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + default: + /* nothing to do */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + uint8_least idxSrc, idxDst = 0u; + + /* #20 Linearly copy and swap the bytes using a loop */ + for (idxSrc = 0u; idxSrc < nCnt; idxSrc += 4u) /* FETA_VSTDLIB_LOC_MEMCPYSWAPENDIAN_X_X */ + { + VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian(&pSrc8[idxSrc], &pDst32[idxDst]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + idxDst++; + } + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} /* VStdLib_Loc_MemCpySwapEndian_Int32_32() */ + +# if defined (PLATFORM_SUPPORT_SINT64_UINT64) + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian_Int64_32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian_Int64_32( + P2VAR(uint64, AUTOMATIC, VSTDLIB_VAR_FAR) pDst64, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint8_least nCnt) +{ + /* ----- Implementation ----------------------------------------------- */ +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #10 Copy and swap up to 32 bytes using a jump table */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (nCnt) + { + case 32: + VStdLib_Loc_ConvertUint8ArrayToUint64SwapEndian(&pSrc8[24], &pDst64[3]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 24: + VStdLib_Loc_ConvertUint8ArrayToUint64SwapEndian(&pSrc8[16], &pDst64[2]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 16: + VStdLib_Loc_ConvertUint8ArrayToUint64SwapEndian(&pSrc8[8], &pDst64[1]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + case 8: + VStdLib_Loc_ConvertUint8ArrayToUint64SwapEndian(&pSrc8[0], &pDst64[0]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + /* intentionally no break */ + default: + /* nothing to do */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + uint8_least idxSrc, idxDst = 0u; + + /* #20 Linearly copy and swap the bytes using a loop */ + for (idxSrc = 0u; idxSrc < nCnt; idxSrc += 8u) /* FETA_VSTDLIB_LOC_MEMCPYSWAPENDIAN_X_X */ + { + VStdLib_Loc_ConvertUint8ArrayToUint64SwapEndian(&pSrc8[idxSrc], &pDst64[idxDst]); /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + idxDst++; + } + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} /* VStdLib_Loc_MemCpySwapEndianInt64_8_32() */ + +# endif /* defined PLATFORM_SUPPORT_SINT64_UINT64 */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian_32_Aligned() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt, + uint8 intType) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Execute integer type dependent copying and swapping */ + switch (intType) + { + case VSTDLIB_INTTYPE_16: + VStdLib_Loc_MemCpySwapEndianInt16_32_Aligned(pDst32, pSrc32, nCnt); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INTX_X */ + break; + + case VSTDLIB_INTTYPE_32: + VStdLib_Loc_MemCpySwapEndianInt32_32_Aligned(pDst32, pSrc32, nCnt); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INTX_X */ + break; + +# if defined (PLATFORM_SUPPORT_SINT64_UINT64) + case VSTDLIB_INTTYPE_64: + VStdLib_Loc_MemCpySwapEndianInt64_32_Aligned(pDst32, pSrc32, nCnt); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INTX_X */ + break; +# endif + + default: + /* #20 Do not copy and swap for any unsupported intType */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + errorId = VSTDLIB_E_PARAM_INTTYPE; +# endif + break; + } + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_COPY_SWAP_ENDIAN, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} /* VStdLib_Loc_MemCpySwapEndian_32_Aligned() */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndianInt16_32_Aligned() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndianInt16_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32_least dPos = 0u; /* == sPos */ + uint32_least remaining; + uint32 x0, x1, x2, x3; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Linearly copy and swap 16-byte blocks using 32-bit accesses in a loop */ + for (remaining = nCnt; remaining >= 16u; remaining -= 16u) /* FETA_VSTDLIB_LOC_MEMCPYSWAPENDIAN_X_X */ + { + x0 = VStdLib_Loc_SwapEndianInt16_32(pSrc32[dPos]); + x1 = VStdLib_Loc_SwapEndianInt16_32(pSrc32[dPos + 1u]); + x2 = VStdLib_Loc_SwapEndianInt16_32(pSrc32[dPos + 2u]); + x3 = VStdLib_Loc_SwapEndianInt16_32(pSrc32[dPos + 3u]); + pDst32[dPos] = x0; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 1u] = x1; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 2u] = x2; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 3u] = x3; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + dPos += 4u; + } + +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #20 Copy and swap the remaining block using a jump table */ + /* Only a multiple of VSTDLIB_INTTYPE_16 is possible (precondition) - remaining count can be only 14, 12, 10, 8, 6, 4, 2 or 0 here */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (remaining) + { + case 12: + pDst32[dPos] = VStdLib_Loc_SwapEndianInt16_32(pSrc32[dPos]); /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + dPos++; + /* intentionally no break */ + case 8: + pDst32[dPos] = VStdLib_Loc_SwapEndianInt16_32(pSrc32[dPos]); /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + dPos++; + /* intentionally no break */ + case 4: + pDst32[dPos] = VStdLib_Loc_SwapEndianInt16_32(pSrc32[dPos]); /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + break; + default: /* case 14, 10, 6, 2, 0 - 32-bit access too complex due to the next two 16-bit values are shared over two different 32-bit source values */ + /* Destination is also expected to be 16-bit aligned as described in precondition */ + VStdLib_Loc_MemCpySwapEndian_Int16_32( /* SBSW_VSTDLIB_CALL_REMAINING */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INT16_32_REMAINING */ + (P2VAR(uint16, AUTOMATIC, VSTDLIB_VAR_FAR)) &pDst32[dPos], /* PRQA S 0310 */ /* MD_VStdLib_PtrCast */ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pSrc32[dPos], + (uint8_least) remaining); + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + /* #30 Copy and swap the remaining block using a 16-bit-wise algorithm */ + /* Destination is also expected to be 16-bit aligned as described in precondition */ + VStdLib_Loc_MemCpySwapEndian_Int16_32( /* SBSW_VSTDLIB_CALL_REMAINING */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INT16_32_REMAINING */ + (P2VAR(uint16, AUTOMATIC, VSTDLIB_VAR_FAR)) &pDst32[dPos], /* PRQA S 0310 */ /* MD_VStdLib_PtrCast */ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pSrc32[dPos], + (uint8_least) remaining); + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} /* VStdLib_Loc_MemCpySwapEndianInt16_32_Aligned */ + +/********************************************************************************************************************** + * VStdLib_Loc_SwapEndianInt16_32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint32, VSTDLIB_CODE) VStdLib_Loc_SwapEndianInt16_32(uint32 src32) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32 dst; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Swap endianness of two 16-bit values in a 32-bit value */ + dst = VStdLib_SwapEndianUint16((uint16)((src32 & VSTDLIB_MASK_UPPER_TWO_BYTES) >> 16u)); + dst = ((uint32)dst << 16u) | (uint32)VStdLib_SwapEndianUint16((uint16)(src32 & VSTDLIB_MASK_LOWER_TWO_BYTES)); + + return dst; +} /* VStdLib_Loc_SwapEndianInt16_32 */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndianInt32_32_Aligned() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndianInt32_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32_least dPos = 0u; /* == sPos */ + uint32_least remaining; + uint32 x0, x1, x2, x3; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Linearly copy and swap 16-byte blocks using 32-bit accesses in a loop */ + for (remaining = nCnt; remaining >= 16u; remaining -= 16u) /* FETA_VSTDLIB_LOC_MEMCPYSWAPENDIAN_X_X */ + { + x0 = VStdLib_SwapEndianUint32(pSrc32[dPos]); + x1 = VStdLib_SwapEndianUint32(pSrc32[dPos + 1u]); + x2 = VStdLib_SwapEndianUint32(pSrc32[dPos + 2u]); + x3 = VStdLib_SwapEndianUint32(pSrc32[dPos + 3u]); + pDst32[dPos] = x0; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 1u] = x1; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 2u] = x2; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 3u] = x3; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + dPos += 4u; + } + +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #20 Copy and swap the remaining block using a jump table */ + /* Only a multiple of VSTDLIB_INTTYPE_32 is possible (precondition) - remaining count can be only 12, 8, 4 or 0 here */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (remaining) + { + case 12: + pDst32[dPos] = VStdLib_SwapEndianUint32(pSrc32[dPos]); /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + dPos++; + /* intentionally no break */ + case 8: + pDst32[dPos] = VStdLib_SwapEndianUint32(pSrc32[dPos]); /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + dPos++; + /* intentionally no break */ + case 4: + pDst32[dPos] = VStdLib_SwapEndianUint32(pSrc32[dPos]); /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + /* intentionally no break */ + default: + /* nothing to do */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + /* #30 Copy and swap the remaining block using a 32-bit-wise algorithm */ + VStdLib_Loc_MemCpySwapEndian_Int32_32( /* SBSW_VSTDLIB_CALL_REMAINING */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INT32_32_REMAINING */ + &pDst32[dPos], + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pSrc32[dPos], + (uint8_least) remaining); + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} + +# if defined (PLATFORM_SUPPORT_SINT64_UINT64) + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndianInt64_32_Aligned() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndianInt64_32_Aligned( + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc32, + uint32_least nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32_least dPos = 0u; /* == sPos */ + uint32_least remaining; + uint32 x0, x1, x2, x3; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Linearly copy and swap 16-byte blocks using 32-bit accesses in a loop */ + for (remaining = nCnt; remaining >= 16u; remaining -= 16u) /* FETA_VSTDLIB_LOC_MEMCPYSWAPENDIAN_X_X */ + { + /* 64-bit value is shared over two 32-bit values - swap each 32-bit value and then the order of both values */ + /* 64-bit value */ + x1 = VStdLib_SwapEndianUint32(pSrc32[dPos]); + x0 = VStdLib_SwapEndianUint32(pSrc32[dPos + 1u]); + + /* 64-bit value */ + x3 = VStdLib_SwapEndianUint32(pSrc32[dPos + 2u]); + x2 = VStdLib_SwapEndianUint32(pSrc32[dPos + 3u]); + + pDst32[dPos] = x0; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 1u] = x1; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 2u] = x2; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + pDst32[dPos + 3u] = x3; /* SBSW_VSTDLIB_ACCESS_32_LOOP */ + dPos += 4u; + } + +# if (VSTDLIB_USE_JUMPTABLES == STD_ON) + + /* #20 Copy and swap the remaining block using a jump table */ + /* Only a multiple of VSTDLIB_INTTYPE_64 is possible (precondition) - remaining count can be only 8 or 0 here */ + /* PRQA S 2003 VSTDLIB_NO_CASE_BREAK */ /* MD_VStdLib_NoCaseBreak */ + switch (remaining) + { + case 8: + pDst32[dPos + 1u] = VStdLib_SwapEndianUint32(pSrc32[dPos]); /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + pDst32[dPos] = VStdLib_SwapEndianUint32(pSrc32[dPos + 1u]); /* SBSW_VSTDLIB_ACCESS_32_JUMPTABLE */ + /* intentionally no break */ + default: + /* nothing to do */ + break; + } + /* PRQA L:VSTDLIB_NO_CASE_BREAK */ + +# else /* VSTDLIB_USE_JUMPTABLES == STD_OFF */ + + /* #30 Copy and swap the remaining block using a 64-bit-wise algorithm */ + /* Destination is also expected to be 64-bit aligned as described in precondition */ + VStdLib_Loc_MemCpySwapEndian_Int64_32( /* SBSW_VSTDLIB_CALL_REMAINING */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INT64_32_REMAINING */ + (P2VAR(uint64, AUTOMATIC, VSTDLIB_VAR_FAR)) &pDst32[dPos], /* PRQA S 0310, 3305 */ /* MD_VStdLib_PtrCast */ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pSrc32[dPos], + (uint8_least) remaining); + +# endif /* VSTDLIB_USE_JUMPTABLES */ +} /* VStdLib_Loc_MemCpySwapEndianInt64_32_Aligned */ + +# endif /* defined PLATFORM_SUPPORT_SINT64_UINT64 */ +# endif /* VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON */ + +/********************************************************************************************************************** + * VStdLib_Loc_MemCpySwapEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_MemCpySwapEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + uint32_least nCnt, + uint8 intType) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint32_least idxSrc, idxDst = 0u; + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Linearly copy and swap nCnt bytes using a loop */ + switch (intType) + { + case VSTDLIB_INTTYPE_16: + { + P2VAR(uint16, AUTOMATIC, VSTDLIB_VAR_FAR) pDst16 = \ + (P2VAR(uint16, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + + for (idxSrc = 0u; idxSrc < nCnt; idxSrc += 2u) /* FETA_VSTDLIB_LOC_MEMCPYSWAPENDIAN_X_X */ + { + VStdLib_Loc_ConvertUint8ArrayToUint16SwapEndian( /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + &pSrc8[idxSrc], + &pDst16[idxDst]); + + idxDst++; + } + } + break; + + case VSTDLIB_INTTYPE_32: + { + P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst32 = \ + (P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + + for (idxSrc = 0u; idxSrc < nCnt; idxSrc += 4u) /* FETA_VSTDLIB_LOC_MEMCPYSWAPENDIAN_X_X */ + { + VStdLib_Loc_ConvertUint8ArrayToUint32SwapEndian( /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + &pSrc8[idxSrc], + &pDst32[idxDst]); + + idxDst++; + } + } + break; + +# if defined (PLATFORM_SUPPORT_SINT64_UINT64) + case VSTDLIB_INTTYPE_64: + { + P2VAR(uint64, AUTOMATIC, VSTDLIB_VAR_FAR) pDst64 = \ + (P2VAR(uint64, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + + for (idxSrc = 0u; idxSrc < nCnt; idxSrc += 8u) /* FETA_VSTDLIB_LOC_MEMCPYSWAPENDIAN_X_X */ + { + VStdLib_Loc_ConvertUint8ArrayToUint64SwapEndian( /* SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT */ + &pSrc8[idxSrc], + &pDst64[idxDst]); + + idxDst++; + } + } + break; +# endif /* defined PLATFORM_SUPPORT_SINT64_UINT64 */ + + default: + /* #20 Do not copy and swap for any unsupported intType */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + errorId = VSTDLIB_E_PARAM_INTTYPE; +# endif + break; + } + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_COPY_SWAP_ENDIAN, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} /* VStdLib_Loc_MemCpySwapEndian() */ + +#endif /* VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyConvertBitCounting() + **********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(VStdLib_CntType, VSTDLIB_CODE) VStdLib_Loc_BitCpyConvertBitCounting(VStdLib_CntType bitPos) +{ + VStdLib_CntType bitPosConverted = (VStdLib_CntType) ((7u - (bitPos & 7u)) + (8u * (bitPos >> 3u))); + + return bitPosConverted; +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyGetLastIterByte() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(VStdLib_CntType, VSTDLIB_CODE) VStdLib_Loc_BitCpyGetLastIterByte( + VStdLib_CntType lengthInBits) +{ + /* ----- Implementation ----------------------------------------------- */ + /* #100 Calculate the last iteration byte from the length in bits */ + VStdLib_CntType lastIterByte = lengthInBits / 8u; + + /* #110 If the length in bits is not divisible by 8, increment the last iteration byte by 1 */ + if ((lengthInBits % 8u) != 0u) + { + lastIterByte++; + } + + return lastIterByte; +} + +#if ((VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON) || \ + (VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON)) + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyIter() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyIter( + P2VAR(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pIter, + VStdLib_CntType nBitOffset, + VStdLib_CntType nCnt) +{ + /* ----- Implementation ----------------------------------------------- */ + /* #10 Initialize all iteration parameters */ + pIter->startByte = (VStdLib_CntType) (nBitOffset / 8u); /* SBSW_VSTDLIB_ACCESS_STRUCT_LOCAL */ + pIter->lastByte = VStdLib_Loc_BitCpyGetLastIterByte(nBitOffset + nCnt); /* SBSW_VSTDLIB_ACCESS_STRUCT_LOCAL */ + pIter->bitOffsetStartByte = (uint8) (nBitOffset % 8u); /* SBSW_VSTDLIB_ACCESS_STRUCT_LOCAL */ + /* converts monotone to sawtooth bit position and vice versa */ + pIter->bitOffsetEndByte = VStdLib_Loc_BitCpyGetOffsetInBitsEndByte(pIter->bitOffsetStartByte + nCnt); /* SBSW_VSTDLIB_ACCESS_STRUCT_LOCAL */ +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyGetOffsetInBitsEndByte() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_BitCpyGetOffsetInBitsEndByte(VStdLib_CntType lengthInBits) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 lengthMod = (uint8) (lengthInBits % 8u); + uint8 offset = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 If the bit length is a multiple of 8 */ + if (lengthMod != 0u) + { + /* #110 Calculate the offset in last byte to copy to or from */ + offset = 8u - lengthMod; + } + + return offset; +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyBigEndianSrc_7() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyBigEndianSrc_7( /* PRQA S 6060 */ /* MD_MSR_STPAR */ + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + VStdLib_CntType dstByteIdx, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift, + uint8 dstBitMask) +{ + /* ----- Implementation ----------------------------------------------- */ + /* #10 Read source byte */ + uint8 srcByte = VStdLib_Loc_BitCpyBigEndianSrc( + pSrc8, + srcByteIdx, + pSrcIter, + srcShift); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + + /* #20 Read destination byte */ + uint8 tmpByte = pDst8[dstByteIdx]; + + /* #30 Get relevant bits to copy */ + srcByte &= dstBitMask; + tmpByte &= (~dstBitMask); + tmpByte |= srcByte; + + /* #40 Copy the bits */ + pDst8[dstByteIdx] = tmpByte; /* SBSW_VSTDLIB_ACCESS_8 */ +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyLittleEndianSrc_7() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyLittleEndianSrc_7( /* PRQA S 6060 */ /* MD_MSR_STPAR */ + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + VStdLib_CntType dstByteIdx, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift, + uint8 dstBitMask) +{ + /* ----- Implementation ----------------------------------------------- */ + /* #10 Read source byte */ + uint8 srcByte = VStdLib_Loc_BitCpyLittleEndianSrc( + pSrc8, + srcByteIdx, + pSrcIter, + srcShift); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + + /* #20 Read destination byte */ + uint8 tmpByte = pDst8[dstByteIdx]; + + /* #30 Get relevant bits to copy */ + srcByte &= dstBitMask; + tmpByte &= (~dstBitMask); + tmpByte |= srcByte; + + /* #40 Copy the bits */ + pDst8[dstByteIdx] = tmpByte; /* SBSW_VSTDLIB_ACCESS_8 */ +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyBigEndianSrc() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_BitCpyBigEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 srcByte = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'srcByteIdx' against the index of the last iteration source byte */ + if (srcByteIdx < pSrcIter->lastByte) + { + srcByte = pSrc8[srcByteIdx]; + } + /* #20 If the source shift is not 0 */ + if (srcShift != 0) + { + /* #30 If the source shift is bigger than 0, use VStdLib_Loc_BitCpyShiftRight_BigEndianSrc() + * to shift the source byte to the right and merge with missing bits from the previous relevant source byte */ + if (srcShift > 0) + { + VStdLib_Loc_BitCpyShiftRight_BigEndianSrc(pSrc8, &srcByte, srcByteIdx, pSrcIter, srcShift); /* SBSW_VSTDLIB_CALL_MODIFIABLE_SRCBYTE */ + } + /* #40 Else, use VStdLib_Loc_BitCpyShiftLeft_BigEndianSrc() to shift the source byte to the left + * and merge with missing bits from the next relevant source byte */ + else + { + VStdLib_Loc_BitCpyShiftLeft_BigEndianSrc(pSrc8, &srcByte, srcByteIdx, pSrcIter, srcShift); /* SBSW_VSTDLIB_CALL_MODIFIABLE_SRCBYTE */ + } + } + + return srcByte; +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyLittleEndianSrc() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_BitCpyLittleEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 srcByte = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'srcByteIdx' against the index of the last iteration source byte */ + if (srcByteIdx < pSrcIter->lastByte) + { + srcByte = pSrc8[srcByteIdx]; + } + /* #20 If the source shift is not 0 */ + if (srcShift != 0) + { + /* #30 If the source shift is bigger than 0, use VStdLib_Loc_BitCpyShiftRight_LittleEndianSrc() + * to shift the source byte to the right and merge with missing bits from the next relevant source byte */ + if (srcShift > 0) + { + VStdLib_Loc_BitCpyShiftRight_LittleEndianSrc(pSrc8, &srcByte, srcByteIdx, pSrcIter, srcShift); /* SBSW_VSTDLIB_CALL_MODIFIABLE_SRCBYTE */ + } + /* #40 Else, use VStdLib_Loc_BitCpyShiftLeft_LittleEndianSrc() to shift the source byte to the left + * and merge with missing bits from the previous relevant source byte */ + else + { + VStdLib_Loc_BitCpyShiftLeft_LittleEndianSrc(pSrc8, &srcByte, srcByteIdx, pSrcIter, srcShift); /* SBSW_VSTDLIB_CALL_MODIFIABLE_SRCBYTE */ + } + } + + return srcByte; +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyShiftRight_BigEndianSrc() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyShiftRight_BigEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcByte, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 unsignedSrcShift = (uint8) srcShift; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Shift the source byte to the right */ + *(pSrcByte) >>= unsignedSrcShift; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + + /* #20 If bits are missing to fill destination byte get missing bits from previous relevant source byte + * and merge them with current source byte */ + if (srcByteIdx > pSrcIter->startByte) + { + uint8 missingBits = (uint8) (pSrc8[srcByteIdx - 1u] << (8u - unsignedSrcShift)); + *(pSrcByte) |= missingBits; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + } +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyShiftLeft_BigEndianSrc() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyShiftLeft_BigEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcByte, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 unsignedSrcShift = (uint8) (-srcShift); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Shift the source byte to the left */ + *(pSrcByte) <<= unsignedSrcShift; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + + /* #20 If bits are missing to fill destination byte get missing bits from next relevant source byte + * and merge them with current source byte */ + if ((srcByteIdx + 1u) < pSrcIter->lastByte) + { + uint8 missingBits = (pSrc8[srcByteIdx + 1u] >> (8u - unsignedSrcShift)); + *(pSrcByte) |= missingBits; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + } +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyShiftRight_LittleEndianSrc() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyShiftRight_LittleEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcByte, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 unsignedSrcShift = (uint8) srcShift; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Shift the source byte to the right */ + *(pSrcByte) >>= unsignedSrcShift; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + + /* #20 If bits are missing to fill destination byte get missing bits from next relevant source byte + * and merge them with current source byte */ + if ((srcByteIdx + 1u) < pSrcIter->lastByte) + { + uint8 missingBits = (uint8) (pSrc8[srcByteIdx + 1u] << (8u - unsignedSrcShift)); + *(pSrcByte) |= missingBits; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + } +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyShiftLeft_LittleEndianSrc() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyShiftLeft_LittleEndianSrc( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcByte, + VStdLib_CntType srcByteIdx, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter, + sint8 srcShift) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 unsignedSrcShift = (uint8) (-srcShift); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Shift the source byte to the left */ + *(pSrcByte) <<= unsignedSrcShift; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + + /* #20 If bits are missing to fill destination byte get missing bits from previous relevant source byte + * and merge them with current source byte */ + if (srcByteIdx > pSrcIter->startByte) + { + uint8 missingBits = (pSrc8[srcByteIdx - 1u] >> (8u - unsignedSrcShift)); + *(pSrcByte) |= missingBits; /* SBSW_VSTDLIB_ACCESS_LOCAL */ + } +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpySwapEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpySwapEndian( + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pDstIter, + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8, + P2CONST(VStdLib_BitCpyIterType, AUTOMATIC, VSTDLIB_VAR_FAR) pSrcIter) +{ + VStdLib_CntType idx; /* Explicitly not initialized. Used as for-loop counter (first usage in for-initialization statement) */ + VStdLib_CntType srcIdx = (VStdLib_CntType) (pSrcIter->lastByte - 1u); + + for (idx = pDstIter->startByte; idx < pDstIter->lastByte; idx++) /* FETA_VSTDLIB_LOC_BITCPYSWAPENDIAN */ + { + pDst8[idx] = pSrc8[srcIdx]; /* SBSW_VSTDLIB_ACCESS_LOOP_ENDIDX */ + srcIdx--; + } +} + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyBigToBigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyBigToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt) +{ + /* #10 If parameters 'nDstBitOffsetMon' and 'nSrcBitOffsetMon' are both 0 and parameter 'nCnt' is a multiple of 8 */ + if ((nDstBitOffsetMon == 0u) && (nSrcBitOffsetMon == 0u) && ((nCnt % 8u) == 0u)) + { + VStdLib_CntType nCntInBytes = nCnt / 8u; + + /* #20 Use VStdLib_MemCpy algorithm to copy data */ + VStdLib_MemCpy(pDst, pSrc, nCntInBytes); /* SBSW_VSTDLIB_CALL_CONVERTED_BITCNT */ /* FETA_VSTDLIB_CALL_MEMCPY_IN_LOC_BITCPY */ + } + /* #30 Else */ + else + { + VStdLib_BitCpyIterType srcIter; /* Struct is explicitly not initialized. Is initialized with call of VStdLib_Loc_BitCpyIter() by passing address of struct */ + VStdLib_BitCpyIterType dstIter; /* Struct is explicitly not initialized. Is initialized with call of VStdLib_Loc_BitCpyIter() by passing address of struct */ + VStdLib_CntType dstByteIdx; /* Explicitly not initialized. Is initialized after call of VStdLib_Loc_BitCpyIter() */ + VStdLib_CntType srcByteIdx; /* Explicitly not initialized. Is initialized after call of VStdLib_Loc_BitCpyIter() */ + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8 = \ + (P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8 = \ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pSrc; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + sint8 srcShift = 0; + uint8 bitMaskStart = 0xFFu; + uint8 bitMaskEnd = 0xFFu; + + /* #40 Use VStdLib_Loc_BitCpyIter to set the iteration parameters */ + VStdLib_Loc_BitCpyIter( + &srcIter, + nSrcBitOffsetMon, + nCnt); /* SBSW_VSTDLIB_CALL_MODIFIABLE_ITER */ + + VStdLib_Loc_BitCpyIter( + &dstIter, + nDstBitOffsetMon, + nCnt); /* SBSW_VSTDLIB_CALL_MODIFIABLE_ITER */ + + dstByteIdx = dstIter.startByte; + srcByteIdx = srcIter.startByte; + + /* #50 Set the source shift if the bit offset of the leftmost destination and source byte are not equal */ + if (dstIter.bitOffsetStartByte != srcIter.bitOffsetStartByte) + { + srcShift = (sint8) dstIter.bitOffsetStartByte - (sint8) srcIter.bitOffsetStartByte; + } + + /* Set the bit masks for the first and last destination byte */ + bitMaskStart >>= dstIter.bitOffsetStartByte; + bitMaskEnd <<= dstIter.bitOffsetEndByte; + + /* #60 If the first destination byte to copy to is equal to the last byte to copy to, copy relevant bits to only this + * destination byte */ + if (dstIter.startByte == (dstIter.lastByte - 1u)) + { + /* Adjust start bit mask */ + bitMaskStart &= bitMaskEnd; + + VStdLib_Loc_BitCpyBigEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskStart); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + } + /* #70 Else */ + else + { + /* #80 Use VStdLib_Loc_BitCpyBigEndianSrc_7() to copy the first bits separately */ + VStdLib_Loc_BitCpyBigEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskStart); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + + srcByteIdx++; + dstByteIdx++; + + /* #90 Use VStdLib_Loc_BitCpyBigEndianSrc() to copy the bits inbetween the first and last source byte byte-wise */ + for (; dstByteIdx < (dstIter.lastByte - 1u); dstByteIdx++) /* FETA_VSTDLIB_LOC_BITCPY */ + { + pDst8[dstByteIdx] = VStdLib_Loc_BitCpyBigEndianSrc( + pSrc8, + srcByteIdx, + &srcIter, + srcShift); /* SBSW_VSTDLIB_ACCESS_LOOP_ENDIDX */ /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ + + srcByteIdx++; + } + + /* #100 Use VStdLib_Loc_BitCpyBigEndianSrc_7() to copy the last bits separately */ + VStdLib_Loc_BitCpyBigEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskEnd); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + } + } +} /* VStdLib_Loc_BitCpyBigToBigEndian() */ + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyBigToLittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyBigToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8 = \ + (P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8 = \ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pSrc; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + VStdLib_BitCpyIterType srcIter; /* Struct is explicitly not initialized. Is initialized with call of VStdLib_Loc_BitCpyIter() by passing address of struct */ + VStdLib_BitCpyIterType dstIter; /* Struct is explicitly not initialized. Is initialized with call of VStdLib_Loc_BitCpyIter() by passing address of struct */ + + /* #10 Use VStdLib_Loc_BitCpyIter to set the iteration parameters */ + VStdLib_Loc_BitCpyIter( + &srcIter, + nSrcBitOffsetMon, + nCnt); /* SBSW_VSTDLIB_CALL_MODIFIABLE_ITER */ + + VStdLib_Loc_BitCpyIter( + &dstIter, + nDstBitOffsetSaw, + nCnt); /* SBSW_VSTDLIB_CALL_MODIFIABLE_ITER */ + + /* #20 If parameter 'nDstBitOffsetSaw' and 'nSrcBitOffsetMon' are both 0 and parameter 'nCnt' is a multiple of 8 */ + if ((nDstBitOffsetSaw == 0u) && (nSrcBitOffsetMon == 0u) && ((nCnt % 8u) == 0u)) + { + /* #30 Use VStdLib_Loc_BitCpySwapEndian algorithm to copy data in reverse order */ + VStdLib_Loc_BitCpySwapEndian(pDst8, &dstIter, pSrc8, &srcIter); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ /* FETA_VSTDLIB_CALL_LOC_BITCPYSWAPENDIAN */ + } + /* #40 Else */ + else + { + sint8 srcShift = 0; + VStdLib_CntType dstByteIdx = dstIter.startByte; + VStdLib_CntType srcByteIdx = (VStdLib_CntType) (srcIter.lastByte - 1u); + uint8 bitMaskStart = 0xFFu; + uint8 bitMaskEnd = 0xFFu; + + /* #50 Set the source shift if the bit offset of the leftmost destination byte and the bit offset of + * the rightmost source byte are not equal */ + if (dstIter.bitOffsetStartByte != srcIter.bitOffsetEndByte) + { + srcShift = (sint8) srcIter.bitOffsetEndByte - (sint8) dstIter.bitOffsetStartByte; + } + + /* Set the bit masks for the first and last destination byte */ + bitMaskStart <<= dstIter.bitOffsetStartByte; + bitMaskEnd >>= dstIter.bitOffsetEndByte; + + /* #60 If the first destination byte to copy to is equal to the last byte to copy to, copy relevant bits to only this + * destination byte */ + if (dstIter.startByte == (dstIter.lastByte - 1u)) + { + /* Adjust start bit mask */ + bitMaskStart &= bitMaskEnd; + + VStdLib_Loc_BitCpyBigEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskStart); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + } + /* #70 Else */ + else + { + /* #80 Use VStdLib_Loc_BitCpyBigEndianSrc_7() to copy the first bits separately */ + VStdLib_Loc_BitCpyBigEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskStart); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + + srcByteIdx--; + dstByteIdx++; + + /* #90 Use VStdLib_Loc_BitCpyBigEndianSrc() to copy the bits inbetween the first and last source byte byte-wise */ + for (; dstByteIdx < (dstIter.lastByte - 1u); dstByteIdx++) /* FETA_VSTDLIB_LOC_BITCPY */ + { + pDst8[dstByteIdx] = VStdLib_Loc_BitCpyBigEndianSrc( + pSrc8, + srcByteIdx, + &srcIter, + srcShift); /* SBSW_VSTDLIB_ACCESS_LOOP_ENDIDX */ /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ + + srcByteIdx--; + } + + /* #100 Use VStdLib_Loc_BitCpyBigEndianSrc_7() to copy the last bits separately */ + VStdLib_Loc_BitCpyBigEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskEnd); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + } + } +} /* VStdLib_Loc_BitCpyBigToLittleEndian() */ + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyLittleToBigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyLittleToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8 = \ + (P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8 = \ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pSrc; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + VStdLib_BitCpyIterType srcIter; /* Struct is explicitly not initialized. Is initialized with call of VStdLib_Loc_BitCpyIter() by passing address of struct */ + VStdLib_BitCpyIterType dstIter; /* Struct is explicitly not initialized. Is initialized with call of VStdLib_Loc_BitCpyIter() by passing address of struct */ + + /* #10 Use VStdLib_Loc_BitCpyIter to set the iteration parameters */ + VStdLib_Loc_BitCpyIter( + &srcIter, + nSrcBitOffsetSaw, + nCnt); /* SBSW_VSTDLIB_CALL_MODIFIABLE_ITER */ + + VStdLib_Loc_BitCpyIter( + &dstIter, + nDstBitOffsetMon, + nCnt); /* SBSW_VSTDLIB_CALL_MODIFIABLE_ITER */ + + /* #20 If parameter 'nDstBitOffsetSaw' and 'nSrcBitOffsetMon' are both 0 and parameter 'nCnt' is a multiple of 8 */ + if ((nDstBitOffsetMon == 0u) && (nSrcBitOffsetSaw == 0u) && ((nCnt % 8u) == 0u)) + { + /* #30 Use VStdLib_Loc_BitCpySwapEndian algorithm to copy data in reverse order */ + VStdLib_Loc_BitCpySwapEndian(pDst8, &dstIter, pSrc8, &srcIter); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ /* FETA_VSTDLIB_CALL_LOC_BITCPYSWAPENDIAN */ + } + /* #40 Else */ + else + { + sint8 srcShift = 0; + VStdLib_CntType dstByteIdx = dstIter.startByte; + VStdLib_CntType srcByteIdx = (VStdLib_CntType) (srcIter.lastByte - 1u); + uint8 bitMaskStart = 0xFFu; + uint8 bitMaskEnd = 0xFFu; + + /* #50 Set the source shift if the bit offset of the leftmost destination byte and the bit offset of + * the rightmost source byte are not equal */ + if (dstIter.bitOffsetStartByte != srcIter.bitOffsetEndByte) + { + srcShift = (sint8) dstIter.bitOffsetStartByte - (sint8) srcIter.bitOffsetEndByte; + } + + /* Set the bit masks for the first and last destination byte */ + bitMaskStart >>= dstIter.bitOffsetStartByte; + bitMaskEnd <<= dstIter.bitOffsetEndByte; + + /* #60 If the first destination byte to copy to is equal to the last byte to copy to, copy relevant bits to only this + * destination byte */ + if (dstIter.startByte == (dstIter.lastByte - 1u)) + { + /* Adjust start bit mask */ + bitMaskStart &= bitMaskEnd; + + VStdLib_Loc_BitCpyLittleEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskStart); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + } + /* #70 Else */ + else + { + /* #80 Use VStdLib_Loc_BitCpyLittleEndianSrc_7() to copy the first bits separately */ + VStdLib_Loc_BitCpyLittleEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskStart); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + + srcByteIdx--; + dstByteIdx++; + + /* #90 Use VStdLib_Loc_BitCpyLittleEndianSrc() to copy the bits inbetween the first and last source byte byte-wise */ + for (; dstByteIdx < (dstIter.lastByte - 1u); dstByteIdx++) /* FETA_VSTDLIB_LOC_BITCPY */ + { + pDst8[dstByteIdx] = VStdLib_Loc_BitCpyLittleEndianSrc( + pSrc8, + srcByteIdx, + &srcIter, + srcShift); /* SBSW_VSTDLIB_ACCESS_LOOP_ENDIDX */ /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ + + srcByteIdx--; + } + + /* #100 Use VStdLib_Loc_BitCpyLittleEndianSrc_7() to copy the last bits separately */ + VStdLib_Loc_BitCpyLittleEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskEnd); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + } + } +} /* VStdLib_Loc_BitCpyLittleToBigEndian() */ + +/********************************************************************************************************************** + * VStdLib_Loc_BitCpyLittleToLittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_BitCpyLittleToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt) +{ + /* #10 If parameters 'nDstBitOffsetSaw' and 'nSrcBitOffsetSaw' are both 0 and parameter 'nCnt' is a multiple of 8 */ + if ((nDstBitOffsetSaw == 0u) && (nSrcBitOffsetSaw == 0u) && ((nCnt % 8u) == 0u)) + { + VStdLib_CntType nCntInBytes = nCnt / 8u; + + /* #20 Use VStdLib_MemCpy algorithm to copy data */ + VStdLib_MemCpy(pDst, pSrc, nCntInBytes); /* SBSW_VSTDLIB_CALL_CONVERTED_BITCNT */ /* FETA_VSTDLIB_CALL_MEMCPY_IN_LOC_BITCPY */ + } + /* #30 Else */ + else + { + VStdLib_BitCpyIterType srcIter; /* Struct is explicitly not initialized. Is initialized with call of VStdLib_Loc_BitCpyIter() by passing address of struct */ + VStdLib_BitCpyIterType dstIter; /* Struct is explicitly not initialized. Is initialized with call of VStdLib_Loc_BitCpyIter() by passing address of struct */ + VStdLib_CntType dstByteIdx; /* Explicitly not initialized. Is initialized after call of VStdLib_Loc_BitCpyIter() */ + VStdLib_CntType srcByteIdx; /* Explicitly not initialized. Is initialized after call of VStdLib_Loc_BitCpyIter() */ + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8 = \ + (P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8 = \ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pSrc; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + sint8 srcShift = 0; + uint8 bitMaskStart = 0xFFu; + uint8 bitMaskEnd = 0xFFu; + + /* #40 Use VStdLib_Loc_BitCpyIter to set the iteration parameters */ + VStdLib_Loc_BitCpyIter( + &srcIter, + nSrcBitOffsetSaw, + nCnt); /* SBSW_VSTDLIB_CALL_MODIFIABLE_ITER */ + + VStdLib_Loc_BitCpyIter( + &dstIter, + nDstBitOffsetSaw, + nCnt); /* SBSW_VSTDLIB_CALL_MODIFIABLE_ITER */ + + dstByteIdx = dstIter.startByte; + srcByteIdx = srcIter.startByte; + + + /* #50 Set the source shift if the bit offset of the leftmost destination and source byte are not equal */ + if (dstIter.bitOffsetStartByte != srcIter.bitOffsetStartByte) + { + srcShift = (sint8) srcIter.bitOffsetStartByte - (sint8) dstIter.bitOffsetStartByte; + } + + /* Set the bit masks for the first and last destination byte */ + bitMaskStart <<= dstIter.bitOffsetStartByte; + bitMaskEnd >>= dstIter.bitOffsetEndByte; + + /* #60 If the first destination byte to copy to is equal to the last byte to copy to, copy relevant bits to only this + * destination byte */ + if (dstIter.startByte == (dstIter.lastByte - 1u)) + { + /* Adjust start bit mask */ + bitMaskStart &= bitMaskEnd; + + VStdLib_Loc_BitCpyLittleEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskStart); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + } + /* #70 Else */ + else + { + /* #80 Use VStdLib_Loc_BitCpyLittleEndianSrc_7() to copy the first bits separately */ + VStdLib_Loc_BitCpyLittleEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskStart); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + + srcByteIdx++; + dstByteIdx++; + + /* #90 Use VStdLib_Loc_BitCpyLittleEndianSrc() to copy the bits inbetween the first and last source byte byte-wise */ + for (; dstByteIdx < (dstIter.lastByte - 1u); dstByteIdx++) /* FETA_VSTDLIB_LOC_BITCPY */ + { + pDst8[dstByteIdx] = VStdLib_Loc_BitCpyLittleEndianSrc( + pSrc8, + srcByteIdx, + &srcIter, + srcShift); /* SBSW_VSTDLIB_ACCESS_LOOP_ENDIDX */ /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ + + srcByteIdx++; + } + + /* #100 Use VStdLib_Loc_BitCpyLittleEndianSrc_7() to copy the last bits separately */ + VStdLib_Loc_BitCpyLittleEndianSrc_7( + pDst8, + dstByteIdx, + pSrc8, + srcByteIdx, + &srcIter, + srcShift, + bitMaskEnd); /* SBSW_VSTDLIB_CALL_MODIFIED_IDX */ + } + } +} /* VStdLib_Loc_BitCpyLittleToLittleEndian() */ + +#endif /* (VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON) || \ + (VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON) */ + +#if (VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION != STD_ON) + +/********************************************************************************************************************** +* VStdLib_Loc_GetMemCheckResult() +*********************************************************************************************************************/ +/*! +* Internal comment removed. + * + * +*/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_Loc_GetMemCheckResult( + uint32 nBufValue, + uint32 nPattern, + P2VAR(Std_ReturnType, AUTOMATIC, VSTDLIB_VAR_FAR) pRetVal, + Std_ReturnType errorCode) +{ + /* ----- Implementation ----------------------------------------------- */ + /* #10 If the buffer value and pattern are not equal, store errorCode at pRetVal */ + if (nBufValue != nPattern) + { + *(pRetVal) = errorCode; /* SBSW_VSTDLIB_ACCESS_PASSED_INT */ + } +} + +/********************************************************************************************************************** + * VStdLib_Loc_MemCheck_8() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_Loc_MemCheck_8( + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf8, + uint8 nPattern, + uint32_least nCnt, + Std_ReturnType errorCode) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_OK; + uint32_least idx = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Linearly check the bytes using a loop */ + for (; ((idx < nCnt) && (retVal == E_OK)); idx++) /* FETA_VSTDLIB_LOC_MEMCHECK_X_NCNT, FETA_VSTDLIB_LOC_MEMCHECK_X_RETVAL */ + { + VStdLib_Loc_GetMemCheckResult( /* SBSW_VSTDLIB_CALL_MODIFIABLE_RETVAL */ + pBuf8[idx], + nPattern, + &retVal, + errorCode); + } + + return retVal; +} /* VStdLib_Loc_MemCheck_8() */ + +# if (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON) + +/********************************************************************************************************************** + * VStdLib_Loc_MemCheck_32_Aligned() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_Loc_MemCheck_32_Aligned( + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf32, + uint8 nPattern, + uint32_least nCnt, + Std_ReturnType errorCode) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_OK; + uint32_least dPos = 0u; + uint32_least remaining = nCnt; + uint32 nPattern32 = + (uint32)(((uint32)nPattern << 24u) | ((uint32)nPattern << 16u) | ((uint32)nPattern << 8u) | nPattern); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Linearly check 4-byte-wise using 32-bit accesses in a loop */ + for (; ((remaining >= 4u) && (retVal == E_OK)); remaining -= 4u) /* FETA_VSTDLIB_LOC_MEMCHECK_X_NCNT, FETA_VSTDLIB_LOC_MEMCHECK_X_RETVAL */ + { + VStdLib_Loc_GetMemCheckResult( /* SBSW_VSTDLIB_CALL_MODIFIABLE_RETVAL */ + pBuf32[dPos], + nPattern32, + &retVal, + errorCode); + dPos++; + } + + /* #20 If no mismatch was found, check the remaining bytes using a byte-wise algorithm */ + if (retVal == E_OK) + { + retVal = VStdLib_Loc_MemCheck_8( /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCHECK_8_REMAINING */ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) &pBuf32[dPos], + nPattern, + remaining, + errorCode); + } + + return retVal; +} /* VStdLib_Loc_MemCheck_32_Aligned() */ + +# endif /* VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON */ +#endif /* VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTIONS != STD_ON */ + +#if ((VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || \ + (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || ((defined PLATFORM_SUPPORT_SINT64_UINT64) && \ + (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON))) + +/********************************************************************************************************************** + * VStdLib_Loc_GetHighestBitPosOneInByte() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetHighestBitPosOneInByte(uint8 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Does the upper nibble contain a set bit? */ + if ((value & VSTDLIB_MASK_UPPER_NIBBLE) != 0u) + { + /* #110 Shift upper nibble in lower nibble and adapt postion */ + value >>= 4u; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + pos = 4u; + } + + /* #200 Determine bit position in lower nibble */ + pos += VStdLib_Loc_GetHighestBitPosOneInNibble(value); + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_Loc_GetLowestBitPosOneInByte() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetLowestBitPosOneInByte(uint8 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Does the lower nibble contain a set bit? */ + if ((value & VSTDLIB_MASK_LOWER_NIBBLE) != 0u) + { + /* #110 Mask lower nibble */ + value &= VSTDLIB_MASK_LOWER_NIBBLE; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + } + else + { + /* #120 Shift upper nibble in lower nibble and adapt postion */ + value >>= 4u; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + pos = 4u; + } + + /* #200 Determine bit position in lower nibble */ + pos += VStdLib_Loc_GetLowestBitPosOneInNibble(value); + + return pos; +} + +#endif /* (VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || + (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || ((defined PLATFORM_SUPPORT_SINT64_UINT64) && + (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) */ + +#if ((VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || \ + ((defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON))) + +/********************************************************************************************************************** + * VStdLib_Loc_GetHighestBitPosOneInTwoBytes() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetHighestBitPosOneInTwoBytes(uint16 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Does the upper byte contain a set bit? */ + if ((value & VSTDLIB_MASK_UPPER_BYTE) != 0u) + { + /* #110 Shift upper byte in lower byte and adapt postion */ + value >>= 8u; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + pos = 8u; + } + + /* #200 Determine bit position in lower byte */ + pos += VStdLib_Loc_GetHighestBitPosOneInByte((uint8)(value)); + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_Loc_GetLowestBitPosOneInTwoBytes() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetLowestBitPosOneInTwoBytes(uint16 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Does the lower byte contain a set bit? */ + if ((value & VSTDLIB_MASK_LOWER_BYTE) != 0u) + { + /* #110 Mask lower byte */ + value &= VSTDLIB_MASK_LOWER_BYTE; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + } + else + { + /* #120 Shift upper byte in lower byte and adapt postion */ + value >>= 8u; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + pos = 8u; + } + + /* #200 Determine bit position in lower byte */ + pos += VStdLib_Loc_GetLowestBitPosOneInByte((uint8)(value)); + + return pos; +} + +#endif /* (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || + ((defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) */ + +#if ((VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || ((defined PLATFORM_SUPPORT_SINT64_UINT64) && \ + (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON))) + + +/********************************************************************************************************************** + * VStdLib_Loc_GetHighestBitPosOneInFourBytes() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetHighestBitPosOneInFourBytes(uint32 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Does the upper two bytes contain a set bit? */ + if ((value & VSTDLIB_MASK_UPPER_TWO_BYTES) != 0u) + { + /* #110 Shift upper two bytes in lower two bytes and adapt postion */ + value >>= 16u; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + pos = 16u; + } + + /* #200 Determine bit position in lower two bytes */ + pos += VStdLib_Loc_GetHighestBitPosOneInTwoBytes((uint16)(value)); + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_Loc_GetLowestBitPosOneInFourBytes() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetLowestBitPosOneInFourBytes(uint32 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Does the lower two bytes contain a set bit? */ + if ((value & VSTDLIB_MASK_LOWER_TWO_BYTES) != 0u) + { + /* #110 Mask lower two bytes */ + value &= VSTDLIB_MASK_LOWER_TWO_BYTES; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + } + else + { + /* #120 Shift upper two bytes in lower two bytes and adapt postion */ + value >>= 16u; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + pos = 16u; + } + + /* #200 Determine bit position in lower two bytes */ + pos += VStdLib_Loc_GetLowestBitPosOneInTwoBytes((uint16)(value)); + + return pos; +} + +#endif /* (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) || ((defined PLATFORM_SUPPORT_SINT64_UINT64) && + (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) */ + +#if ((defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) + +/********************************************************************************************************************** + * VStdLib_Loc_GetHighestBitPosOneInEightBytes() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetHighestBitPosOneInEightBytes(uint64 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Does the upper four bytes contain a set bit? */ + if ((value & VSTDLIB_MASK_UPPER_FOUR_BYTES) != 0u) + { + /* #110 Shift upper four bytes in lower four bytes and adapt postion */ + value >>= 32u; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + pos = 32u; + } + + /* #200 Determine bit position in lower four bytes */ + pos += VStdLib_Loc_GetHighestBitPosOneInFourBytes((uint32)(value)); + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_Loc_GetLowestBitPosOneInEightBytes() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint8, VSTDLIB_CODE) VStdLib_Loc_GetLowestBitPosOneInEightBytes(uint64 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = 0u; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Does the lower four bytes contain a set bit? */ + if ((value & VSTDLIB_MASK_LOWER_FOUR_BYTES) != 0u) + { + /* #110 Mask lower four bytes */ + value &= VSTDLIB_MASK_LOWER_FOUR_BYTES; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + } + else + { + /* #120 Shift upper four bytes in lower four bytes and adapt postion */ + value >>= 32u; /* PRQA S 1338 */ /* MD_VStdLib_ParamValueMod */ + pos = 32u; + } + + /* #200 Determine bit position in lower four bytes */ + pos += VStdLib_Loc_GetLowestBitPosOneInFourBytes((uint32)(value)); + + return pos; +} + +#endif /* (defined PLATFORM_SUPPORT_SINT64_UINT64 ) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +#if (VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_MemSet() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_MemSet(P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + uint8 nPattern, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8 = \ + (P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameter 'pDst' */ + if (pDst == NULL_PTR) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ +# if (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON) + + /* #20 If less than 32 bytes have to be initialized */ + if (nCnt < 32u) + { + /* #30 Use a byte-wise algorithm */ + VStdLib_Loc_MemSet_8_31( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_LOC_MEMSET_X_X */ + pDst8, + nPattern, + (uint8_least) nCnt); + } + /* #40 Else */ + else + { + /* #50 Get the destination pointer offset to the next 32-bit boundary */ + uint8_least nDstOffset = VSTDLIB_ALIGN_OFFSET(pDst8); /* PRQA S 0306 */ /* MD_VStdLib_PtrCastToInt */ + + /* #60 If the destination is not aligned */ + if (nDstOffset != 0u) + { + /* #70 Initialize the amount of bytes to reach the alignment boundary and adjust the pointer */ + VStdLib_Loc_MemSet_8_3( /* SBSW_VSTDLIB_CALL_MODIFIED_CNT */ /* FETA_VSTDLIB_CALL_LOC_MEMSET_8_3 */ + pDst8, + nPattern, + nDstOffset); + + pDst8 = &pDst8[nDstOffset]; + nCnt -= nDstOffset; /* PRQA S 1338 */ /* MD_VStdLib_ParamMod */ + } + + /* #80 The pointer is aligned, use the 32-bit aligned memset */ + VStdLib_Loc_MemSet_32_Aligned( /* SBSW_VSTDLIB_CALL_MODIFIED_PTR_CNT */ /* FETA_VSTDLIB_CALL_LOC_MEMSET_X_X */ + (P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst8, /* PRQA S 0310, 3305 */ /* MD_VStdLib_PtrCast */ + nPattern, + nCnt); + } + +# else /* VSTDLIB_RUNTIME_OPTIMIZATION == STD_OFF */ + + VStdLib_CntType idx; + + /* #90 Linearly initialize nCnt bytes using a loop */ + for (idx = 0u; idx < nCnt; idx++) /* FETA_VSTDLIB_MEMSET */ + { + pDst8[idx] = nPattern; /* SBSW_VSTDLIB_ACCESS_LOOP */ + } + +# endif /* VSTDLIB_RUNTIME_OPTIMIZATION */ + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_SET, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} /* VStdLib_MemSet() */ + +/********************************************************************************************************************** + * VStdLib_MemCpy() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_MemCpy(P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8 = \ + (P2VAR(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8 = \ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pSrc; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ +# if (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON) + + /* #20 If less than 32 bytes have to be copied */ + if (nCnt < 32u) + { + /* #30 Use a byte-wise algorithm */ + VStdLib_Loc_MemCpy_8_31( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_LOC_MEMCPY_X_X */ + pDst8, + pSrc8, + (uint8_least) nCnt); + } + /* #40 Else */ + else + { + /* #50 Get the source pointer offset to the next 32-bit boundary */ + uint8_least nSrcOffset = VSTDLIB_ALIGN_OFFSET(pSrc8); /* PRQA S 0306 */ /* MD_VStdLib_PtrCastToInt */ + uint8_least nDstOffset; + + /* #60 If the source is not aligned */ + if (nSrcOffset != 0u) + { + /* #70 Copy the amount of bytes to reach the alignment boundary and adjust the pointers */ + VStdLib_Loc_MemCpy_8_3( /* SBSW_VSTDLIB_CALL_MODIFIED_CNT */ /* FETA_VSTDLIB_CALL_LOC_MEMCPY_8_3 */ + pDst8, + pSrc8, + nSrcOffset); + + pSrc8 = &pSrc8[nSrcOffset]; + pDst8 = &pDst8[nSrcOffset]; + nCnt -= nSrcOffset; /* PRQA S 1338 */ /* MD_VStdLib_ParamMod */ + } + + /* #80 Get the destination pointer offset to the next 32-bit boundary */ + nDstOffset = VSTDLIB_ALIGN_OFFSET(pDst8); /* PRQA S 0306 */ /* MD_VStdLib_PtrCastToInt */ + + /* #90 If destination is aligned */ + if (nDstOffset == 0u) + { + /* #100 Both pointers are aligned, use the 32-bit aligned memcpy */ + VStdLib_Loc_MemCpy_32_Aligned( /* SBSW_VSTDLIB_CALL_MODIFIED_PTR_CNT */ /* FETA_VSTDLIB_CALL_LOC_MEMCPY_X_X */ + (P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst8, /* PRQA S 0310, 3305 */ /* MD_VStdLib_PtrCast */ + (P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) pSrc8, /* PRQA S 0310, 3305 */ /* MD_VStdLib_PtrCast */ + nCnt); + } + /* #110 Else */ + else + { + /* #120 Use the 32-bit unaligned memcpy */ + VStdLib_Loc_MemCpy_32_Unaligned( /* SBSW_VSTDLIB_CALL_MODIFIED_PTR_CNT */ /* FETA_VSTDLIB_CALL_LOC_MEMCPY_X_X, FETA_VSTDLIB_CALL_LOC_MEMCPY_32_UNALIGNED_NDSTOFFSET */ + pDst8, + (P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) pSrc8, /* PRQA S 0310, 3305 */ /* MD_VStdLib_PtrCast */ + nCnt, + nDstOffset); + } + } + +# else /* VSTDLIB_RUNTIME_OPTIMIZATION == STD_OFF */ + + VStdLib_CntType idx; + + /* #130 Linearly copy nCnt bytes using a loop */ + for (idx = 0u; idx < nCnt; idx++) /* FETA_VSTDLIB_MEMCPY */ + { + pDst8[idx] = pSrc8[idx]; /* SBSW_VSTDLIB_ACCESS_LOOP */ + } + +# endif /* VSTDLIB_RUNTIME_OPTIMIZATION */ + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_COPY, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} /* VStdLib_MemCpy() */ + +/********************************************************************************************************************** + * VStdLib_MemCpy16() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_MemCpy16(P2VAR(uint16, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(uint16, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + VStdLib_CntType idx; + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #20 Linearly copy nCnt 16-bit blocks using a loop */ + for (idx = 0u; idx < nCnt; idx++) /* FETA_VSTDLIB_MEMCPY */ + { + pDst[idx] = pSrc[idx]; /* SBSW_VSTDLIB_ACCESS_LOOP */ + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_COPY_16, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} /* VStdLib_MemCpy16() */ + +/********************************************************************************************************************** + * VStdLib_MemCpy32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_MemCpy32(P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + VStdLib_CntType idx; + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #20 Linearly copy nCnt 32-bit blocks using a loop */ + for (idx = 0u; idx < nCnt; idx++) /* FETA_VSTDLIB_MEMCPY */ + { + pDst[idx] = pSrc[idx]; /* SBSW_VSTDLIB_ACCESS_LOOP */ + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_COPY_32, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} /* VStdLib_MemCpy32() */ + +#endif /* VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_MemCpy_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_MemCpy_s(P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'nDstSize' (independently of development error detection) */ + if (nCnt > nDstSize) + { + errorId = VSTDLIB_E_PARAM_SIZE; + } + else + { + /* #20 Call VStdLib_MemCpy() */ + VStdLib_MemCpy(pDst, pSrc, nCnt); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_MEMCPY */ + } + + /* ----- Development Error Report ------------------------------------- */ +#if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_COPY_S, errorId); + } +#else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif +} /* VStdLib_MemCpy_s() */ + +/********************************************************************************************************************** + * VStdLib_MemCpy_Return_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_MemCpy_Return_s(P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt, + Std_ReturnType errorCode) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + Std_ReturnType retVal = E_OK; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'nDstSize' (independently of development error detection) */ + if (nCnt > nDstSize) + { + errorId = VSTDLIB_E_PARAM_SIZE; + retVal = errorCode; + } + else + { + /* #20 Call VStdLib_MemCpy() */ + VStdLib_MemCpy(pDst, pSrc, nCnt); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_MEMCPY */ + } + + /* ----- Development Error Report ------------------------------------- */ +#if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_COPY_S, errorId); + } +#else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} /* VStdLib_MemCpy_Return_s() */ + +#if (VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_MemCmp() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(sint8, VSTDLIB_CODE) VStdLib_MemCmp( + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf1, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf2, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf1_8 = \ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR))pBuf1; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf2_8 = \ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR))pBuf2; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + sint8 result = VSTDLIB_MEM_CMP_RES_EQ; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameter 'pBuf1' */ + if (pBuf1 == NULL_PTR) + { + errorId = VSTDLIB_E_PARAM_POINTER; + result = VSTDLIB_MEM_CMP_RES_L; + } + /* #20 Check parameter 'pBuf2' */ + else if (pBuf2 == NULL_PTR) + { + errorId = VSTDLIB_E_PARAM_POINTER; + result = VSTDLIB_MEM_CMP_RES_G; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 If buffer1 and buffer2 can be unequal */ + if (pBuf1 != pBuf2) + { +# if (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON) + /* #110 If less than 32 bytes have to be compared */ + if (nCnt < 32u) + { + /* #120 Use byte-wise memcmp */ + result = VStdLib_Loc_MemCmp_8(pBuf1_8, pBuf2_8, nCnt); /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCMP_X_X */ + } + /* #130 Else */ + else + { + /* #140 Get the pointer offset from buffer1 to the next 32-bit boundary */ + uint8_least nBuf1Offset = VSTDLIB_ALIGN_OFFSET(pBuf1_8); /* PRQA S 0306 */ /* MD_VStdLib_PtrCastToInt */ + + /* #150 If buffer1 is not aligned */ + if (nBuf1Offset != 0u) + { + /* #160 Compare the amount of bytes to reach the alignment boundary of buffer1 */ + result = VStdLib_Loc_MemCmp_8(pBuf1_8, pBuf2_8, nBuf1Offset); /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCMP_8_NBUF1OFFSET */ + } + + /* #170 If buffers are still equal */ + if (result == VSTDLIB_MEM_CMP_RES_EQ) + { + uint8_least nBuf2Offset; + + /* #180 Adjust the pointers for buffer1 and buffer2 */ + pBuf1_8 = &pBuf1_8[nBuf1Offset]; + pBuf2_8 = &pBuf2_8[nBuf1Offset]; + nCnt -= nBuf1Offset; /* PRQA S 1338 */ /* MD_VStdLib_ParamMod */ + + /* #190 Get the pointer offset from buffer2 to the next 32-bit boundary */ + nBuf2Offset = VSTDLIB_ALIGN_OFFSET(pBuf2_8); /* PRQA S 0306 */ /* MD_VStdLib_PtrCastToInt */ + + /* #200 If buffer2 is aligned */ + if (nBuf2Offset == 0u) + { + /* #210 Both pointers are aligned, use the 32-bit aligned memcmp */ + result = VStdLib_Loc_MemCmp_32_Aligned( /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCMP_X_X */ + (P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) pBuf1_8, /* PRQA S 0310, 3305 */ /* MD_VStdLib_PtrCast */ + (P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) pBuf2_8, /* PRQA S 0310, 3305 */ /* MD_VStdLib_PtrCast */ + nCnt); + } + /* #220 Else buffer2 is not aligned and buffer 1 is aligned */ + else + { + /* #230 Use the 32-bit unaligned memcmp */ + result = VStdLib_Loc_MemCmp_32_Unaligned( /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCMP_X_X, FETA_VSTDLIB_CALL_LOC_MEMCMP_32_UNALIGNED_NBUF2OFFSET */ + (P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) pBuf1_8, /* PRQA S 0310, 3305 */ /* MD_VStdLib_PtrCast */ + pBuf2_8, + nCnt, + nBuf2Offset); + } + } + } +# else /* VSTDLIB_RUNTIME_OPTIMIZATION == STD_OFF */ + + /* #240 Use byte-wise memcmp */ + result = VStdLib_Loc_MemCmp_8(pBuf1_8, pBuf2_8, nCnt); /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCMP_X_X */ + +# endif /* VSTDLIB_RUNTIME_OPTIMIZATION */ + } + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_CMP, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif + + return result; +} + +#endif /* VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON */ + +#if (VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON) + +/********************************************************************************************************************** + * VStdLib_MemCpySwapEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +/* PRQA S 6080 1 */ /* MD_MSR_STMIF */ +FUNC(void, VSTDLIB_CODE) VStdLib_MemCpySwapEndian(P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt, + uint8 intType) +{ + /* ----- Local Variables ---------------------------------------------- */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc8 = \ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pSrc; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ +# if ((VSTDLIB_DEV_ERROR_DETECT == STD_ON) || (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON)) + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pDst8 = \ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ +# endif + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + /* #20 Check parameter 'pDst' is aligned according to the integer type */ +# if (CPU_TYPE == CPU_TYPE_64) + else if (((uint64)pDst8 % (uint64)intType) != 0u) /* PRQA S 0306 */ /* MD_VStdLib_PtrCastToInt */ +# else + else if (((uint32_least)pDst8 % (uint32_least)intType) != 0u) /* PRQA S 0306 */ /* MD_VStdLib_PtrCastToInt */ +# endif + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + /* #30 Check parameter 'nCnt' is a multiple of integer type size */ + else if ((nCnt % (VStdLib_CntType)intType) != 0u) + { + errorId = VSTDLIB_E_PARAM_SIZE; + } + /* Parameter intType is checked in the local functions. No copy and swap is executed for any unsupported intType + and VSTDLIB_E_PARAM_INTTYPE is reported if VSTDLIB_DEV_ERROR_REPORT is enabled */ + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 If integer type is VSTDLIB_INTTYPE_8, call VStdLib_MemCpy() */ + if (intType == VSTDLIB_INTTYPE_8) + { + VStdLib_MemCpy(pDst, pSrc, nCnt); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_MEMCPY */ + } + else + { +# if (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON) + /* #110 If less than 33 bytes have to be copied and swapped */ + if (nCnt < 33u) + { + /* #120 Use a integer-type-wise algorithm (for dst) */ + VStdLib_Loc_MemCpySwapEndian_IntType_32( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_X_X */ + pDst, + pSrc8, + (uint8_least) nCnt, + intType); + } + /* #130 If destination and source are 32-bit aligned */ + else if ((VSTDLIB_ALIGN_OFFSET(pDst8) == 0u) && (VSTDLIB_ALIGN_OFFSET(pSrc8) == 0u)) /* PRQA S 0306 */ /* MD_VStdLib_PtrCastToInt */ + { + /* #140 Use a 32-bit-wise algorithm (for dst and src) */ + VStdLib_Loc_MemCpySwapEndian_32_Aligned( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_X_X */ + (P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) pDst, /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + (P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) pSrc, /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + nCnt, + intType); + } + /* #150 Else destination or source is not aligned */ + else + { + /* #160 Linearly copy and swap nCnt bytes using a loop (integer type access to dst) */ + VStdLib_Loc_MemCpySwapEndian(pDst, pSrc8, nCnt, intType); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_X_X */ + } +# else /* VSTDLIB_RUNTIME_OPTIMIZATION == STD_OFF */ + /* #170 Linearly copy and swap nCnt bytes using a loop (integer type access to dst) */ + VStdLib_Loc_MemCpySwapEndian(pDst, pSrc8, nCnt, intType); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ +# endif /* VSTDLIB_RUNTIME_OPTIMIZATION */ + } + } + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_COPY_SWAP_ENDIAN, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} /* VStdLib_MemCpySwapEndian() */ + +#endif /* VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_MemCpySwapEndian_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_MemCpySwapEndian_s( /* PRQA S 6060 */ /* MD_MSR_STPAR */ + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt, + uint8 intType, + Std_ReturnType errorCode) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + Std_ReturnType retval = E_OK; + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'nDstSize' (independently of development error detection) */ + if (nCnt > nDstSize) + { + errorId = VSTDLIB_E_PARAM_SIZE; + retval = errorCode; + } + else + { + /* #20 Call VStdLib_MemCpySwapEndian() */ + VStdLib_MemCpySwapEndian(pDst, pSrc, nCnt, intType); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ /* FETA_VSTDLIB_CALL_MEMCPYSWAPENDIAN */ + /* retval is already set to E_OK */ + } + + /* ----- Development Error Report ------------------------------------- */ +#if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_COPY_SWAP_ENDIAN_S, errorId); + } +#else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retval; +} /* VStdLib_MemCpySwapEndian_s() */ + +#if (VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_BitCpySawBigToBigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpySawBigToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* For big endian data use monotone bit counting */ + VStdLib_CntType nDstBitOffsetSawToMon = VStdLib_Loc_BitCpyConvertBitCounting(nDstBitOffsetSaw); + VStdLib_CntType nSrcBitOffsetSawToMon = VStdLib_Loc_BitCpyConvertBitCounting(nSrcBitOffsetSaw); + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + /* #20 Use VStdLib_Loc_BitCpyBigToBigEndian() to copy data if parameter 'nCnt' is bigger than 0 */ + else +# endif + { + /* Catch the case, if there is nothing to copy. If it is not catched here, it needs to be catch in + VStdLib_Loc_BitCpyBigToBigEndian() */ + if (nCnt > 0u) + { + VStdLib_Loc_BitCpyBigToBigEndian( /* FETA_VSTDLIB_CALL_LOC_BITCPY */ + pDst, + nDstBitOffsetSawToMon, + pSrc, + nSrcBitOffsetSawToMon, + nCnt); /* SBSW_VSTDLIB_CALL_CONVERTED_BITOFFSET */ + } + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_SAW, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_BitCpySawBigToLittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpySawBigToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* For big endian data use monotone bit counting */ + VStdLib_CntType nSrcBitOffsetSawToMon = VStdLib_Loc_BitCpyConvertBitCounting(nSrcBitOffsetSaw); + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + /* #20 Use VStdLib_Loc_BitCpyBigToLittleEndian() to copy data if parameter 'nCnt' is bigger than 0 */ + else +# endif + { + /* Catch the case, if there is nothing to copy. If it is not catched here, it needs to be catch in + VStdLib_Loc_BitCpyBigToLittleEndian() */ + if (nCnt > 0u) + { + VStdLib_Loc_BitCpyBigToLittleEndian( /* FETA_VSTDLIB_CALL_LOC_BITCPY */ + pDst, + nDstBitOffsetSaw, + pSrc, + nSrcBitOffsetSawToMon, + nCnt); /* SBSW_VSTDLIB_CALL_CONVERTED_BITOFFSET */ + } + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_SAW, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_BitCpySawLittleToBigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpySawLittleToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* For big endian data use monotone bit counting */ + VStdLib_CntType nDstBitOffsetSawToMon = VStdLib_Loc_BitCpyConvertBitCounting(nDstBitOffsetSaw); + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + /* #20 Use VStdLib_Loc_BitCpyLittleToBigEndian() to copy data if parameter 'nCnt' is bigger than 0 */ + else +# endif + { + /* Catch the case, if there is nothing to copy. If it is not catched here, it needs to be catch in + VStdLib_Loc_BitCpyLittleToBigEndian() */ + if (nCnt > 0u) + { + VStdLib_Loc_BitCpyLittleToBigEndian( /* FETA_VSTDLIB_CALL_LOC_BITCPY */ + pDst, + nDstBitOffsetSawToMon, + pSrc, + nSrcBitOffsetSaw, + nCnt); /* SBSW_VSTDLIB_CALL_CONVERTED_BITOFFSET */ + } + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_SAW, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_BitCpySawLittleToLittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpySawLittleToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + /* #20 Use VStdLib_Loc_BitCpyLittleToLittleEndian() to copy data if parameter 'nCnt' is bigger than 0 */ + else +# endif + { + /* Catch the case, if there is nothing to copy. If it is not catched here, it needs to be catch in + VStdLib_Loc_BitCpyLittleToLittleEndian() */ + if (nCnt > 0u) + { + VStdLib_Loc_BitCpyLittleToLittleEndian( /* FETA_VSTDLIB_CALL_LOC_BITCPY */ + pDst, + nDstBitOffsetSaw, + pSrc, + nSrcBitOffsetSaw, + nCnt); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + } + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_SAW, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} + +#endif /* VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_BitCpySawBigToBigEndian_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpySawBigToBigEndian_s( /* PRQA S 6060 */ /* MD_MSR_STPAR */ + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt, + Std_ReturnType errorCode) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_OK; + uint8 errorId = VSTDLIB_E_NO_ERROR; + /* For big endian destination data use monotone bit counting */ + VStdLib_CntType nDstBitOffsetSawToMon = VStdLib_Loc_BitCpyConvertBitCounting(nDstBitOffsetSaw); + VStdLib_CntType dstEndByte = VStdLib_Loc_BitCpyGetLastIterByte(nCnt + nDstBitOffsetSawToMon); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'nDstSize' (independently of development error detection) */ + if (dstEndByte > nDstSize) + { + errorId = VSTDLIB_E_PARAM_SIZE; + retVal = errorCode; + } + else + { + /* #20 Call VStdLib_BitCpySawBigToBigEndian() */ + VStdLib_BitCpySawBigToBigEndian( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + pDst, + nDstBitOffsetSaw, + pSrc, + nSrcBitOffsetSaw, + nCnt); + } + + /* ----- Development Error Report ------------------------------------- */ +#if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_SAW_S, errorId); + } +#else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} + +/********************************************************************************************************************** + * VStdLib_BitCpySawBigToLittleEndian_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpySawBigToLittleEndian_s( /* PRQA S 6060 */ /* MD_MSR_STPAR */ + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt, + Std_ReturnType errorCode) + +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_OK; + uint8 errorId = VSTDLIB_E_NO_ERROR; + VStdLib_CntType dstEndByte = VStdLib_Loc_BitCpyGetLastIterByte(nCnt + nDstBitOffsetSaw); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'nDstSize' (independently of development error detection) */ + if (dstEndByte > nDstSize) + { + errorId = VSTDLIB_E_PARAM_SIZE; + retVal = errorCode; + } + else + { + /* #20 Call VStdLib_BitCpySawBigToLittleEndian() */ + VStdLib_BitCpySawBigToLittleEndian( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + pDst, + nDstBitOffsetSaw, + pSrc, + nSrcBitOffsetSaw, + nCnt); + } + + /* ----- Development Error Report ------------------------------------- */ +#if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_SAW_S, errorId); + } +#else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} + +/********************************************************************************************************************** + * VStdLib_BitCpySawLittleToBigEndian_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpySawLittleToBigEndian_s( /* PRQA S 6060 */ /* MD_MSR_STPAR */ + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt, + Std_ReturnType errorCode) + +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_OK; + uint8 errorId = VSTDLIB_E_NO_ERROR; + /* For big endian destination data use monotone bit counting */ + VStdLib_CntType nDstBitOffsetSawToMon = VStdLib_Loc_BitCpyConvertBitCounting(nDstBitOffsetSaw); + VStdLib_CntType dstEndByte = VStdLib_Loc_BitCpyGetLastIterByte(nCnt + nDstBitOffsetSawToMon); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'nDstSize' (independently of development error detection) */ + if (dstEndByte > nDstSize) + { + errorId = VSTDLIB_E_PARAM_SIZE; + retVal = errorCode; + } + else + { + /* #20 Call VStdLib_BitCpySawLittleToBigEndian() */ + VStdLib_BitCpySawLittleToBigEndian( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + pDst, + nDstBitOffsetSaw, + pSrc, + nSrcBitOffsetSaw, + nCnt); + } + + /* ----- Development Error Report ------------------------------------- */ +#if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_SAW_S, errorId); + } +#else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} + +/********************************************************************************************************************** + * VStdLib_BitCpySawLittleToLittleEndian_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpySawLittleToLittleEndian_s( /* PRQA S 6060 */ /* MD_MSR_STPAR */ + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt, + Std_ReturnType errorCode) + +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_OK; + uint8 errorId = VSTDLIB_E_NO_ERROR; + VStdLib_CntType dstEndByte = VStdLib_Loc_BitCpyGetLastIterByte(nCnt + nDstBitOffsetSaw); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'nDstSize' (independently of development error detection) */ + if (dstEndByte > nDstSize) + { + errorId = VSTDLIB_E_PARAM_SIZE; + retVal = errorCode; + } + else + { + /* #20 Call VStdLib_BitCpySawLittleToLittleEndian() */ + VStdLib_BitCpySawLittleToLittleEndian( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + pDst, + nDstBitOffsetSaw, + pSrc, + nSrcBitOffsetSaw, + nCnt); + } + + /* ----- Development Error Report ------------------------------------- */ +#if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_SAW_S, errorId); + } +#else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} + +#if (VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_BitCpyMonBigToBigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpyMonBigToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + /* #20 Use VStdLib_Loc_BitCpyBigToBigEndian() to copy data if parameter 'nCnt' is bigger than 0 */ + else +# endif + { + /* Catch the case, if there is nothing to copy. If it is not catched here, it needs to be catch in + VStdLib_Loc_BitCpyBigToBigEndian() */ + if (nCnt > 0u) + { + VStdLib_Loc_BitCpyBigToBigEndian( /* FETA_VSTDLIB_CALL_LOC_BITCPY */ + pDst, + nDstBitOffsetMon, + pSrc, + nSrcBitOffsetMon, + nCnt); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + } + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_MON, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_BitCpyMonBigToLittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpyMonBigToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* For little endian data use sawtooth bit counting */ + VStdLib_CntType nDstBitOffsetMonToSaw = VStdLib_Loc_BitCpyConvertBitCounting(nDstBitOffsetMon); + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + /* #20 Use VStdLib_Loc_BitCpyBigToLittleEndian() to copy data if parameter 'nCnt' is bigger than 0 */ + else +# endif + { + /* Catch the case, if there is nothing to copy. If it is not catched here, it needs to be catch in + VStdLib_Loc_BitCpyBigToLittleEndian() */ + if (nCnt > 0u) + { + VStdLib_Loc_BitCpyBigToLittleEndian( /* FETA_VSTDLIB_CALL_LOC_BITCPY */ + pDst, + nDstBitOffsetMonToSaw, + pSrc, + nSrcBitOffsetMon, + nCnt); /* SBSW_VSTDLIB_CALL_CONVERTED_BITOFFSET */ + } + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_MON, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_BitCpyMonLittleToBigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpyMonLittleToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* For little endian data use sawtooth bit counting */ + VStdLib_CntType nSrcBitOffsetMonToSaw = VStdLib_Loc_BitCpyConvertBitCounting(nSrcBitOffsetMon); + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + /* #20 Use VStdLib_Loc_BitCpyLittleToBigEndian() to copy data if parameter 'nCnt' is bigger than 0 */ + else +# endif + { + /* Catch the case, if there is nothing to copy. If it is not catched here, it needs to be catch in + VStdLib_Loc_BitCpyLittleToBigEndian() */ + if (nCnt > 0u) + { + VStdLib_Loc_BitCpyLittleToBigEndian( /* FETA_VSTDLIB_CALL_LOC_BITCPY */ + pDst, + nDstBitOffsetMon, + pSrc, + nSrcBitOffsetMonToSaw, + nCnt); /* SBSW_VSTDLIB_CALL_CONVERTED_BITOFFSET */ + } + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_MON, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_BitCpyMonLittleToLittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpyMonLittleToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + /* For little endian data use sawtooth bit counting */ + VStdLib_CntType nDstBitOffsetMonToSaw = VStdLib_Loc_BitCpyConvertBitCounting(nDstBitOffsetMon); + VStdLib_CntType nSrcBitOffsetMonToSaw = VStdLib_Loc_BitCpyConvertBitCounting(nSrcBitOffsetMon); + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'pDst' and 'pSrc' */ + if ((pDst == NULL_PTR) || (pSrc == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + /* #20 Use VStdLib_Loc_BitCpyLittleToLittleEndian() to copy data if parameter 'nCnt' is bigger than 0 */ + else +# endif + { + /* Catch the case, if there is nothing to copy. If it is not catched here, it needs to be catch in + VStdLib_Loc_BitCpyLittleToLittleEndian() */ + if (nCnt > 0u) + { + VStdLib_Loc_BitCpyLittleToLittleEndian( /* FETA_VSTDLIB_CALL_LOC_BITCPY */ + pDst, + nDstBitOffsetMonToSaw, + pSrc, + nSrcBitOffsetMonToSaw, + nCnt); /* SBSW_VSTDLIB_CALL_CONVERTED_BITOFFSET */ + } + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_MON, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} + +#endif /* VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_BitCpyMonBigToBigEndian_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpyMonBigToBigEndian_s( /* PRQA S 6060 */ /* MD_MSR_STPAR */ + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt, + Std_ReturnType errorCode) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + Std_ReturnType retVal = E_OK; + VStdLib_CntType dstEndByte = VStdLib_Loc_BitCpyGetLastIterByte(nCnt + nDstBitOffsetMon); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'nDstSize' (independently of development error detection) */ + if (dstEndByte > nDstSize) + { + errorId = VSTDLIB_E_PARAM_SIZE; + retVal = errorCode; + } + else + { + /* #20 Call VStdLib_BitCpyMonBigToBigEndian() */ + VStdLib_BitCpyMonBigToBigEndian( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + pDst, + nDstBitOffsetMon, + pSrc, + nSrcBitOffsetMon, + nCnt); + } + + /* ----- Development Error Report ------------------------------------- */ +#if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_MON_S, errorId); + } +#else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} + +/********************************************************************************************************************** + * VStdLib_BitCpyMonBigToLittleEndian_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpyMonBigToLittleEndian_s( /* PRQA S 6060 */ /* MD_MSR_STPAR */ + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt, + Std_ReturnType errorCode) + +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_OK; + uint8 errorId = VSTDLIB_E_NO_ERROR; + /* For little endian destination data use sawtooth bit counting */ + VStdLib_CntType nDstBitOffsetMonToSaw = VStdLib_Loc_BitCpyConvertBitCounting(nDstBitOffsetMon); + VStdLib_CntType dstEndByte = VStdLib_Loc_BitCpyGetLastIterByte(nCnt + nDstBitOffsetMonToSaw); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'nDstSize' (independently of development error detection) */ + if (dstEndByte > nDstSize) + { + errorId = VSTDLIB_E_PARAM_SIZE; + retVal = errorCode; + } + else + { + /* #20 Call VStdLib_BitCpyMonBigToLittleEndian() */ + VStdLib_BitCpyMonBigToLittleEndian( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + pDst, + nDstBitOffsetMon, + pSrc, + nSrcBitOffsetMon, + nCnt); + } + + /* ----- Development Error Report ------------------------------------- */ +#if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_MON_S, errorId); + } +#else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} + +/********************************************************************************************************************** + * VStdLib_BitCpyMonLittleToBigEndian_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpyMonLittleToBigEndian_s( /* PRQA S 6060 */ /* MD_MSR_STPAR */ + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt, + Std_ReturnType errorCode) + +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_OK; + uint8 errorId = VSTDLIB_E_NO_ERROR; + VStdLib_CntType dstEndByte = VStdLib_Loc_BitCpyGetLastIterByte(nCnt + nDstBitOffsetMon); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'nDstSize' (independently of development error detection) */ + if (dstEndByte > nDstSize) + { + errorId = VSTDLIB_E_PARAM_SIZE; + retVal = errorCode; + } + else + { + /* #20 Call VStdLib_BitCpyMonLittleToBigEndian() */ + VStdLib_BitCpyMonLittleToBigEndian( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + pDst, + nDstBitOffsetMon, + pSrc, + nSrcBitOffsetMon, + nCnt); + } + + /* ----- Development Error Report ------------------------------------- */ +#if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_MON_S, errorId); + } +#else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} + +/********************************************************************************************************************** + * VStdLib_BitCpyMonLittleToLittleEndian_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpyMonLittleToLittleEndian_s( /* PRQA S 6060 */ /* MD_MSR_STPAR */ + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt, + Std_ReturnType errorCode) + +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_OK; + uint8 errorId = VSTDLIB_E_NO_ERROR; + /* For little endian destination data use sawtooth bit counting */ + VStdLib_CntType nDstBitOffsetMonToSaw = VStdLib_Loc_BitCpyConvertBitCounting(nDstBitOffsetMon); + VStdLib_CntType dstEndByte = VStdLib_Loc_BitCpyGetLastIterByte(nCnt + nDstBitOffsetMonToSaw); + + /* ----- Implementation ----------------------------------------------- */ + /* #10 Check parameter 'nDstSize' (independently of development error detection) */ + if (dstEndByte > nDstSize) + { + errorId = VSTDLIB_E_PARAM_SIZE; + retVal = errorCode; + } + else + { + /* #20 Call VStdLib_BitCpyMonLittleToLittleEndian() */ + VStdLib_BitCpyMonLittleToLittleEndian( /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + pDst, + nDstBitOffsetMon, + pSrc, + nSrcBitOffsetMon, + nCnt); + } + + /* ----- Development Error Report ------------------------------------- */ +#if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_BIT_COPY_MON_S, errorId); + } +#else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +#endif + + return retVal; +} + +#if (VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION != STD_ON) + +/********************************************************************************************************************** + * VStdLib_MemCheck() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + * + * + * + * + * + * + * + */ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_MemCheck( + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf, + uint8 nPattern, + VStdLib_CntType nCnt, + Std_ReturnType errorCode) +{ + /* ----- Local Variables ---------------------------------------------- */ + Std_ReturnType retVal = E_OK; + + P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf8 = \ + (P2CONST(uint8, AUTOMATIC, VSTDLIB_VAR_FAR)) pBuf; /* PRQA S 0316 */ /* MD_VStdLib_PtrCast */ + + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check the parameter 'pBuf' */ + if (pBuf == NULL_PTR) + { + retVal = errorCode; + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ +# if (VSTDLIB_RUNTIME_OPTIMIZATION == STD_ON) + /* #20 If less than 32 bytes of memory have to be checked for nPattern */ + if (nCnt < 32u) + { + /* #30 Use a byte-wise memcheck */ + retVal = VStdLib_Loc_MemCheck_8( /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCHECK_X */ + pBuf8, + nPattern, + nCnt, + errorCode); + } + /* #40 Else */ + else + { + /* #50 Get the pointer offset to the next 32-bit boundary */ + uint8_least nBufOffset = VSTDLIB_ALIGN_OFFSET(pBuf8); /* PRQA S 0306 */ /* MD_VStdLib_PtrCastToInt */ + + /* #60 If the pointer is not aligned */ + if (nBufOffset != 0u) + { + /* #70 Check the amount of bytes to reach the alignment boundary and adjust the pointer */ + retVal = VStdLib_Loc_MemCheck_8( /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCHECK_8_NBUFOFFSET */ + pBuf8, + nPattern, + nBufOffset, + errorCode); + + pBuf8 = &pBuf8[nBufOffset]; + nCnt -= nBufOffset; /* PRQA S 1338 */ /* MD_VStdLib_ParamMod */ + } + + if (retVal == E_OK) + { + /* #80 The pointer is aligned, use the 32-bit aligned memcheck */ + retVal = VStdLib_Loc_MemCheck_32_Aligned( /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCHECK_X */ + (P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR)) pBuf8, /* PRQA S 0310, 3305 */ /* MD_VStdLib_PtrCast */ + nPattern, + nCnt, + errorCode); + } + } + +# else /* VSTDLIB_RUNTIME_OPTIMIZATION == STD_OFF */ + + /* #90 Use byte-wise memcheck */ + retVal = VStdLib_Loc_MemCheck_8( /* SBSW_VSTDLIB_CALL_NO_PTR_WRITE */ /* FETA_VSTDLIB_CALL_LOC_MEMCHECK_X */ + pBuf8, + nPattern, + nCnt, + errorCode); + +# endif /* VSTDLIB_RUNTIME_OPTIMIZATION */ + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_MEM_CHECK, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif + + return retVal; +} /* VStdLib_MemCheck() */ + +#endif /* VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION != STD_ON */ + +#if (VSTDLIB_VERSION_INFO_API == STD_ON) + +/********************************************************************************************************************** + * VStdLib_GetVersionInfo() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(void, VSTDLIB_CODE) VStdLib_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, VSTDLIB_APPL_VAR) versioninfo) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameter 'versioninfo' */ + if (versioninfo == NULL_PTR) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #20 Write component data to 'versioninfo' */ + versioninfo->vendorID = VSTDLIB_VENDOR_ID; /* SBSW_VSTDLIB_ACCESS_VERSIONINFO */ + versioninfo->moduleID = VSTDLIB_MODULE_ID; /* SBSW_VSTDLIB_ACCESS_VERSIONINFO */ + versioninfo->sw_major_version = VSTDLIB_SW_MAJOR_VERSION; /* SBSW_VSTDLIB_ACCESS_VERSIONINFO */ + versioninfo->sw_minor_version = VSTDLIB_SW_MINOR_VERSION; /* SBSW_VSTDLIB_ACCESS_VERSIONINFO */ + versioninfo->sw_patch_version = VSTDLIB_SW_PATCH_VERSION; /* SBSW_VSTDLIB_ACCESS_VERSIONINFO */ + } + + /* ----- Development Error Report ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if (errorId != VSTDLIB_E_NO_ERROR) + { + (void) Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_GET_VERSION_INFO, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ +# endif +} /* VStdLib_GetVersionInfo() */ + +#endif /* VSTDLIB_VERSION_INFO_API == STD_ON */ + +#if (VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosOne8() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosOne8(uint8 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get the bit position of the highest set bit */ + pos = VStdLib_Loc_GetHighestBitPosOneInByte(value); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosZero8() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosZero8(uint8 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_ONE_BYTE) + { + /* #110 Get the bit position of the highest unset bit */ + pos = VStdLib_Loc_GetHighestBitPosOneInByte((uint8)(~value)); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosOne8() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosOne8(uint8 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get the bit position of the lowest set bit */ + pos = VStdLib_Loc_GetLowestBitPosOneInByte(value); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosZero8() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosZero8(uint8 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_ONE_BYTE) + { + /* #110 Get the bit position of the lowest unset bit */ + pos = VStdLib_Loc_GetLowestBitPosOneInByte((uint8)(~value)); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingOnes8() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingOnes8(uint8 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_ONE_BYTE) + { + /* #110 Get count of leading ones */ + cnt = (uint8) (7u - VStdLib_Loc_GetHighestBitPosOneInByte((uint8)(~value))); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingZeros8() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingZeros8(uint8 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get count of leading zeros */ + cnt = (uint8) (7u - VStdLib_Loc_GetHighestBitPosOneInByte(value)); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingOnes8() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingOnes8(uint8 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_ONE_BYTE) + { + /* #110 Get count of trailing ones */ + cnt = VStdLib_Loc_GetLowestBitPosOneInByte((uint8)(~value)); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingZeros8() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingZeros8(uint8 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get count of trailing zeros */ + cnt = VStdLib_Loc_GetLowestBitPosOneInByte(value); + } + + return cnt; +} + +#endif /* VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON */ + +#if (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosOne16() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosOne16(uint16 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get the bit position of the highest set bit */ + pos = VStdLib_Loc_GetHighestBitPosOneInTwoBytes(value); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosZero16() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosZero16(uint16 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_TWO_BYTES) + { + /* #110 Get the bit position of the highest unset bit */ + pos = VStdLib_Loc_GetHighestBitPosOneInTwoBytes((uint16)(~value)); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosOne16() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosOne16(uint16 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get the bit position of the lowest set bit */ + pos = VStdLib_Loc_GetLowestBitPosOneInTwoBytes(value); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosZero16() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosZero16(uint16 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_TWO_BYTES) + { + /* #110 Get the bit position of the lowest unset bit */ + pos = VStdLib_Loc_GetLowestBitPosOneInTwoBytes((uint16)(~value)); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingOnes16() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingOnes16(uint16 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_TWO_BYTES) + { + /* #110 Get count of leading ones */ + cnt = (uint8) (15u - VStdLib_Loc_GetHighestBitPosOneInTwoBytes((uint16)(~value))); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingZeros16() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingZeros16(uint16 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get count of leading zeros */ + cnt = (uint8) (15u - VStdLib_Loc_GetHighestBitPosOneInTwoBytes(value)); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingOnes16() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingOnes16(uint16 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_TWO_BYTES) + { + /* #110 Get count of trailing ones */ + cnt = VStdLib_Loc_GetLowestBitPosOneInTwoBytes((uint16)(~value)); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingZeros16() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingZeros16(uint16 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get count of trailing zeros */ + cnt = VStdLib_Loc_GetLowestBitPosOneInTwoBytes(value); + } + + return cnt; +} + +#endif /* VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON */ + +#if (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosOne32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosOne32(uint32 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get the bit position of the highest set bit */ + pos = VStdLib_Loc_GetHighestBitPosOneInFourBytes(value); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosZero32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosZero32(uint32 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_FOUR_BYTES) + { + /* #110 Get the bit position of the highest unset bit */ + pos = VStdLib_Loc_GetHighestBitPosOneInFourBytes((uint32)(~value)); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosOne32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosOne32(uint32 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get the bit position of the lowest set bit */ + pos = VStdLib_Loc_GetLowestBitPosOneInFourBytes(value); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosZero32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosZero32(uint32 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_FOUR_BYTES) + { + /* #110 Get the bit position of the lowest unset bit */ + pos = VStdLib_Loc_GetLowestBitPosOneInFourBytes((uint32)(~value)); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingOnes32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingOnes32(uint32 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_FOUR_BYTES) + { + /* #110 Get count of leading ones */ + cnt = (uint8) (31u - VStdLib_Loc_GetHighestBitPosOneInFourBytes((uint32)(~value))); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingZeros32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingZeros32(uint32 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get count of leading zeros */ + cnt = (uint8) (31u - VStdLib_Loc_GetHighestBitPosOneInFourBytes(value)); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingOnes32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingOnes32(uint32 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_FOUR_BYTES) + { + /* #110 Get count of trailing ones */ + cnt = VStdLib_Loc_GetLowestBitPosOneInFourBytes((uint32)(~value)); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingZeros32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingZeros32(uint32 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get count of trailing zeros */ + cnt = VStdLib_Loc_GetLowestBitPosOneInFourBytes(value); + } + + return cnt; +} + +#endif /* VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON */ + +#if ((defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosOne64() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosOne64(uint64 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get the bit position of the highest set bit */ + pos = VStdLib_Loc_GetHighestBitPosOneInEightBytes(value); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosZero64() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosZero64(uint64 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_EIGHT_BYTES) + { + /* #110 Get the bit position of the highest unset bit */ + pos = VStdLib_Loc_GetHighestBitPosOneInEightBytes((uint64)(~value)); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosOne64() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosOne64(uint64 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get the bit position of the lowest set bit */ + pos = VStdLib_Loc_GetLowestBitPosOneInEightBytes(value); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosZero64() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosZero64(uint64 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 pos = VSTDLIB_BITPOS_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_EIGHT_BYTES) + { + /* #110 Get the bit position of the lowest unset bit */ + pos = VStdLib_Loc_GetLowestBitPosOneInEightBytes((uint64)(~value)); + } + + return pos; +} + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingOnes64() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingOnes64(uint64 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_EIGHT_BYTES) + { + /* #110 Get count of leading ones */ + cnt = (uint8) (63u - VStdLib_Loc_GetHighestBitPosOneInEightBytes((uint64)(~value))); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingZeros64() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingZeros64(uint64 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get count of leading zeros */ + cnt = (uint8) (63u - VStdLib_Loc_GetHighestBitPosOneInEightBytes(value)); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingOnes64() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingOnes64(uint64 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one unset bit */ + if (value != VSTDLIB_MASK_ALLBITS_IN_EIGHT_BYTES) + { + /* #110 Get count of trailing ones */ + cnt = VStdLib_Loc_GetLowestBitPosOneInEightBytes((uint64)(~value)); + } + + return cnt; +} + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingZeros64() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingZeros64(uint64 value) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 cnt = VSTDLIB_BITCNT_NA; + + /* ----- Implementation ----------------------------------------------- */ + /* #100 Verify that the passed value contains at least one set bit */ + if (value != 0u) + { + /* #110 Get count of trailing zeros */ + cnt = VStdLib_Loc_GetLowestBitPosOneInEightBytes(value); + } + + return cnt; +} + +#endif /* (defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) */ + +#define VSTDLIB_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * MISRA JUSTIFICATIONS + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_VStdLib_NoCaseBreak: + Reason: Break statements are omitted due to performance reasons when using jump tables. + Risk: Resulting code is misleading. + Prevention: Code comments, code inspection and test of the different variants in the component test. + + MD_VStdLib_ParamMod: + Reason: Pointers and counts given as function parameters are modified during different algorithm stages. + Risk: Wrong pointer access is performed. + Prevention: Silent analysis, code inspection and test of the different variants in the component test. + + MD_VStdLib_ParamValueMod: + Reason: The direct modification of the function parameter leads to code which is easier to read and maintain. + Risk: Incorrect expectation of the value of the modified function parameter. + Prevention: Code inspection and test of the different variants in the component test. + + MD_VStdLib_PtrCast: + Reason: Pointer is casted as different memory access sizes are utilized due to performance reasons. + Risk: Wrong pointer access is performed. + Prevention: Code inspection and test of the different variants in the component test. + + MD_VStdLib_PtrCastToInt: + Reason: Pointer is casted to an integral type in order to get the target alignment. + Risk: None, as only LSBs are evaluated. + Prevention: None. + + MD_VStdLib_Para2ConstPtr + Reason: The address of a parameter is stored in a constant pointer in order to use the VStdLib_MemCpy(). + Risk: None. + Prevention: None. + + MD_VStdLib_NotUsedInUnit: + Reason: Static inline function is not used within this translation unit, because it is intended to be used as + a inline function by other modules. + Risk: None. + Prevention: None. + + MD_VStdLib_FileScope: + Reason: Constant tables are kept at a central location for a better overview and maintenance. + Risk: None. + Prevention: None. + + MD_VStdLib_Metrics: + Reason: No separation of functionality due to performance reasons when using jump tables. + Risk: None, as the complexity arises from one single switch statement. + Prevention: None. + +*/ + +/*********************************************************************************************************************** + * SILENTBSW JUSTIFICATIONS + **********************************************************************************************************************/ + +/* SBSW_JUSTIFICATION_BEGIN + + \ID SBSW_VSTDLIB_CALL_UNMODIFIED + \DESCRIPTION A function is called with unmodified 'pDst' and 'nCnt' parameters. + \COUNTERMEASURE \N The caller of the function ensures that 'pDst' and 'nCnt' are valid. These parameters are passed + to the callee without modifications. If the parameters are casted there are no side effects. + + \ID SBSW_VSTDLIB_CALL_MODIFIED_CNT + \DESCRIPTION A static function is called with unmodified 'pDst' parameter and a modified 'nCnt' parameter. + \COUNTERMEASURE \N The caller of the function ensures that 'pDst' and 'nCnt' are valid. The offset value is + always smaller than 4 due to VSTDLIB_ALIGN_OFFSET() and 'nCnt' is 32 or higher at this point. + Therefore 'pDst' and 'nCnt' for the callee are valid. + + \ID SBSW_VSTDLIB_CALL_MODIFIED_IDX + \DESCRIPTION A static function is called with unmodified 'pDst' parameter starting at a specific offset and a modified + 'nCnt' parameter. + \COUNTERMEASURE \N The caller of the function ensures that 'pDst' starting at offset and 'nCnt' are valid. The index + is always smaller equal to 'nCnt' bits starting at offset. Therefore 'pDst' starting at a + specific offset and 'nCnt' are valid for the callee. + + \ID SBSW_VSTDLIB_CALL_CONVERTED_BITCNT + \DESCRIPTION A static function is called with unmodified 'pDst' parameter starting at a specific offset and a modified + 'nCnt' parameter. + \COUNTERMEASURE \N The caller of the function ensures that 'pDst' and 'nCnt' are valid. 'nCntInBytes' is 'nCnt' + devided by 8. The devision by 8 converts the bit count in a valid byte count where the byte count + defines the same range as the bit count in a different format. Therefore 'pDst' starting at a + specific offset and 'nCnt' are valid for the callee. + + \ID SBSW_VSTDLIB_CALL_CONVERTED_BITOFFSET + \DESCRIPTION A static function is called with unmodified 'pDst' starting at a specific offset and 'nCnt' parameters + but converted offset parameter(s). + \COUNTERMEASURE \N The caller of the function ensures that 'pDst' starting at offset is valid for 'nCnt' bits. + The conversion changes offset numbering from sawtooth to monotone or from monotone to sawtooth. + The change of the value of the offset from one numbering method to the other is 7 at most. The + offset is therfore still within the same byte. Thus the start byte and the end byte don't change + when converting bit counting numbering. Therefore 'pDst' starting at a specific offset and 'nCnt' + are valid for the callee. + + \ID SBSW_VSTDLIB_CALL_MODIFIED_PTR_CNT + \DESCRIPTION A static function can be called with unmodified or modified 'pDst' and 'nCnt' parameters. + \COUNTERMEASURE \N The caller of the function ensures that 'pDst' and 'nCnt' are valid. In case the function is + called with modified parameters (pointer alignment was performed), 'pDst' is incremented by + the value of 'nDstOffset' and 'nCnt' is decremented by the same value. Therefore 'pDst' + and 'nCnt' for the callee are valid. + + \ID SBSW_VSTDLIB_ACCESS_LOOP + \DESCRIPTION Linear memory access using a for loop. + \COUNTERMEASURE \N The caller of this function ensures that 'pDst' and 'nCnt' are valid. The for loop ensures that + the loop index is always smaller than nCnt. Therefore only valid memory is accessed. + + \ID SBSW_VSTDLIB_ACCESS_LOOP_ENDIDX + \DESCRIPTION Linear memory access using a for loop. + \COUNTERMEASURE \N The caller of this function ensures that 'pDst' starting at a specific offset and 'nCnt' bits are + valid. The for loop ensures that the loop index is always smaller than the length of the first and + last byte to copy to (number of iterations) which is determined with 'nCnt' bits starting a specific + destination offset. Therefore only valid memory is accessed. + + \ID SBSW_VSTDLIB_ACCESS_8_JUMPTABLE + \DESCRIPTION Linear 8-bit-access using a switch statement. + \COUNTERMEASURE \N The caller of this function ensures that 'pDst' and 'nCnt' are valid. The constant indices are + always smaller than the value of 'nCnt'. Therefore only valid memory is accessed. + + \ID SBSW_VSTDLIB_ACCESS_8 + \DESCRIPTION Linear 8-bit-access. + \COUNTERMEASURE \N The caller of this function ensures that 'pDst' starting at a specific offset and 'dstByteIdx' are + valid. Therefore only valid memory is accessed. + + \ID SBSW_VSTDLIB_ACCESS_32_LOOP + \DESCRIPTION Linear 32-bit-access using a for loop. + \COUNTERMEASURE \N The caller of this function ensures that 'pDst' and 'nCnt' are valid. The access index 'dPos' + is initialized with 0. The loop control variable 'remaining' is decremented by 16 per iteration. + The exit condition ensures that at least 16 bytes are valid per iteration. The access index + 'dPos' plus constant offset ensures that exactly 16 valid bytes are accessed. 'dPos' is + incremented by 4 (that equals 16 bytes) after the access. + + \ID SBSW_VSTDLIB_ACCESS_32_LOOP_REMAINING + \DESCRIPTION Linear 32-bit-access using a for loop. + \COUNTERMEASURE \N The caller of this function ensures that 'pDst' and 'nCnt' are valid. After the for loop above + 'remaining' bytes of valid memory start at the address that is indicated by 'dPos'. The loop + control variable 'remaining' is decremented by 4 per iteration. The exit condition ensures that + at least 4 bytes are valid per iteration. The access index 'dPos' ensures that exactly 4 valid + bytes are accessed. 'dPos' is incremented by 1 (that equals 4 bytes) after the access. + + \ID SBSW_VSTDLIB_ACCESS_32_JUMPTABLE + \DESCRIPTION Linear 32-bit-access using a switch statement. + \COUNTERMEASURE \N The caller of this function ensures that 'pDst' and 'nCnt' are valid. After the for loop above + 'remaining' bytes of valid memory start at the address that is indicated by 'dPos'. The switch + statement ensures that an access is only made if at least 4 byte are valid. 'dPos' is + incremented by 4 after the access. + + \ID SBSW_VSTDLIB_CALL_REMAINING_JUMPTABLE + \DESCRIPTION A static function is called to access the remaining bytes at the end of processing a 32-bit jump table. + \COUNTERMEASURE \N The caller of this function ensures that 'pDst' and 'nCnt' are valid. At this point 0-3 + bytes of valid memory (indicated by the LSBs of 'remaining') start at the address that is + indicated by 'dPos'. Due to the usage of VSTDLIB_MASK_3 'pDst' and 'nCnt' for the callee are + valid. + + \ID SBSW_VSTDLIB_CALL_REMAINING + \DESCRIPTION A static function is called to access the remaining bytes after 32-bit operations. + \COUNTERMEASURE \N The caller of this function ensures that 'pDst' and 'nCnt' are valid. After the for loop above + 'remaining' bytes of valid memory start at the address that is indicated by 'dPos'. Therefore + 'pDst' and 'nCnt' for the callee are valid. + + \ID SBSW_VSTDLIB_CALL_REMAINING_PARTIAL + \DESCRIPTION A static function is called to access the remaining partial word after 32-bit displacement operations. + \COUNTERMEASURE \N The caller of this function ensures that 'pDst' and 'nCnt' are valid. At this point at least + (4 - 'nDstOffset') bytes of valid memory start at the address that is indicated by 'dPos'. + Therefore 'pDst' and 'nCnt' for the callee are valid. + + \ID SBSW_VSTDLIB_ACCESS_LOCAL + \DESCRIPTION Access to a pointer referencing a local variable. + \COUNTERMEASURE \N The function is only called with valid pointers to local variables. + + \ID SBSW_VSTDLIB_ACCESS_STRUCT_LOCAL + \DESCRIPTION Access to a pointer referencing a local structure. + \COUNTERMEASURE \N The function is only called with valid pointers to local structures. The structure elements + are modified. + + \ID SBSW_VSTDLIB_CALL_NO_PTR_WRITE + \DESCRIPTION The static function is called with pointer parameters. The pointers are only accessed for reading. + \COUNTERMEASURE \N None. + + \ID SBSW_VSTDLIB_CALL_MODIFIABLE_RETVAL + \DESCRIPTION A static function is called with a pointer parameter 'pRetval' which can be possibly modified. + \COUNTERMEASURE \N The caller of the function ensures that 'pRetVal' is valid. + + \ID SBSW_VSTDLIB_CALL_MODIFIABLE_SRCBYTE + \DESCRIPTION A static function is called with a pointer parameter 'pSrcByte' which is modified. + \COUNTERMEASURE \N The caller of the function ensures that 'pSrcByte' is valid. + + \ID SBSW_VSTDLIB_CALL_MODIFIABLE_ITER + \DESCRIPTION A static function is called with a pointer parameter to a structure 'pSrcIter' or 'pDstIter' where + the structure elements are modified. + \COUNTERMEASURE \N The caller of the function ensures that 'pSrcIter' or 'pDstIter' is valid. + + \ID SBSW_VSTDLIB_ACCESS_VERSIONINFO + \DESCRIPTION The function VStdLib_GetVersionInfo() writes to the object referenced by parameter 'versioninfo'. + \COUNTERMEASURE \N The caller ensures that the pointer passed to the parameter 'versioninfo' is valid and references + an object of type Std_VersionInfoType. + + \ID SBSW_VSTDLIB_ACCESS_PASSED_ARRAY + \DESCRIPTION Write access to an element of an array. + The array is referenced by a pointer parameter. The element is accessed by a static index. + \COUNTERMEASURE \N [CM_VSTDLIB_ARRAY] + + \ID SBSW_VSTDLIB_ACCESS_PASSED_INT + \DESCRIPTION Write access to the integer variable which is referenced by a pointer parameter. + \COUNTERMEASURE \N The caller ensures that the pointer references a valid variable. + + \ID SBSW_VSTDLIB_CALL_MEM_CPY + \DESCRIPTION The function VStdLib_MemCpy is called with the pointer parameter to an array from the caller + and a static size for the number of bytes to copy. + \COUNTERMEASURE \N [CM_VSTDLIB_ARRAY] + + \ID SBSW_VSTDLIB_CALL_CNV_ARRAY_TO_UINT + \DESCRIPTION The function VStdLib_ConvertUint8ArrayToUint[16,32,64][Big,Little]Endian is called with the pointer + parameter to an array from the caller. + \COUNTERMEASURE \N [CM_VSTDLIB_ARRAY] + +SBSW_JUSTIFICATION_END */ + +/* +\CM CM_VSTDLIB_ARRAY The caller ensures that the referenced array is valid for the required size. +*/ + +/********************************************************************************************************************** + * FETA JUSTIFICATIONS + *********************************************************************************************************************/ + +/* FETA_JUSTIFICATION_BEGIN + +\ID FETA_VSTDLIB_LOC_MEMSET_X_X +\DESCRIPTION Function parameter [nCnt] specifies the number of iterations to use to initialize the destination with a + pattern value. +\COUNTERMEASURE \N [CM_VSTDLIB_PARA_NCNT] + +\ID FETA_VSTDLIB_CALL_LOC_MEMSET_8_X_REMAINING +\DESCRIPTION Function parameter [nCnt] from the callee (VStdLib_Loc_MemSet_8_3 or VStdLib_Loc_MemSet_8_31) specifies + the number of iteration to use to initialize the destination with a pattern value. + The value for [nCnt] is determined within this caller. The correctness of the function parameter [nCnt] + from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_MEMSET_X_X. +\COUNTERMEASURE \D VStdLib_Loc_MemSet_32_Aligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMSET_8_3 +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemSet_8_3() specifies the number of iterations to use + to initialize the destination with a pattern value. + The value for [nCnt] is determined within this caller. +\COUNTERMEASURE \D VStdLib_MemSet + +\ID FETA_VSTDLIB_CALL_LOC_MEMSET_X_X +\DESCRIPTION Function parameter [nCnt] from callee (VStdLib_Loc_MemSet_8_31 or VStdLib_Loc_MemSet_32_Aligned) specifies + the number of iterations to use to initialize the destination with a pattern value. + The value for [nCnt] is the value of the caller's function parameter [nCnt]. + The user of the caller (service function VStdLib_MemSet) has to ensure the correctness of value for [nCnt]. +\COUNTERMEASURE \S SMI-494148 + +\ID FETA_VSTDLIB_MEMSET +\DESCRIPTION Function parameter [nCnt] specifies the number of iteration to use to initialize the destination with a + pattern value. + The user of the service function VStdLib_MemSet has to ensure the correctness of value for [nCnt]. +\COUNTERMEASURE \S SMI-494148 + +\ID FETA_VSTDLIB_MEMSET_MACRO +\DESCRIPTION Function parameter [nCnt] specifies the number of iteration to use to initialize the destination with a + pattern value. + The user of the macro has to ensure the correctness of value for [nCnt]. +\COUNTERMEASURE \S SMI-494148 + + +\ID FETA_VSTDLIB_LOC_MEMCPY_X_X +\DESCRIPTION Function parameter [nCnt] specifies the number of iterations to use to copy data from source to destination. +\COUNTERMEASURE \N [CM_VSTDLIB_PARA_NCNT] + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPY_8_X_REMAINING +\DESCRIPTION Function parameter [nCnt] from the callee (VStdLib_Loc_MemCpy_8_3 or VStdLib_Loc_MemCpy_8_31) specifies + the number of iteration to use to copy data from source to destination. + The value for [nCnt] is determined within this caller. The correctness of the function parameter [nCnt] + from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_MEMCPY_X_X. +\COUNTERMEASURE \D VStdLib_Loc_MemCpy_32_Aligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPY_8_31_REMAINING +\DESCRIPTION Function parameter [nCnt] from calee VStdLib_Loc_MemCpy_8_31 specifies the number of iteration to use to + copy data from source to destination. + The value for [nCnt] is determined within this caller. The correctness of the function parameter [nCnt] + from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_MEMCPY_X_X. +\COUNTERMEASURE \D VStdLib_Loc_MemCpy_32_Unaligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPY_8_3 +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemCpy_8_3() specifies the number of iterations to use + to copy data from source to destination. + The value for [nCnt] is determined within this caller. +\COUNTERMEASURE \D VStdLib_MemCpy + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPY_X_X +\DESCRIPTION Function parameter [nCnt] from callee (VStdLib_Loc_MemCpy_8_31 or VStdLib_Loc_MemCpy_32_Aligned or + VStdLib_Loc_MemCpy_32_Unaligned) specifies the number of iterations to use to copy data from source to + destination. + The value for [nCnt] is the value of the caller's function parameter [nCnt]. + The user of the caller (service function VStdLib_MemCpy) has to ensure the correctness of value for [nCnt]. +\COUNTERMEASURE \S SMI-494148 + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPY_8_PARTIALWORD +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemCpy_8_PartialWord specifies the number of iteration + to use to copy data from source to destination. + The value for [nCnt] is set by the caller to the value of its function parameter [nDstOffset]. +\COUNTERMEASURE \N CM_VSTDLIB_PARA_NCNT + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPY_8_PARTIALWORD_CALC +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemCpy_8_PartialWord specifies the number of iteration + to use to copy data from source to destination. + The value for [nCnt] is determined (4u - nDstOffset) within this caller. The correctness of the function + parameter [nDstOffset] from the caller used for the determination is ensured by + FETA_VSTDLIB_CALL_LOC_MEMCPY_32_UNALIGNED_NDSTOFFSET. +\COUNTERMEASURE \D VStdLib_Loc_MemCpy_32_Unaligned + +\ID FETA_VSTDLIB_LOC_MEMCPY_32_UNALIGNED +\DESCRIPTION Local variable [remaining] specifies the number of iteration to use to copy data from source to destination. + The value of [remaining] is determined within this caller. The correctness of the function + parameter [nCnt] from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_MEMCPY_X_X. +\COUNTERMEASURE \D VStdLib_Loc_MemCpy_32_Unaligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPY_32_UNALIGNED_NDSTOFFSET +\DESCRIPTION Function parameter [nDstOffset] from VStdLib_Loc_MemCpy_32_Unaligned specifies the number of iteration to + use to copy data from source to destination. + The value (0, 1, 2 or 3) for [nDstOffset] is determined within this caller. +\COUNTERMEASURE \D VStdLib_MemCpy + +\ID FETA_VSTDLIB_MEMCPY +\DESCRIPTION Function parameter [nCnt] specifies the number of iterations to use to copy data from source to destination. + The user of the service function VStdLib_MemCpy or VStdLib_MemCpy16 or VStdLib_MemCpy32 has to ensure the + correctness of value for [nCnt]. +\COUNTERMEASURE \S SMI-494148 + +\ID FETA_VSTDLIB_CALL_MEMCPY +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_MemCpy specifies the number of iterations to use to copy + data from source to destination. + The value for [nCnt] is the value of the caller's function parameter [nCnt]. + The user of the caller (service function VStdLib_MemCpy_s, VStdLib_MemCpy_Return_s or VStdLib_MemCpySwapEndian) has to ensure the + correctness of value for [nCnt]. +\COUNTERMEASURE \S SMI-494148 + +\ID FETA_VSTDLIB_MEMCPY_MACRO +\DESCRIPTION Function parameter [nCnt] specifies the number of iterations to use to copy data from source to destination. + The user of the macro has to ensure the correctness of value for [nCnt]. +\COUNTERMEASURE \S SMI-494148 + +\ID FETA_VSTDLIB_CALL_MEMCPY_MACRO +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_MemCpyMacro specifies the number of iterations to use to + copy data from source to destination. + The value for [nCnt] is the value of the caller's function parameter [nCnt]. + The user of the caller (macro VStdLib_MemCpyMacro_s) has to ensure the correctness of value for [nCnt]. +\COUNTERMEASURE \S SMI-494148 + + +\ID FETA_VSTDLIB_LOC_MEMCMP_X_X +\DESCRIPTION Function parameter [nCnt] specifies the number of iterations to use to compare data from buffer1 with + buffer2. +\COUNTERMEASURE \N CM_VSTDLIB_PARA_NCNT + +\ID FETA_VSTDLIB_CALL_LOC_MEMCMP_8_ALIGNED_REMAINING +\DESCRIPTION Function parameter [nCnt] from the callee VStdLib_Loc_MemCmp_32_Aligned specifies the number of iteration + to use to compare data from buffer1 with buffer2. + The value for [nCnt] is determined within this caller. The correctness of the function parameter [nCnt] + from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_MEMCMP_X_X. +\COUNTERMEASURE \D VStdLib_Loc_MemCmp_32_Aligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMCMP_X_X +\DESCRIPTION Function parameter [nCnt] from callee (VStdLib_Loc_MemCmp_8 or VStdLib_MemCmp_32_Aligned or + VStdLib_MemCmp_32_Unaligned) specifies the number of iterations to use to compare data from buffer1 with + buffer2. + The value for [nCnt] is the value of the caller's function parameter [nCnt]. + The user of the caller (service function VStdLib_MemCmp) has to ensure the correctness of value for [nCnt]. +\COUNTERMEASURE \S SMI-494148 + +\ID FETA_VSTDLIB_CALL_LOC_MEMCMP_8_NBUF2OFFSET +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemCmp_8 specifies the number of iteration to use to + compare data from buffer1 with buffer2. + The value for [nCnt] is set by the caller to the value of its function parameter [nBuf2Offset]. +\COUNTERMEASURE \N CM_VSTDLIB_PARA_NCNT + +\ID FETA_VSTDLIB_CALL_LOC_MEMCMP_8_CALC +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemCmp_8 specifies the number of iteration to use to + compare data from buffer1 with buffer2. + The value for [nCnt] is determined (4u - nBuf2Offset) within this caller. The correctness of the function + parameter [nBuf2Offset] from the caller used for the determination is ensured by + FETA_VSTDLIB_CALL_LOC_MEMCMP_32_UNALIGNED_NBUF2OFFSET. +\COUNTERMEASURE \D VStdLib_Loc_MemCmp_32_Unaligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMCMP_8_UNALIGNED_REMAINING +\DESCRIPTION Function parameter [nCnt] from the callee VStdLib_Loc_MemCmp_32_Unaligned specifies the number of iteration + to use to compare data from buffer1 with buffer2. + The value for [nCnt] is determined within this caller. The correctness of the function parameter [nCnt] + from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_MEMCMP_X_X. +\COUNTERMEASURE \D VStdLib_Loc_MemCmp_32_Unaligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMCMP_8_NBUF1OFFSET +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemCmp_8 specifies the number of iteration to use to + compare data from buffer1 with buffer2. + The value (0, 1, 2 or 3) for [nCnt] is determined within this caller. +\COUNTERMEASURE \D VStdLib_MemCmp + +\ID FETA_VSTDLIB_LOC_MEMCMP_32_UNALIGNED +\DESCRIPTION Local variable [remaining] specifies the number of iteration to use to compare data from buffer1 with + buffer2. + The value of [remaining] is determined within this caller. The correctness of the function + parameter [nCnt] from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_MEMCMP_X_X. +\COUNTERMEASURE \D VStdLib_Loc_MemCpy_32_Unaligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMCMP_32_UNALIGNED_NBUF2OFFSET +\DESCRIPTION Function parameter [nBuf2Offset] from VStdLib_Loc_MemCmp_32_Unaligned specifies the number of iteration to + compare data from buffer1 with buffer2. + The value (0, 1, 2 or 3) for [nBuf2Offset] is determined within this caller. +\COUNTERMEASURE \D VStdLib_MemCmp + + +\ID FETA_VSTDLIB_LOC_MEMCPYSWAPENDIAN_X_X +\DESCRIPTION Function parameter [nCnt] specifies the number of iterations to use to copy and swap data from source to + destination. +\COUNTERMEASURE \N [CM_VSTDLIB_PARA_NCNT] + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INTX_X +\DESCRIPTION Function parameter [nCnt] from callee (VStdLib_Loc_MemCpySwapEndian_Int16_32 or + VStdLib_Loc_MemCpySwapEndian_Int32_32 or VStdLib_Loc_MemCpySwapEndian_Int64_32 or + VStdLib_Loc_MemCpySwapEndianInt16_32_Aligned or VStdLib_Loc_MemCpySwapEndianInt32_32_Aligned or + VStdLib_Loc_MemCpySwapEndianInt64_32_Aligned) specifies the number of iterations to use to copy and swap + data from source to destination. + The value for [nCnt] is set by the caller to the value of its function parameter [nCnt]. +\COUNTERMEASURE \N [CM_VSTDLIB_PARA_NCNT] + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INT16_32_REMAINING +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemCpySwapEndian_Int16_32 specifies the number of + iterations to use to copy and swap data from source to destination. + The value for [nCnt] is determined within this caller. The correctness of the function parameter [nCnt] + from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INTX_X. +\COUNTERMEASURE \D VStdLib_Loc_MemCpySwapEndianInt16_32_Aligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INT32_32_REMAINING +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemCpySwapEndian_Int32_32 specifies the number of + iterations to use to copy and swap data from source to destination. + The value for [nCnt] is determined within this caller. The correctness of the function parameter [nCnt] + from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INTX_X. +\COUNTERMEASURE \D VStdLib_Loc_MemCpySwapEndianInt32_32_Aligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INT64_32_REMAINING +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemCpySwapEndian_Int64_32 specifies the number of + iterations to use to copy and swap data from source to destination. + The value for [nCnt] is determined within this caller. The correctness of the function parameter [nCnt] + from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_INTX_X. +\COUNTERMEASURE \D VStdLib_Loc_MemCpySwapEndianInt64_32_Aligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMCPYSWAPENDIAN_X_X +\DESCRIPTION Function parameter [nCnt] from callee (VStdLib_Loc_MemCpySwapEndian_IntType_32 or + VStdLib_Loc_MemCpySwapEndian_32_Aligned or VStdLib_Loc_MemCpySwapEndian) specifies the number of + iterations to use to compare data from buffer1 with buffer2. + The value for [nCnt] is the value of the caller's function parameter [nCnt]. + The user of the caller (service function VStdLib_MemCpySwapEndian) has to ensure the correctness of value + for [nCnt]. +\COUNTERMEASURE \S SMI-494148 + +\ID FETA_VSTDLIB_CALL_MEMCPYSWAPENDIAN +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_MemCpySwapEndian specifies the number of iterations to use + to copy and swap data from source to destination. + The value for [nCnt] is the value of the caller's function parameter [nCnt]. + The user of the caller (service function VStdLib_MemCpySwapEndian_s) has to ensure the + correctness of value for [nCnt]. +\COUNTERMEASURE \S SMI-494148 + + +\ID FETA_VSTDLIB_LOC_MEMCHECK_X_NCNT +\DESCRIPTION Function parameter [nCnt] specifies the number of iterations to use to check data from buffer against a + pattern. +\COUNTERMEASURE \N CM_VSTDLIB_PARA_NCNT + +\ID FETA_VSTDLIB_LOC_MEMCHECK_X_RETVAL +\DESCRIPTION Local variable [retVal] is used to break the loop before [nCnt] iterations when the check detects a + mismatch. + The value for [retVal] is determined for each iteration by the called function + VStdLib_Loc_GetMemCheckResult. +\COUNTERMEASURE \D DSGN-VStdLib-MemCheck + +\ID FETA_VSTDLIB_CALL_LOC_MEMCHECK_8_REMAINING +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemCheck_8 specifies the number of iterations to use to + check data from buffer against a pattern. + The value for [nCnt] is determined within this caller. The correctness of the function parameter [nCnt] + from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_MEMCHECK_X. +\COUNTERMEASURE \D VStdLib_Loc_MemCheck_32_Aligned + +\ID FETA_VSTDLIB_CALL_LOC_MEMCHECK_8_NBUFOFFSET +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_Loc_MemCheck_8 specifies the number of iterations to use to + check data from buffer against a pattern. + The value (0, 1, 2 or 3) for [nCnt] is determined within this caller. +\COUNTERMEASURE \D VStdLib_MemCheck + +\ID FETA_VSTDLIB_CALL_LOC_MEMCHECK_X +\DESCRIPTION Function parameter [nCnt] from callee (VStdLib_Loc_MemCheck_8 or VStdLib_Loc_MemCheck_32_Aligned) + specifies the number of iterations to use to check data from buffer against a pattern. + The value for [nCnt] is the value of the caller's function parameter [nCnt]. + The user of the caller (service function VStdLib_MemCheck) has to ensure the correctness of value for + [nCnt]. +\COUNTERMEASURE \S SMI-494148 + + +\ID FETA_VSTDLIB_LOC_BITCPYSWAPENDIAN +\DESCRIPTION The function parameter [pDstIter] is a pointer to a local struct. The struct holds the integer element + [lastByte]. [lastByte] specifies the number of iterations to use to copy data from source to destination. +\COUNTERMEASURE \N Caller ensures correctness of value [lastByte] from function parameter [pDstIter] + +\ID FETA_VSTDLIB_CALL_LOC_BITCPYSWAPENDIAN +\DESCRIPTION The function parameter [pDstIter] from the callee VStdLib_Loc_BitCpySwapEndian is a pointer to a local struct. + The struct holds the integer element [lastByte]. [lastByte] specifies the number of iterations to use to copy + data from source to destination. The value for [lastByte] is determined within this caller by the local + function VStdLib_Loc_BitCpyIter. The correctness of the function parameters [nCnt] and + [nDstBitOffsetSaw/nDstBitOffsetMon] from the caller used for the determination is ensured by + FETA_VSTDLIB_CALL_LOC_BITCPY. +\COUNTERMEASURE \D VStdLib_Loc_BitCpyBigToLittleEndian or VStdLib_Loc_BitCpyLittleToBigEndian + +\ID FETA_VSTDLIB_CALL_MEMCPY_IN_LOC_BITCPY +\DESCRIPTION Function parameter [nCnt] from callee VStdLib_MemCpy specifies the number of iterations to use to copy data + from source to destination. The value for [nCnt] is determined within this caller. The correctness of the + function parameter [nCnt] from the caller used for the determination is ensured by FETA_VSTDLIB_CALL_LOC_BITCPY. +\COUNTERMEASURE \D VStdLib_Loc_BitCpyBigToBigEndian or VStdLib_Loc_BitCpyLittleToLittleEndian + +\ID FETA_VSTDLIB_LOC_BITCPY +\DESCRIPTION Function parameters [nCnt] and [nDstBitOffsetSaw/nDstBitOffsetMon] are used by the local function VStdLib_Loc_BitCpyIter + to determine number of iterations to use to copy data from source to destination. The correctness of the function + parameters [nCnt] and [nDstBitOffsetSaw/nDstBitOffsetMon] from the caller used for the determination is ensured by + FETA_VSTDLIB_CALL_LOC_BITCPY. +\COUNTERMEASURE \D DSGN-VStdLib-BitCpy + +\ID FETA_VSTDLIB_CALL_LOC_BITCPY +\DESCRIPTION Function parameters [nCnt] and [nDstBitOffsetSaw/nDstBitOffsetMon] from the callee are used to determine the number + of iterations to use to copy data from source to destination. The value for [nCnt] is the value of the caller's function + parameter [nCnt]. The user of the caller (service functions for BitCpy) has to ensure the correctness of + value for [nCnt] and [nDstBitOffsetSaw/nDstBitOffsetMon]. +\COUNTERMEASURE \S SMI-494148 + +FETA_JUSTIFICATION_END */ + +/* +\CM CM_VSTDLIB_PARA_NCNT Caller ensures correctness of value for function parameter [nCnt]. +*/ + +/********************************************************************************************************************** + * END OF FILE: vstdlib.c + *********************************************************************************************************************/ diff --git a/Source/bsw/VStdLib/vstdlib.h b/Source/bsw/VStdLib/vstdlib.h new file mode 100644 index 0000000..c3eebba --- /dev/null +++ b/Source/bsw/VStdLib/vstdlib.h @@ -0,0 +1,4362 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/*! \file vstdlib.h + * \brief Interface of the generic Vector Standard Library (VStdLib_GenericAsr) + * \details This is the header file of the VStdLib. It contains the public (inline) APIs and global data of + * the VStdLib. + * It has to be included by other modules to access the APIs of the VStdLib. + * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2012-05-08 vistvi Creation + * 01.00.01 2013-09-04 vistvi ESCAN00064708: Inconsistent file names + * 01.01.00 2013-12-10 vistvi ESCAN00073131: MISRA Improvements + * 02.00.00 2015-01-12 vistkr ESCAN00080277: FEAT-427: SafeBSW Step I + * ESCAN00081720: Extended version check is not available for MSR4 + * 2015-05-04 vistkr ESCAN00081765: FEAT-1275: SafeBSW Step 2 + * ESCAN00082267: FEAT-1379: Optimized copy operation for large data + * 02.00.01 2015-12-02 vistkr ESCAN00086942: Compiler error: Last line of file ends without a newline + * 02.00.02 2016-04-14 vistkr ESCAN00089506: Remove trace links for memory manipulation services + * 03.00.00 2018-10-23 vistkr STORYC-6844: MISRA-C:2012: VStdLib + * 03.01.00 2021-01-18 visgaz CAN-1574: [VStdLib] Support bit search functions + * 03.02.00 2021-03-15 visgaz CAN-1579: [VStdLib] Support memory comparison functions + * CAN-1577: [VStdLib] Support serialization functions + * 03.03.00 2021-04-12 visgaz CAN-2834: [VStdLib] Optimize memory comparison functions + * CAN-2831: [VStdLib] Optimize serialization functions + * CAN-1576: [VStdLib] Support endianess conversion functions + * ESCAN00108975: Compiler warning: 'type cast': pointer truncation from 'uint8 *' to 'uint32_least' + * 03.04.00 2021-06-07 visgaz CANCORE-325: [VStdLib] Convert CReqSpec, CAD and TestSpec to the new textbased format + * ESCAN00109680: Compiler warning: Conversion from 'uint8 *' to 'uint64' is sign-extended + * 03.05.00 2022-03-29 visgaz CANCORE-455: [VStdLib] Support MemCpy with endianness conversion functions + * ESCAN00110377: Compiler warning: Constant out of range + * ESCAN00110415: Compiler warning: Narrowing or signed-to-unsigned type conversion found + * - Refactored description for endianness conversion and (de-)serialization feature + * 2022-07-07 visnaj CANHAL-1215: [VStdLib] Support VStdLib_MemCheck() + * 03.06.00 2023-01-10 visgaz CANCORE-1197: [VStdLib] Finite Execution Time Analysis + * 2023-01-25 CANCORE-1379: [VStdLib] Safety analysis + * 03.07.00 2023-02-14 vismte CANCORE-1647: [VStdLib] Implementation of sawtooth functions for BitCopy + * CANCORE-1699: [VStdLib] Implementation of monotone functions for BitCopy + * 2023-03-23 vismte ESCAN00114258: Incomplete description for FETA-ID FETA_VSTDLIB_CALL_LOC_MEMCHECK_8_REMAINING + * 03.08.00 2023-04-13 vismte CANCORE-1904: [VStdLib] Review findings + * CANCORE-1203: [VStdLib] Support MemCpy_s with return value + * CANCORE-1201: [VStdLib] Extend Embedded Compiler tests and fix compiler warnings + * 03.08.01 2023-07-26 vismte ESCAN00115111: Compiler error during VCA analysis in _VStdLib.vcaspecs.c + * 03.09.00 2024-09-24 hjenhani CANCORE-2865: [VStdLib] Make VStdLib VCA (Silent Analysis) compatible + *********************************************************************************************************************/ + +#ifndef VSTDLIB_H +# define VSTDLIB_H + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +# include "Std_Types.h" + +# include "VStdLib_Cfg.h" + +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) +# include "Det.h" +# endif + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/* Vendor and module identification */ +# define VSTDLIB_VENDOR_ID (30u) +# if !defined (VSTDLIB_MODULE_ID) +# define VSTDLIB_MODULE_ID (255u) +# endif + +/* Component version information (decimal version of ALM implementation package) */ +# define VSTDLIB_SW_MAJOR_VERSION (3u) +# define VSTDLIB_SW_MINOR_VERSION (9u) +# define VSTDLIB_SW_PATCH_VERSION (0u) + +# if !defined (VSTDLIB_INSTANCE_ID_DET) +# define VSTDLIB_INSTANCE_ID_DET (0u) +# endif + +/* API service IDs */ +# define VSTDLIB_SID_MEM_SET (0x00u) /*!< Service ID: VStdLib_MemClr(), VStdLib_MemSet() */ +# define VSTDLIB_SID_MEM_COPY (0x01u) /*!< Service ID: VStdLib_MemCpy(), VStdLib_MemCpyEndianPlatformToBig(), VStdLib_MemCpyEndianPlatformToLittle(), + VStdLib_MemCpyEndianBigToPlatform(), VStdLib_MemCpyEndianLittleToPlatform() */ +# define VSTDLIB_SID_MEM_COPY_16 (0x02u) /*!< Service ID: VStdLib_MemCpy16() */ +# define VSTDLIB_SID_MEM_COPY_32 (0x03u) /*!< Service ID: VStdLib_MemCpy32() */ +# define VSTDLIB_SID_MEM_COPY_S (0x04u) /*!< Service ID: VStdLib_MemCpy_s(), VStdLib_MemCpy_Return_s(), VStdLib_MemCpyEndianPlatformToBig_s(), + VStdLib_MemCpyEndianPlatformToLittle_s(), VStdLib_MemCpyEndianBigToPlatform_s(), + VStdLib_MemCpyEndianLittleToPlatform_s() */ +# define VSTDLIB_SID_GET_VERSION_INFO (0x05u) /*!< Service ID: VStdLib_GetVersionInfo() */ +# define VSTDLIB_SID_MEM_CMP (0x06u) /*!< Service ID: VStdLib_MemCmp() */ +# define VSTDLIB_SID_CNV_UINT16_TO_ARRAY_BE (0x07u) /*!< Service ID: VStdLib_ConvertUint16ToUint8ArrayBigEndian(), VStdLib_ConvertSint16ToUint8ArrayBigEndian() */ +# define VSTDLIB_SID_CNV_UINT16_TO_ARRAY_LE (0x08u) /*!< Service ID: VStdLib_ConvertUint16ToUint8ArrayLittleEndian(), VStdLib_ConvertSint16ToUint8ArrayLittleEndian() */ +# define VSTDLIB_SID_CNV_ARRAY_TO_UINT16_BE (0x09u) /*!< Service ID: VStdLib_ConvertUint8ArrayToUint16BigEndian(), VStdLib_ConvertUint8ArrayToSint16BigEndian() */ +# define VSTDLIB_SID_CNV_ARRAY_TO_UINT16_LE (0x0Au) /*!< Service ID: VStdLib_ConvertUint8ArrayToUint16LittleEndian(), VStdLib_ConvertUint8ArrayToSint16LittleEndian() */ +# define VSTDLIB_SID_CNV_UINT32_TO_ARRAY_BE (0x0Bu) /*!< Service ID: VStdLib_ConvertUint32ToUint8ArrayBigEndian(), VStdLib_ConvertSint32ToUint8ArrayBigEndian() */ +# define VSTDLIB_SID_CNV_UINT32_TO_ARRAY_LE (0x0Cu) /*!< Service ID: VStdLib_ConvertUint32ToUint8ArrayLittleEndian(), VStdLib_ConvertSint32ToUint8ArrayLittleEndian() */ +# define VSTDLIB_SID_CNV_ARRAY_TO_UINT32_BE (0x0Du) /*!< Service ID: VStdLib_ConvertUint8ArrayToUint32BigEndian(), VStdLib_ConvertUint8ArrayToSint32BigEndian() */ +# define VSTDLIB_SID_CNV_ARRAY_TO_UINT32_LE (0x0Eu) /*!< Service ID: VStdLib_ConvertUint8ArrayToUint32LittleEndian(), VStdLib_ConvertUint8ArrayToSint32LittleEndian() */ +# define VSTDLIB_SID_CNV_UINT64_TO_ARRAY_BE (0x0Fu) /*!< Service ID: VStdLib_ConvertUint64ToUint8ArrayBigEndian(), VStdLib_ConvertSint64ToUint8ArrayBigEndian() */ +# define VSTDLIB_SID_CNV_UINT64_TO_ARRAY_LE (0x10u) /*!< Service ID: VStdLib_ConvertUint64ToUint8ArrayLittleEndian(), VStdLib_ConvertSint64ToUint8ArrayLittleEndian() */ +# define VSTDLIB_SID_CNV_ARRAY_TO_UINT64_BE (0x11u) /*!< Service ID: VStdLib_ConvertUint8ArrayToUint64BigEndian(), VStdLib_ConvertUint8ArrayToSint64BigEndian() */ +# define VSTDLIB_SID_CNV_ARRAY_TO_UINT64_LE (0x12u) /*!< Service ID: VStdLib_ConvertUint8ArrayToUint64LittleEndian(), VStdLib_ConvertUint8ArrayToSint64LittleEndian() */ +# define VSTDLIB_SID_MEM_COPY_SWAP_ENDIAN (0x13u) /*!< Service ID: VStdLib_MemCpySwapEndian(), VStdLib_MemCpyEndianPlatformToBig(), + VStdLib_MemCpyEndianPlatformToLittle(), VStdLib_MemCpyEndianBigToPlatform(), + VStdLib_MemCpyEndianLittleToPlatform() */ +# define VSTDLIB_SID_MEM_COPY_SWAP_ENDIAN_S (0x14u) /*!< Service ID: VStdLib_MemCpySwapEndian_s(), VStdLib_MemCpyEndianPlatformToBig_s(), + VStdLib_MemCpyEndianPlatformToLittle_s(), VStdLib_MemCpyEndianBigToPlatform_s(), + VStdLib_MemCpyEndianLittleToPlatform_s() */ +# define VSTDLIB_SID_MEM_CHECK (0x15u) /*!< Service ID: VStdLib_MemCheck() */ + +# define VSTDLIB_SID_BIT_COPY_SAW (0x16u) /*!< Service ID: VStdLib_BitCpySawBigToBigEndian(), VStdLib_BitCpySawBigToLittleEndian(), + VStdLib_BitCpySawLittleToBigEndian(), VStdLib_BitCpySawLittleToLittleEndian() */ +# define VSTDLIB_SID_BIT_COPY_MON (0x17u) /*!< Service ID: VStdLib_BitCpyMonBigToBigEndian(), VStdLib_BitCpyMonBigToLittleEndian(), + VStdLib_BitCpyMonLittleToBigEndian(), VStdLib_BitCpyMonLittleToLittleEndian() */ +# define VSTDLIB_SID_BIT_COPY_SAW_S (0x18u) /*!< Service ID: VStdLib_BitCpySawBigToBigEndian_s(), VStdLib_BitCpySawBigToLittleEndian_s(), + VStdLib_BitCpySawLittleToBigEndian_s(), VStdLib_BitCpySawLittleToLittleEndian_s() */ +# define VSTDLIB_SID_BIT_COPY_MON_S (0x19u) /*!< Service ID: VStdLib_BitCpyMonBigToBigEndian_s(), VStdLib_BitCpyMonBigToLittleEndian_s(), + VStdLib_BitCpyMonLittleToBigEndian_s(), VStdLib_BitCpyMonLittleToLittleEndian_s() */ + +/* Error codes */ +# define VSTDLIB_E_NO_ERROR (0x00u) /*!< Used to check if no error occurred */ +# define VSTDLIB_E_PARAM_POINTER (0x01u) /*!< Error code: API used with invalid pointer parameter (e.g. NULL) */ +# define VSTDLIB_E_PARAM_SIZE (0x02u) /*!< Error code: API used with invalid destination buffer size */ +# define VSTDLIB_E_PARAM_INTTYPE (0x03u) /*!< Error code: API used with invalid integer type parameter */ + +/* Large data support */ +# if !defined (VSTDLIB_SUPPORT_LARGE_DATA) +# define VSTDLIB_SUPPORT_LARGE_DATA STD_ON +# endif + +/* Return value from bit search APIs, if bit position or bit count is not available */ +# define VSTDLIB_BITPOS_NA (0x80u) +# define VSTDLIB_BITCNT_NA VSTDLIB_BITPOS_NA + +/*! Possible values for the integer type parameter of the memory copy with endianness conversion APIs */ +# define VSTDLIB_INTTYPE_8 (1u) +# define VSTDLIB_INTTYPE_16 (2u) +# define VSTDLIB_INTTYPE_32 (4u) +# if defined (PLATFORM_SUPPORT_SINT64_UINT64) +# define VSTDLIB_INTTYPE_64 (8u) +# endif + +/********************************************************************************************************************** + * GLOBAL DATA TYPES AND STRUCTURES + *********************************************************************************************************************/ + +/* Module specific definition of LOCAL_INLINE */ +# if !defined (VSTDLIB_LOCAL_INLINE) +# define VSTDLIB_LOCAL_INLINE LOCAL_INLINE +# endif + +/*! Data type for nCnt API parameters */ +# if (VSTDLIB_SUPPORT_LARGE_DATA == STD_ON) +typedef uint32_least VStdLib_CntType; +# else +typedef uint16_least VStdLib_CntType; +# endif + +/********************************************************************************************************************** + * GLOBAL FUNCTION MACROS (MACRO API) + *********************************************************************************************************************/ + +/* PRQA S 3453 VSTDLIB_FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +# if (VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_MemClr() + *********************************************************************************************************************/ +/*! \brief Initializes memory to zero. + * \details Sets nCnt bytes starting at pDst to zero. + * \param[out] pDst Pointer to the memory location to be initialized, must not be NULL. + * \param[in] nCnt Number of bytes to initialize, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_ON, + * else it is realized by a call to VStdLib_MemSet() with 'nPattern' == 0. + * The compatible definition VStdLib_MemClrLarge() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + *********************************************************************************************************************/ +# define VStdLib_MemClr(pDst, nCnt) VStdLib_MemSet((pDst), 0, (nCnt)) + +# endif /* VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON */ + +# if (VSTDLIB_SUPPORT_LARGE_DATA == STD_ON) + +/********************************************************************************************************************** + * VStdLib_MemClrLarge() + *********************************************************************************************************************/ +/*! \brief Initializes memory to zero. + * \details Sets nCnt bytes starting at pDst to zero. + * \param[out] pDst Pointer to the memory location to be initialized, must not be NULL. + * \param[in] nCnt Number of bytes to initialize, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + *********************************************************************************************************************/ +# define VStdLib_MemClrLarge(pDst, nCnt) VStdLib_MemClr((pDst), (nCnt)) + +/********************************************************************************************************************** + * VStdLib_MemSetLarge() + *********************************************************************************************************************/ +/*! \brief Initializes memory to a specified pattern. + * \details Sets nCnt bytes starting at pDst to the character nPattern. + * \param[out] pDst Pointer to the memory location to be initialized, must not be NULL. + * \param[in] nPattern The character to be used to initialize the memory. + * \param[in] nCnt Number of bytes to initialize, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + *********************************************************************************************************************/ +# define VStdLib_MemSetLarge(pDst, nPattern, nCnt) VStdLib_MemSet((pDst), (nPattern), (nCnt)) + +/********************************************************************************************************************** + * VStdLib_MemCpyLarge() + *********************************************************************************************************************/ +/*! \brief Copies data from one memory location to another. + * \details Copies nCnt bytes starting at pSrc to another memory location starting at pDst. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpyLarge(pDst, pSrc, nCnt) VStdLib_MemCpy((pDst), (pSrc), (nCnt)) + +/********************************************************************************************************************** + * VStdLib_MemCpy16Large() + *********************************************************************************************************************/ +/*! \brief Copies data from one memory location to another. + * \details Copies nCnt 16-bit blocks starting at pSrc to another memory location starting at pDst. + * \param[out] pDst Pointer to the memory location to copy to, 16-bit aligned and not NULL. + * \param[in] pSrc Pointer to the memory location to copy from, 16-bit aligned and not NULL. + * \param[in] nCnt Number of 16-bit blocks to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpy16Large(pDst, pSrc, nCnt) VStdLib_MemCpy16((pDst), (pSrc), (nCnt)) + +/********************************************************************************************************************** + * VStdLib_MemCpy32Large() + *********************************************************************************************************************/ +/*! \brief Copies data from one memory location to another. + * \details Copies nCnt 32-bit blocks starting at pSrc to another memory location starting at pDst. + * \param[out] pDst Pointer to the memory location to copy to, 32-bit aligned and not NULL. + * \param[in] pSrc Pointer to the memory location to copy from, 32-bit aligned and not NULL. + * \param[in] nCnt Number of 32-bit blocks to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpy32Large(pDst, pSrc, nCnt) VStdLib_MemCpy32((pDst), (pSrc), (nCnt)) + +/********************************************************************************************************************** + * VStdLib_MemCpyLarge_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location to another. + * \details Uses VStdLib_MemCpy() to copy nCnt bytes starting at pSrc to another memory location starting + * at pDst, if nDstSize is greater than or equal to nCnt. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpyLarge_s(pDst, nDstSize, pSrc, nCnt) VStdLib_MemCpy_s((pDst), (nDstSize), (pSrc), (nCnt)) + +/********************************************************************************************************************** + * VStdLib_MemCpyLarge_Return_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location to another. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpy() to + * copy nCnt bytes starting at pSrc to another memory location starting at pDst. + * Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +# define VStdLib_MemCpyLarge_Return_s(pDst, nDstSize, pSrc, nCnt, errorCode) \ + VStdLib_MemCpy_Return_s((pDst), (nDstSize), (pSrc), (nCnt), (errorCode)) + +/********************************************************************************************************************** + * VStdLib_MemCmpLarge() + *********************************************************************************************************************/ +/*! \brief Compares two buffers for the specified number of bytes and returns whether they are equal or not. + * \details - + * \param[in] pBuf1 Pointer to first buffer for comparison, must not be NULL. + * \param[in] pBuf2 Pointer to second buffer for comparison, must not be NULL. + * \param[in] nCnt Number of bytes to compare, pBuf1 and pBuf2 must be valid for this amount. + * \return < 0 The first buffer contains a smaller value than the second buffer. + * \return 0 The two buffers are equal for the number of compared bytes. + * \return > 0 The first buffer contains a greater value than the second buffer. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pBuf1' and 'pBuf2' have to point to valid memory areas. Each memory area has to be + * valid for at least the byte count defined in parameter 'nCnt'. + * The memory areas defined by parameters 'pBuf1', 'pBuf2' and 'nCnt' must not be changed by another + * context whilethe comparison is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCmpLarge(pBuf1, pBuf2, nCnt) VStdLib_MemCmp((pBuf1), (pBuf2), (nCnt)) + +/********************************************************************************************************************** + * VStdLib_MemCpySwapEndianLarge() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bytes starting at pSrc to another memory location starting at pDst in the swapped + * endianness according to the integer type intType. + * \details Depending on the configuration (VSTDLIB_RUNTIME_OPTIMIZATION) and the passed arguments for parameter + * intType and nCnt different memory access sizes are used (see TechRef). + * intType value VSTDLIB_INTTYPE_64 is only supported if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType') and writable from the calling context. + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpySwapEndianLarge(pDst, pSrc, nCnt, intType) \ + VStdLib_MemCpySwapEndian((pDst), (pSrc), (nCnt), (intType)) + +/********************************************************************************************************************** + * VStdLib_MemCpySwapEndianLarge_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location to another in the swapped + * endianness according to the integer type intType. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpySwapEndian() to copy and swap nCnt + * bytes starting at pSrc to another memory location starting at pDst. + * Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +# define VStdLib_MemCpySwapEndianLarge_s(pDst, nDstSize, pSrc, nCnt, intType, errorCode) \ + VStdLib_MemCpySwapEndian_s((pDst), (nDstSize), (pSrc), (nCnt), (intType), (errorCode)); + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianPlatformToBigLarge() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bytes starting at pSrc (platform endianness) to another memory location starting at pDst + * in big endian according to the integer type intType. + * \details Depending on the configuration (VSTDLIB_RUNTIME_OPTIMIZATION) and the passed arguments for parameter + * intType and nCnt different memory access sizes are used (see TechRef). + * intType value VSTDLIB_INTTYPE_64 is only supported if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType') and writable from the calling context. + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianPlatformToBigLarge(pDst, pSrc, nCnt, intType) \ + VStdLib_MemCpyEndianPlatformToBig((pDst), (pSrc), (nCnt), (intType)) + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianPlatformToBigLarge_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location (platform endianness) to + * another in big endian according to the integer type intType. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpy()/VStdLib_MemCpySwapEndian() to + * copy nCnt bytes starting at pSrc to another memory location starting at pDst in big endian. + * Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianPlatformToBigLarge_s(pDst, nDstSize, pSrc, nCnt, intType, errorCode) \ + VStdLib_MemCpyEndianPlatformToBig_s((pDst), (nDstSize), (pSrc), (nCnt), (intType), (errorCode)) + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianPlatformToLittleLarge() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bytes starting at pSrc (platform endianness) to another memory location starting at pDst + * in little endian according to the integer type intType. + * \details Depending on the configuration (VSTDLIB_RUNTIME_OPTIMIZATION) and the passed arguments for parameter + * intType and nCnt different memory access sizes are used (see TechRef). + * intType value VSTDLIB_INTTYPE_64 is only supported if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType') and writable from the calling context. + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianPlatformToLittleLarge(pDst, pSrc, nCnt, intType) \ + VStdLib_MemCpyEndianPlatformToLittle((pDst), (pSrc), (nCnt), (intType)) + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianPlatformToLittleLarge_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location (platform endianness) to + * another in little endian according to the integer type intType. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpy()/VStdLib_MemCpySwapEndian() to + * copy nCnt bytes starting at pSrc to another memory location starting at pDst in little endian. + * Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area. + * The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType') that is writable from the + * calling context. + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianPlatformToLittleLarge_s(pDst, nDstSize, pSrc, nCnt, intType, errorCode) \ + VStdLib_MemCpyEndianPlatformToLittle_s((pDst), (nDstSize), (pSrc), (nCnt), (intType), (errorCode)) + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianBigToPlatformLarge() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bytes starting at pSrc (big endian) to another memory location starting at pDst in the + * platform endianness according to the integer type intType. + * \details Depending on the configuration (VSTDLIB_RUNTIME_OPTIMIZATION) and the passed arguments for parameter + * intType and nCnt different memory access sizes are used (see TechRef). + * intType value VSTDLIB_INTTYPE_64 is only supported if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType') and writable from the calling context. + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianBigToPlatformLarge(pDst, pSrc, nCnt, intType) \ + VStdLib_MemCpyEndianBigToPlatform((pDst), (pSrc), (nCnt), (intType)) + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianBigToPlatformLarge_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location (big endian) to another in the + * platform endianness according to the integer type intType. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpy()/VStdLib_MemCpySwapEndian() to + * copy nCnt bytes starting at pSrc to another memory location starting at pDst in the platform + * endianness Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianBigToPlatformLarge_s(pDst, nDstSize, pSrc, nCnt, intType, errorCode) \ + VStdLib_MemCpyEndianBigToPlatform_s((pDst), (nDstSize), (pSrc), (nCnt), (intType), (errorCode)) + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianLittleToPlatformLarge() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bytes starting at pSrc (little endian) to another memory location starting at pDst in the + * platform endianness according to the integer type intType. + * \details Depending on the configuration (VSTDLIB_RUNTIME_OPTIMIZATION) and the passed arguments for parameter + * intType and nCnt different memory access sizes are used (see TechRef). + * intType value VSTDLIB_INTTYPE_64 is only supported if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType') and writable from the calling context. + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianLittleToPlatformLarge(pDst, pSrc, nCnt, intType) \ + VStdLib_MemCpyEndianLittleToPlatform((pDst), (pSrc), (nCnt), (intType)) + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianLittleToPlatformLarge_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location (little endian) to another in + * the platform endianness according to the integer type intType. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpy()/VStdLib_MemCpySwapEndian() to + * copy nCnt bytes starting at pSrc to another memory location starting at pDst in the platform + * endianness. Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianLittleToPlatformLarge_s(pDst, nDstSize, pSrc, nCnt, intType, errorCode) \ + VStdLib_MemCpyEndianLittleToPlatform_s((pDst), (nDstSize), (pSrc), (nCnt), (intType), (errorCode)) + +/********************************************************************************************************************** + * VStdLib_MemCheckLarge() + *********************************************************************************************************************/ +/*! \brief Compares the content of a memory area to a specified pattern. + * \details Compares nCnt bytes of memory starting at pBuf to the character nPattern. + * \param[in] pBuf Pointer to the memory location to be checked, must not be NULL. + * \param[in] nPattern The character to be checked for in the memory. + * \param[in] nCnt Number of bytes to be checked, pBuf must be valid for this amount. + * \param[in] errorCode Value to be returned, if content of pBuf is not equal to pattern. + * Should not be equal to E_OK. + * \return E_OK Content of pBuf is equal to pattern. + * \return errorCode Content of pBuf is not equal to pattern. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_SUPPORT_LARGE_DATA == STD_ON + * \pre The parameters 'pBuf' and 'nCnt' have to define a valid memory area. + * The memory area defined by parameters 'pBuf' and 'nCnt' must not be changed by another context while + * the comparison is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +# define VStdLib_MemCheckLarge(pBuf, nPattern, nCnt, errorCode) VStdLib_MemCheck((pBuf), (nPattern), (nCnt), (errorCode)) + +# endif /* VSTDLIB_SUPPORT_LARGE_DATA == STD_ON */ + +# if (VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_ConvertSint16ToUint8ArrayBigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 16-bit value to an unsigned 8-bit array according to big endian. + * \details - + * \param[in] src The signed 16-bit value, which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least two elements that is writable + * from the calling context. + *********************************************************************************************************************/ +# define VStdLib_ConvertSint16ToUint8ArrayBigEndian(src, dst) VStdLib_ConvertUint16ToUint8ArrayBigEndian(((uint16)(src)), (dst)) + +/********************************************************************************************************************** + * VStdLib_ConvertSint16ToUint8ArrayLittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 16-bit value to an unsigned 8-bit array according to little endian. + * \details - + * \param[in] src The signed 16-bit value, which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least two elements that is writable + * from the calling context. + *********************************************************************************************************************/ +# define VStdLib_ConvertSint16ToUint8ArrayLittleEndian(src, dst) VStdLib_ConvertUint16ToUint8ArrayLittleEndian(((uint16)(src)), (dst)) + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToSint16BigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to a signed 16-bit value according to big endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to a signed 16-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least two elements. + * The parameter 'dst' has to point to a signed 16-bit variable that is writable from the calling + * context. + *********************************************************************************************************************/ +# define VStdLib_ConvertUint8ArrayToSint16BigEndian(src, dst) VStdLib_ConvertUint8ArrayToUint16BigEndian((src), ((uint16*)(dst))) + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToSint16LittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to a signed 16-bit value according to little endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to a signed 16-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least two elements. + * The parameter 'dst' has to point to a signed 16-bit variable that is writable from the calling + * context. + *********************************************************************************************************************/ +# define VStdLib_ConvertUint8ArrayToSint16LittleEndian(src, dst) VStdLib_ConvertUint8ArrayToUint16LittleEndian((src), ((uint16*)(dst))) + +# endif /* VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON */ + +# if (VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_ConvertSint32ToUint8ArrayBigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 32-bit value to an unsigned 8-bit array according to big endian. + * \details - + * \param[in] src The signed 32-bit value, which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least four elements that is writable + * from the calling context. + *********************************************************************************************************************/ +# define VStdLib_ConvertSint32ToUint8ArrayBigEndian(src, dst) VStdLib_ConvertUint32ToUint8ArrayBigEndian(((uint32)(src)), (dst)) + +/********************************************************************************************************************** + * VStdLib_ConvertSint32ToUint8ArrayLittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 32-bit value to an unsigned 8-bit array according to little endian. + * \details - + * \param[in] src The signed 32-bit value, which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least four elements that is writable + * from the calling context. + *********************************************************************************************************************/ +# define VStdLib_ConvertSint32ToUint8ArrayLittleEndian(src, dst) VStdLib_ConvertUint32ToUint8ArrayLittleEndian(((uint32)(src)), (dst)) + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToSint32BigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to a signed 32-bit value according to big endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to a signed 32-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least two elements. + * The parameter 'dst' has to point to a signed 32-bit variable that is writable from the calling + * context. + *********************************************************************************************************************/ +# define VStdLib_ConvertUint8ArrayToSint32BigEndian(src, dst) VStdLib_ConvertUint8ArrayToUint32BigEndian(src, ((uint32*)(dst))) + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToSint32LittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to a signed 32-bit value according to little endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to a signed 32-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least two elements. + * The parameter 'dst' has to point to a signed 32-bit variable that is writable from the calling + * context. + *********************************************************************************************************************/ +# define VStdLib_ConvertUint8ArrayToSint32LittleEndian(src, dst) VStdLib_ConvertUint8ArrayToUint32LittleEndian((src), ((uint32*)(dst))) + +# endif /* VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON */ + +# if (defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON)) + +/********************************************************************************************************************** + * VStdLib_ConvertSint64ToUint8ArrayBigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 64-bit value to an unsigned 8-bit array according to big endian. + * \details - + * \param[in] src The signed 64-bit value, which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least eight elements that is writable + * from the calling context. + *********************************************************************************************************************/ +# define VStdLib_ConvertSint64ToUint8ArrayBigEndian(src, dst) VStdLib_ConvertUint64ToUint8ArrayBigEndian(((uint64)(src)), (dst)) + +/********************************************************************************************************************** + * VStdLib_ConvertSint64ToUint8ArrayLittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 64-bit value to an unsigned 8-bit array according to little endian. + * \details - + * \param[in] src The signed 64-bit value, which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least eight elements that is writable + * from the calling context. + *********************************************************************************************************************/ +# define VStdLib_ConvertSint64ToUint8ArrayLittleEndian(src, dst) VStdLib_ConvertUint64ToUint8ArrayLittleEndian(((uint64)(src)), (dst)) + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToSint64BigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to a signed 64-bit value according to big endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to a signed 64-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least eight elements. + * The parameter 'dst' has to point to a signed 64-bit variable that is writable from the calling + * context. + *********************************************************************************************************************/ +# define VStdLib_ConvertUint8ArrayToSint64BigEndian(src, dst) VStdLib_ConvertUint8ArrayToUint64BigEndian((src), ((uint64*)(dst))) + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToSint64LittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to a signed 64-bit value according to little endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to a signed 64-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least eight elements. + * The parameter 'dst' has to point to a signed 64-bit variable that is writable from the calling + * context. + *********************************************************************************************************************/ +# define VStdLib_ConvertUint8ArrayToSint64LittleEndian(src, dst) VStdLib_ConvertUint8ArrayToUint64LittleEndian((src), ((uint64*)(dst))) + +# endif /* defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON) */ + +# if (VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_SwapEndianSint16() + *********************************************************************************************************************/ +/*! \brief Swaps the endianness of the specified signed 16-bit value. + * \details - + * \param[in] value Signed 16-bit value, whose endianness shall be swapped. + * \return Value in the swapped endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +# define VStdLib_SwapEndianSint16(value) ((sint16)VStdLib_SwapEndianUint16(((uint16)(value)))) + +# endif /* VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToBigUint16() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 16-bit value from the platform endianness to big endian. + * \details - + * \param[in] value Unsigned 16-bit value according to the platform endianness, which shall be converted to big + * endian. + * \return Value in big endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) +# define VStdLib_ConvertEndianPlatformToBigUint16(value) (value) +# else +# define VStdLib_ConvertEndianPlatformToBigUint16(value) VStdLib_SwapEndianUint16((value)) +# endif + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToBigSint16() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 16-bit value from the platform endianness to big endian. + * \details - + * \param[in] value Signed 16-bit value according to the platform endianness, which shall be converted to big + * endian. + * \return Value in big endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianPlatformToBigSint16(value) ((sint16)VStdLib_ConvertEndianPlatformToBigUint16(((uint16)(value)))) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToLittleUint16() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 16-bit value from the platform endianness to little endian. + * \details - + * \param[in] value Unsigned 16-bit value according to the platform endianness, which shall be converted to little + * endian. + * \return Value in little endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) +# define VStdLib_ConvertEndianPlatformToLittleUint16(value) (value) +# else +# define VStdLib_ConvertEndianPlatformToLittleUint16(value) VStdLib_SwapEndianUint16((value)) +# endif + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToLittleSint16() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 16-bit value from the platform endianness to little endian. + * \details - + * \param[in] value Signed 16-bit value according to the platform endianness, which shall be converted to little + * endian. + * \return Value in little endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianPlatformToLittleSint16(value) ((sint16)VStdLib_ConvertEndianPlatformToLittleUint16(((uint16)(value)))) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianBigToPlatformUint16() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 16-bit value from big endian to the platform endianness. + * \details - + * \param[in] value Unsigned 16-bit value according to big endian, which shall be converted to the platform + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianBigToPlatformUint16(value) VStdLib_ConvertEndianPlatformToBigUint16((value)) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianBigToPlatformSint16() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 16-bit value from big endian to the platform endianness. + * \details - + * \param[in] value Signed 16-bit value according to big endian, which shall be converted to the platform. + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianBigToPlatformSint16(value) VStdLib_ConvertEndianPlatformToBigSint16((value)) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianLittleToPlatformUint16() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 16-bit value from little endian to the platform endianness. + * \details - + * \param[in] value Unsigned 16-bit value according to little endian, which shall be converted to the platform + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianLittleToPlatformUint16(value) VStdLib_ConvertEndianPlatformToLittleUint16((value)) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianLittleToPlatformSint16() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 16-bit value from little endian to the platform endianness. + * \details - + * \param[in] value Signed 16-bit value according to little endian, which shall be converted to the platform + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianLittleToPlatformSint16(value) VStdLib_ConvertEndianPlatformToLittleSint16((value)) + +# if (VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_SwapEndianSint32() + *********************************************************************************************************************/ +/*! \brief Swaps the endianness of the specified signed 32-bit value. + * \details - + * \param[in] value Signed 32-bit value, whose endianness shall be swapped. + * \return Value in the swapped endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +# define VStdLib_SwapEndianSint32(value) ((sint32)VStdLib_SwapEndianUint32(((uint32)(value)))) + +# endif /* VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToBigUint32() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 32-bit value from the platform endianness to big endian. + * \details - + * \param[in] value Unsigned 32-bit value according to the platform endianness, which shall be converted to big + * endian. + * \return Value in big endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) +# define VStdLib_ConvertEndianPlatformToBigUint32(value) (value) +# else +# define VStdLib_ConvertEndianPlatformToBigUint32(value) VStdLib_SwapEndianUint32((value)) +# endif + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToBigSint32() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 32-bit value from the platform endianness to big endian. + * \details - + * \param[in] value Signed 32-bit value according to the platform endianness, which shall be converted to big + * endian. + * \return Value in big endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianPlatformToBigSint32(value) ((sint32)VStdLib_ConvertEndianPlatformToBigUint32(((uint32)(value)))) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToLittleUint32() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 32-bit value from the platform endianness to little endian. + * \details - + * \param[in] value Unsigned 32-bit value according to the platform endianness, which shall be converted to little + * endian. + * \return Value in little endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) +# define VStdLib_ConvertEndianPlatformToLittleUint32(value) (value) +# else +# define VStdLib_ConvertEndianPlatformToLittleUint32(value) VStdLib_SwapEndianUint32((value)) +# endif + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToLittleSint32() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 32-bit value from the platform endianness to little endian. + * \details - + * \param[in] value Signed 32-bit value according to the platform endianness, which shall be converted to little + * endian. + * \return Value in little endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianPlatformToLittleSint32(value) ((sint32)VStdLib_ConvertEndianPlatformToLittleUint32(((uint32)(value)))) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianBigToPlatformUint32() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 32-bit value from big endian to the platform endianness. + * \details - + * \param[in] value Unsigned 32-bit value according to big endian, which shall be converted to the platform + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianBigToPlatformUint32(value) VStdLib_ConvertEndianPlatformToBigUint32((value)) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianBigToPlatformSint32() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 32-bit value from big endian to the platform endianness. + * \details - + * \param[in] value Signed 32-bit value according to big endian, which shall be converted to the platform + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianBigToPlatformSint32(value) VStdLib_ConvertEndianPlatformToBigSint32((value)) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianLittleToPlatformUint32() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 32-bit value from little endian to the platform endianness. + * \details - + * \param[in] value Unsigned 32-bit value according to little endian, which shall be converted to the platform + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianLittleToPlatformUint32(value) VStdLib_ConvertEndianPlatformToLittleUint32((value)) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianLittleToPlatformSint32() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 32-bit value from little endian to the platform endianness. + * \details - + * \param[in] value Signed 32-bit value according to little endian, which shall be converted to the platform + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config - + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianLittleToPlatformSint32(value) VStdLib_ConvertEndianPlatformToLittleSint32((value)) + +# if defined (PLATFORM_SUPPORT_SINT64_UINT64) +# if (VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_SwapEndianSint64() + *********************************************************************************************************************/ +/*! \brief Swaps the endianness of the specified signed 64-bit value. + * \details - + * \param[in] value Signed 64-bit value, whose endianness shall be swapped. + * \return Value in the swapped endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +# define VStdLib_SwapEndianSint64(value) ((sint64)VStdLib_SwapEndianUint64(((uint64)(value)))) + +# endif /* VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToBigUint64() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 64-bit value from the platform endianness to big endian. + * \details - + * \param[in] value Unsigned 64-bit value according to the platform endianness, which shall be converted to big + * endian. + * \return Value in big endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \pre - + *********************************************************************************************************************/ +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) +# define VStdLib_ConvertEndianPlatformToBigUint64(value) (value) +# else +# define VStdLib_ConvertEndianPlatformToBigUint64(value) VStdLib_SwapEndianUint64((value)) +# endif + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToBigSint64() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 64-bit value from the platform endianness to big endian. + * \details - + * \param[in] value Signed 64-bit value according to the platform endianness, which shall be converted to big + * endian. + * \return Value in big endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianPlatformToBigSint64(value) ((sint64)VStdLib_ConvertEndianPlatformToBigUint64(((uint64)(value)))) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToLittleUint64() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 64-bit value from the platform endianness to little endian. + * \details - + * \param[in] value Unsigned 64-bit value according to the platform endianness, which shall be converted to little + * endian. + * \return Value in little endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \pre - + *********************************************************************************************************************/ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) +# define VStdLib_ConvertEndianPlatformToLittleUint64(value) (value) +# else +# define VStdLib_ConvertEndianPlatformToLittleUint64(value) VStdLib_SwapEndianUint64((value)) +# endif + +/********************************************************************************************************************** + * VStdLib_ConvertEndianPlatformToLittleSint64() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 64-bit value from the platform endianness to little endian. + * \details - + * \param[in] value Signed 64-bit value according to the platform endianness, which shall be converted to little + * endian. + * \return Value in little endian. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianPlatformToLittleSint64(value) ((sint64)VStdLib_ConvertEndianPlatformToLittleUint64(((uint64)(value)))) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianBigToPlatformUint64() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 64-bit value from big endian to the platform endianness. + * \details - + * \param[in] value Unsigned 64-bit value according to big endian, which shall be converted to the platform + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianBigToPlatformUint64(value) VStdLib_ConvertEndianPlatformToBigUint64((value)) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianBigToPlatformSint64() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 64-bit value from big endian to the platform endianness. + * \details - + * \param[in] value Signed 64-bit value according to big endian, which shall be converted to the platform + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianBigToPlatformSint64(value) VStdLib_ConvertEndianPlatformToBigSint64((value)) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianLittleToPlatformUint64() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 64-bit value from little endian to the platform endianness. + * \details - + * \param[in] value Unsigned 64-bit value according to little endian, which shall be converted to the platform + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianLittleToPlatformUint64(value) VStdLib_ConvertEndianPlatformToLittleUint64((value)) + +/********************************************************************************************************************** + * VStdLib_ConvertEndianLittleToPlatformSint64() + *********************************************************************************************************************/ +/*! \brief Converts the specified signed 64-bit value from little endian to the platform endianness. + * \details - + * \param[in] value Signed 64-bit value according to little endian, which shall be converted to the platform + * endianness. + * \return Value in the platform endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \pre - + *********************************************************************************************************************/ +# define VStdLib_ConvertEndianLittleToPlatformSint64(value) VStdLib_ConvertEndianPlatformToLittleSint64((value)) + +# endif /* defined (PLATFORM_SUPPORT_SINT64_UINT64) */ + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianPlatformToBig() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bytes starting at pSrc (platform endianness) to another memory location starting at pDst + * in big endian according to the integer type intType. + * \details Depending on the configuration (VSTDLIB_RUNTIME_OPTIMIZATION) and the passed arguments for parameter + * intType and nCnt different memory access sizes are used (see TechRef). + * intType value VSTDLIB_INTTYPE_64 is only supported if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config The compatible definition VStdLib_MemCpyEndianPlatformToBigLarge() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType') and writable from the calling context. + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) +# define VStdLib_MemCpyEndianPlatformToBig(pDst, pSrc, nCnt, intType) VStdLib_MemCpy((pDst), (pSrc), (nCnt)) +# else +# define VStdLib_MemCpyEndianPlatformToBig(pDst, pSrc, nCnt, intType) VStdLib_MemCpySwapEndian((pDst), (pSrc), (nCnt), (intType)) +# endif + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianPlatformToLittle() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bytes starting at pSrc (platform endianness) to another memory location starting at pDst + * in little endian according to the integer type intType. + * \details Depending on the configuration (VSTDLIB_RUNTIME_OPTIMIZATION) and the passed arguments for parameter + * intType and nCnt different memory access sizes are used (see TechRef). + * intType value VSTDLIB_INTTYPE_64 is only supported if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config The compatible definition VStdLib_MemCpyEndianPlatformToLittleLarge() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType') and writable from the calling context. + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) +# define VStdLib_MemCpyEndianPlatformToLittle(pDst, pSrc, nCnt, intType) \ + VStdLib_MemCpy((pDst), (pSrc), (nCnt)) +# else +# define VStdLib_MemCpyEndianPlatformToLittle(pDst, pSrc, nCnt, intType) \ + VStdLib_MemCpySwapEndian((pDst), (pSrc), (nCnt), (intType)) +# endif + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianBigToPlatform() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bytes starting at pSrc (big endian) to another memory location starting at pDst in the + * platform endianness according to the integer type intType. + * \details Depending on the configuration (VSTDLIB_RUNTIME_OPTIMIZATION) and the passed arguments for parameter + * intType and nCnt different memory access sizes are used (see TechRef). + * intType value VSTDLIB_INTTYPE_64 is only supported if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config The compatible definition VStdLib_MemCpyEndianBigToPlatformLarge() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType') and writable from the calling context. + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianBigToPlatform(pDst, pSrc, nCnt, intType) \ + VStdLib_MemCpyEndianPlatformToBig((pDst), (pSrc), (nCnt), (intType)) + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianBigToPlatform_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location (big endian) to another in the + * platform endianness according to the integer type intType. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpy()/VStdLib_MemCpySwapEndian() to + * copy nCnt bytes starting at pSrc to another memory location starting at pDst in the platform + * endianness. Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config The compatible definition VStdLib_MemCpyEndianBigToPlatformLarge_s() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianBigToPlatform_s(pDst, nDstSize, pSrc, nCnt, intType, errorCode) \ + VStdLib_MemCpyEndianPlatformToBig_s((pDst), (nDstSize), (pSrc), (nCnt), (intType), (errorCode)) + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianLittleToPlatform() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bytes starting at pSrc (little endian) to another memory location starting at pDst in the + * platform endianness according to the integer type intType. + * \details Depending on the configuration (VSTDLIB_RUNTIME_OPTIMIZATION) and the passed arguments for parameter + * intType and nCnt different memory access sizes are used (see TechRef). + * intType value VSTDLIB_INTTYPE_64 is only supported if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config The compatible definition VStdLib_MemCpyEndianLittleToPlatformLarge() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType') and writable from the calling context. + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianLittleToPlatform(pDst, pSrc, nCnt, intType) \ + VStdLib_MemCpyEndianPlatformToLittle((pDst), (pSrc), (nCnt), (intType)) + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianLittleToPlatform_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location (little endian) to another in + * the platform endianness according to the integer type intType. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpy()/VStdLib_MemCpySwapEndian() to + * copy nCnt bytes starting at pSrc to another memory location starting at pDst in the platform + * endianness. Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config The compatible definition VStdLib_MemCpyEndianLittleToPlatformLarge_s() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +# define VStdLib_MemCpyEndianLittleToPlatform_s(pDst, nDstSize, pSrc, nCnt, intType, errorCode) \ + VStdLib_MemCpyEndianPlatformToLittle_s((pDst), (nDstSize), (pSrc), (nCnt), (intType), (errorCode)) + +/* PRQA L:VSTDLIB_FUNCTION_LIKE_MACRO */ + +# if !defined (VStdLib_MemClrMacro) + +/********************************************************************************************************************** + * VStdLib_MemClrMacro() + *********************************************************************************************************************/ +/*! \brief Initializes memory to zero (macro implementation). + * \details Sets nCnt blocks starting at pDst to zero (block-size is given by the type of pDst). + * \param[out] pDst Any typed pointer to the memory location to be initialized, must be aligned + * corresponding to its type and not be NULL. + * \param[in] nCnt Number of blocks to initialize, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + *********************************************************************************************************************/ +# define VStdLib_MemClrMacro(pDst, nCnt) \ + { VStdLib_CntType __i; for ( __i = 0u; __i < (nCnt); ++__i) { (pDst)[__i] = 0; } } /* FETA_VSTDLIB_MEMSET_MACRO */ + +# endif + +# if !defined (VStdLib_MemSetMacro) + +/********************************************************************************************************************** + * VStdLib_MemSetMacro() + *********************************************************************************************************************/ +/*! \brief Initializes memory to a specified pattern (macro implementation). + * \details Sets nCnt blocks starting at pDst to nPattern (block-size is given by the type of pDst). + * \param[out] pDst Any typed pointer to the memory location to be initialized, must be aligned + * corresponding to its type and not be NULL. + * \param[in] nPattern The pattern to be used to initialize the memory (consider the correlation between its + * type and the type of pDst). + * \param[in] nCnt Number of blocks to initialize, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + *********************************************************************************************************************/ +# define VStdLib_MemSetMacro(pDst, nPattern, nCnt) \ + { VStdLib_CntType __i; for ( __i = 0u; __i < (nCnt); ++__i) { (pDst)[__i] = (nPattern); } } /* FETA_VSTDLIB_MEMSET_MACRO */ + +# endif + +# if !defined (VStdLib_MemCpyMacro) + +/********************************************************************************************************************** + * VStdLib_MemCpyMacro() + *********************************************************************************************************************/ +/*! \brief Copies data from one memory location to another (macro implementation). + * \details Copies nCnt blocks starting at pSrc to another memory location starting at pDst (block-size is given + * by the type of pDst). + * \param[out] pDst Any typed pointer to the memory location to copy to, must be aligned corresponding + * to its type and not be NULL. + * \param[in] pSrc Any typed pointer to the memory location to copy from, must be aligned corresponding + * to its type and not be NULL. + * \param[in] nCnt Number of blocks to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpyMacro(pDst, pSrc, nCnt) \ + { VStdLib_CntType __i; for ( __i = 0u; __i < (nCnt); ++__i) { (pDst)[__i] = (pSrc)[__i]; } } /* FETA_VSTDLIB_MEMCPY_MACRO */ + +# endif + +# if !defined (VStdLib_MemCpyMacro_s) + +/********************************************************************************************************************** + * VStdLib_MemCpyMacro_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location to another (macro + * implementation). + * \details Uses VStdLib_MemCpyMacro() to copy nCnt blocks starting at pSrc to another memory location starting + * at pDst (block-size is given by the type of pDst), if nDstSize is greater than or equal to nCnt. + * \param[out] pDst Any typed pointer to the memory location to copy to, must be aligned corresponding + * to its type and not be NULL. + * \param[in] nDstSize Maximum number of blocks available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Any typed pointer to the memory location to copy from, must be aligned corresponding + * to its type and not be NULL. + * \param[in] nCnt Number of blocks to copy. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +# define VStdLib_MemCpyMacro_s(pDst, nDstSize, pSrc, nCnt) \ + { if ((nDstSize) >= (nCnt)) { VStdLib_MemCpyMacro((pDst), (pSrc), (nCnt)); } } /* FETA_VSTDLIB_CALL_MEMCPY_MACRO */ + +# endif + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES (FUNCTION API) + *********************************************************************************************************************/ + +# define VSTDLIB_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if (VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_MemSet() + *********************************************************************************************************************/ +/*! \brief Initializes memory to a specified pattern. + * \details Sets nCnt bytes starting at pDst to the character nPattern. + * \param[out] pDst Pointer to the memory location to be initialized, must not be NULL. + * \param[in] nPattern The character to be used to initialize the memory. + * \param[in] nCnt Number of bytes to initialize, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_ON. + * The compatible definition VStdLib_MemSetLarge() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_MemSet(P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + uint8 nPattern, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_MemCpy() + *********************************************************************************************************************/ +/*! \brief Copies data from one memory location to another. + * \details Copies nCnt bytes starting at pSrc to another memory location starting at pDst. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_ON. + * The compatible definition VStdLib_MemCpyLarge() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_MemCpy(P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_MemCpy16() + *********************************************************************************************************************/ +/*! \brief Copies data from one memory location to another. + * \details Copies nCnt 16-bit blocks starting at pSrc to another memory location starting at pDst. + * \param[out] pDst Pointer to the memory location to copy to, 16-bit aligned and not NULL. + * \param[in] pSrc Pointer to the memory location to copy from, 16-bit aligned and not NULL. + * \param[in] nCnt Number of 16-bit blocks to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_ON. + * The compatible definition VStdLib_MemCpy16Large() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_MemCpy16(P2VAR(uint16, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(uint16, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_MemCpy32() + *********************************************************************************************************************/ +/*! \brief Copies data from one memory location to another. + * \details Copies nCnt 32-bit blocks starting at pSrc to another memory location starting at pDst. + * \param[out] pDst Pointer to the memory location to copy to, 32-bit aligned and not NULL. + * \param[in] pSrc Pointer to the memory location to copy from, 32-bit aligned and not NULL. + * \param[in] nCnt Number of 32-bit blocks to copy, pDst must be valid for this amount. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_ON. + * The compatible definition VStdLib_MemCpy32Large() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nCnt' have to define a valid memory area that is writable from the calling + * context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_MemCpy32(P2VAR(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(uint32, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt); + +# endif /* VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_MemCpy_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location to another. + * \details Uses VStdLib_MemCpy() to copy nCnt bytes starting at pSrc to another memory location starting + * at pDst, if nDstSize is greater than or equal to nCnt. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config The compatible definition VStdLib_MemCpyLarge_s() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_MemCpy_s(P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_MemCpy_Return_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location to another. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpy() to + * copy nCnt bytes starting at pSrc to another memory location starting at pDst. + * Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config The compatible definition VStdLib_MemCpyLarge_Return_s() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_MemCpy_Return_s(P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt, + Std_ReturnType errorCode); + +/********************************************************************************************************************** + * VStdLib_MemCpySwapEndian_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location to another in the swapped + * endianness according to the integer type intType. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpySwapEndian() to copy and swap nCnt + * bytes starting at pSrc to another memory location starting at pDst. + * Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config The compatible definition VStdLib_MemCpySwapEndianLarge_s() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_MemCpySwapEndian_s(P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt, + uint8 intType, + Std_ReturnType errorCode); + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianPlatformToBig_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location (platform endianness) to + * another in big endian according to the integer type intType. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpy()/VStdLib_MemCpySwapEndian() to + * copy nCnt bytes starting at pSrc to another memory location starting at pDst in big endian. + * Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config The compatible definition VStdLib_MemCpyEndianPlatformToBigLarge_s() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + * \vcaattr EscalateFindings((The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the calling context)) + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_MemCpyEndianPlatformToBig_s( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt, + uint8 intType, + Std_ReturnType errorCode); + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianPlatformToLittle_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies data from one memory location (platform endianness) to + * another in little endian according to the integer type intType. + * \details If nDstSize is greater than or equal to nCnt, it uses VStdLib_MemCpy()/VStdLib_MemCpySwapEndian() to + * copy nCnt bytes starting at pSrc to another memory location starting at pDst in little endian. + * Otherwise no copying is performed and the passed errorCode is returned. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \param[in] errorCode Value to be returned, if nCnt exceeds nDstSize. + * Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode nCnt exceeds nDstSize. No copying was performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nDstSize' + * \synchronous TRUE + * \config The compatible definition VStdLib_MemCpyEndianPlatformToLittleLarge_s() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the + * calling context. + * The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType'). + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + * \vcaattr EscalateFindings((The parameters 'pDst' and 'nDstSize' have to define a valid memory area that is writable from the calling context)) + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_MemCpyEndianPlatformToLittle_s( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt, + uint8 intType, + Std_ReturnType errorCode); + +# if (VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_MemCmp() + *********************************************************************************************************************/ +/*! \brief Compares two buffers for the specified number of bytes and returns whether they are equal or not. + * \details - + * \param[in] pBuf1 Pointer to first buffer for comparison, must not be NULL. + * \param[in] pBuf2 Pointer to second buffer for comparison, must not be NULL. + * \param[in] nCnt Number of bytes to compare, pBuf1 and pBuf2 must be valid for this amount. + * \return < 0 The first buffer contains a smaller value than the second buffer. + * \return 0 The two buffers are equal for the number of compared bytes. + * \return > 0 The first buffer contains a greater value than the second buffer. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_LIBRARY_FUNCTIONS == STD_ON. + * The compatible definition VStdLib_MemCmpLarge() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pBuf1' and 'pBuf2' have to point to valid memory areas. Each memory area has to be + * valid for at least the byte count defined in parameter 'nCnt'. + * The memory areas defined by parameters 'pBuf1', 'pBuf2' and 'nCnt' must not be changed by another + * context while the comparison is being executed. + *********************************************************************************************************************/ +FUNC(sint8, VSTDLIB_CODE) VStdLib_MemCmp(P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf1, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf2, + VStdLib_CntType nCnt); + +# endif /* VSTDLIB_USE_LIBRARY_FUNCTIONS != STD_ON */ + +# if (VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON) + +/********************************************************************************************************************** + * VStdLib_MemCpySwapEndian() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bytes starting at pSrc to another memory location starting at pDst in the swapped + * endianness according to the integer type intType. + * \details Depending on the configuration (VSTDLIB_RUNTIME_OPTIMIZATION) and the passed arguments for parameter + * intType and nCnt different memory access sizes are used (see TechRef). + * intType value VSTDLIB_INTTYPE_64 is only supported if PLATFORM_SUPPORT_SINT64_UINT64 is defined. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nCnt Number of bytes to copy, pDst must be valid for this amount. + * \param[in] intType Integer type with which the memory locations are interpreted + * (VSTDLIB_INTTYPE_[8, 16, 32, 64]). + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst' and 'nCnt' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION == STD_ON. + * The compatible definition VStdLib_MemCpySwapEndianLarge() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pDst' and 'nCnt' have to define a memory area that is valid for a multiple of the + * integer type size (parameter 'intType') and writable from the calling context. + * The parameter 'pDst' is aligned according to the integer type 'intType'. + * The source memory area defined by parameters 'pSrc' and 'nCnt' must not be changed by another context + * while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_MemCpySwapEndian(P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt, + uint8 intType); + +# endif /* VSTDLIB_USE_MEM_CPY_ENDIAN_CONVERSION_LIBRARY_FUNCTION != STD_ON */ + +# if(VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_BitCpySawBigToBigEndian() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bits of big endian data from one memory location to another memory location with big + * endian data. + * \details - + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetSaw'. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffetSaw' and 'nCnt'. + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameters 'pDst', 'nDstBitOffsetSaw' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetSaw' and 'nCnt' must not + * be changed by another context while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpySawBigToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_BitCpySawBigToLittleEndian() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bits of big endian data from one memory location to another memory location with little + * endian data. + * \details - + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetSaw'. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffetSaw' and 'nCnt'. + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameters 'pDst', 'nDstBitOffsetSaw' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetSaw' and 'nCnt' must not + * be changed by another context while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpySawBigToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_BitCpySawLittleToBigEndian() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bits of little endian data from one memory location to another memory location with big + * endian data. + * \details - + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetSaw'. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffetSaw' and 'nCnt'. + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameters 'pDst', 'nDstBitOffsetSaw' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetSaw' and 'nCnt' must not + * be changed by another context while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpySawLittleToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_BitCpySawLittleToLittleEndian() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bits of little endian data from one memory location to another memory location with + * little endian data. + * \details - + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetSaw'. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffetSaw' and 'nCnt'. + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameters 'pDst', 'nDstBitOffsetSaw' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetSaw' and 'nCnt' must not + * be changed by another context while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpySawLittleToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt); + +# endif /* VSTDLIB_USE_BITCPYSAWTOOTH_LIBRARY_FUNCTIONS != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_BitCpySawBigToBigEndian_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies nCnt bits of big endian data from one memory location to + * another memory location with big endian data. + * \details Uses VStdLib_BitCpySawBigToBigEndian() to copy data, if nDstSize is greater than or equal to the last + * byte to copy to. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] nDstBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetSaw'. + * \param[in] errorCode Value to be returned, if 'nCnt' bits starting at 'nDstBitOffsetSaw' exceeds + * 'nDstSize'. Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode 'nCnt' bits starting at 'nDstBitOffsetSaw'' exceeds 'nDstSize'. No copying was + * performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffetSaw' and 'nCnt'. + * \synchronous TRUE + * \config - + * \pre The parameters 'pDst', 'nDstBitOffsetSaw' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetSaw' and 'nCnt' must not + * be changed by another context while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpySawBigToBigEndian_s( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt, + Std_ReturnType errorCode); + +/********************************************************************************************************************** + * VStdLib_BitCpySawBigToLittleEndian_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies nCnt bits of big endian data from one memory location to + * another memory location with little endian data. + * \details Uses VStdLib_BitCpySawBigToLittleEndian() to copy data, if nDstSize is greater than or equal to the + * last byte to copy to. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] nDstBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetSaw'. + * \param[in] errorCode Value to be returned, if 'nCnt' bits starting at 'nDstBitOffsetSaw' exceeds + * 'nDstSize'. Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode 'nCnt' bits starting at 'nDstBitOffsetSaw' exceeds 'nDstSize'. No copying was + * performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffetSaw' and 'nCnt'. + * \synchronous TRUE + * \config - + * \pre The parameters 'pDst', 'nDstBitOffsetSaw' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetSaw' and 'nCnt' must not + * be changed by another context while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpySawBigToLittleEndian_s( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt, + Std_ReturnType errorCode); + +/********************************************************************************************************************** + * VStdLib_BitCpySawLittleToBigEndian_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies nCnt bits of little endian data from one memory location to + * another memory location with big endian data. + * \details Uses VStdLib_BitCpySawLittleToBigEndian() to copy data, if nDstSize is greater than or equal to the + * last byte to copy to. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] nDstBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetSaw'. + * \param[in] errorCode Value to be returned, if 'nCnt' bits starting at 'nDstBitOffsetSaw' exceeds + * 'nDstSize'. Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode 'nCnt' bits starting at 'nDstBitOffsetSaw' exceeds 'nDstSize'. No copying was + * performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffetSaw' and 'nCnt'. + * \synchronous TRUE + * \config - + * \pre The parameters 'pDst', 'nDstBitOffsetSaw' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetSaw' and 'nCnt' must not + * be changed by another context while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpySawLittleToBigEndian_s( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt, + Std_ReturnType errorCode); + +/********************************************************************************************************************** + * VStdLib_BitCpySawLittleToLittleEndian_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies nCnt bits of little endian data from one memory location to + * another memory location with little endian data. + * \details Uses VStdLib_BitCpySawLittleToLittleEndian() to copy data, if nDstSize is greater than or equal to + * the last byte to copy to. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] nDstBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetSaw Bit offset (it can even be greater than 7) in sawtooth numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetSaw'. + * \param[in] errorCode Value to be returned, if 'nCnt' bits starting at 'nDstBitOffsetSaw' exceeds + * 'nDstSize'. Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode 'nCnt' bits starting at 'nDstBitOffsetSaw' exceeds 'nDstSize'. No copying was + * performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffetSaw' and 'nCnt'. + * \synchronous TRUE + * \config - + * \pre The parameters 'pDst', 'nDstBitOffsetSaw' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetSaw' and 'nCnt' must not + * be changed by another context while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpySawLittleToLittleEndian_s( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetSaw, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetSaw, + VStdLib_CntType nCnt, + Std_ReturnType errorCode); + +# if(VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_BitCpyMonBigToBigEndian() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bits of big endian data from one memory location to another memory location with big + * endian data. + * \details - + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetMon'. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt'. + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetMon' and 'nCnt' must not + * be changed by another context while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpyMonBigToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_BitCpyMonBigToLittleEndian() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bits of big endian data from one memory location to another memory location with little + * endian data. + * \details - + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetMon'. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt'. + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetMon' and 'nCnt' must not + * be changed by another context while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpyMonBigToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_BitCpyMonLittleToBigEndian() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bits of little endian data from one memory location to another memory location with big + * endian data. + * \details - + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetMon'. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt'. + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetMon' and 'nCnt' must not + * be changed by another context while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpyMonLittleToBigEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt); + +/********************************************************************************************************************** + * VStdLib_BitCpyMonLittleToLittleEndian() + *********************************************************************************************************************/ +/*! \brief Copies nCnt bits of little endian data from one memory location to another memory location with + * little endian data. + * \details - + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetMon'. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt'. + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetMon' and 'nCnt' must not + * be changed by another context while the copying is being executed. + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_BitCpyMonLittleToLittleEndian( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt); + +# endif /* VSTDLIB_USE_BITCPYMONOTONE_LIBRARY_FUNCTIONS != STD_ON */ + +/********************************************************************************************************************** + * VStdLib_BitCpyMonBigToBigEndian_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies nCnt bits of big endian data from one memory location to + * another memory location with big endian data. + * \details Uses VStdLib_BitCpyMonBigToBigEndian() to copy data, if nDstSize is greater than or equal to the last + * byte to copy to. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] nDstBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetMon'. + * \param[in] errorCode Value to be returned, if 'nCnt' bits starting at 'nDstBitOffsetMon' exceeds + * 'nDstSize'. Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode 'nCnt' bits starting at 'nDstBitOffsetMon' exceeds 'nDstSize'. No copying was + * performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt'. + * \synchronous TRUE + * \config - + * \pre The parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetMon' and 'nCnt' must not + * be changed by another context while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpyMonBigToBigEndian_s( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt, + Std_ReturnType errorCode); + +/********************************************************************************************************************** + * VStdLib_BitCpyMonBigToLittleEndian_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies nCnt bits of big endian data from one memory location to + * another memory location with little endian data. + * \details Uses VStdLib_BitCpyMonBigToLittleEndian() to copy data, if nDstSize is greater than or equal to the + * last byte to copy to. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] nDstBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetMon'. + * \param[in] errorCode Value to be returned, if 'nCnt' bits starting at 'nDstBitOffsetMon' exceeds + * 'nDstSize'. Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode 'nCnt' bits starting at 'nDstBitOffsetMon' exceeds 'nDstSize'. No copying was + * performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt'. + * \synchronous TRUE + * \config - + * \pre The parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetMon' and 'nCnt' must not + * be changed by another context while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpyMonBigToLittleEndian_s( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt, + Std_ReturnType errorCode); + +/********************************************************************************************************************** + * VStdLib_BitCpyMonLittleToBigEndian_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies nCnt bits of little endian data from one memory location to + * another memory location with big endian data + * \details Uses VStdLib_BitCpyMonLittleToBigEndian() to copy data, if nDstSize is greater than or equal to the + * last byte to copy to. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] nDstBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetMon'. + * \param[in] errorCode Value to be returned, if 'nCnt' bits starting at 'nDstBitOffsetMon' exceeds + * 'nDstSize'. Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode 'nCnt' bits starting at 'nDstBitOffsetMon' exceeds 'nDstSize'. No copying was + * performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt'. + * \synchronous TRUE + * \config - + * \pre The parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetMon' and 'nCnt' must not + * be changed by another context while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpyMonLittleToBigEndian_s( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt, + Std_ReturnType errorCode); + +/********************************************************************************************************************** + * VStdLib_BitCpyMonLittleToLittleEndian_s() + *********************************************************************************************************************/ +/*! \brief Verifies the destination size and copies nCnt bits of little endian data from one memory location to + * another memory location with little endian data. + * \details Uses VStdLib_BitCpyMonLittleToLittleEndian() to copy data, if nDstSize is greater than or equal to + * the last byte to copy to. + * \param[out] pDst Pointer to the memory location to copy to, must not be NULL. + * \param[in] nDstSize Maximum number of bytes available in the destination (typically the size of the + * destination object). + * \param[in] nDstBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pDst'. Bits are copied to exactly this bit position. + * \param[in] pSrc Pointer to the memory location to copy from, must not be NULL. + * \param[in] nSrcBitOffsetMon Bit offset (it can even be greater than 7) in monotone numbering is added to + * 'pSrc'. Bits are copied from exactly this bit position. + * \param[in] nCnt Number of bits to copy starting at 'nDstBitOffsetMon'. + * \param[in] errorCode Value to be returned, if 'nCnt' bits starting at 'nDstBitOffsetMon' exceeds + * 'nDstSize'. Should not be equal to E_OK. + * \return E_OK Copying was performed. + * \return errorCode 'nCnt' bits starting at 'nDstBitOffsetMon' exceeds 'nDstSize'. No copying was + * performed. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt'. + * \synchronous TRUE + * \config - + * \pre The parameters 'pDst', 'nDstBitOffsetMon' and 'nCnt' have to define a valid memory area that is + * writable from the calling context. + * The source memory area defined by parameters 'pSrc', 'nSrcBitOffsetMon' and 'nCnt' must not + * be changed by another context while the copying is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_BitCpyMonLittleToLittleEndian_s( + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + VStdLib_CntType nDstBitOffsetMon, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nSrcBitOffsetMon, + VStdLib_CntType nCnt, + Std_ReturnType errorCode); + +# if (VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION != STD_ON) + +/********************************************************************************************************************** + * VStdLib_MemCheck() + *********************************************************************************************************************/ +/*! \brief Compares the content of a memory area to a specified pattern. + * \details Compares nCnt bytes of memory starting at pBuf to the character nPattern. + * \param[in] pBuf Pointer to the memory location to be checked, must not be NULL. + * \param[in] nPattern The character to be checked for in the memory. + * \param[in] nCnt Number of bytes to be checked, pBuf must be valid for this amount. + * \param[in] errorCode Value to be returned, if content of pBuf is not equal to pattern. + * Should not be equal to E_OK. + * \return E_OK Content of pBuf is equal to pattern. + * \return errorCode Content of pBuf is not equal to pattern. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_MEMCHECK_FUNCTION == STD_ON. + * The compatible definition VStdLib_MemCheckLarge() exists additionally (and solely) + * if VSTDLIB_SUPPORT_LARGE_DATA == STD_ON. + * \pre The parameters 'pBuf' and 'nCnt' have to define a valid memory area. + * The memory area defined by parameters 'pBuf' and 'nCnt' must not be changed by another context while + * the comparison is being executed. + * The parameter 'errorCode' must not be E_OK. + *********************************************************************************************************************/ +FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_MemCheck(P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pBuf, + uint8 nPattern, + VStdLib_CntType nCnt, + Std_ReturnType errorCode); + +# endif /* VSTDLIB_USE_MEM_CHECK_LIBRARY_FUNCTION != STD_ON */ + +# if (VSTDLIB_VERSION_INFO_API == STD_ON) + +/********************************************************************************************************************** + * VStdLib_GetVersionInfo() + *********************************************************************************************************************/ +/*! \brief Returns the version information of this module. + * \details Returns version information, vendor ID and AUTOSAR module ID of the component. + * \param[out] versioninfo Pointer to where to store the version information, must not be NULL. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config VSTDLIB_VERSION_INFO_API == STD_ON + * \pre The parameter 'versioninfo' has to be valid and reference an object of type Std_VersionInfoType. + * \trace CREQ-VStdLib-VersionInformation + *********************************************************************************************************************/ +FUNC(void, VSTDLIB_CODE) VStdLib_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, VSTDLIB_APPL_VAR) versioninfo); + +# endif /* VSTDLIB_VERSION_INFO_API == STD_ON */ + +# if (VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosOne8() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of a set bit in the specified 8-bit value. + * \details - + * \param[in] value The 8-bit value in which the highest set bit shall be found. + * \return 0-7 Bit position of the highest set bit. + * \return VSTDLIB_BITPOS_NA 8-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosOne8(uint8 value); + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosZero8() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of an unset bit in the specified 8-bit value. + * \details - + * \param[in] value The 8-bit value in which the highest unset bit shall be found. + * \return 0-7 Bit position of the highest unset bit. + * \return VSTDLIB_BITPOS_NA 8-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosZero8(uint8 value); + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosOne8() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of a set bit in the specified 8-bit value. + * \details - + * \param[in] value The 8-bit value in which the lowest set bit shall be found. + * \return 0-7 Bit position of the lowest set bit. + * \return VSTDLIB_BITPOS_NA 8-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosOne8(uint8 value); + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosZero8() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of an unset bit in the specified 8-bit value. + * \details - + * \param[in] value The 8-bit value in which the lowest unset bit shall be found. + * \return 0-7 Bit position of the lowest unset bit. + * \return VSTDLIB_BITPOS_NA 8-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosZero8(uint8 value); + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingOnes8() + *********************************************************************************************************************/ +/*! \brief Returns the count of set bits preceding the highest unset bit in the specified 8-bit value. + * \details - + * \param[in] value The 8-bit value in which the count of leading ones shall be determined. + * \return 0-7 Count of leading ones. + * \return VSTDLIB_BITCNT_NA 8-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingOnes8(uint8 value); + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingZeros8() + *********************************************************************************************************************/ +/*! \brief Returns the count of unset bits preceding the highest set bit in the specified 8-bit value. + * \details - + * \param[in] value The 8-bit value in which the count of leading zeros shall be determined. + * \return 0-7 Count of leading zeros. + * \return VSTDLIB_BITCNT_NA 8-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingZeros8(uint8 value); + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingOnes8() + *********************************************************************************************************************/ +/*! \brief Returns the count of set bits following the lowest unset bit in the specified 8-bit value. + * \details - + * \param[in] value The 8-bit value in which the count of trailing ones shall be determined. + * \return 0-7 Count of trailing ones. + * \return VSTDLIB_BITCNT_NA 8-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingOnes8(uint8 value); + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingZeros8() + *********************************************************************************************************************/ +/*! \brief Returns the count of unset bits following the lowest set bit in the specified 8-bit value. + * \details - + * \param[in] value The 8-bit value in which the count of trailing zeros shall be determined. + * \return 0-7 Count of trailing zeros. + * \return VSTDLIB_BITCNT_NA 8-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingZeros8(uint8 value); + +# endif /* VSTDLIB_USE_8BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON */ + +# if (VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosOne16() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of a set bit in the specified 16-bit value. + * \details - + * \param[in] value The 16-bit value in which the highest set bit shall be found. + * \return 0-15 Bit position of the highest set bit. + * \return VSTDLIB_BITPOS_NA 16-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosOne16(uint16 value); + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosZero16() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of an unset bit in the specified 16-bit value. + * \details - + * \param[in] value The 16-bit value in which the highest unset bit shall be found. + * \return 0-15 Bit position of the highest unset bit. + * \return VSTDLIB_BITPOS_NA 16-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosZero16(uint16 value); + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosOne16() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of a set bit in the specified 16-bit value. + * \details - + * \param[in] value The 16-bit value in which the lowest set bit shall be found. + * \return 0-15 Bit position of the lowest set bit. + * \return VSTDLIB_BITPOS_NA 16-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosOne16(uint16 value); + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosZero16() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of an unset bit in the specified 16-bit value. + * \details - + * \param[in] value The 16-bit value in which the lowest unset bit shall be found. + * \return 0-15 Bit position of the lowest unset bit. + * \return VSTDLIB_BITPOS_NA 16-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosZero16(uint16 value); + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingOnes16() + *********************************************************************************************************************/ +/*! \brief Returns the count of set bits preceding the highest unset bit in the specified 16-bit value. + * \details - + * \param[in] value The 16-bit value in which the count of leading ones shall be determined. + * \return 0-15 Count of leading ones. + * \return VSTDLIB_BITCNT_NA 16-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingOnes16(uint16 value); + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingZeros16() + *********************************************************************************************************************/ +/*! \brief Returns the count of unset bits preceding the highest set bit in the specified 16-bit value. + * \details - + * \param[in] value The 16-bit value in which the count of leading zeros shall be determined. + * \return 0-15 Count of leading zeros. + * \return VSTDLIB_BITCNT_NA 16-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingZeros16(uint16 value); + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingOnes16() + *********************************************************************************************************************/ +/*! \brief Returns the count of set bits following the lowest unset bit in the specified 16-bit value. + * \details - + * \param[in] value The 16-bit value in which the count of trailing ones shall be determined. + * \return 0-15 Count of trailing ones. + * \return VSTDLIB_BITCNT_NA 16-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingOnes16(uint16 value); + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingZeros16() + *********************************************************************************************************************/ +/*! \brief Returns the count of unset bits following the lowest set bit in the specified 16-bit value. + * \details - + * \param[in] value The 16-bit value in which the count of trailing zeros shall be determined. + * \return 0-15 Count of trailing zeros. + * \return VSTDLIB_BITCNT_NA 16-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingZeros16(uint16 value); + +# endif /* VSTDLIB_USE_16BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON */ + +# if (VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosOne32() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of a set bit in the specified 32-bit value. + * \details - + * \param[in] value The 32-bit value in which the highest set bit shall be found. + * \return 0-31 Bit position of the highest set bit. + * \return VSTDLIB_BITPOS_NA 32-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosOne32(uint32 value); + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosZero32() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of an unset bit in the specified 32-bit value. + * \details - + * \param[in] value The 32-bit value in which the highest unset bit shall be found. + * \return 0-31 Bit position of the highest unset bit. + * \return VSTDLIB_BITPOS_NA 32-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosZero32(uint32 value); + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosOne32() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of a set bit in the specified 32-bit value. + * \details - + * \param[in] value The 32-bit value in which the lowest set bit shall be found. + * \return 0-31 Bit position of the lowest set bit. + * \return VSTDLIB_BITPOS_NA 32-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosOne32(uint32 value); + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosZero32() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of an unset bit in the specified 32-bit value. + * \details - + * \param[in] value The 32-bit value in which the lowest unset bit shall be found. + * \return 0-31 Bit position of the lowest unset bit. + * \return VSTDLIB_BITPOS_NA 32-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosZero32(uint32 value); + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingOnes32() + *********************************************************************************************************************/ +/*! \brief Returns the count of set bits preceding the highest unset bit in the specified 32-bit value. + * \details - + * \param[in] value The 32-bit value in which the count of leading ones shall be determined. + * \return 0-31 Count of leading ones. + * \return VSTDLIB_BITCNT_NA 32-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingOnes32(uint32 value); + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingZeros32() + *********************************************************************************************************************/ +/*! \brief Returns the count of unset bits preceding the highest set bit in the specified 32-bit value. + * \details - + * \param[in] value The 32-bit value in which the count of leading zeros shall be determined. + * \return 0-31 Count of leading zeros. + * \return VSTDLIB_BITCNT_NA 32-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingZeros32(uint32 value); + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingOnes32() + *********************************************************************************************************************/ +/*! \brief Returns the count of set bits following the lowest unset bit in the specified 32-bit value. + * \details - + * \param[in] value The 32-bit value in which the count of trailing ones shall be determined. + * \return 0-31 Count of trailing ones. + * \return VSTDLIB_BITCNT_NA 32-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingOnes32(uint32 value); + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingZeros32() + *********************************************************************************************************************/ +/*! \brief Returns the count of unset bits following the lowest set bit in the specified 32-bit value. + * \details - + * \param[in] value The 32-bit value in which the count of trailing zeros shall be determined. + * \return 0-31 Count of trailing zeros. + * \return VSTDLIB_BITCNT_NA 32-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingZeros32(uint32 value); + +# endif /* VSTDLIB_USE_32BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON */ + +# if ((defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON)) + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosOne64() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of a set bit in the specified 64-bit value. + * \details - + * \param[in] value The 64-bit value in which the highest set bit shall be found. + * \return 0-63 Bit position of the highest set bit. + * \return VSTDLIB_BITPOS_NA 64-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosOne64(uint64 value); + +/********************************************************************************************************************** + * VStdLib_GetHighestBitPosZero64() + *********************************************************************************************************************/ +/*! \brief Returns the highest bit position of an unset bit in the specified 64-bit value. + * \details - + * \param[in] value The 64-bit value in which the highest unset bit shall be found. + * \return 0-63 Bit position of the highest unset bit. + * \return VSTDLIB_BITPOS_NA 64-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetHighestBitPosZero64(uint64 value); + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosOne64() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of a set bit in the specified 64-bit value. + * \details - + * \param[in] value The 64-bit value in which the lowest set bit shall be found. + * \return 0-63 Bit position of the lowest set bit. + * \return VSTDLIB_BITPOS_NA 64-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosOne64(uint64 value); + +/********************************************************************************************************************** + * VStdLib_GetLowestBitPosZero64() + *********************************************************************************************************************/ +/*! \brief Returns the lowest bit position of an unset bit in the specified 64-bit value. + * \details - + * \param[in] value The 64-bit value in which the lowest unset bit shall be found. + * \return 0-63 Bit position of the lowest unset bit. + * \return VSTDLIB_BITPOS_NA 64-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetLowestBitPosZero64(uint64 value); + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingOnes64() + *********************************************************************************************************************/ +/*! \brief Returns the count of set bits preceding the highest unset bit in the specified 64-bit value. + * \details - + * \param[in] value The 64-bit value in which the count of leading ones shall be determined. + * \return 0-63 Count of leading ones. + * \return VSTDLIB_BITCNT_NA 64-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingOnes64(uint64 value); + +/********************************************************************************************************************** + * VStdLib_GetCountLeadingZeros64() + *********************************************************************************************************************/ +/*! \brief Returns the count of unset bits preceding the highest set bit in the specified 64-bit value. + * \details - + * \param[in] value The 64-bit value in which the count of leading zeros shall be determined. + * \return 0-63 Count of leading zeros. + * \return VSTDLIB_BITCNT_NA 64-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountLeadingZeros64(uint64 value); + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingOnes64() + *********************************************************************************************************************/ +/*! \brief Returns the count of set bits following the lowest unset bit in the specified 64-bit value. + * \details - + * \param[in] value The 64-bit value in which the count of trailing ones shall be determined. + * \return 0-63 Count of trailing ones. + * \return VSTDLIB_BITCNT_NA 64-bit value contains no unset bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingOnes64(uint64 value); + +/********************************************************************************************************************** + * VStdLib_GetCountTrailingZeros64() + *********************************************************************************************************************/ +/*! \brief Returns the count of unset bits following the lowest set bit in the specified 64-bit value. + * \details - + * \param[in] value The 64-bit value in which the count of trailing zeros shall be determined. + * \return 0-63 Count of trailing zeros. + * \return VSTDLIB_BITCNT_NA 64-bit value contains no set bit. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +FUNC(uint8, VSTDLIB_CODE) VStdLib_GetCountTrailingZeros64(uint64 value); + +# endif /* (defined PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_SEARCH_LIBRARY_FUNCTIONS != STD_ON) */ + +# if (VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_ConvertUint16ToUint8ArrayBigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 16-bit value to an unsigned 8-bit array according to big endian. + * \details - + * \param[in] src The unsigned 16-bit value which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least two elements that is writable + * from the calling context. + * \spec + * requires $lengthOf(dst) >= 2; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint16ToUint8ArrayBigEndian( + uint16 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +/********************************************************************************************************************** + * VStdLib_ConvertUint16ToUint8ArrayLittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 16-bit value to an unsigned 8-bit array according to little endian. + * \details - + * \param[in] src The unsigned 16-bit value, which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least two elements that is writable + * from the calling context. + * \spec + * requires $lengthOf(dst) >= 2; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint16ToUint8ArrayLittleEndian( + uint16 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint16BigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to an unsigned 16-bit value according to big endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to an unsigned 16-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least two elements. + * The parameter 'dst' has to point to an unsigned 16-bit variable that is writable from the calling + * context. + * \spec + * requires $lengthOf(src) >= 2; + * requires $lengthOf(dst) >= 1; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint16BigEndian( + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint16, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint16LittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to an unsigned 16-bit value according to little endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to an unsigned 16-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least two elements. + * The parameter 'dst' has to point to an unsigned 16-bit variable that is writable from the calling + * context. + * \spec + * requires $lengthOf(src) >= 2; + * requires $lengthOf(dst) >= 1; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint16LittleEndian( + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint16, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +# endif /* VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON */ + +# if (VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_ConvertUint32ToUint8ArrayBigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 32-bit value to an unsigned 8-bit array according to big endian. + * \details - + * \param[in] src The unsigned 32-bit value, which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least four elements that is writable + * from the calling context. + * \spec + * requires $lengthOf(dst) >= 4; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint32ToUint8ArrayBigEndian( + uint32 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +/********************************************************************************************************************** + * VStdLib_ConvertUint32ToUint8ArrayLittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 32-bit value to an unsigned 8-bit array according to little endian. + * \details - + * \param[in] src The unsigned 32-bit value, which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least four elements that is writable + * from the calling context. + * \spec + * requires $lengthOf(dst) >= 4; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint32ToUint8ArrayLittleEndian( + uint32 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint32BigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to an unsigned 32-bit value according to big endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to an unsigned 32-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least four elements. + * The parameter 'dst' has to point to an unsigned 32-bit variable that is writable from the calling + * context. + * \spec + * requires $lengthOf(src) >= 4; + * requires $lengthOf(dst) >= 1; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint32BigEndian( + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint32, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint32LittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to an unsigned 32-bit value according to little endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to an unsigned 32-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least four elements. + * The parameter 'dst' has to point to an unsigned 32-bit variable that is writable from the calling + * context. + * \spec + * requires $lengthOf(src) >= 4; + * requires $lengthOf(dst) >= 1; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint32LittleEndian( + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint32, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +# endif /* VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON */ + +# if (defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON)) + +/********************************************************************************************************************** + * VStdLib_ConvertUint64ToUint8ArrayBigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 64-bit value to an unsigned 8-bit array according to big endian. + * \details - + * \param[in] src The unsigned 64-bit value, which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least eight elements that is writable + * from the calling context. + * \spec + * requires $lengthOf(dst) >= 8; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint64ToUint8ArrayBigEndian( + uint64 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +/********************************************************************************************************************** + * VStdLib_ConvertUint64ToUint8ArrayLittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 64-bit value to an unsigned 8-bit array according to little endian. + * \details - + * \param[in] src The unsigned 64-bit value, which shall be converted. + * \param[out] dst Pointer to an unsigned 8-bit array, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'dst' has to point to an unsigned 8-bit array of at least eight elements that is writable + * from the calling context. + * \spec + * requires $lengthOf(dst) >= 8; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint64ToUint8ArrayLittleEndian( + uint64 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint64BigEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to an unsigned 64-bit value according to big endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to an unsigned 64-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least eight elements. + * The parameter 'dst' has to point to an unsigned 64-bit variable that is writable from the calling + * context. + * \spec + * requires $lengthOf(src) >= 8; + * requires $lengthOf(dst) >= 1; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint64BigEndian( + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint64, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint64LittleEndian() + *********************************************************************************************************************/ +/*! \brief Converts the specified unsigned 8-bit array to an unsigned 64-bit value according to little endian. + * \details - + * \param[in] src Pointer to an unsigned 8-bit array, which shall be converted. + * \param[out] dst Pointer to an unsigned 64-bit variable, where the conversion result will be stored. + * \context ANY + * \reentrant TRUE for different memory areas defined by parameter 'dst' + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined. This service is implemented + * externally if VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS == STD_ON. + * \pre The parameter 'src' has to point to an unsigned 8-bit array of at least eight elements. + * The parameter 'dst' has to point to an unsigned 64-bit variable that is writable from the calling + * context. + * \spec + * requires $lengthOf(src) >= 8; + * requires $lengthOf(dst) >= 1; + * \endspec + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint64LittleEndian( + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint64, AUTOMATIC, VSTDLIB_APPL_VAR) dst); + +# endif /* defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON) */ + +# if (VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_SwapEndianUint16() + *********************************************************************************************************************/ +/*! \brief Swaps the endianness of the specified unsigned 16-bit value. + * \details - + * \param[in] value Unsigned 16-bit value, whose endianness shall be swapped. + * \return Value in the swapped endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint16, VSTDLIB_CODE) VStdLib_SwapEndianUint16(uint16 value); + +# endif /* VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON */ + +# if (VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_SwapEndianUint32() + *********************************************************************************************************************/ +/*! \brief Swaps the endianness of the specified unsigned 32-bit value. + * \details - + * \param[in] value Unsigned 32-bit value, whose endianness shall be swapped. + * \return Value in the swapped endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is implemented externally if VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint32, VSTDLIB_CODE) VStdLib_SwapEndianUint32(uint32 value); + +# endif /* VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON */ + +# if (defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON)) + +/********************************************************************************************************************** + * VStdLib_SwapEndianUint64() + *********************************************************************************************************************/ +/*! \brief Swaps the endianness of the specified unsigned 64-bit value. + * \details - + * \param[in] value Unsigned 64-bit value, whose endianness shall be swapped. + * \return Value in the swapped endianness. + * \context ANY + * \reentrant TRUE + * \synchronous TRUE + * \config This service is only available if PLATFORM_SUPPORT_SINT64_UINT64 is defined.This service is implemented + * externally if VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS == STD_ON. + * \pre - + *********************************************************************************************************************/ +VSTDLIB_LOCAL_INLINE FUNC(uint64, VSTDLIB_CODE) VStdLib_SwapEndianUint64(uint64 value); + +# endif /* defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON) */ + +# define VSTDLIB_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ +# define VSTDLIB_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +# if( VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_ConvertUint16ToUint8ArrayBigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint16ToUint8ArrayBigEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + uint16 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameter 'dst' */ + if(dst == NULL_PTR) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert unsigned 16-bit value to big endian byte array */ +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, &src, 2u); /* PRQA S 0315, 1340 */ /* MD_MSR_VStdLibCopy, MD_VStdLib_Para2ConstPtr */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + dst[0u] = (uint8)((src & 0xFF00u) >> 8u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[1u] = (uint8)( src & 0x00FFu); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ +# endif /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_UINT16_TO_ARRAY_BE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_ConvertUint16ToUint8ArrayLittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint16ToUint8ArrayLittleEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + uint16 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameter 'dst' */ + if(dst == NULL_PTR) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert unsigned 16-bit value to lillte endian byte array */ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, &src, 2u); /* PRQA S 0315, 1340 */ /* MD_MSR_VStdLibCopy, MD_VStdLib_Para2ConstPtr */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + dst[0u] = (uint8)( src & 0x00FFu); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[1u] = (uint8)((src & 0xFF00u) >> 8u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ +# endif /* CPU_BYTE_ORDER == LOW_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_UINT16_TO_ARRAY_LE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint16BigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint16BigEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint16, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameter 'dst' */ + if((src == NULL_PTR) || (dst == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert big endian byte array to unsigned 16-bit value */ +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, src, 2u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + (*dst) = (uint16)((((uint16)src[0u]) << 8u) |/* SBSW_VSTDLIB_ACCESS_PASSED_INT */ + ((uint16)src[1u])); +# endif /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_ARRAY_TO_UINT16_BE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint16LittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint16LittleEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint16, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'src' and 'dst' */ + if((src == NULL_PTR) || (dst == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert lillte endian byte array to unsigned 16-bit value */ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, src, 2u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + (*dst) = (uint16)(((uint16)src[0u]) | /* SBSW_VSTDLIB_ACCESS_PASSED_INT */ + (((uint16)src[1u]) << 8u)); +# endif /* CPU_BYTE_ORDER == LOW_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_ARRAY_TO_UINT16_LE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +# endif /* VSTDLIB_USE_16BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON */ + +# if (VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_ConvertUint32ToUint8ArrayBigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint32ToUint8ArrayBigEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + uint32 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameter 'dst' */ + if(dst == NULL_PTR) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert unsigned 32-bit value to big endian byte array */ +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, &src, 4u); /* PRQA S 0315, 1340 */ /* MD_MSR_VStdLibCopy, MD_VStdLib_Para2ConstPtr */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + dst[0u] = (uint8)((src & 0xFF000000u) >> 24u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[1u] = (uint8)((src & 0x00FF0000u) >> 16u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[2u] = (uint8)((src & 0x0000FF00u) >> 8u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[3u] = (uint8)( src & 0x000000FFu); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ +# endif /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_UINT32_TO_ARRAY_BE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_ConvertUint32ToUint8ArrayLittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint32ToUint8ArrayLittleEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + uint32 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameter 'dst' */ + if(dst == NULL_PTR) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert unsigned 32-bit value to lillte endian byte array */ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, &src, 4u); /* PRQA S 0315, 1340 */ /* MD_MSR_VStdLibCopy, MD_VStdLib_Para2ConstPtr */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + dst[0u] = (uint8)( src & 0x000000FFu); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[1u] = (uint8)((src & 0x0000FF00u) >> 8u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[2u] = (uint8)((src & 0x00FF0000u) >> 16u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[3u] = (uint8)((src & 0xFF000000u) >> 24u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ +# endif /* CPU_BYTE_ORDER == LOW_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_UINT32_TO_ARRAY_LE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint32BigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint32BigEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint32, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'src' and 'dst' */ + if((src == NULL_PTR) || (dst == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert big endian byte array to unsigned 32-bit value */ +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, src, 4u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + (*dst) = (uint32)((((uint32)src[0u]) << 24u) | /* SBSW_VSTDLIB_ACCESS_PASSED_INT */ + (((uint32)src[1u]) << 16u) | + (((uint32)src[2u]) << 8u) | + ((uint32)src[3u]) + ); +# endif /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_ARRAY_TO_UINT32_BE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint32LittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint32LittleEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint32, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'src' and 'dst' */ + if((src == NULL_PTR) || (dst == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert lillte endian byte array to unsigned 32-bit value */ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, src, 4u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + (*dst) = (uint32)( ((uint32)src[0u]) | /* SBSW_VSTDLIB_ACCESS_PASSED_INT */ + (((uint32)src[1u]) << 8u) | + (((uint32)src[2u]) << 16u) | + (((uint32)src[3u]) << 24u) + ); +# endif /* CPU_BYTE_ORDER == LOW_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_ARRAY_TO_UINT32_LE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +# endif /* VSTDLIB_USE_32BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON */ + +# if (defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON)) + +/********************************************************************************************************************** + * VStdLib_ConvertUint64ToUint8ArrayBigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint64ToUint8ArrayBigEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + uint64 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameter 'dst' */ + if(dst == NULL_PTR) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert unsigned 64-bit value to big endian byte array */ +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, &src, 8u); /* PRQA S 0315, 1340 */ /* MD_MSR_VStdLibCopy, MD_VStdLib_Para2ConstPtr */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + dst[0u] = (uint8)((src & 0xFF00000000000000uLL) >> 56u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[1u] = (uint8)((src & 0x00FF000000000000uLL) >> 48u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[2u] = (uint8)((src & 0x0000FF0000000000uLL) >> 40u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[3u] = (uint8)((src & 0x000000FF00000000uLL) >> 32u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[4u] = (uint8)((src & 0x00000000FF000000uLL) >> 24u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[5u] = (uint8)((src & 0x0000000000FF0000uLL) >> 16u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[6u] = (uint8)((src & 0x000000000000FF00uLL) >> 8u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[7u] = (uint8)( src & 0x00000000000000FFuLL); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ +# endif /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_UINT64_TO_ARRAY_BE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_ConvertUint64ToUint8ArrayLittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint64ToUint8ArrayLittleEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + uint64 src, + P2VAR(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameter 'dst' */ + if(dst == NULL_PTR) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert unsigned 64-bit value to lillte endian byte array */ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, &src, 8u); /* PRQA S 0315, 1340 */ /* MD_MSR_VStdLibCopy, MD_VStdLib_Para2ConstPtr */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + dst[0u] = (uint8)( src & 0x00000000000000FFuLL); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[1u] = (uint8)((src & 0x000000000000FF00uLL) >> 8u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[2u] = (uint8)((src & 0x0000000000FF0000uLL) >> 16u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[3u] = (uint8)((src & 0x00000000FF000000uLL) >> 24u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[4u] = (uint8)((src & 0x000000FF00000000uLL) >> 32u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[5u] = (uint8)((src & 0x0000FF0000000000uLL) >> 40u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[6u] = (uint8)((src & 0x00FF000000000000uLL) >> 48u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ + dst[7u] = (uint8)((src & 0xFF00000000000000uLL) >> 56u); /* SBSW_VSTDLIB_ACCESS_PASSED_ARRAY */ +# endif /* CPU_BYTE_ORDER == LOW_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_UINT64_TO_ARRAY_LE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint64BigEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint64BigEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint64, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'src' and 'dst' */ + if((src == NULL_PTR) || (dst == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert big endian byte array to unsigned 64-bit value */ +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, src, 8u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + (*dst) = (uint64)((((uint64)src[0u]) << 56u) | /* SBSW_VSTDLIB_ACCESS_PASSED_INT */ + (((uint64)src[1u]) << 48u) | + (((uint64)src[2u]) << 40u) | + (((uint64)src[3u]) << 32u) | + (((uint64)src[4u]) << 24u) | + (((uint64)src[5u]) << 16u) | + (((uint64)src[6u]) << 8u) | + ((uint64)src[7u]) + ); +# endif /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_ARRAY_TO_UINT64_BE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +/********************************************************************************************************************** + * VStdLib_ConvertUint8ArrayToUint64LittleEndian() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(void, VSTDLIB_CODE) VStdLib_ConvertUint8ArrayToUint64LittleEndian( /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ + P2CONST(uint8, AUTOMATIC, VSTDLIB_APPL_VAR) src, + P2VAR(uint64, AUTOMATIC, VSTDLIB_APPL_VAR) dst) +{ + /* ----- Local Variables ---------------------------------------------- */ + uint8 errorId = VSTDLIB_E_NO_ERROR; + + /* ----- Development Error Checks ------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_DETECT == STD_ON) + /* #10 Check parameters 'src' and 'dst' */ + if((src == NULL_PTR) || (dst == NULL_PTR)) + { + errorId = VSTDLIB_E_PARAM_POINTER; + } + else +# endif + { + /* ----- Implementation ----------------------------------------------- */ + /* #100 Convert lillte endian byte array to unsigned 64-bit value */ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + /* Optimization possible, if target platform optimized VStdLib_MemCpy() is used */ + VStdLib_MemCpy(dst, src, 8u); /* PRQA S 0315 */ /* MD_MSR_VStdLibCopy */ /* SBSW_VSTDLIB_CALL_MEM_CPY */ +# else + (*dst) = (uint64)( ((uint64)src[0u]) | /* SBSW_VSTDLIB_ACCESS_PASSED_INT */ + (((uint64)src[1u]) << 8u) | + (((uint64)src[2u]) << 16u) | + (((uint64)src[3u]) << 24u) | + (((uint64)src[4u]) << 32u) | + (((uint64)src[5u]) << 40u) | + (((uint64)src[6u]) << 48u) | + (((uint64)src[7u]) << 56u) + ); +# endif /* CPU_BYTE_ORDER == LOW_BYTE_FIRST */ + } + + /* ----- Development Error Report --------------------------------------- */ +# if (VSTDLIB_DEV_ERROR_REPORT == STD_ON) + if(errorId != VSTDLIB_E_NO_ERROR) + { + (void)Det_ReportError(VSTDLIB_MODULE_ID, VSTDLIB_INSTANCE_ID_DET, VSTDLIB_SID_CNV_ARRAY_TO_UINT64_LE, errorId); + } +# else + VSTDLIB_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3122 */ /* MD_MSR_DummyStmt */ +# endif +} + +# endif /* defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_DE_SERIALIZATION_LIBRARY_FUNCTIONS != STD_ON) */ + +# if (VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_SwapEndianUint16() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint16, VSTDLIB_CODE) VStdLib_SwapEndianUint16(uint16 value) /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ +{ + /* ----- Implementation ----------------------------------------------- */ + + /* #100 Swap endianness */ + return (uint16)(((value & 0xFF00u) >> 8u) | ((value & 0x00FFu) << 8u)); +} + +# endif /* VSTDLIB_USE_16BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON */ + +# if (VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON) + +/********************************************************************************************************************** + * VStdLib_SwapEndianUint32() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint32, VSTDLIB_CODE) VStdLib_SwapEndianUint32(uint32 value) /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ +{ + /* ----- Implementation ----------------------------------------------- */ + + /* #100 Swap endianness */ + return (uint32)(((value & 0xFF000000u) >> 24u) | /* 3 to 0 */ + ((value & 0x00FF0000u) >> 8u) | /* 2 to 1 */ + ((value & 0x0000FF00u) << 8u) | /* 1 to 2 */ + ((value & 0x000000FFu) << 24u) /* 0 to 3 */ + ); +} + +# endif /* VSTDLIB_USE_32BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON */ + +# if (defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON)) + +/********************************************************************************************************************** + * VStdLib_SwapEndianUint64() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(uint64, VSTDLIB_CODE) VStdLib_SwapEndianUint64(uint64 value) /* PRQA S 3219 */ /* MD_VStdLib_NotUsedInUnit */ +{ + /* ----- Implementation ----------------------------------------------- */ + + /* #100 Swap endianness */ + return (uint64)(((value & 0xFF00000000000000uLL) >> 56u) | /* 7 to 0 */ + ((value & 0x00FF000000000000uLL) >> 40u) | /* 6 to 1 */ + ((value & 0x0000FF0000000000uLL) >> 24u) | /* 5 to 2 */ + ((value & 0x000000FF00000000uLL) >> 8u) | /* 4 to 3 */ + ((value & 0x00000000FF000000uLL) << 8u) | /* 3 to 4 */ + ((value & 0x0000000000FF0000uLL) << 24u) | /* 2 to 5 */ + ((value & 0x000000000000FF00uLL) << 40u) | /* 1 to 6 */ + ((value & 0x00000000000000FFuLL) << 56u) /* 0 to 7 */ + ); +} + +# endif /* defined (PLATFORM_SUPPORT_SINT64_UINT64) && (VSTDLIB_USE_64BIT_ENDIAN_CONVERSION_LIBRARY_FUNCTIONS != STD_ON) */ + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianPlatformToBig_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_MemCpyEndianPlatformToBig_s( /* PRQA S 3219, 6060 */ /* MD_VStdLib_NotUsedInUnit, MD_MSR_STPAR */ + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt, + uint8 intType, + Std_ReturnType errorCode) +{ +# if (CPU_BYTE_ORDER == HIGH_BYTE_FIRST) + /* #10 Call VStdLib_MemCpy_Return_s() */ + VSTDLIB_DUMMY_STATEMENT(intType); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ + return VStdLib_MemCpy_Return_s(pDst, nDstSize, pSrc, nCnt, errorCode); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + +# else /* CPU_BYTE_ORDER == LOW_BYTE_FIRST) */ + /* #20 Call VStdLib_MemCpySwapEndian_s() */ + return VStdLib_MemCpySwapEndian_s(pDst, nDstSize, pSrc, nCnt, intType, errorCode); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ +# endif /* CPU_BYTE_ORDER */ +} + +/********************************************************************************************************************** + * VStdLib_MemCpyEndianPlatformToLittle_s() + *********************************************************************************************************************/ +/*! + * Internal comment removed. + * + * + * + * + * + */ +VSTDLIB_LOCAL_INLINE FUNC(Std_ReturnType, VSTDLIB_CODE) VStdLib_MemCpyEndianPlatformToLittle_s( /* PRQA S 3219, 6060 */ /* MD_VStdLib_NotUsedInUnit, MD_MSR_STPAR */ + P2VAR(void, AUTOMATIC, VSTDLIB_VAR_FAR) pDst, + VStdLib_CntType nDstSize, + P2CONST(void, AUTOMATIC, VSTDLIB_VAR_FAR) pSrc, + VStdLib_CntType nCnt, + uint8 intType, + Std_ReturnType errorCode) +{ +# if (CPU_BYTE_ORDER == LOW_BYTE_FIRST) + /* #10 Call VStdLib_MemCpy_Return_s() */ + VSTDLIB_DUMMY_STATEMENT(intType); /* PRQA S 2983, 3112 */ /* MD_MSR_DummyStmt */ + return VStdLib_MemCpy_Return_s(pDst, nDstSize, pSrc, nCnt, errorCode); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ + +# else /* CPU_BYTE_ORDER == HIGH_BYTE_FIRST) */ + /* #20 Call VStdLib_MemCpySwapEndian_s() */ + return VStdLib_MemCpySwapEndian_s(pDst, nDstSize, pSrc, nCnt, intType, errorCode); /* SBSW_VSTDLIB_CALL_UNMODIFIED */ +# endif /* CPU_BYTE_ORDER */ +} + +# define VSTDLIB_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/********************************************************************************************************************** + * COMPATIBILITY MACROS + *********************************************************************************************************************/ + +# define VSTDLIB__COREHLL_VERSION (0x0308u) /* last core version this component was based on */ +# define VSTDLIB__COREHLL_RELEASE_VERSION (0x00u) +# define VSTDLIB_GENERICASR_VERSION ((VSTDLIB_SW_MAJOR_VERSION << 8u) | VSTDLIB_SW_MINOR_VERSION) +# define VSTDLIB_GENERICASR_RELEASE_VERSION VSTDLIB_SW_PATCH_VERSION +# define kVStdMainVersion VSTDLIB_SW_MAJOR_VERSION +# define kVStdSubVersion VSTDLIB_SW_MINOR_VERSION +# define kVStdReleaseVersion VSTDLIB_SW_PATCH_VERSION + +# define kVStdErrorIntDisableTooOften (0x01u) +# define kVStdErrorIntRestoreTooOften (0x02u) +# define kVStdErrorMemClrInvalidParameter (0x03u) +# define kVStdErrorMemCpyInvalidParameter (0x04u) +# define kVStdErrorFunctionNotSupportedByHw (0x05u) +# define kVStdErrorMemSetInvalidParameter (0x06u) +# define kVStdErrorUnexpectedLockState (0x07u) + +# define VSTD_HL_DISABLE_SUPPORT_MEM_FCT +# define VSTD_HL_DISABLE_MEM_FCT_MAPPING +# define VSTD_HL_USE_VSTD_MEMCLR +# define VSTD_HL_USE_VSTD_MEMSET +# define VSTD_HL_USE_VSTD_RAMMEMCPY +# define VSTD_HL_USE_VSTD_ROMMEMCPY +# define VSTD_HL_USE_VSTD_WORD_MEMCPY +# define VSTD_HL_USE_VSTD_DWORD_MEMCPY + +# define VStdInitPowerOn() + +/* PRQA S 3453 VSTDLIB_FUNCTION_LIKE_MACRO */ /* MD_MSR_FctLikeMacro */ + +# if !defined (VStdLib_MemCpyRom) +# define VStdLib_MemCpyRom(d, s, c) VStdLib_MemCpy((d), (s), (c)) +# endif + +# define VStdMemClr(d, c) VStdLib_MemClr((d), (c)) +# define VStdMemNearClr(d, c) VStdLib_MemClr((d), (c)) +# define VStdMemFarClr(d, c) VStdLib_MemClr((d), (c)) +# define VStdMemSet(d, p, c) VStdLib_MemSet((d), (p), (c)) +# define VStdMemNearSet(d, p, c) VStdLib_MemSet((d), (p), (c)) +# define VStdMemFarSet(d, p, c) VStdLib_MemSet((d), (p), (c)) + +# define VStdMemCpy(d, s, c) VStdLib_MemCpy((d), (s), (c)) +# define VStdMemCpyRom(d, s, c) VStdLib_MemCpyRom((d), (s), (c)) +# define VStdMemCpyRamToRam(d, s, c) VStdLib_MemCpy((d), (s), (c)) +# define VStdMemCpyRomToRam(d, s, c) VStdLib_MemCpyRom((d), (s), (c)) +# define VStdMemCpyRamToNearRam(d, s, c) VStdLib_MemCpy((d), (s), (c)) +# define VStdMemCpyRomToNearRam(d, s, c) VStdLib_MemCpyRom((d), (s), (c)) +# define VStdMemCpyRamToFarRam(d, s, c) VStdLib_MemCpy((d), (s), (c)) +# define VStdMemCpyRomToFarRam(d, s, c) VStdLib_MemCpyRom((d), (s), (c)) +# define VStdMemCpyFarRamToRam(d, s, c) VStdLib_MemCpy((d), (s), (c)) +# define VStdMemCpyFarRamToFarRam(d, s, c) VStdLib_MemCpy((d), (s), (c)) +# define VStdMemCpyFarRomToFarRam(d, s, c) VStdLib_MemCpyRom((d), (s), (c)) +# define VStdRamMemCpy(d, s, c) VStdLib_MemCpy((d), (s), (c)) +# define VStdRomMemCpy(d, s, c) VStdLib_MemCpyRom((d), (s), (c)) + +# define VStdMemCpy16(d, s, c) VStdLib_MemCpy16((d), (s), (c)) +# define VStdMemCpy16RamToRam(d, s, c) VStdLib_MemCpy16((d), (s), (c)) +# define VStdMemCpy16RamToNearRam(d, s, c) VStdLib_MemCpy16((d), (s), (c)) +# define VStdMemCpy16NearRamToRam(d, s, c) VStdLib_MemCpy16((d), (s), (c)) +# define VStdMemCpy16RamToFarRam(d, s, c) VStdLib_MemCpy16((d), (s), (c)) +# define VStdMemCpy16FarRamToRam(d, s, c) VStdLib_MemCpy16((d), (s), (c)) +# define VStdRamMemCpy16(d, s, c) VStdLib_MemCpy16((d), (s), (c)) + +# define VStdMemCpy32(d, s, c) VStdLib_MemCpy32((d), (s), (c)) +# define VStdMemCpy32RamToRam(d, s, c) VStdLib_MemCpy32((d), (s), (c)) +# define VStdMemCpy32RamToNearRam(d, s, c) VStdLib_MemCpy32((d), (s), (c)) +# define VStdMemCpy32NearRamToRam(d, s, c) VStdLib_MemCpy32((d), (s), (c)) +# define VStdMemCpy32RamToFarRam(d, s, c) VStdLib_MemCpy32((d), (s), (c)) +# define VStdMemCpy32FarRamToRam(d, s, c) VStdLib_MemCpy32((d), (s), (c)) +# define VStdRamMemCpy32(d, s, c) VStdLib_MemCpy32((d), (s), (c)) + +# if !defined (VStdLib_MemCpyRomMacro) +# define VStdLib_MemCpyRomMacro(d, s, c) VStdLib_MemCpyMacro((d), (s), (c)) +# endif + +# define VStdMemClr_Macro(d, c) VStdLib_MemClrMacro((d), (c)) +# define VStdMemSet_Macro(d, p, c) VStdLib_MemSetMacro((d), (p), (c)) +# define VStdMemCpy_Macro(d, s, c) VStdLib_MemCpyMacro((d), (s), (c)) +# define VStdMemCpyRom_Macro(d, s, c) VStdLib_MemCpyRomMacro((d), (s), (c)) + +/* PRQA L:VSTDLIB_FUNCTION_LIKE_MACRO */ + +#endif /* VSTDLIB_H */ + +/********************************************************************************************************************** + * END OF FILE: vstdlib.h + *********************************************************************************************************************/ diff --git a/Source/bsw/WrapNv/Make/WrapNv_cfg.mak b/Source/bsw/WrapNv/Make/WrapNv_cfg.mak new file mode 100644 index 0000000..20e4358 --- /dev/null +++ b/Source/bsw/WrapNv/Make/WrapNv_cfg.mak @@ -0,0 +1,12 @@ +############################################################################### +# File Name : WrapNv_cfg.mak +# Description: Configuration makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2021 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the WrapNv_rules.mak file. +############################################################################### \ No newline at end of file diff --git a/Source/bsw/WrapNv/Make/WrapNv_check.mak b/Source/bsw/WrapNv/Make/WrapNv_check.mak new file mode 100644 index 0000000..28c0c4e --- /dev/null +++ b/Source/bsw/WrapNv/Make/WrapNv_check.mak @@ -0,0 +1,12 @@ +############################################################################### +# File Name : WrapNv_check.mak +# Description: Configuration check makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2021 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the WrapNv_rules.mak file. +############################################################################### diff --git a/Source/bsw/WrapNv/Make/WrapNv_defs.mak b/Source/bsw/WrapNv/Make/WrapNv_defs.mak new file mode 100644 index 0000000..b7d82ec --- /dev/null +++ b/Source/bsw/WrapNv/Make/WrapNv_defs.mak @@ -0,0 +1,12 @@ +############################################################################### +# File Name : WrapNv_defs.mak +# Description: Public makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2021 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Refer to the WrapNv_rules.mak file. +############################################################################### diff --git a/Source/bsw/WrapNv/Make/WrapNv_rules.mak b/Source/bsw/WrapNv/Make/WrapNv_rules.mak new file mode 100644 index 0000000..792abfe --- /dev/null +++ b/Source/bsw/WrapNv/Make/WrapNv_rules.mak @@ -0,0 +1,25 @@ +############################################################################### +# File Name : WrapNv_rules.mak +# Description: Rules makefile +#------------------------------------------------------------------------------ +# COPYRIGHT +#------------------------------------------------------------------------------ +# Copyright (c) 2021 by Vector Informatik GmbH. All rights reserved. +#------------------------------------------------------------------------------ +# REVISION HISTORY +#------------------------------------------------------------------------------ +# Version Date Author Description +#------------------------------------------------------------------------------ +# 1.00.00 2021-04-01 visrcn Initial commit +#------------------------------------------------------------------------------ +# TemplateVersion = 1.02 +############################################################################### + +# Component Files +CC_FILES_TO_BUILD += WrapNv$(BSW_SRC_DIR)\WrapNv.c +GENERATED_SOURCE_FILES += $(GENDATA_DIR)\WrapNv_Cfg.c +GENERATED_SOURCE_FILES += $(GENDATA_DIR)\..\Source\WrapNv_Callout_Stubs.c + +# Library Settings +LIBRARIES_TO_BUILD += WrapNv +WrapNv_FILES += WrapNv$(BSW_SRC_DIR)\WrapNv.c \ No newline at end of file diff --git a/Source/bsw/WrapNv/WrapNv.c b/Source/bsw/WrapNv/WrapNv.c new file mode 100644 index 0000000..a191b66 --- /dev/null +++ b/Source/bsw/WrapNv/WrapNv.c @@ -0,0 +1,1880 @@ +/********************************************************************************************************************** + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file WrapNv.c + * \brief Wrapper for NV-memory access + * ------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/*********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#define WRAPNV_SOURCE + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +#include "WrapNv.h" + +#if defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) || \ + defined( WRAPNV_USECASE_NVM ) +/* Critical sections handled by SchM */ +# include "SchM_WrapNv.h" + +# if (WRAPNV_DEV_ERROR_REPORT == STD_ON) +# include "Det.h" +# endif /* WRAPNV_DEV_ERROR_REPORT */ +#endif /* WRAPNV_USECASE_ */ + +#if defined( WRAPNV_USECASE_DRVEEP ) +# include "EepInc.h" +#endif +#if defined( WRAPNV_USECASE_EEPM ) +# include "EepMgr_Inc.h" +#endif + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +#if ( SYSSERVICE_WRAPPERNV_VERSION != 0x0402u ) || \ + ( SYSSERVICE_WRAPPERNV_RELEASE_VERSION != 0x00u ) +# error "Error in WrapNv.c: Source and header file are inconsistent!" +#endif + +/********************************************************************************************************************** + * DEFINES + *********************************************************************************************************************/ + +#if defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) || \ + defined( WRAPNV_USECASE_NVM ) +/** Default value, in case block/data is not available and explicit default value not given */ +# if !defined( WRAPNV_DEFAULT_VALUE ) +# define WRAPNV_DEFAULT_VALUE 0xFFu +# endif /* WRAPNV_DEFAULT_VALUE */ + +# if !defined( STATIC ) +# define STATIC static +# endif + +# if (WRAPNV_DEV_ERROR_REPORT == STD_ON) +/* PRQA S 3453 1 */ /* MD_MSR_19.7 */ +# define WrapNv_Det_ReportError(ApiId, ErrorCode) (void)Det_ReportError(WRAPNV_MODULE_ID, WRAPNV_INSTANCE_ID, (ApiId), (ErrorCode)) +# endif + +# define WrapNv_EnterCritical() SchM_Enter_WrapNv_WRAPNV_EXCLUSIVE_AREA_0() +# define WrapNv_LeaveCritical() SchM_Exit_WrapNv_WRAPNV_EXCLUSIVE_AREA_0() + +/*********************************************************************************************************************** + * TYPEDEFS + **********************************************************************************************************************/ + +/** Specifies the current state of the operation */ +typedef enum +{ + WRAPNV_STATE_IDLE = 0u, /** No operation in progress */ + WRAPNV_STATE_READ_INIT, /** Initialize read operation */ + WRAPNV_STATE_READ_PENDING, /** Wait until read operation has finished */ + WRAPNV_STATE_READ_MODIFY_INIT, /** Initialize read operation for read-modify-write operation */ + WRAPNV_STATE_READ_MODIFY_PENDING, /** Wait until read operation has finished */ + WRAPNV_STATE_MODIFY_DATA, /** Modify data for write operation */ + WRAPNV_STATE_WRITE_INIT, /** Initialize write operation */ + WRAPNV_STATE_WRITE_PENDING, /** Wait until write operation has finished */ + WRAPNV_STATE_DELETE_INIT, /** Initialize delete operation */ + WRAPNV_STATE_DELETE_PENDING, /** Wait until delete operation has finished */ + WRAPNV_STATE_CANCEL /** Process cancel operation */ +} tWrapNvState; + +/** Defines the current operation which is processed by the WrapNv */ +typedef enum +{ + WRAPNV_OPERATION_IDLE = 0u, /** No operation in progress */ + WRAPNV_OPERATION_READ, /** Read operation in progress */ + WRAPNV_OPERATION_READPARTIAL, /** ReadPartial operation in progress */ + WRAPNV_OPERATION_WRITE, /** Write operation in progress */ + WRAPNV_OPERATION_DELETE /** Delete operation in progress */ +} tWrapNvOperation; + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +# define WRAPNV_START_SEC_VAR_NOINIT_UNSPECIFIED +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +/* NV block specific */ +STATIC VAR(uint16, WRAPNV_VAR_NOINIT) gWrapNvRecordNumber; /**< Record ID */ +STATIC VAR(uint16, WRAPNV_VAR_NOINIT) gWrapNvBlockNumber; /**< Number of block */ +STATIC VAR(uint16, WRAPNV_VAR_NOINIT) gWrapNvBlockDataset; /**< Dataset of block */ +STATIC VAR(uint8, WRAPNV_VAR_NOINIT) gWrapNvBlockBuffer[WRAPNV_MAX_BLOCK_LENGTH]; /**< Data buffer for whole NV block */ /* PRQA S 3218 */ /* MD_WrapNv_3218 */ +STATIC P2CONST(uint8, AUTOMATIC, WRAPNV_CONST) gWrapNvBlockDefaultValue; /**< Default value of a NV block, if invalid/not present */ +# if defined( WRAPNV_USECASE_NVM ) +STATIC VAR(uint16, WRAPNV_VAR_NOINIT) gWrapNvBlockMaxDataset; /**< Maximum number of datasets of the block */ +# endif /* WRAPNV_USECASE_NVM */ + +/* Data specific */ +STATIC VAR(uint16, WRAPNV_VAR_NOINIT) gWrapNvReadDataOffset; /**< Offset in NV block to the data */ +STATIC VAR(uint16, WRAPNV_VAR_NOINIT) gWrapNvReadDataLength; /**< Length of data inside the NV block */ +STATIC VAR(tWrapNvRamData, WRAPNV_VAR_NOINIT) gWrapNvReadDataBuffer; /**< Input buffer from upper layer */ +STATIC VAR(uint16, WRAPNV_VAR_NOINIT) gWrapNvWriteDataOffset; /**< Offset in NV block to the data */ +STATIC VAR(uint16, WRAPNV_VAR_NOINIT) gWrapNvWriteDataLength; /**< Length of data inside the NV block */ +STATIC VAR(tWrapNvConstData, WRAPNV_VAR_NOINIT) gWrapNvWriteDataBuffer; /**< Write buffer from upper layer */ +STATIC VAR(tWrapNvRamData, WRAPNV_VAR_NOINIT) gWrapNvBlockAccessBuffer; /**< Buffer used to read and/or write data from/to the NV block */ + +STATIC VAR(tWrapNvState, WRAPNV_VAR_NOINIT) gWrapNvCurrentState; /**< Current state of NV access (read/modify/write) */ +STATIC VAR(tWrapNvOperation, WRAPNV_VAR_NOINIT) gWrapNvCurrentOperation; /**< Current operation */ + +# define WRAPNV_STOP_SEC_VAR_NOINIT_UNSPECIFIED +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ +#endif /* WRAPNV_USECASE_* */ + +/*********************************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **********************************************************************************************************************/ +#define WRAPNV_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#if defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) || \ + defined( WRAPNV_USECASE_NVM ) +STATIC FUNC(MemIf_StatusType, WRAPNV_CODE) WrapNv_GetStatus( void ); +STATIC FUNC(MemIf_JobResultType, WRAPNV_CODE) WrapNv_GetJobResult( void ); +# if defined( WRAPNV_USECASE_NVM ) +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_SetDataIndex( void ); +# endif /* WRAPNV_USECASE_NVM */ +STATIC FUNC(void, WRAPNV_CODE) WrapNv_InitInternal( void ); +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_Cancel( void ); +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_Read( uint16 id, uint16 idx, tWrapNvRamData buffer, tWrapNvAccessType access); +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadAsyncInternal(uint16 id, uint16 idx, tWrapNvRamData buffer, + tWrapNvOpStatus opStatus, tWrapNvAccessType access); +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartial( uint16 id, uint16 idx, tWrapNvRamData buffer, uint16 offset, + uint16 length, tWrapNvAccessType access); +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartialAsyncInternal(uint16 id, uint16 idx, tWrapNvRamData buffer, + uint16 offset, uint16 length, tWrapNvOpStatus opStatus, tWrapNvAccessType access); +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_Delete( uint16 id, uint16 idx ); +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_Write( uint16 id, uint16 idx, tWrapNvConstData buffer, tWrapNvAccessType access ); +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_WriteAsyncInternal(uint16 id, uint16 idx, tWrapNvConstData buffer, + tWrapNvOpStatus opStatus, tWrapNvAccessType access); +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_MainFunction( void ); +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_PollMainFunctions( void ); + +/*********************************************************************************************************************** + * LOCAL FUNCTIONS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * WrapNv_GetStatus + **********************************************************************************************************************/ +/*! \brief Checks the process state of the NV + * \return MEMIF_IDLE in case job is finished (failed or OK state), otherwise MEMIF_BUSY + **********************************************************************************************************************/ +STATIC FUNC(MemIf_StatusType, WRAPNV_CODE) WrapNv_GetStatus( void ) +{ + MemIf_StatusType result; + +# if defined( WRAPNV_USECASE_NVM ) + NvM_RequestResultType nvmStatus; + + if (E_OK == NvM_GetErrorStatus(gWrapNvBlockNumber, &nvmStatus)) + { + /* Check if NVM currently processes a request */ + if (NVM_REQ_PENDING == nvmStatus) + { + result = MEMIF_BUSY; + } + else + { + result = MEMIF_IDLE; + } + } + else + { + result = MEMIF_IDLE; + } +# elif defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) + result = WrapNv_MemDrvGetStatus(); +# endif /* WRAPNV_USECASE_* */ + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_GetJobResult + **********************************************************************************************************************/ +/*! \brief Checks the result of the last request + * \pre WrapNv_GetStatus has been called and returned MEMIF_IDLE + * \return return MEMIF_JOB_OK in case data could be read successfully + * MEMIF_BLOCK_INCONSISTENT in case data could not be read (e.g. data are corrupt) + * MEMIF_INVALID in case the block has been invalidated previously + * MEMIF_JOB_FAILED otherwise + **********************************************************************************************************************/ +STATIC FUNC(MemIf_JobResultType, WRAPNV_CODE) WrapNv_GetJobResult( void ) +{ + MemIf_JobResultType result; + +# if defined( WRAPNV_USECASE_NVM ) + NvM_RequestResultType nvmStatus; + + if (E_OK == NvM_GetErrorStatus(gWrapNvBlockNumber, &nvmStatus)) + { + /* Remap NVM status to MEMIF status */ + switch (nvmStatus) + { + case NVM_REQ_OK: + { + result = MEMIF_JOB_OK; + break; + } + case NVM_REQ_NOT_OK: + { + result = MEMIF_JOB_FAILED; + break; + } + case NVM_REQ_INTEGRITY_FAILED: + { + result = MEMIF_BLOCK_INCONSISTENT; + break; + } + case NVM_REQ_NV_INVALIDATED: + { + result = MEMIF_BLOCK_INVALID; + break; + } + default: + { + /* Unknown state */ + result = MEMIF_JOB_FAILED; + break; + } + } + } + else + { + result = MEMIF_JOB_FAILED; + } +# elif defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) + result = WrapNv_MemDrvGetJobResult(); +# endif /* WRAPNV_USECASE_* */ + + return result; +} + +# if defined( WRAPNV_USECASE_NVM ) +/*********************************************************************************************************************** + * WrapNv_SetDataIndex + **********************************************************************************************************************/ +/*! \brief Sets the data index (dataset) of current block + * \pre Global variables (gWrapNvBlockMaxDataset, gWrapNvBlockNumber and gWrapNvBlockDataset) have to be initialized + * \return return WRAPNV_E_OK in case data index could be set or if it must not be set at all (e.g. only one + * dataset configured/available) + * WRAPNV_E_NOT_OK in case NvM couldn't set data data index + **********************************************************************************************************************/ +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_SetDataIndex( void ) +{ + WrapNv_ReturnType result; + + /* Initialize variables */ + result = WRAPNV_E_OK; + + /* At least two datasets must be configured/available to set the data index for the NVM */ + if (gWrapNvBlockMaxDataset > 1u) + { + if (E_OK != NvM_SetDataIndex(gWrapNvBlockNumber, (uint8)(gWrapNvBlockDataset & 0xFFu))) + { + result = WRAPNV_E_NOT_OK; + } + } + + return result; +} +# endif /* WRAPNV_USECASE_NVM */ + +/*********************************************************************************************************************** + * WrapNv_InitInternal + **********************************************************************************************************************/ +/*! \brief Initializes internal states/variables + **********************************************************************************************************************/ +STATIC FUNC(void, WRAPNV_CODE) WrapNv_InitInternal( void ) +{ + /* Initialize state */ + gWrapNvCurrentState = WRAPNV_STATE_IDLE; + gWrapNvCurrentOperation = WRAPNV_OPERATION_IDLE; + + /* Initialize variables */ + gWrapNvRecordNumber = 0xFFFFu; + gWrapNvBlockDataset = 0xFFFFu; + gWrapNvReadDataOffset = 0xFFFFu; + gWrapNvReadDataLength = 0xFFFFu; + gWrapNvReadDataBuffer = NULL_PTR; + gWrapNvWriteDataBuffer = NULL_PTR; +} + +/*********************************************************************************************************************** + * WrapNv_Cancel + **********************************************************************************************************************/ +/*! \brief Cancels current pending job + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed + **********************************************************************************************************************/ +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_Cancel( void ) +{ + WrapNv_ReturnType result; + + /* Setup the cancel request */ + gWrapNvCurrentState = WRAPNV_STATE_CANCEL; + result = WrapNv_MainFunction(); + + /* Reset internal states */ + WrapNv_InitInternal(); + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_Read + **********************************************************************************************************************/ +/*! \brief Initialize the read operation + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[out] buffer Pointer to data buffer + * \param[in] access Type of access + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_Read( uint16 id, uint16 idx, tWrapNvRamData buffer, tWrapNvAccessType access) +{ + WrapNv_ReturnType result; + uint8 errorId; + P2CONST(tWrapNvRecordTbl, AUTOMATIC, WRAPNV_CONST) localRecordPtr; + P2CONST(tWrapNvBlockTbl, AUTOMATIC, WRAPNV_CONST) localBlockPtr; + + /* Initialize variable */ + result = WRAPNV_E_NOT_OK; + errorId = WRAPNV_E_NO_ERROR; + + if (WRAPNV_STATE_IDLE != gWrapNvCurrentState) + { + errorId = WRAPNV_E_NOT_IDLE; + } + /* Check if ID is valid */ + else if (id >= kWrapNvNrOfRecord) + { + errorId = WRAPNV_E_PARAM_ID; + } + /* Check if dataset is valid */ + else if ( (idx >= kWrapNvRecordTbl[id].recordBlockPtr->blockMaxDatasets) + || (idx > 0xFFu)) + { + errorId = WRAPNV_E_PARAM_DATASET; + } + else + { + localRecordPtr = &kWrapNvRecordTbl[id]; + localBlockPtr = localRecordPtr->recordBlockPtr; + + gWrapNvRecordNumber = id; + gWrapNvBlockNumber = localBlockPtr->blockNumber; + gWrapNvBlockDataset = idx; +# if defined( WRAPNV_USECASE_NVM ) + gWrapNvBlockMaxDataset = localBlockPtr->blockMaxDatasets; +# endif /* WRAPNV_USECASE_NVM */ + gWrapNvBlockDefaultValue = localBlockPtr->blockDefaultValue; + + if (access == WRAPNV_ACCESS_DATAELEMENT) + { + gWrapNvReadDataOffset = localRecordPtr->recordDataOffset; + gWrapNvReadDataLength = localRecordPtr->recordDataLength; + } + else + { + gWrapNvReadDataOffset = 0u; + gWrapNvReadDataLength = localBlockPtr->blockLength; + } + + gWrapNvReadDataBuffer = buffer; + + gWrapNvWriteDataOffset = 0u; + gWrapNvWriteDataLength = 0u; + gWrapNvWriteDataBuffer = NULL_PTR; + +# if defined( WRAPNV_USECASE_NVM ) + gWrapNvBlockAccessBuffer = gWrapNvBlockBuffer; +# elif defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) + gWrapNvBlockAccessBuffer = NULL_PTR; +# endif /* WRAPNV_USECASE_* */ + + gWrapNvCurrentState = WRAPNV_STATE_READ_INIT; + + result = WrapNv_MainFunction(); + } + +# if (WRAPNV_DEV_ERROR_REPORT == STD_ON) + if(errorId != WRAPNV_E_NO_ERROR) + { + WrapNv_Det_ReportError(WRAPNV_APIID_READ, errorId ); + } +# else + (void)errorId; +# endif /* (WRAPNV_DEV_ERROR_REPORT == STD_ON) */ + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_ReadPartial + **********************************************************************************************************************/ +/*! \brief Initialize operation for reading only partial of the data + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[out] buffer Pointer to data buffer + * \param[in] offset Offset in the entry to read only partial + * \param[in] length Length of the partial read + * \param[in] access Type of access + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +/* PRQA S 6060, 6080 1 */ /* MD_MSR_STPAR, MD_MSR_STMIF */ +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartial( uint16 id, uint16 idx, tWrapNvRamData buffer, + uint16 offset, uint16 length, tWrapNvAccessType access) +{ + WrapNv_ReturnType result; + uint8 errorId; + P2CONST(tWrapNvRecordTbl, AUTOMATIC, WRAPNV_CONST) localRecordPtr; + P2CONST(tWrapNvBlockTbl, AUTOMATIC, WRAPNV_CONST) localBlockPtr; + + /* Initialize variable */ + result = WRAPNV_E_NOT_OK; + errorId = WRAPNV_E_NO_ERROR; + + if (WRAPNV_STATE_IDLE != gWrapNvCurrentState) + { + errorId = WRAPNV_E_NOT_IDLE; + } + /* Check if ID is valid */ + else if (id >= kWrapNvNrOfRecord) + { + errorId = WRAPNV_E_PARAM_ID; + } + /* Check if dataset is valid */ + else if ( (idx >= kWrapNvRecordTbl[id].recordBlockPtr->blockMaxDatasets) + || (idx > 0xFFu)) + { + errorId = WRAPNV_E_PARAM_DATASET; + } + else if ( ( (access == WRAPNV_ACCESS_DATAELEMENT) && + ( (offset + length) > kWrapNvRecordTbl[id].recordDataLength) ) || + ( (access == WRAPNV_ACCESS_BLOCKELEMENT) && + ( (offset + length) > kWrapNvRecordTbl[id].recordBlockPtr->blockLength) ) ) + { + errorId = WRAPNV_E_PARAM_READ; + } + else + { + localRecordPtr = &kWrapNvRecordTbl[id]; + localBlockPtr = localRecordPtr->recordBlockPtr; + + gWrapNvRecordNumber = id; + gWrapNvBlockNumber = localBlockPtr->blockNumber; + gWrapNvBlockDataset = idx; +# if defined( WRAPNV_USECASE_NVM ) + gWrapNvBlockMaxDataset = localBlockPtr->blockMaxDatasets; +# endif /* WRAPNV_USECASE_NVM */ + gWrapNvBlockDefaultValue = localBlockPtr->blockDefaultValue; + + if (access == WRAPNV_ACCESS_DATAELEMENT) + { + gWrapNvReadDataOffset = localRecordPtr->recordDataOffset + offset; + gWrapNvReadDataLength = length; + } + else + { + gWrapNvReadDataOffset = offset; + gWrapNvReadDataLength = length; + } + + gWrapNvReadDataBuffer = buffer; + + gWrapNvWriteDataOffset = 0u; + gWrapNvWriteDataLength = 0u; + gWrapNvWriteDataBuffer = NULL_PTR; + +# if defined( WRAPNV_USECASE_NVM ) + gWrapNvBlockAccessBuffer = gWrapNvBlockBuffer; +# elif defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) + gWrapNvBlockAccessBuffer = NULL_PTR; +# endif /* WRAPNV_USECASE_* */ + + gWrapNvCurrentState = WRAPNV_STATE_READ_INIT; + + result = WrapNv_MainFunction(); + } + +# if (WRAPNV_DEV_ERROR_REPORT == STD_ON) + if(errorId != WRAPNV_E_NO_ERROR) + { + WrapNv_Det_ReportError(WRAPNV_APIID_READPARTIAL, errorId ); + } +# else + (void)errorId; +# endif /* (WRAPNV_DEV_ERROR_REPORT == STD_ON) */ + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_Delete + **********************************************************************************************************************/ +/*! \brief Initialize the delete operation + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_Delete( uint16 id, uint16 idx ) +{ + WrapNv_ReturnType result; + uint8 errorId; + P2CONST(tWrapNvRecordTbl, AUTOMATIC, WRAPNV_CONST) localRecordPtr; + P2CONST(tWrapNvBlockTbl, AUTOMATIC, WRAPNV_CONST) localBlockPtr; + + /* Initialize variable */ + result = WRAPNV_E_NOT_OK; + errorId = WRAPNV_E_NO_ERROR; + + if (WRAPNV_STATE_IDLE != gWrapNvCurrentState) + { + errorId = WRAPNV_E_NOT_IDLE; + } + /* Check if ID is valid */ + else if (id >= kWrapNvNrOfRecord) + { + errorId = WRAPNV_E_PARAM_ID; + } + /* Check if dataset is valid */ + else if ( (idx >= kWrapNvRecordTbl[id].recordBlockPtr->blockMaxDatasets) + || (idx > 0xFFu)) + { + errorId = WRAPNV_E_PARAM_DATASET; + } + else + { + localRecordPtr = &kWrapNvRecordTbl[id]; + localBlockPtr = localRecordPtr->recordBlockPtr; + + gWrapNvRecordNumber = id; + gWrapNvBlockNumber = localBlockPtr->blockNumber; + gWrapNvBlockDataset = idx; +# if defined( WRAPNV_USECASE_NVM ) + gWrapNvBlockMaxDataset = localBlockPtr->blockMaxDatasets; +# endif /* WRAPNV_USECASE_NVM */ + gWrapNvBlockDefaultValue = localBlockPtr->blockDefaultValue; + + gWrapNvReadDataOffset = 0u; + gWrapNvReadDataLength = 0u; + gWrapNvReadDataBuffer = NULL_PTR; + + gWrapNvWriteDataOffset = 0u; + gWrapNvWriteDataLength = 0u; + gWrapNvWriteDataBuffer = NULL_PTR; + + gWrapNvBlockAccessBuffer = NULL_PTR; + + gWrapNvCurrentState = WRAPNV_STATE_DELETE_INIT; + + result = WrapNv_MainFunction(); + } + +# if (WRAPNV_DEV_ERROR_REPORT == STD_ON) + if(errorId != WRAPNV_E_NO_ERROR) + { + WrapNv_Det_ReportError(WRAPNV_APIID_DELETE, errorId ); + } +# else + (void)errorId; +# endif /* (WRAPNV_DEV_ERROR_REPORT == STD_ON) */ + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_Write + **********************************************************************************************************************/ +/*! \brief Initialize the write operation + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[in] buffer Pointer to data buffer + * \param[in] access Type of access + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_Write( uint16 id, uint16 idx, tWrapNvConstData buffer, tWrapNvAccessType access) +{ + WrapNv_ReturnType result; + uint8 errorId; + P2CONST(tWrapNvRecordTbl, AUTOMATIC, WRAPNV_CONST) localRecordPtr; + P2CONST(tWrapNvBlockTbl, AUTOMATIC, WRAPNV_CONST) localBlockPtr; + + /* Initialize variable */ + result = WRAPNV_E_NOT_OK; + errorId = WRAPNV_E_NO_ERROR; + + if (WRAPNV_STATE_IDLE != gWrapNvCurrentState) + { + errorId = WRAPNV_E_NOT_IDLE; + } + /* Check if ID is valid */ + else if (id >= kWrapNvNrOfRecord) + { + errorId = WRAPNV_E_PARAM_ID; + } + /* Check if dataset is valid */ + else if ( (idx >= kWrapNvRecordTbl[id].recordBlockPtr->blockMaxDatasets) + || (idx > 0xFFu)) + { + errorId = WRAPNV_E_PARAM_DATASET; + } + else + { + localRecordPtr = &kWrapNvRecordTbl[id]; + localBlockPtr = localRecordPtr->recordBlockPtr; + + gWrapNvRecordNumber = id; + gWrapNvBlockNumber = localBlockPtr->blockNumber; + gWrapNvBlockDataset = idx; +# if defined( WRAPNV_USECASE_NVM ) + gWrapNvBlockMaxDataset = localBlockPtr->blockMaxDatasets; +# endif /* WRAPNV_USECASE_NVM */ + gWrapNvBlockDefaultValue = localBlockPtr->blockDefaultValue; + + if ( (localBlockPtr->blockDataAccess == WRAPNV_RECORDACCESS_STRUCTURED) && + (access == WRAPNV_ACCESS_DATAELEMENT) ) + { + gWrapNvReadDataOffset = 0u; + gWrapNvReadDataLength = localBlockPtr->blockLength; + gWrapNvReadDataBuffer = gWrapNvBlockBuffer; /* Map the read buffer to the same buffer as the access buffer */ + + gWrapNvWriteDataOffset = localRecordPtr->recordDataOffset; + gWrapNvWriteDataLength = localRecordPtr->recordDataLength; + gWrapNvWriteDataBuffer = buffer; + + gWrapNvBlockAccessBuffer = gWrapNvBlockBuffer; + + gWrapNvCurrentState = WRAPNV_STATE_READ_MODIFY_INIT; + } + else + { + gWrapNvReadDataOffset = 0u; + gWrapNvReadDataLength = 0u; + gWrapNvReadDataBuffer = NULL_PTR; + + gWrapNvWriteDataOffset = 0u; + gWrapNvWriteDataLength = 0u; + gWrapNvWriteDataBuffer = NULL_PTR; + + gWrapNvBlockAccessBuffer = (tWrapNvRamData)buffer; /* PRQA S 0311 */ /* MD_WrapNv_0311 */ + + gWrapNvCurrentState = WRAPNV_STATE_WRITE_INIT; + } + + result = WrapNv_MainFunction(); + } + +# if (WRAPNV_DEV_ERROR_REPORT == STD_ON) + if(errorId != WRAPNV_E_NO_ERROR) + { + WrapNv_Det_ReportError(WRAPNV_APIID_WRITE, errorId ); + } +# else + (void)errorId; +# endif /* (WRAPNV_DEV_ERROR_REPORT == STD_ON) */ + + return result; +} + +/*********************************************************************************************************************** +* WrapNv_ReadAsyncInternal +**********************************************************************************************************************/ +/*! \brief Reads specific data asynchronously from a NV block +* \param[in] id Id of record +* \param[in] idx Dataset of block +* \param[out] buffer Pointer to data buffer +* \param[in] opStatus Operation status of calling instance + * \param[in] access Type of access +* \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, +* WRAPNV_E_PENDING if job needs more time +**********************************************************************************************************************/ +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadAsyncInternal(uint16 id, uint16 idx, tWrapNvRamData buffer, + tWrapNvOpStatus opStatus, tWrapNvAccessType access) +{ + WrapNv_ReturnType result; + tWrapNvOpStatus currentOpStatus; + + WrapNv_EnterCritical(); + + /* Check if WrapNv is idle so it can accept a new request */ + if (WRAPNV_OPERATION_IDLE == gWrapNvCurrentOperation) + { + /* Check if new job is canceled */ + if (opStatus == WRAPNV_OPSTATUS_CANCEL) + { + currentOpStatus = WRAPNV_OPSTATUS_CANCEL; + } + else + { + /* Parameters will be stored in WrapNv_Read() call */ + currentOpStatus = WRAPNV_OPSTATUS_INIT; + gWrapNvCurrentOperation = WRAPNV_OPERATION_READ; + } + } + else + { + /* Check if this is a different request to the current pending request */ + if ((id == gWrapNvRecordNumber) + && (idx == gWrapNvBlockDataset) + && (buffer == gWrapNvReadDataBuffer) + && (WRAPNV_OPERATION_READ == gWrapNvCurrentOperation) + ) + { + /* Check if the current job should be canceled */ + if (opStatus == WRAPNV_OPSTATUS_CANCEL) + { + currentOpStatus = WRAPNV_OPSTATUS_CANCEL; + } + else + { + /* Process current request */ + currentOpStatus = WRAPNV_OPSTATUS_PENDING; + } + } + else + { + /* Wait until other request has been finished */ + currentOpStatus = WRAPNV_OPSTATUS_IDLE; + } + } + + WrapNv_LeaveCritical(); + + /* Only init and pending states are allowed at this point */ + switch (currentOpStatus) + { + case WRAPNV_OPSTATUS_INIT: + { + result = WrapNv_Read(id, idx, buffer, access); + break; + } + case WRAPNV_OPSTATUS_PENDING: + { + result = WrapNv_MainFunction(); + break; + } + case WRAPNV_OPSTATUS_IDLE: /* Used when two instances access the WrapNv */ + { + result = WRAPNV_E_PENDING; + break; + } + case WRAPNV_OPSTATUS_CANCEL: + { + result = WrapNv_Cancel(); + break; + } + default: + { /* PRQA S 2880 1 */ /* MD_MSR_Unreachable */ + result = WRAPNV_E_NOT_OK; + break; + } + } + + /* Check if current operation has finished */ + if (WRAPNV_E_PENDING != result) + { + gWrapNvCurrentOperation = WRAPNV_OPERATION_IDLE; + } + + return result; +} + +/*********************************************************************************************************************** +* WrapNv_ReadPartialAsyncInternal +**********************************************************************************************************************/ +/*! \brief Reads partial data asynchronously from a NV block +* \param[in] id Id of record +* \param[in] idx Dataset of block +* \param[out] buffer Pointer to data buffer +* \param[in] offset Offset in the entry to read only partial +* \param[in] length Length of the partial read +* \param[in] opStatus Operation status of calling instance +* \param[in] access Type of access +* \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, +* WRAPNV_E_PENDING if job needs more time +**********************************************************************************************************************/ +/* PRQA S 6060 1 */ /* MD_MSR_STPAR */ +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartialAsyncInternal(uint16 id, uint16 idx, tWrapNvRamData buffer, + uint16 offset, uint16 length, tWrapNvOpStatus opStatus, tWrapNvAccessType access) +{ + WrapNv_ReturnType result; + tWrapNvOpStatus currentOpStatus; + + WrapNv_EnterCritical(); + + /* Check if WrapNv is idle so it can accept a new request */ + if (WRAPNV_OPERATION_IDLE == gWrapNvCurrentOperation) + { + /* Check if new job is canceled */ + if (opStatus == WRAPNV_OPSTATUS_CANCEL) + { + currentOpStatus = WRAPNV_OPSTATUS_CANCEL; + } + else + { + /* Parameters will be stored in WrapNv_ReadPartial() call */ + currentOpStatus = WRAPNV_OPSTATUS_INIT; + gWrapNvCurrentOperation = WRAPNV_OPERATION_READPARTIAL; + } + } + else + { + /* Check if this is a different request to the current pending request */ + if ((id == gWrapNvRecordNumber) + && (idx == gWrapNvBlockDataset) + && (buffer == gWrapNvReadDataBuffer) + && (offset == gWrapNvReadDataOffset) + && (length == gWrapNvReadDataLength) + && (WRAPNV_OPERATION_READPARTIAL == gWrapNvCurrentOperation) + ) + { + /* Check if the current job should be canceled */ + if (opStatus == WRAPNV_OPSTATUS_CANCEL) + { + currentOpStatus = WRAPNV_OPSTATUS_CANCEL; + } + else + { + /* Process current request */ + currentOpStatus = WRAPNV_OPSTATUS_PENDING; + } + } + else + { + /* Wait until other request has been finished */ + currentOpStatus = WRAPNV_OPSTATUS_IDLE; + } + } + + WrapNv_LeaveCritical(); + + /* Only init and pending states are allowed at this point */ + switch (currentOpStatus) + { + case WRAPNV_OPSTATUS_INIT: + { + result = WrapNv_ReadPartial(id, idx, buffer, offset, length, access); + break; + } + case WRAPNV_OPSTATUS_PENDING: + { + result = WrapNv_MainFunction(); + break; + } + case WRAPNV_OPSTATUS_IDLE: /* Used when two instances access the WrapNv */ + { + result = WRAPNV_E_PENDING; + break; + } + case WRAPNV_OPSTATUS_CANCEL: + { + result = WrapNv_Cancel(); + break; + } + default: + { /* PRQA S 2880 1 */ /* MD_MSR_Unreachable */ + result = WRAPNV_E_NOT_OK; + break; + } + } + + /* Check if current operation has finished */ + if (WRAPNV_E_PENDING != result) + { + gWrapNvCurrentOperation = WRAPNV_OPERATION_IDLE; + } + + return result; +} + +/*********************************************************************************************************************** +* WrapNv_WriteAsyncInternal +**********************************************************************************************************************/ +/*! \brief Writes specific data asynchronously to a NV block +* \param[in] id Id of record +* \param[in] idx Dataset of block +* \param[in] buffer Pointer to data buffer +* \param[in] opStatus Operation status of calling instance +* \param[in] access Type of access +* \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, +* WRAPNV_E_PENDING if job needs more time +**********************************************************************************************************************/ +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_WriteAsyncInternal(uint16 id, uint16 idx, tWrapNvConstData buffer, + tWrapNvOpStatus opStatus, tWrapNvAccessType access) +{ + WrapNv_ReturnType result; + tWrapNvOpStatus currentOpStatus; + + WrapNv_EnterCritical(); + + /* Check if WrapNv is idle so it can accept a new request */ + if (WRAPNV_OPERATION_IDLE == gWrapNvCurrentOperation) + { + /* Check if new job is canceled */ + if (opStatus == WRAPNV_OPSTATUS_CANCEL) + { + currentOpStatus = WRAPNV_OPSTATUS_CANCEL; + } + else + { + /* Parameters will be stored in WrapNv_Write() call */ + currentOpStatus = WRAPNV_OPSTATUS_INIT; + gWrapNvCurrentOperation = WRAPNV_OPERATION_WRITE; + } + } + else + { + /* Check if this is a different request to the current pending request */ + if ((id == gWrapNvRecordNumber) + && (idx == gWrapNvBlockDataset) + && ((buffer == gWrapNvWriteDataBuffer) || (buffer == gWrapNvBlockAccessBuffer)) + && (WRAPNV_OPERATION_WRITE == gWrapNvCurrentOperation) + ) + { + /* Check if the current job should be canceled */ + if (opStatus == WRAPNV_OPSTATUS_CANCEL) + { + currentOpStatus = WRAPNV_OPSTATUS_CANCEL; + } + else + { + /* Process current request */ + currentOpStatus = WRAPNV_OPSTATUS_PENDING; + } + } + else + { + /* Wait until other request has been finished */ + currentOpStatus = WRAPNV_OPSTATUS_IDLE; + } + } + + WrapNv_LeaveCritical(); + + /* Only init and pending states are allowed at this point */ + switch (currentOpStatus) + { + case WRAPNV_OPSTATUS_INIT: + { + result = WrapNv_Write(id, idx, buffer, access); + break; + } + case WRAPNV_OPSTATUS_PENDING: + { + result = WrapNv_MainFunction(); + break; + } + case WRAPNV_OPSTATUS_IDLE: /* Used when two instances access the WrapNv */ + { + result = WRAPNV_E_PENDING; + break; + } + case WRAPNV_OPSTATUS_CANCEL: + { + result = WrapNv_Cancel(); + break; + } + default: + { /* PRQA S 2880 1 */ /* MD_MSR_Unreachable */ + result = WRAPNV_E_NOT_OK; + break; + } + } + + /* Check if current operation has finished */ + if (WRAPNV_E_PENDING != result) + { + gWrapNvCurrentOperation = WRAPNV_OPERATION_IDLE; + } + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_MainFunction + **********************************************************************************************************************/ +/*! \brief Main task of the NV-Wrapper to get the current status of the read/write operation + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +/* PRQA S 6030, 6080 1 */ /* MD_MSR_STCYC, MD_MSR_STMIF */ +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_MainFunction( void ) +{ + WrapNv_ReturnType result = WRAPNV_E_PENDING; + uint16_least index; + + switch (gWrapNvCurrentState) + { + case WRAPNV_STATE_READ_INIT: /* Intentional fall through */ + case WRAPNV_STATE_READ_MODIFY_INIT: + { + if (MEMIF_IDLE == WrapNv_GetStatus()) + { +# if defined( WRAPNV_USECASE_NVM ) + result = WrapNv_SetDataIndex(); + if (WRAPNV_E_OK == result) + { + /* PRQA S 0314 1 */ /* MD_WrapNv_0314 */ + result = NvM_ReadBlock(gWrapNvBlockNumber, (P2VAR(void, AUTOMATIC, NVM_APPL_DATA))gWrapNvBlockAccessBuffer); + } +# elif defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) + result = WrapNv_MemDrvRead(gWrapNvBlockNumber | gWrapNvBlockDataset, gWrapNvReadDataOffset, gWrapNvReadDataBuffer, gWrapNvReadDataLength); +# endif /* WRAPNV_USECASE_* */ + + /* If read request was successful, remap result to WRAPNV_E_PENDING */ + if (WRAPNV_E_OK == result) + { + result = WRAPNV_E_PENDING; + + if (WRAPNV_STATE_READ_INIT == gWrapNvCurrentState) + { + gWrapNvCurrentState = WRAPNV_STATE_READ_PENDING; + } + else + { + gWrapNvCurrentState = WRAPNV_STATE_READ_MODIFY_PENDING; + } + } + else + { + /* Error occurred, go back to idle state */ + gWrapNvCurrentState = WRAPNV_STATE_IDLE; + } + } + break; + } + case WRAPNV_STATE_READ_PENDING: /* Intentional fall through */ + case WRAPNV_STATE_READ_MODIFY_PENDING: + { + if (MEMIF_IDLE == WrapNv_GetStatus()) + { + switch( WrapNv_GetJobResult() ) + { + case MEMIF_JOB_OK: + { +# if defined( WRAPNV_USECASE_NVM ) + for (index = 0u; index < gWrapNvReadDataLength; index++) + { + gWrapNvReadDataBuffer[index] = gWrapNvBlockAccessBuffer[gWrapNvReadDataOffset + index]; + } +# endif /* WRAPNV_USECASE_NVM */ + + result = WRAPNV_E_OK; + break; + } + case MEMIF_BLOCK_INCONSISTENT: + case MEMIF_BLOCK_INVALID: + { + if (gWrapNvBlockDefaultValue != NULL_PTR) + { + for (index = 0u; index < gWrapNvReadDataLength; index++) + { + gWrapNvReadDataBuffer[index] = gWrapNvBlockDefaultValue[gWrapNvReadDataOffset + index]; + } + } + else + { + /* No explicit default value configured - fill read buffer with default value */ + for (index = 0u; index < gWrapNvReadDataLength; index++) + { + gWrapNvReadDataBuffer[index] = WRAPNV_DEFAULT_VALUE; + } + } + result = WRAPNV_E_OK; + break; + } + default: + { + result = WRAPNV_E_NOT_OK; + break; + } + } + + if (WRAPNV_E_OK == result) + { + if (WRAPNV_STATE_READ_PENDING == gWrapNvCurrentState) + { + /* No more action required - reset state */ + gWrapNvCurrentState = WRAPNV_STATE_IDLE; + } + else + { + /* This is a read-modify-write operation - remap WRAPNV_E_OK state to WRAPNV_E_PENDING */ + result = WRAPNV_E_PENDING; + gWrapNvCurrentState = WRAPNV_STATE_MODIFY_DATA; + } + } + else + { + /* Error occurred, go back to idle state */ + gWrapNvCurrentState = WRAPNV_STATE_IDLE; + } + } + break; + } + case WRAPNV_STATE_MODIFY_DATA: + { + /* Modify data with new information */ + for (index = 0u; index < gWrapNvWriteDataLength; index++) + { + gWrapNvBlockAccessBuffer[gWrapNvWriteDataOffset + index] = gWrapNvWriteDataBuffer[index]; + } + + gWrapNvCurrentState = WRAPNV_STATE_WRITE_INIT; + } /* Intentional fall through */ + case WRAPNV_STATE_WRITE_INIT: /* PRQA S 2003 */ /* MD_WrapNv_2003 */ + { + if (MEMIF_IDLE == WrapNv_GetStatus()) + { +# if defined( WRAPNV_USECASE_NVM ) + result = WrapNv_SetDataIndex(); + if (WRAPNV_E_OK == result) + { + /* PRQA S 0314 1 */ /* MD_WrapNv_0314 */ + result = NvM_WriteBlock(gWrapNvBlockNumber, (P2CONST(void, AUTOMATIC, NVM_APPL_DATA))gWrapNvBlockAccessBuffer); + } +# elif defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) + result = WrapNv_MemDrvWrite(gWrapNvBlockNumber | gWrapNvBlockDataset, gWrapNvBlockAccessBuffer); +# endif /* WRAPNV_USECASE_* */ + + /* If write request was successful, remap result to WRAPNV_E_PENDING */ + if (WRAPNV_E_OK == result) + { + result = WRAPNV_E_PENDING; + + gWrapNvCurrentState = WRAPNV_STATE_WRITE_PENDING; + } + else + { + /* Error occurred, go back to idle state */ + gWrapNvCurrentState = WRAPNV_STATE_IDLE; + } + } + break; + } + case WRAPNV_STATE_DELETE_INIT: + { + if (MEMIF_IDLE == WrapNv_GetStatus()) + { +# if defined( WRAPNV_USECASE_NVM ) + result = WrapNv_SetDataIndex(); + if (WRAPNV_E_OK == result) + { + result = NvM_InvalidateNvBlock(gWrapNvBlockNumber); + } +# elif defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) + result = WrapNv_MemDrvInvalidateBlock(gWrapNvBlockNumber | gWrapNvBlockDataset); +# endif /* WRAPNV_USECASE_* */ + + /* If invalidate request was successful, remap result to WRAPNV_E_PENDING */ + if (WRAPNV_E_OK == result) + { + result = WRAPNV_E_PENDING; + + gWrapNvCurrentState = WRAPNV_STATE_DELETE_PENDING; + } + else + { + /* Error occurred, go back to idle state */ + gWrapNvCurrentState = WRAPNV_STATE_IDLE; + } + } + break; + } + case WRAPNV_STATE_WRITE_PENDING: /* Intentional fall through */ + case WRAPNV_STATE_DELETE_PENDING: + { + if (MEMIF_IDLE == WrapNv_GetStatus()) + { + if (MEMIF_JOB_OK == WrapNv_GetJobResult()) + { + result = WRAPNV_E_OK; + } + else + { + result = WRAPNV_E_NOT_OK; + } + + /* Regardless of result, go back to idle state */ + gWrapNvCurrentState = WRAPNV_STATE_IDLE; + } + break; + } + case WRAPNV_STATE_CANCEL: + { +# if defined( WRAPNV_USECASE_NVM ) + result = WrapNv_SetDataIndex(); + if (WRAPNV_E_OK == result) + { + result = NvM_CancelJobs(gWrapNvBlockNumber); + } +# elif defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) + WrapNv_MemDrvCancel(); + result = WRAPNV_E_OK; +# endif /* WRAPNV_USECASE_* */ + + /* Regardless of result, go back to idle state */ + gWrapNvCurrentState = WRAPNV_STATE_IDLE; + break; + } + default: + { + result = WRAPNV_E_NOT_OK; + break; + } + } + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_PollMainFunctions + **********************************************************************************************************************/ +/*! \brief Function to poll all sub modules + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +STATIC FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_PollMainFunctions( void ) +{ + WrapNv_ReturnType result; + + result = WrapNv_MainFunction(); + +# if (WRAPNV_MAINFUNCTION_POLLING == STD_ON) + WrapNv_PollMainFunctionsInternalIdle(); + + if (WrapNv_TriggerFct_Callout() == WRAPNV_E_OK) + { + WrapNv_PollMainFunctionsInternalTimer(); + } +# endif + + return result; +} +#endif /* WRAPNV_USECASE_* */ + +/********************************************************************************************************************** + * GLOBAL FUNCTIONS + *********************************************************************************************************************/ + +/*********************************************************************************************************************** + * WrapNv_Init + **********************************************************************************************************************/ +/*! \brief Initializes NV-Wrapper to access FEE/EA/NVM/EEPM/DrvEEP and also async tasks from the NvM + **********************************************************************************************************************/ +FUNC(void, WRAPNV_CODE) WrapNv_Init( void ) +{ +#if defined( WRAPNV_USECASE_DRVEEP ) + (void)EepromDriver_InitSync(((void *)0)); +#elif defined( WRAPNV_USECASE_EEPM ) + (void)EepMgrInitPowerOn(kEepMgrInitFull); +#elif defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) || \ + defined( WRAPNV_USECASE_NVM ) + WrapNv_InitConfig(); + WrapNv_InitInternal(); + +# if defined ( WRAPNV_USECASE_NVM ) && defined( WRAPNV_ENABLE_NVM_MULTIBLOCK_HANDLING ) + (void)WrapNv_NvM_ReadAllSync(); +# endif /* WRAPNV_USECASE_NVM && WRAPNV_ENABLE_NVM_MULTIBLOCK_HANDLING */ + +#endif /* WRAPNV_USECASE_* */ +} + +/*********************************************************************************************************************** + * WrapNv_Deinit + **********************************************************************************************************************/ +/*! \brief De-initializes NV-Wrapper tasks from NVM + **********************************************************************************************************************/ +FUNC(void, WRAPNV_CODE) WrapNv_Deinit( void ) +{ +#if defined( WRAPNV_USECASE_NVM ) && defined( WRAPNV_ENABLE_NVM_MULTIBLOCK_HANDLING ) + (void)WrapNv_NvM_WriteAllSync(); +#endif /* WRAPNV_USECASE_NVM && WRAPNV_ENABLE_NVM_MULTIBLOCK_HANDLING */ +} + +#if defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) || \ + defined( WRAPNV_USECASE_NVM ) +/*********************************************************************************************************************** + * WrapNv_ReadSync + **********************************************************************************************************************/ +/*! \brief Reads specific data synchronously from a NV block + * \pre Function must only be called from where MainFunction polling is allowed. + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[in] buffer Pointer to data buffer + * \return kFblOk if succeeded, kFblFailed otherwise + **********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadSync( uint16 id, uint16 idx, tWrapNvRamData buffer ) +{ + WrapNv_ReturnType result; + + result = WrapNv_Read(id, idx, buffer, WRAPNV_ACCESS_DATAELEMENT); + + while (WRAPNV_E_PENDING == result) + { + result = WrapNv_PollMainFunctions(); + } + + return result; +} + +/*********************************************************************************************************************** +* WrapNv_ReadBlockSync +**********************************************************************************************************************/ +/*! \brief Reads an entire WrapNv block synchronously from a NV block +* \pre Function must only be called from where MainFunction polling is allowed. +* \param[in] id Id of record contained in the block +* \param[in] idx Dataset of block +* \param[in] buffer Pointer to data buffer +* \return kFblOk if succeeded, kFblFailed otherwise +**********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadBlockSync(uint16 id, uint16 idx, tWrapNvRamData buffer) +{ + WrapNv_ReturnType result; + + result = WrapNv_Read(id, idx, buffer, WRAPNV_ACCESS_BLOCKELEMENT); + + while (WRAPNV_E_PENDING == result) + { + result = WrapNv_PollMainFunctions(); + } + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_ReadPartialSync + **********************************************************************************************************************/ +/*! \brief Reads partial data synchronously from a NV block + * \pre Function must only be called from where MainFunction polling is allowed. + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[in] buffer Pointer to data buffer + * \param[in] offset Offset in the entry to read only partial + * \param[in] length Length of the partial read + * \return kFblOk if succeeded, kFblFailed otherwise + **********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartialSync( uint16 id, uint16 idx, tWrapNvRamData buffer, + uint16 offset, uint16 length ) +{ + WrapNv_ReturnType result; + + result = WrapNv_ReadPartial(id, idx, buffer, offset, length, WRAPNV_ACCESS_DATAELEMENT); + + while (WRAPNV_E_PENDING == result) + { + result = WrapNv_PollMainFunctions(); + } + + return result; +} + +/*********************************************************************************************************************** +* WrapNv_ReadPartialBlockSync +**********************************************************************************************************************/ +/*! \brief Reads partial block synchronously from a NV block +* \pre Function must only be called from where MainFunction polling is allowed. +* \param[in] id Id of record contained in the block +* \param[in] idx Dataset of block +* \param[in] buffer Pointer to data buffer +* \param[in] offset Offset in the entry to read only partial +* \param[in] length Length of the partial read +* \return kFblOk if succeeded, kFblFailed otherwise +**********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartialBlockSync(uint16 id, uint16 idx, tWrapNvRamData buffer, + uint16 offset, uint16 length) +{ + WrapNv_ReturnType result; + + result = WrapNv_ReadPartial(id, idx, buffer, offset, length, WRAPNV_ACCESS_BLOCKELEMENT); + + while (WRAPNV_E_PENDING == result) + { + result = WrapNv_PollMainFunctions(); + } + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_WriteSync + **********************************************************************************************************************/ +/*! \brief Writes specific data synchronously to a NV block + * \pre Function must only be called from where MainFunction polling is allowed. + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[in] buffer Pointer to data buffer + * \return kFblOk if succeeded, kFblFailed otherwise + **********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_WriteSync( uint16 id, uint16 idx, tWrapNvConstData buffer ) +{ + WrapNv_ReturnType result; + + result = WrapNv_Write(id, idx, buffer, WRAPNV_ACCESS_DATAELEMENT); + + while (WRAPNV_E_PENDING == result) + { + result = WrapNv_PollMainFunctions(); + } + + return result; +} + +/*********************************************************************************************************************** +* WrapNv_WriteBlockSync +**********************************************************************************************************************/ +/*! \brief Writes specific block synchronously to a NV block +* \pre Function must only be called from where MainFunction polling is allowed. +* \param[in] id Id of record contained in the block +* \param[in] idx Dataset of block +* \param[in] buffer Pointer to data buffer +* \return kFblOk if succeeded, kFblFailed otherwise +**********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_WriteBlockSync(uint16 id, uint16 idx, tWrapNvConstData buffer) +{ + WrapNv_ReturnType result; + + result = WrapNv_Write(id, idx, buffer, WRAPNV_ACCESS_BLOCKELEMENT); + + while (WRAPNV_E_PENDING == result) + { + result = WrapNv_PollMainFunctions(); + } + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_DeleteSync + **********************************************************************************************************************/ +/*! \brief Delete specific NV block synchronously + * \pre Function must only be called from where MainFunction polling is allowed. + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \return kFblOk if succeeded, kFblFailed otherwise + **********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_DeleteSync( uint16 id, uint16 idx ) +{ + WrapNv_ReturnType result; + + result = WrapNv_Delete(id, idx); + + while (WRAPNV_E_PENDING == result) + { + result = WrapNv_PollMainFunctions(); + } + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_ReadAsync + **********************************************************************************************************************/ +/*! \brief Reads specific data asynchronously from a NV block + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[out] buffer Pointer to data buffer + * \param[in] opStatus Operation status of calling instance + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadAsync( uint16 id, uint16 idx, tWrapNvRamData buffer, + tWrapNvOpStatus opStatus) +{ + WrapNv_ReturnType result; + result = WrapNv_ReadAsyncInternal(id, idx, buffer, opStatus, WRAPNV_ACCESS_DATAELEMENT); + + return result; +} + +/*********************************************************************************************************************** +* WrapNv_ReadBlockAsync +**********************************************************************************************************************/ +/*! \brief Reads specific block asynchronously from a NV block + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[in] buffer Pointer to data buffer + * \param[in] opStatus Operation status of calling instance + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadBlockAsync(uint16 id, uint16 idx, tWrapNvRamData buffer, + tWrapNvOpStatus opStatus) +{ + WrapNv_ReturnType result; + result = WrapNv_ReadAsyncInternal(id, idx, buffer, opStatus, WRAPNV_ACCESS_BLOCKELEMENT); + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_ReadPartialAsync + **********************************************************************************************************************/ +/*! \brief Reads specific data asynchronously from a NV block + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[in] buffer Pointer to data buffer + * \param[in] offset Offset in the entry to read only partial + * \param[in] length Length of the partial read + * \param[in] opStatus Operation status of calling instance + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +/* PRQA S 6060 1 */ /* MD_MSR_STPAR */ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartialAsync( uint16 id, uint16 idx, tWrapNvRamData buffer, + uint16 offset, uint16 length, tWrapNvOpStatus opStatus) +{ + WrapNv_ReturnType result; + result = WrapNv_ReadPartialAsyncInternal(id, idx, buffer, offset, length, opStatus, WRAPNV_ACCESS_DATAELEMENT); + + return result; +} + +/*********************************************************************************************************************** +* WrapNv_ReadPartialBlockAsync +**********************************************************************************************************************/ +/*! \brief Reads partial data in WrapNv block asynchronously from a NV block + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[in] buffer Pointer to data buffer + * \param[in] offset Offset in the entry to read only partial + * \param[in] length Length of the partial read + * \param[in] opStatus Operation status of calling instance + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +/* PRQA S 6060 1 */ /* MD_MSR_STPAR */ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartialBlockAsync(uint16 id, uint16 idx, tWrapNvRamData buffer, + uint16 offset, uint16 length, tWrapNvOpStatus opStatus) +{ + WrapNv_ReturnType result; + result = WrapNv_ReadPartialAsyncInternal(id, idx, buffer, offset, length, opStatus, WRAPNV_ACCESS_BLOCKELEMENT); + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_WriteAsync + **********************************************************************************************************************/ +/*! \brief Writes specific data asynchronously to a NV block + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[in] buffer Pointer to data buffer + * \param[in] opStatus Operation status of calling instance + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_WriteAsync( uint16 id, uint16 idx, tWrapNvConstData buffer, + tWrapNvOpStatus opStatus) +{ + WrapNv_ReturnType result; + result = WrapNv_WriteAsyncInternal(id, idx, buffer, opStatus, WRAPNV_ACCESS_DATAELEMENT); + + return result; +} + +/*********************************************************************************************************************** +* WrapNv_WriteBlockAsync +**********************************************************************************************************************/ +/*! \brief Writes specific block asynchronously to a NV block +* \param[in] id Id of record +* \param[in] idx Dataset of block +* \param[in] buffer Pointer to data buffer +* \param[in] opStatus Operation status of calling instance +* \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, +* WRAPNV_E_PENDING if job needs more time +**********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_WriteBlockAsync(uint16 id, uint16 idx, tWrapNvConstData buffer, + tWrapNvOpStatus opStatus) +{ + WrapNv_ReturnType result; + result = WrapNv_WriteAsyncInternal(id, idx, buffer, opStatus, WRAPNV_ACCESS_BLOCKELEMENT); + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_DeleteAsync + **********************************************************************************************************************/ +/*! \brief Delete specific NV block asynchronously + * \param[in] id Id of record + * \param[in] idx Dataset of block + * \param[in] opStatus Operation status of calling instance + * \return result WRAPNV_E_OK on job completion, WRAPNV_E_NOT_OK if job execution failed, + * WRAPNV_E_PENDING if job needs more time + **********************************************************************************************************************/ +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_DeleteAsync( uint16 id, uint16 idx, tWrapNvOpStatus opStatus) +{ + WrapNv_ReturnType result; + tWrapNvOpStatus currentOpStatus; + + WrapNv_EnterCritical(); + + /* Check if WrapNv is idle so it can accept a new request */ + if (WRAPNV_OPERATION_IDLE == gWrapNvCurrentOperation) + { + /* Check if new job is canceled */ + if (opStatus == WRAPNV_OPSTATUS_CANCEL) + { + currentOpStatus = WRAPNV_OPSTATUS_CANCEL; + } + else + { + /* Parameters will be stored in WrapNv_Delete() call */ + currentOpStatus = WRAPNV_OPSTATUS_INIT; + gWrapNvCurrentOperation = WRAPNV_OPERATION_DELETE; + } + } + else + { + /* Check if this is a different request to the current pending request */ + if ( (id == gWrapNvRecordNumber) + && (idx == gWrapNvBlockDataset) + && (WRAPNV_OPERATION_DELETE == gWrapNvCurrentOperation) + ) + { + /* Check if the current job should be canceled */ + if (opStatus == WRAPNV_OPSTATUS_CANCEL) + { + currentOpStatus = WRAPNV_OPSTATUS_CANCEL; + } + else + { + /* Process current request */ + currentOpStatus = WRAPNV_OPSTATUS_PENDING; + } + } + else + { + /* Wait until other request has been finished */ + currentOpStatus = WRAPNV_OPSTATUS_IDLE; + } + } + + WrapNv_LeaveCritical(); + + /* Only init and pending states are allowed at this point */ + switch (currentOpStatus) + { + case WRAPNV_OPSTATUS_INIT: + { + result = WrapNv_Delete(id, idx); + break; + } + case WRAPNV_OPSTATUS_PENDING: + { + result = WrapNv_MainFunction(); + break; + } + case WRAPNV_OPSTATUS_IDLE: /* Used when two instances access the WrapNv */ + { + result = WRAPNV_E_PENDING; + break; + } + case WRAPNV_OPSTATUS_CANCEL: + { + result = WrapNv_Cancel(); + break; + } + default: + { /* PRQA S 2880 1 */ /* MD_MSR_Unreachable */ + result = WRAPNV_E_NOT_OK; + break; + } + } + + /* Check if current operation has finished */ + if (WRAPNV_E_PENDING != result) + { + gWrapNvCurrentOperation = WRAPNV_OPERATION_IDLE; + } + + return result; +} + +# if defined( WRAPNV_USECASE_NVM ) +# if defined( WRAPNV_ENABLE_NVMAPIS_HANDLING ) +/*********************************************************************************************************************** + * WrapNv_NvM_WriteBlockSync + **********************************************************************************************************************/ +/*! \brief Synchronous wrapper to the NvM API NvM_WriteBlock + * \param[in] blockId NvM ID of NvM block + * \param[in] buffer Pointer to the RAM buffer NvM shall write + * \return result E_OK on successful operation, E_NOT_OK if operation failed + **********************************************************************************************************************/ +FUNC(Std_ReturnType, WRAPNV_CODE) WrapNv_NvM_WriteBlockSync( NvM_BlockIdType blockId, tWrapNvNvMConstData buffer ) +{ + Std_ReturnType result = E_NOT_OK; + NvM_RequestResultType operationStatus = NVM_REQ_PENDING; + + result = NvM_WriteBlock(blockId, buffer); + while ((result == E_OK) && (operationStatus == NVM_REQ_PENDING)) + { + WrapNv_PollMainFunctionsInternalIdle(); + if (WrapNv_TriggerFct_Callout() == WRAPNV_E_OK) + { + WrapNv_PollMainFunctionsInternalTimer(); + } + result = NvM_GetErrorStatus(blockId, &operationStatus); + } + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_NvM_ReadBlockSync + **********************************************************************************************************************/ +/*! \brief Synchronous wrapper to the NvM API NvM_ReadBlock + * \param[in] blockId NvM ID of NvM block + * \param[in] buffer Pointer to the RAM buffer NvM shall write + * \return result E_OK on successful operation, E_NOT_OK if operation failed + **********************************************************************************************************************/ +FUNC(Std_ReturnType, WRAPNV_CODE) WrapNv_NvM_ReadBlockSync( NvM_BlockIdType blockId, tWrapNvNvMRamData buffer ) +{ + Std_ReturnType result = E_NOT_OK; + NvM_RequestResultType operationStatus = NVM_REQ_PENDING; + + result = NvM_ReadBlock(blockId, buffer); + while ((result == E_OK) && (operationStatus == NVM_REQ_PENDING)) + { + WrapNv_PollMainFunctionsInternalIdle(); + if (WrapNv_TriggerFct_Callout() == WRAPNV_E_OK) + { + WrapNv_PollMainFunctionsInternalTimer(); + } + result = NvM_GetErrorStatus(blockId, &operationStatus); + } + + return result; +} +# endif /* WRAPNV_ENABLE_NVMAPIS_HANDLING */ + +# if defined( WRAPNV_ENABLE_NVM_MULTIBLOCK_HANDLING ) +/*********************************************************************************************************************** + * WrapNv_NvM_WriteAllSync + **********************************************************************************************************************/ +/*! \brief Executes the NvM API NvM_WriteAll synchronously + * \return result E_OK on successful operation, E_NOT_OK if operation failed + **********************************************************************************************************************/ +FUNC(Std_ReturnType, WRAPNV_CODE) WrapNv_NvM_WriteAllSync( void ) +{ + Std_ReturnType result = E_OK; + NvM_RequestResultType operationStatus = NVM_REQ_PENDING; + + NvM_WriteAll(); + while ((result == E_OK) && (operationStatus == NVM_REQ_PENDING)) + { + WrapNv_PollMainFunctionsInternalIdle(); + if (WrapNv_TriggerFct_Callout() == WRAPNV_E_OK) + { + WrapNv_PollMainFunctionsInternalTimer(); + } + result = NvM_GetErrorStatus(NvMConf___MultiBlockRequest, &operationStatus); + } + + return result; +} + +/*********************************************************************************************************************** + * WrapNv_NvM_ReadAllSync + **********************************************************************************************************************/ +/*! \brief Executes the NvM API NvM_ReadAll synchronously + * \return result E_OK on successful operation, E_NOT_OK if operation failed + **********************************************************************************************************************/ +FUNC(Std_ReturnType, WRAPNV_CODE) WrapNv_NvM_ReadAllSync( void ) +{ + Std_ReturnType result = E_OK; + NvM_RequestResultType operationStatus = NVM_REQ_PENDING; + + NvM_ReadAll(); + while ((result == E_OK) && (operationStatus == NVM_REQ_PENDING)) + { + WrapNv_PollMainFunctionsInternalIdle(); + if (WrapNv_TriggerFct_Callout() == WRAPNV_E_OK) + { + WrapNv_PollMainFunctionsInternalTimer(); + } + result = NvM_GetErrorStatus(NvMConf___MultiBlockRequest, &operationStatus); + } + + return result; +} +# endif /* WRAPNV_ENABLE_NVM_MULTIBLOCK_HANDLING */ +# endif /* WRAPNV_USECASE_NVM */ +#endif /* WRAPNV_USECASE_* */ + +#define WRAPNV_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +/*********************************************************************************************************************** + * MISRA DEVIATIONS + **********************************************************************************************************************/ + +/* Justification for module-specific MISRA deviations: + + MD_WrapNv_0311: + Reason: Provide simplified function interface and reduce stack consumption by avoiding separate pointers for + read and write buffer. + Risk: The content of the write buffer might be accidentally overwritten. + Prevention: Covered by code review. + + MD_WrapNv_0314: + Reason: API is defined with pointer to void parameter, so pointer has to be casted to or from void. + Risk: Wrong data access or undefined behavior for platforms where the byte alignment is not arbitrary. + Prevention: Code inspection and test with the target compiler/platform in the component test. + + MD_WrapNv_2003: + Reason: Intentionally switch case with out break statement to proceed the next step immediately + Risk: No identifiable risk. + Prevention: Covered by code review. + + MD_WrapNv_3218: + Reason: The usage of variables depend on configuration aspects and may be used only once. + Risk: No identifiable risk. + Prevention: No prevention required. + +*/ + +/*********************************************************************************************************************** + * END OF FILE: WRAPNV.C + **********************************************************************************************************************/ diff --git a/Source/bsw/WrapNv/WrapNv.h b/Source/bsw/WrapNv/WrapNv.h new file mode 100644 index 0000000..0b81d2c --- /dev/null +++ b/Source/bsw/WrapNv/WrapNv.h @@ -0,0 +1,241 @@ +/********************************************************************************************************************** + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file WrapNv.h + * \brief Wrapper for NV-memory access + * ------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/*********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 02.00.00 2016-02-22 visrie ESCAN00088726 Added support for Fee/NvM + * Removed unused code + * 02.01.00 2016-03-09 visrie ESCAN00088817 Removed function call NvM_Errorhook + * ESCAN00088819 Abstraction of Fls interface + * 02.02.00 2016-07-05 visrie ESCAN00090830 Added support for no NV driver use-case + * 02.02.01 2016-09-06 visrie ESCAN00091757 Fixed MISRA findings + * 02.02.02 2016-10-17 visrie ESCAN00092351 Configure used FEE functions + * 02.03.00 2017-09-19 visrie ESCAN00094172 Fixed compiler warning undefined preprocessor define + * ESCAN00095574 Added support for EA + * 02.04.00 2017-11-29 visrie ESCAN00096851 Updated APIs for MSR-Release 18 + * ESCAN00097590 Added error code for Record ID check + * ESCAN00097591 Added support for sequential queue handling of asynchronous access + * 02.04.01 2018-01-11 visrie ESCAN00097944 Fixed state handling + * ESCAN00097953 Fixed endless loop + * 02.05.00 2018-02-08 visrie ESCAN00097770 Consider main function call cycle + * 02.06.00 2018-03-21 visrie ESCAN00098860 Added support for EEL + * 02.06.01 2018-04-06 visrie ESCAN00099015 No changes + * 02.06.02 2018-12-07 visrie ESCAN00099155 No changes + * ESCAN00101194 Reworked include structure + * 03.00.00 2020-04-02 visrie FBL-1331 Support of new generator + * 04.00.00 2020-05-26 visrie FBL-1016 Support EcuM_Init() mechanism + * 04.00.01 2020-07-16 visrie FBL-2160 Removed use case filtering + * 04.00.02 2021-04-01 visrcn FBL-3009 Make polling function configurable + * FBL-3095 Add support for DET usage + * 04.01.00 2022-07-11 vistmo FBL-5336 Adding support for block access + * 04.01.01 2024-07-08 visrie ESCAN00117458 WrapNv doesn't accept further requests + * ESCAN00115730 Compiler warning: no 'break' or comment before case label + * 04.02.00 2024-10-23 visjns FBL-9560 Introduce handling of NvM access by MSR modules + * ESCAN00114856 Compiler warning: zero used for undefined preprocessing identifier + *********************************************************************************************************************/ + +#ifndef WRAPNV_H +#define WRAPNV_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : SysService_WrapperNv CQComponent : Implementation */ +# define SYSSERVICE_WRAPPERNV_VERSION 0x0402u +# define SYSSERVICE_WRAPPERNV_RELEASE_VERSION 0x00u + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +# include "WrapNv_Cfg.h" +# if defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) || \ + defined( WRAPNV_USECASE_NVM ) +# include "Std_Types.h" +# if defined( WRAPNV_USECASE_NVM ) +# include "NvM.h" +# endif /* WRAPNV_USECASE_NVM */ +# endif /* WRAPNV_USECASE_* */ + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ +# if defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) || \ + defined( WRAPNV_USECASE_NVM ) +/* Vendor and module identification */ +# define WRAPNV_VENDOR_ID 30u +# define WRAPNV_MODULE_ID 255u +# define WRAPNV_INSTANCE_ID 0u + +/* Service IDs */ +# define WRAPNV_APIID_INIT 0x00u +# define WRAPNV_APIID_READ 0x01u +# define WRAPNV_APIID_READPARTIAL 0x02u +# define WRAPNV_APIID_WRITE 0x03u +# define WRAPNV_APIID_DELETE 0x04u + +/* Development errors */ +# define WRAPNV_E_NO_ERROR 0x10u +# define WRAPNV_E_NOT_IDLE 0x11u +# define WRAPNV_E_PARAM_DATASET 0x12u +# define WRAPNV_E_PARAM_READ 0x13u +# define WRAPNV_E_PARAM_ID 0x14u +# elif defined( WRAPNV_USECASE_EEPM ) +/* PRQA S 3453 3 */ /* MD_MSR_FctLikeMacro */ +# define NV_MK_STRUCT_ID(structure, id) ((((vuint32)(structure)) << 24uL) | (id)) +# define NV_GET_STRUCT_ID(id) ((id) & 0x00FFFFFFuL) +# define NV_GET_STRUCT_HANDLE(id) (((id) & 0xFF000000uL) >> 24uL) +# endif /* WRAPNV_USECASE_* */ + +/** Positive return value of NV-Wrapper */ +# if defined( kFblOk ) +# define WRAPNV_E_OK kFblOk +# elif defined( kEepMgrOk ) +# define WRAPNV_E_OK kEepMgrOk +# elif defined( E_OK ) +# define WRAPNV_E_OK E_OK +# else +# define WRAPNV_E_OK 0u +# endif + +/** Negative return value of NV-Wrapper */ +# if defined( kFblFailed ) +# define WRAPNV_E_NOT_OK kFblFailed +# elif defined( kEepMgrFailed ) +# define WRAPNV_E_NOT_OK kEepMgrFailed +# elif defined( E_NOT_OK ) +# define WRAPNV_E_NOT_OK E_NOT_OK +# else +# define WRAPNV_E_NOT_OK 1u +# endif + +/** Pending return value of NV-Wrapper */ +# if defined( kEepMgrBusy ) +# define WRAPNV_E_PENDING kEepMgrBusy +# elif defined( E_PENDING ) +# define WRAPNV_E_PENDING E_PENDING +# else +# define WRAPNV_E_PENDING 2u +# endif + +/** Return type of NV-Wrapper */ +# if defined( kFblOk ) +# define WrapNv_ReturnType tFblResult +# elif defined( kEepMgrOk ) +# define WrapNv_ReturnType vuint8 +# elif defined( E_OK ) +# define WrapNv_ReturnType Std_ReturnType +# else +# define WrapNv_ReturnType WrapNv_DefaultReturntype +# endif + +/* Compatibility define for non MSR projects */ +# if !defined( FUNC ) +# define FUNC(rettype, memclass) rettype +# endif + +/********************************************************************************************************************** + * TYPEDEFS + *********************************************************************************************************************/ + +/** Operation status for asynchronous access */ +typedef enum +{ + WRAPNV_OPSTATUS_INIT = 0u, /**< Operation has been initialized */ + WRAPNV_OPSTATUS_PENDING, /**< Operation is currently pending */ + WRAPNV_OPSTATUS_CANCEL, /**< Operation has been canceled */ + WRAPNV_OPSTATUS_IDLE /**< Internal: Currently no operation is active */ +} tWrapNvOpStatus; + +/** Type of data access */ +typedef enum +{ + WRAPNV_ACCESS_DATAELEMENT = 0u, /**< Access is performed at element level */ + WRAPNV_ACCESS_BLOCKELEMENT /**< Access is performed at block level */ +} tWrapNvAccessType; + +# if defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) || \ + defined( WRAPNV_USECASE_NVM ) +typedef P2VAR(uint8, AUTOMATIC, WRAPNV_DATA) tWrapNvRamData; +typedef P2CONST(uint8, AUTOMATIC, WRAPNV_DATA) tWrapNvConstData; +typedef P2VAR(void, AUTOMATIC, WRAPNV_NVM_APPL_DATA) tWrapNvNvMRamData; +typedef P2CONST(void, AUTOMATIC, WRAPNV_NVM_APPL_DATA) tWrapNvNvMConstData; +# endif /* WRAPNV_USECASE_* */ + +typedef unsigned char WrapNv_DefaultReturntype; + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +# define WRAPNV_START_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +FUNC(void, WRAPNV_CODE) WrapNv_Init( void ); +FUNC(void, WRAPNV_CODE) WrapNv_Deinit( void ); + +# if defined( WRAPNV_USECASE_FEE ) || \ + defined( WRAPNV_USECASE_EA ) || \ + defined( WRAPNV_USECASE_NVM ) +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadSync( uint16 id, uint16 idx, tWrapNvRamData buffer ); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadBlockSync(uint16 id, uint16 idx, tWrapNvRamData buffer); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartialSync( uint16 id, uint16 idx, tWrapNvRamData buffer, uint16 offset, uint16 length ); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartialBlockSync(uint16 id, uint16 idx, tWrapNvRamData buffer, uint16 offset, uint16 length); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_DeleteSync( uint16 id, uint16 idx ); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_WriteSync( uint16 id, uint16 idx, tWrapNvConstData buffer ); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_WriteBlockSync( uint16 id, uint16 idx, tWrapNvConstData buffer ); + +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadAsync( uint16 id, uint16 idx, tWrapNvRamData buffer, tWrapNvOpStatus opStatus ); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadBlockAsync(uint16 id, uint16 idx, tWrapNvRamData buffer, tWrapNvOpStatus opStatus); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartialAsync( uint16 id, uint16 idx, tWrapNvRamData buffer, uint16 offset, uint16 length, tWrapNvOpStatus opStatus ); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_ReadPartialBlockAsync( uint16 id, uint16 idx, tWrapNvRamData buffer, uint16 offset, uint16 length, tWrapNvOpStatus opStatus ); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_DeleteAsync( uint16 id, uint16 idx, tWrapNvOpStatus opStatus ); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_WriteAsync( uint16 id, uint16 idx, tWrapNvConstData buffer, tWrapNvOpStatus opStatus ); +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_WriteBlockAsync(uint16 id, uint16 idx, tWrapNvConstData buffer, tWrapNvOpStatus opStatus); +# if defined( WRAPNV_USECASE_NVM ) +# if defined( WRAPNV_ENABLE_NVMAPIS_HANDLING ) +FUNC(Std_ReturnType, WRAPNV_CODE) WrapNv_NvM_WriteBlockSync( NvM_BlockIdType blockId, tWrapNvNvMConstData buffer ); +FUNC(Std_ReturnType, WRAPNV_CODE) WrapNv_NvM_ReadBlockSync( NvM_BlockIdType blockId, tWrapNvNvMRamData buffer ); +# endif /* WRAPNV_ENABLE_NVMAPIS_HANDLING */ +# if defined( WRAPNV_ENABLE_NVM_MULTIBLOCK_HANDLING ) +FUNC(Std_ReturnType, WRAPNV_CODE) WrapNv_NvM_WriteAllSync( void ); +FUNC(Std_ReturnType, WRAPNV_CODE) WrapNv_NvM_ReadAllSync( void ); +# endif /* WRAPNV_ENABLE_NVM_MULTIBLOCK_HANDLING */ +# endif /* WRAPNV_USECASE_NVM */ +# endif /* WRAPNV_USECASE_* */ + +# if (WRAPNV_MAINFUNCTION_POLLING == STD_ON) +FUNC(WrapNv_ReturnType, WRAPNV_CODE) WrapNv_TriggerFct_Callout( void ); +# endif + +# define WRAPNV_STOP_SEC_CODE +# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* WRAPNV_H */ + +/*********************************************************************************************************************** + * END OF FILE: WRAPNV.H + **********************************************************************************************************************/ diff --git a/Source/bsw/WrapNv/_WrapNv_inc.h b/Source/bsw/WrapNv/_WrapNv_inc.h new file mode 100644 index 0000000..500969d --- /dev/null +++ b/Source/bsw/WrapNv/_WrapNv_inc.h @@ -0,0 +1,56 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file WrapNv_inc.h + * \brief Compacts the include files for the NV-Wrapper + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to the module's header file. + *********************************************************************************************************************/ + +#ifndef WRAPNV_INC_H +#define WRAPNV_INC_H + +/*********************************************************************************************************************** + * INCLUDES + **********************************************************************************************************************/ + +#include "WrapNv.h" +#if defined( WRAPNV_USECASE_EEPM ) || \ + defined( WRAPNV_USECASE_DRVEEP ) +/* Include Vector standard includes first */ +# include "fbl_def.h" + +# include "fbl_inc.h" + +# include "iotypes.h" +# if defined( WRAPNV_USECASE_EEPM ) +# include "fbl_flio_xd1.h" +# include "EepMgr_Inc.h" +# else +# include "EepInc.h" +# include "EepIO.h" +# endif +#endif /* WRAPNV_USECASE_EEPM || WRAPNV_USECASE_DRVEEP */ + +#endif /* WRAPNV_INC_H */ + +/*********************************************************************************************************************** + * END OF FILE: WRAPNV_INC.H + **********************************************************************************************************************/ diff --git a/Source/include/ARMBrsHw_CortexR.h b/Source/include/ARMBrsHw_CortexR.h new file mode 100644 index 0000000..53740d9 --- /dev/null +++ b/Source/include/ARMBrsHw_CortexR.h @@ -0,0 +1,327 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: ARMBrsHw_CortexR.h + * Project: Vector Basic Runtime System + * Module: BrsHw for all platforms with ARM core Cortex-R + * + * \brief Description: This is a global, platform-independent header file for the ARM-BRS. + * This file includes all non-platform dependent functions. + * All the (platform depending) rest needs to be defined in BrsHw.c + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2020-15-19 visbwa New branch for vBaseEnv 2.0, based on zBrs_ArmCommon ARMBrsHw_CortexA.c 4.07.01 and ARMStartup_CortexA.c 1.11.01; + * updated vLinkGen define and struct names to new vLinkGen 2.0 naming schema in ARMStartup_CortexA.c + * 01.00.01 2020-06-08 visbwa Fixed support for Tasking compiler and usage of struct vLinkGen_MemArea (vLinkGen_ZeroInit_Early_Blocks, + * vLinkGen_ZeroInit_Early_Groups) -> size is 16Byte per entry in ARMStartup_CortexA.c + * 01.00.02 2020-06-09 visbwa Fixed IAR code to load stack symbols in ARMStartup_CortexA.c + * 01.00.03 2020-07-03 visbwa Added disabling of abort handler and VIC for TDA4VM88@TI; added support for up to 6 cores in ARMStartup_CortexA.c + * 01.01.00 2020-09-18 visbwa Review according to Brs_Template 1.01.00 + * 01.01.01 2020-10-21 vishci Fixed BRS_ISR_KEYWORD of Arm5, Gnu and Iar compiler abstraction in ARMBrsHw_CortexA.h; update to + * Brs_Template 1.01.01; removed AUTHOR IDENTITY; added new file ARMBrsHwIntTb_CortexR.c for FBL projects w/o OS + * 01.01.02 2020-10-23 visbwa Renamed exception vector table according to Brs_Template in ARMBrsHwIntTb_CortexR.c + * 01.01.03 2020-10-28 visbwa No changes in sourcecode, only within ALM package + * 01.01.04 2020-11-09 visbwa No changes in sourcecode, only within ALM package + * 01.01.05 2020-11-12 visdri Support Jacinto7 Cortex-R cores by merging the Jacinto7 startup code provided by TI (disable TCM and call mpu_init + * for Jacinto7 derivative) and fixed activation of FPU + initialization order (switch to system mode after FPU init) + * in ARMStartup_CortexA.c + * 01.01.06 2020-12-07 visjhr Added support for TPR12 derivative and disabling of abort handler and VIC for it + * 01.01.07 2021-01-14 visbwa Fixed BRANCH to startup_block_zero_init_loop_start for ARM compilers in ARMStartup_CortexA.c + * 01.01.08 2021-03-05 visdri Removed Tasking and HighTec from list of supported compilers, + * removed BRS_EXTERN_BRANCH (separation to BRS_BRANCH not needed on Cortex-A/R) and + * fixed branches to stack pointer init routines for MultiCore in ARMStartup_CortexA.c + * 01.01.09 2021-03-08 visbwa Fixed IAR encapsulation of Brs_IarLoadCore0Id (only for MultiCore) and branch extern in ARMStartup_CortexA.c + * 01.02.00 2021-02-02 vismaa Added BrsHw_GetCore() and macros BRS_READ_COREID + brsHwGetMpidr + * 2021-03-09 visbwa Renamed all files from ARMBrsHw_CortexA into ARMBrsHw_CortexR; update to Brs_Template 1.02.00; moved revision + * history of all .c and .h files into ARMBrsHw_CortexR.h; added SingleCore stubs for Read_COREID (always return 0) + * 01.02.01 2021-03-18 vismaa Fixed memory initialization process in ARMStartup_CortexR.c to work properly in MultiCore environments + * 01.03.00 2021-04-20 vishci Added LlvmDiab compiler support, fixed IAR compiler support in FBL CoreExceptionTable + * 2021-05-04 visbwa Review, generalized BrsHwDisableInterruptAtPowerOn(), removed duplicates in TI compiler abstraction + * 01.03.01 2021-05-11 visbwa Fixed brsExcVect section for Arm6 and LlvmDiab in ARMBrsHwIntTb_CortexR.c + * 01.03.02 2021-07-28 visjhr Fixed bug in brsHwGetMpidr(c) for GCC compilers + * 01.03.03 2021-08-03 visjhr Adapted bugfix of brsHwGetMpidr(c) for LLVMDIAB compiler + * 01.03.04 2021-09-21 visbpz Adaptation for IAR + * 01.04.00 2021-10-18 vishci added LLVMTEXASINSTRUMENTS compiler support + * 01.04.01 2021-10-20 visbpz Fix for 8 byte aligned ECC initialization + * 2021-10-25 visbwa Added usage of alignment parameter to distinguish between 4-Byte and 8-Byte init + * 01.04.02 2022-03-01 visbwa ESCAN00111389 Fixed zero_init loops in ARMStartup_CortexR.c, renamed area_zero_init to group_zero_init, + * ESCAN00111390 introduced BRS_BRANCH_GREATER_THAN_OR_EQUAL + * 01.04.03 2022-03-14 visbwa ESCAN00111478 StartupCode is not mapped into specific section "brsStartup" for Arm6 compiler (ARMStartup_CortexR.c), + * ESCAN00111480 StartupCode is using ARM_LIB_STACK instead of STACK_C0 to initialize stackpointer during startup + * (ARMStartup_CortexR.c); removed useless abstraction for asm in ARMBrsHw_CortexR.c; removed unused + * BRS_SECTION_DATA fragments from some compiler abstractions; replaced BRS_DUMMY_FUNC by Startup_Handler_ASM() + * (adjustment with Cortex-M code) + * 01.04.04 2022-04-06 virmid Support for TDA4VE derivative + * 02.00.00 2022-03-17 visjhr Update to Brs_Template 1.03.04 + * 2022-05-23 visbwa Review, harmonized with Implementation_CortexR52; call of __mpu_init moved to BrsHwEarlyInitPowerOn() of + * platform-specific BrsHw packages; fixed encapsulation of _start (alternative start symbol for OS) + * 2022-07-22 visjhr Updated ARM5 implementation of BRS_READ_COREID; BRS_READ_COREID and BrsHw_GetCore() overloadable in platform + * specific BrsHw; changed implementation of BRS_READ_COREID that only AFF0 will be used for core id + * 2022-07-25 visbwa Review; Removed platform specific code from BrsHwDisableInterruptAtPowerOn() and StartupCode; + * Introduced BrsHwDisableInterruptAtPowerOn_Hook() + * 02.00.01 2022-07-26 visbwa Fixed Arm5 assembly abstraction, introduced usage of BRS_ENABLE_OS_STUB for Arm5/Arm6 + * 02.00.02 2022-07-26 visjhr Fixed exception tables for LLVM DIAB and LLVM TI compiler + * 02.00.03 2022-08-04 visrgm Added BRSHW_PRE_ASM_STARTUP_HOOK_AVAILABLE define to ARMStartup_CortexR.c + * 02.00.04 2022-08-11 mhu Fixed Brs_IarLoadCoreConfigSizeSymbol implementation + * 2022-08-12 visqli Introduced BrsHw_ExceptionTable_Init_PostHook in BrsHw_ExceptionTable_Init + * 02.00.05 2022-09-07 visjhr Added code for restoring default Exception Table code on startup (identical for all exceptions) + * 02.01.00 2022-09-21 visjhr Added exception tables for max 8 cores in multicore setups, updated calculation of active exception table address + * during startup, special implementation if core exception table is located at address 0x0 + * 02.01.01 2022-10-10 mhu Fixed multicore implementation of BRS_READ_COREID and BrsHw_GetCore(); updated declartions and definitions of + * intvect_CoreXExceptions for IAR; adapted the position of BRS_READ_COREID to avoid overwrite of R0 in + * ARMStartup_CortexR.c + * visbwa Review, introduced BRS_LOCAL_FUNCTION_PROTOTYPE + * 02.01.02 2023-02-01 mhu Fixed brsHwGetMpidr() definition with IAR compiler for multicore usecase + * 02.02.00 2023-03-02 virjas Changed syntax of brsHwGetMpidr asm macro fro Llvm and IAR compiler to be c99 (__asm) + * 2023-05-23 visbwa Update to Brs_Template 1.03.09: mapping of BrsHw_CoreExceptionHandler() into startup code section in + * ARMBrsHwIntTb_CortexR.c + * 02.02.01 2023-05-25 visdri Fix multicore exception tables in ARMBrsHwIntTb_CortexR.c for TI compiler. + * 02.02.02 2023-06-05 visbwa Introduction of BrsHw_MultiCoreExceptionHandler() as single and independent handler for all additional cores; + * mapped into startup code section in ARMBrsHwIntTb_CortexR.c + * 02.03.00 2023-06-28 visdri Set SCTLR.TE bit in startup code to enter exceptions in ARM state + * 02.04.00 2024-08-01 vishci BASEENV-12178 Unify naming of coreexception table in RAM for FBL usecase + * 02.04.01 2024-09-05 vishci Fixed core exception intvect_CoreExceptions_Ram_Vectortable bug + * 02.05.00 2024-09-16 kal BASEENV-12584 Implemented cache invalidation for all ARMv7-R cores; bugfix for ARM5 compiler + * 02.05.01 2024-11-22 kal BASEENV-12761 Fixed bad instruction in Arm6 Exception table + * 02.05.02 2024-12-11 mhu Fixed #pragma grammar for Arm6 compiler + * 02.05.03 2025-01-15 mhu Fixed BRSHW_DEFINE_STARTUP_STACK define for Arm6 compiler + * 02.05.04 2025-01-31 vismaa BASEENV-13175 Clearing SCTLR V-Bit, assures base location of exception registers is 0x0000_0000 + * 02.05.05 2025-03-28 visbwa BASEENV-13195 Added compiler error for non-first execution instance and exception table in RAM combination + *********************************************************************************************************************/ + +#ifndef _ARMBRSHW_CORTEXR_H_ +#define _ARMBRSHW_CORTEXR_H_ + +/********************************************************************************************************************** + * MODULE VERSION + *********************************************************************************************************************/ +/* + * Description: This is the BrsHw main and bug fix version. The version numbers are BCD coded. + * E.g. a main version of 1.23 is coded with 0x0123, a bug fix version of 9 is coded 0x09. + */ +#define ARMBRSHW_CORTEXR_VERSION 0x0205u +#define ARMBRSHW_CORTEXR_BUGFIX_VERSION 0x05u + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +/* + * Description: The BrsCfg header is used to configure different types of + * tests and system setups. Therefore it must be included first + * in each BRS and test module. + * This file is part of the BRS. + */ +#include "vBrsCfg.h" + +#include "BrsMain.h" + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ +/* Configuration checks performed within platform specific code (BrsHw) */ + +/********************************************************************************************************************** + * GLOBAL TYPE DEFINITIONS + *********************************************************************************************************************/ +#if defined (BRS_ENABLE_OS_MULTICORESUPPORT) +typedef struct +{ + uint32 PhysicalCoreId; + void (*CoreExceptions)(); +}ARMBrsHw_PhysicalCoreId_CoreExceptions_MappingType; +#endif /*BRS_ENABLE_OS_MULTICORESUPPORT*/ + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ +/* + * Description: Macro for access to IO addresses + */ +#define BRSHW_IOS(type, address) (*((volatile type *)(address))) + +#define BRSHWNOP10() do { \ + __asm(" NOP"); \ + __asm(" NOP"); \ + __asm(" NOP"); \ + __asm(" NOP"); \ + __asm(" NOP"); \ + __asm(" NOP"); \ + __asm(" NOP"); \ + __asm(" NOP"); \ + __asm(" NOP"); \ + __asm(" NOP"); \ + } while(0) + +/* + * Description: Macros used in vBRS generated vBrs_Lcfg.c. + */ + #define BRSHW_DEFINE_STARTUP_STACK(x) _STACK_C##x##_LIMIT + + /* No separate ExcVec table on cortexR! OS is defining one interrupt table for exceptions + interrupts */ + #define BRSHW_DEFINE_EXCVEC(x) _OS_EXCVEC_CORE##x##_CODE_START + #define BRSHW_DEFINE_INTVEC(x) _OS_EXCVEC_CORE##x##_CODE_START /* just as dummy to compile vBrs_Lcfg.c, not used in BrsHw_ExceptionTable_Init() */ + +/* Special value, needed for SingleCore UseCase w/o OS (e.g. FBL). vBRS will generate "BRSHW_DEFINE_STARTUP_STACK(BRSHW_INIT_CORE_ID)" + for this. Configure here the valid value for the StartupStack pointer label of the boot core */ +#define _STACK_CBRSHW_INIT_CORE_ID_LIMIT _STACK_C0_LIMIT /* this macro is not used with Arm5/Arm6 compilers */ + +/********************************************************************************************************************** + * Compiler abstraction + *********************************************************************************************************************/ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #define ___asm(c) __asm_(c) + #define __asm_(c) __asm(#c); + #define __as1(c, d) __as1_(c, d) + #define __as1_(c, d) __asm( #c " , " #d); + #define __as2(c, d, e) __as2_(c, d, e) + #define __as2_(c, d, e) __asm( #c " , " #d " , " #e); + #define __as3(c, d, e, f) __as3_(c, d, e, f) + #define __as3_(c, d, e, f) __asm( #c " , " #d " , " #e " , " #f); + #define __as4(c, d, e, f, g) __as4_(c, d, e, f, g) + #define __as4_(c, d, e, f, g) __asm( #c " , " #d " , " #e " , " #f " , " #g); + #define __as5(c, d, e, f, g, h) __as5_(c, d, e, f, g, h) + #define __as5_(c, d, e, f, g, h) __asm( #c " , " #d " , " #e " , " #f " , " #g " , " #h); + + #define BRS_MULTILINE_ASM_BEGIN() + #define BRS_MULTILINE_ASM_END() + + #define BRS_ASM_EQU(Label, Value) __as1(.equ Label, Value) + + #define BRS_ISR_KEYWORD __attribute__ ((interrupt("IRQ"))) + + #define BRS_SECTION_CODE(c) __as1(.section .c , "ax" ) + + #define BRS_GLOBAL(c) ___asm(.globl c) + #define BRS_LOCAL_PROTOTYPE(c) void c (void); + #define BRS_LOCAL_FUNCTION_PROTOTYPE(c) void c (void); + #define BRS_LABEL(c) ___asm(c:) + #define BRS_GLOBAL_END() + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +# define BRS_EXPORT(Label) ___asm(.global Label) /* Causes the identifier Label to be visible externally */ +# endif + + /* Unconditional branch to c */ + #define BRS_BRANCH(c) ___asm(B c) + #define BRS_EXTERN_BRANCH(c) ___asm(B c) + + /* Branch to e if c and d are equal */ + #define BRS_BRANCH_EQUAL(c,d,e) __as1(CMP c, d) \ + ___asm(BEQ e) + + /* Branch to e if c and d are NOT equal */ + #define BRS_BRANCH_NOT_EQUAL(c,d,e) __as1(CMP c, d) \ + ___asm(BNE e) + + /* Branch to e if c is greater than d*/ + #define BRS_BRANCH_GREATER_THAN(c,d,e) __as1(CMP c, d) \ + ___asm(BGT e) + + /* Branch to e if c is greater or equal than d */ + #define BRS_BRANCH_GREATER_THAN_OR_EQUAL(c,d,e) __as1(CMP c, d) \ + ___asm(BGE e) + +# if (BRS_CPU_CORE_AMOUNT>1) +# if !defined (BRSHW_PLATFORM_SPECIFIC_GETCORE_AVAILABLE) + #define BRS_READ_COREID(c) __asm( "mrc p15" "," "#0" "," #c "," "c0" "," "c0" "," "#5" ); \ + __asm( "and r9 " "," #c "," "#255" ); \ + __asm( "and " #c "," #c "," "#0xFF00" ); \ + __asm( "orr " #c "," "r9" "," #c "," "lsr #7" ); + + /* Multiprocessor affinity (MPIDR) */ + #define brsHwGetMpidr(c) __asm("MRC p15, 0, %0, c0, c0, 5" : "=r" (c) :) +# endif /*!BRSHW_PLATFORM_SPECIFIC_GETCORE_AVAILABLE*/ + +# else + /* Stub for SingleCore environments, always returns 0 */ + #define BRS_READ_COREID(c) __as1(MOV c, 0) +# endif /*BRS_CPU_CORE_AMOUNT*/ + +#else + #error "Compiler not yet supported" +#endif /*BRS_COMP_x*/ + +/********************************************************************************************************************** + * BrsHW configuration + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +/*****************************************************************************/ +/* @brief Disable the global system interrupt. + * @pre Must be the first function call in main@BrsMain + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from main@BrsMain at power on initialization + *****************************************************************************/ +void BrsHwDisableInterruptAtPowerOn(void); + +/*****************************************************************************/ +/* @brief Copy exception vectors to active exception table + * @pre - + * @param[in] ExcVecLabel - address of the core exception table + * IntVecLabel - address of the interrupt vector table + * Use BRS_DEFINE_ADDRESS_UNUSED for unused values + * @param[out] - + * @return - + * @context Function is called from main@BrsMain at power on initialization + *****************************************************************************/ +void BrsHw_ExceptionTable_Init(Brs_AddressOfConstType, Brs_AddressOfConstType); + +/*****************************************************************************/ +/* @brief This API is used for the BRS time measurement support to get a + * default time value for all measurements with this platform to + * be able to compare time measurements on different dates based + * on this time result. + * @pre Should be called with interrupts global disabled + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from e.g. component testsuits for calibration + *****************************************************************************/ +void BrsHwTime100NOP(void); + +#if !defined (BRSHW_PLATFORM_SPECIFIC_GETCORE_AVAILABLE) +/*****************************************************************************/ +/* @brief This API is used to read the core ID of the actual running core + * @pre - + * @param[in] - + * @param[out] - + * @return Core ID of the actual running core + * @context Function is e.g. called from main@BrsMain, to only call HW-init + * code once, on the boot core. + * In MultiCore setups, additional BRSHW_INIT_CORE_ID must be + * declared inside BrsHw.h, to configure the proper core ID value + * of that boot core. + *****************************************************************************/ +uint32 BrsHw_GetCore(void); +#endif /*!BRSHW_PLATFORM_SPECIFIC_GETCORE_AVAILABLE*/ + +#endif /*_ARMBRSHW_CORTEXR_H_*/ diff --git a/Source/include/BrsHw.h b/Source/include/BrsHw.h new file mode 100644 index 0000000..5820368 --- /dev/null +++ b/Source/include/BrsHw.h @@ -0,0 +1,392 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsHw.h + * Project: Vector Basic Runtime System + * Module: BrsHw for platform TexasInstruments Sitara AM263x + * + * \brief Description: This is the hardware specific header file for Vector Basic Runtime System (BRS). + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Description + * -------- ---------- ------ ------------------------------------------------------------------------------------- + * 00.01.00 2022-08-01 visjhr Initial creation, based on Brs_AWRgen2 + * Removed all non supported compilers and eval boards from BrsHw_Ports.h + * 2022-08-11 visbwa Update to Brs_Template 1.03.05; UsageType=external in ALM (DemoComponents concept) + * 00.01.01 2022-08-25 visjhr Added iSystems debugger config + * 00.01.02 2022-09-09 visjhr Added _FirstTimeUseEvalBoardPreparation in svn content and a Brs_Readme.txt in + * content referencing it + * 00.01.03 2022-09-21 visjhr Added #define BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0 + * 00.01.04 2022-09-27 visjhr Added Lauterbach debugger config + * 00.01.05 2022-10-11 visjhr Updated implementation of BrsHwSoftwareResetECU and BrsHwGetResetReasonStartup + * according to initialDE_TPR12_LlvmTI_AM263x_V3 + * 00.01.06 2022-12-22 visjhr Integrated libs and sbl from 20221129_AM263x_V4_VectorDE + * 01.00.00 2023-01-13 visjhr Finalized testing on hardware, updated ReadMe.docx, added V3 Drop SBL for HS-FS + * (general purpose) devices and V4 Drop SBL for HS-SE (Security Enforced) device on + * HSR-9782, added vBaseEnv_SitaraAM263x_handout.docx, removed Brs_Readme.txt + * 01.00.01 2023-03-01 visjhr Updated _FirstTimeUseEvalBoardPreparation\Readme.pdf, added folder + * debug_certificate_creation_HSM_core_on_HS_SE_device to + * _FirstTimeUseEvalBoardPreparation - only in SVN, not in ALM content + * 01.00.02 2025-04-22 kal Removed Ethernet support from package (3rd party MCAL), added missing core IDs + * 01.00.03 2025-10-30 vismaa Updated with Brs_Template@Implementation[1.03.14] + *********************************************************************************************************************/ + +#ifndef _BRSHW_H_ +#define _BRSHW_H_ + +/********************************************************************************************************************** + * MODULE VERSION + *********************************************************************************************************************/ +/* +* Description: This is the BrsHw major, minor and patch version. The version numbers are decimally encoded. +* E.g. a version of 01.03.12 is encoded with major 1u, minor 3u and patch version 12u. +* No leading zeroes shall be used, as they would be treated as octal numbers. +*/ + +/* This is the BrsHw template major, minor and patch version, the platform BrsHw is reviewed to */ +#define BRSHW_SOURCECODE_TEMPLATE_MAJOR_VERSION 1u +#define BRSHW_SOURCECODE_TEMPLATE_MINOR_VERSION 3u +#define BRSHW_SOURCECODE_TEMPLATE_PATCH_VERSION 14u + +#define BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED ((BRSHW_SOURCECODE_TEMPLATE_MAJOR_VERSION) * 10000 + \ + (BRSHW_SOURCECODE_TEMPLATE_MINOR_VERSION) * 100 + \ + (BRSHW_SOURCECODE_TEMPLATE_PATCH_VERSION)) + +/* +* Description: This is the legacy BrsHw template main and bug fix version. The version numbers are BCD encoded. +* Nothing to do here, as the version numbers will be generated by macro. +*/ +#define BRSHW_SOURCECODE_TEMPLATE_VERSION (((BRSHW_SOURCECODE_TEMPLATE_MAJOR_VERSION / 10u) << 12u) | \ + ((BRSHW_SOURCECODE_TEMPLATE_MAJOR_VERSION % 10u) << 8u) | \ + ((BRSHW_SOURCECODE_TEMPLATE_MINOR_VERSION / 10u) << 4u) | \ + ((BRSHW_SOURCECODE_TEMPLATE_MINOR_VERSION % 10u))) +#define BRSHW_SOURCECODE_TEMPLATE_BUGFIX_VERSION (((BRSHW_SOURCECODE_TEMPLATE_PATCH_VERSION / 10u) << 4u) | \ + ((BRSHW_SOURCECODE_TEMPLATE_PATCH_VERSION % 10u))) + +/* This is the BrsHw major, minor and patch version */ +#define BRSHW_MAJOR_VERSION 1u +#define BRSHW_MINOR_VERSION 0u +#define BRSHW_PATCH_VERSION 3u + +#define BRSHW_VERSION_COMBINED ((BRSHW_MAJOR_VERSION) * 10000 + (BRSHW_MINOR_VERSION) * 100 + (BRSHW_PATCH_VERSION)) +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +/* + * Description: Inclusion of generic ARM parts + */ +#include "ARMBrsHw_CortexR.h" + +#ifndef SOC_AM263X + #define SOC_AM263X +#endif + +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #include "drivers/hw_include/cslr_soc.h" + #include "drivers/gpio.h" + #include "drivers/soc.h" + #include "drivers/pinmux.h" +#endif + +#if defined (BRS_ENABLE_PORT) + #include "BrsHw_Ports.h" +#endif + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ +/* The following parameters are necessary for this platform, to be generated by BRS-Cfg5-Generator into BrsCfg.h */ +#if !defined (BRS_OSC_CLK) + #error "BRS CHECK: The parameter BRS_OSC_CLK is missing! Please check your BRS Cfg5 configuration." +#endif + +#if !defined (BRS_TIMEBASE_CLOCK) + #error "BRS CHECK: The parameter BRS_TIMEBASE_CLOCK is missing! Please check your BRS Cfg5 configuration." +#endif + +#if !defined (BRS_PERIPH_CLOCK) + #error "BRS CHECK: The parameter BRS_PERIPH_CLOCK is missing! Please check your BRS Cfg5 configuration." +#endif + +#if !defined (BRS_CPU_MAX_FREQUENCY) + #error "BRS CHECK: The parameter BRS_CPU_MAX_FREQUENCY is missing! Please check your BRS Cfg5 configuration." +#endif + +#if !defined (BRS_CPU_CORE_CORTEX_R5F) + #error "BRS CHECK: The parameter BRS_CPU_CORE_x is missing or not supported! Please check your BRS Cfg5 configuration." +#endif + +#if !defined (BRS_CPU_CORE_AMOUNT) + #error "BRS CHECK: The parameter BRS_CPU_CORE_AMOUNT is missing! Please check your BRS Cfg5 configuration." +#endif + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ +/* +/* +* Description: This corresponds to the return value of BRS_READ_COREID and BrsHw_GetCore(). +* BRSHW_INIT_CORE_ID is used e.g. in main@BrsMain to detect the valid core for HW initialization +* (boot core) +*/ +#define BRSHW_DERIVATIVE_CORE0_ID 0x00 /*R5FSS0_0*/ +#define BRSHW_DERIVATIVE_CORE1_ID 0x01 /*R5FSS0_1*/ +#define BRSHW_DERIVATIVE_CORE2_ID 0x02 /*R5FSS1_0*/ +#define BRSHW_DERIVATIVE_CORE3_ID 0x03 /*R5FSS0_1*/ +#define BRSHW_INIT_CORE_ID BRSHW_DERIVATIVE_CORE0_ID + +/* Description: Access the active exception table using base address 0 on all cores */ +#define BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0 + +/********************************************************************************************************************** + * Compiler abstraction + *********************************************************************************************************************/ +/* part of ArmCommon */ + +/********************************************************************************************************************** + * BrsHW configuration + *********************************************************************************************************************/ +/* part of ArmCommon */ + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +#define BRS_START_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +/*****************************************************************************/ +/* @brief This function can be used to initialize controller specific + * stuff that should be handled by the first execution instance, + * even before the memory initialization took place (e.g. + * everything that is necessary to access the memory or to handle + * exceptions). This function is called at the beginning of + * BrsMainStartup(), immediately after the stackpointer was + * initialized in StartupCode + * (if BRSHW_EARLYINIT_AVAILABLE is set in BrsHw.h). + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from Brs_PreMainStartup() at power on + * initialization + *****************************************************************************/ +#define BRSHW_EARLYINIT_AVAILABLE +void BrsHwEarlyInitPowerOn(void); +#define BRS_STOP_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +#endif /* BRS_FIRST_EXECUTION_INSTANCE */ + +/*****************************************************************************/ +/* @brief This function can be used to initialize controller specific + * stuff that is not related to one of the other InitPowerOn + * functions (e.g. code that is always mandatory, also if MCAL + * and/or OS is used). This function is called from BrsMain + * immediately after BrsHwDisableInterruptAtPowerOn() during + * initialization (if BRSHW_PREINIT_AVAILABLE is set in BrsHw.h) or + * from the BrsMain_MemoryInit_StageHardReset_Hook() during + * initialization (if BRS_ENABLE_PREFER_PLL_WATCHDOG_INIT is set). + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from BrsMainInit() at power on initialization + *****************************************************************************/ +#define BRSHW_PREINIT_AVAILABLE +void BrsHwPreInitPowerOn(void); + +#if defined (BRS_ENABLE_WATCHDOG) +/*****************************************************************************/ +/* @brief This function must be used to initialize the Watchdog. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from BrsMainInit() at power on initialization + *****************************************************************************/ +void BrsHwWatchdogInitPowerOn(void); +#endif /* BRS_ENABLE_WATCHDOG */ + +#if defined (BRS_ENABLE_PLLCLOCKS) +/*****************************************************************************/ +/* @brief This function must be used to initialize the PLL. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from BrsMainInit() at power on initialization + *****************************************************************************/ +void BrsHwPllInitPowerOn(void); +#endif /* BRS_ENABLE_PLLCLOCKS */ + +#if defined (BRS_ENABLE_PORT) + +/* BrsHwInitPortInput(), BrsHwInitPortOutput(), BrsHwInitPortInputOutput() are replaced by + * proprietary functions provided by TI. */ + +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_START_SEC_RAM_CODE + #include "Brs_MemMap.h" +# endif +/*****************************************************************************/ +/* @brief This function sets the output level of a port pin. + * @pre Port pin configurations available within BrsHw_Ports.h, + * no DrvPort used for port pin initialization and + * transferred port pin has to be initialized as output pin with + * GPIO functionality. + * @param[in] p - brsHw_Port_PortType, to be set, + * Level - level, port pin has to be set to + * (BRSHW_PORT_LOGIC_LOW or BRSHW_PORT_LOGIC_HIGH). + * @param[out] - + * @return - + * @context Function is called from BrsHwPortInitPowerOn() and + * provided to external modules (e.g. BrsMainTogglePin()). + *****************************************************************************/ +void BrsHwPort_SetLevel(brsHw_Port_PortType, uint8); + +/*****************************************************************************/ +/* @brief This function reads the input level of a port pin. + * @pre Port pin configurations available within BrsHw_Ports.h, + * no DrvPort used for port pin initialization and + * transferred port pin has to be initialized as input pin with + * GPIO functionality. + * @param[in] p - brsHw_Port_PortType, to be read. + * @param[out] - + * @return Level, read from port pin + * (BRSHW_PORT_LOGIC_LOW or BRSHW_PORT_LOGIC_HIGH). + * @context Function is provided to external modules. + *****************************************************************************/ +uint8 BrsHwPort_GetLevel(brsHw_Port_PortType); +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_STOP_SEC_RAM_CODE + #include "Brs_MemMap.h" +# endif + +/*****************************************************************************/ +/* @brief This function must be used to initialize the used ports. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from BrsMainInit() at power on initialization + *****************************************************************************/ +void BrsHwPortInitPowerOn(void); +#endif /* BRS_ENABLE_PORT */ + +/* BrsHwDisableInterruptAtPowerOn() is part of ArmCommon */ + +/* BrsHw_ExceptionTable_Init() is part of ArmCommon */ + +/*****************************************************************************/ +/* @brief Restart ECU (issue a software reset or jump to startup code) + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from e.g. ECU state handling + *****************************************************************************/ +void BrsHwSoftwareResetECU(void); + +#if defined (BRS_FIRST_EXECUTION_INSTANCE) +/* This code is only needed for the first instance/executable in the system */ +#define BRS_START_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +/*****************************************************************************/ +/* @brief Get reset reason + * @pre - + * @param[in] - + * @param[out] - + * @return Reset reason + * @context Function is called from BrsMainStartup to determine if reset + * was triggered through software call (BrsHwSoftwareResetECU()). + * The result is stored by BrsMainStartup in the global variable + * brsMain_ResetReason. It should only be called once, during + * startup. The old API name BrsHwGetResetReason() is remapped + * to BrsMainGetResetReason. + *****************************************************************************/ +brsMain_ResetReasonType BrsHwGetResetReasonStartup(void); +#define BRS_STOP_SEC_STARTUP_CODE +#include "Brs_MemMap.h" + +/* +* Wrapper from old BrsHwGetResetReason() function to new BrsMainGetResetReason(). +* This is to prevent multiple selection of reset reason registers, as this is not +* supported on all HW platforms. +*/ +#define BrsHwGetResetReason() BrsMainGetResetReason() +#endif /* BRS_FIRST_EXECUTION_INSTANCE */ + +/* BrsHwTime100NOP() is part of ArmCommon */ + +#if defined (BRS_ENABLE_SAFECTXSUPPORT) +/*****************************************************************************/ +/* @brief This API is used to enable hardware access in untrusted mode + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function must be called after all depending peripheral modules + * are supplied by proper clocks AND before the OS is started. + *****************************************************************************/ +void BrsHw_EnableHwAccess(void); +#endif /* BRS_ENABLE_SAFECTXSUPPORT */ + +/* BrsHw_GetCore() is part of ArmCommon */ + +/*****************************************************************************/ +/* @brief This API is used to enable an interrupt source in the core + * interrupt controller. + * @pre - + * @param[in] Source to be enabled. + * @param[in] Priority level to be set. + * @param[out] - + * @return - + * @context Function is called from HlpTest and other test environments. + *****************************************************************************/ +void BrsHw_EnableInterrupt(uint32, uint8); + +/*****************************************************************************/ +/* @brief This API is used to disable an interrupt source in the core + * interrupt controller. + * @pre - + * @param[in] Source to be disabled. + * @param[out] - + * @return - + * @context Function is called from HlpTest and other test environments. + *****************************************************************************/ +void BrsHw_DisableInterrupt(uint32); + +/*****************************************************************************/ +/* @brief This API is used to trigger the given software interrupt source. + * @pre - + * @param[in] Source to be triggered. + * Some derivatives only support few software triggerable sources, + * check for their validity. + * @param[out] - + * @return - + * @context Function is called from HlpTest and other test environments. + *****************************************************************************/ +void BrsHw_TriggerSoftwareInterrupt(uint32); +#endif /*_BRSHW_H_*/ diff --git a/Source/include/BrsHw_Ports.h b/Source/include/BrsHw_Ports.h new file mode 100644 index 0000000..c75d28f --- /dev/null +++ b/Source/include/BrsHw_Ports.h @@ -0,0 +1,149 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsHw_Ports.h + * Project: Vector Basic Runtime System + * Module: BrsHw for platform TexasInstruments Sitara AM263x + * + * \brief Description: This header file contains the information for the evalboard specific port settings, + * supported by this Brs implementation. + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to BrsHw.h. + *********************************************************************************************************************/ + +#ifndef _BRSHW_PORTS_H_ +#define _BRSHW_PORTS_H_ + +/******************************************************************************* + * Generic PORT definition types + *******************************************************************************/ +/* GPIO module from TI libraries used for Pin toggling. See GPIO_soc.h for details on the pin declaration */ +typedef struct +{ + uint32 portNumber; +} brsHw_Port_PortType; + +#if defined (_BRSHW_C_) + #define BRSHW_PORT_PIN(name, number) const brsHw_Port_PortType name = {number} +#else + #define BRSHW_PORT_PIN(name, number) extern const brsHw_Port_PortType name +#endif + +#define BRSHW_PORT_LOGIC_HIGH (uint8)1 +#define BRSHW_PORT_LOGIC_LOW (uint8)0 + +/******************************************************************************* + * PIN configuration for alive LED support + *******************************************************************************/ +#if defined (BRS_ENABLE_SUPPORT_LEDS) +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +# if defined (BRS_EVA_BOARD_TI_AM2634_EVM) +BRSHW_PORT_PIN(BRSHW_PORT_LED, /*CSL_MSS_IOMUX_PADCQ_CFG_REG*/ 0); /* GPIOA -> GPIO2 -> T16 */ +# else + #error "Your chosen EvaBoard is not yet supported for LED support. Feel free to add your EvaBoard on top, or disable BRS LED support." +# endif /*BRS_EVA_BOARD_x*/ +# endif /*BRS_COMP_LLVMTEXASINSTRUMENTS*/ +#endif /*BRS_ENABLE_SUPPORT_LEDS*/ + +/******************************************************************************* + * PIN configuration for toggle WD pin support + *******************************************************************************/ +#if defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN) +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_START_SEC_RAM_CONST + #include "Brs_MemMap.h" +# endif + + #error "Please configure here the needed WD-toggle pin and uncomment this error, or disable BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN" */ + +BRSHW_PORT_PIN(BRSHW_PORT_TOGGLE_WD, SOC_TPR12_GPIO_x); + +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_STOP_SEC_RAM_CONST + #include "Brs_MemMap.h" +# endif +#endif /* BRS_ENABLE_SUPPORT_WD_PIN */ + +/******************************************************************************* + * PIN configuration for toggle CUSTOM pin support + *******************************************************************************/ +#if defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN) +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_START_SEC_RAM_CONST + #include "Brs_MemMap.h" +# endif + + #error "Please configure here the needed custom toggle pin and uncomment this error, or disable BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN" */ + +BRSHW_PORT_PIN(BRSHW_PORT_TOGGLE_CUSTOM, SOC_TPR12_GPIO_x); + +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_STOP_SEC_RAM_CONST + #include "Brs_MemMap.h" +# endif +#endif /* BRS_ENABLE_SUPPORT_CUSTOM_PIN */ + +/******************************************************************************* + * ------------------------------------------------------------ + * COMMUNICATION DRIVER SPECIFIC PORT SETTINGS + * ------------------------------------------------------------ + *******************************************************************************/ +/******************************************************************************* + * GENERAL COMMUNICATION DRIVER SPECIFIC SETTINGS + *******************************************************************************/ + +/******************************************************************************* + * CAN driver + *******************************************************************************/ +/* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */ + +/******************************************************************************* + * LIN driver + *******************************************************************************/ +#if defined (BRS_ENABLE_LIN_SUPPORT) + //#error "PortPins for Lin are not yet supported!" +#endif /* BRS_ENABLE_LIN_SUPPORT */ + +/******************************************************************************* + * FLEXRAY driver + *******************************************************************************/ +#if defined (BRS_ENABLE_FLEXRAY_SUPPORT) + #error "PortPins for FlexRay are not yet supported!" +#endif + +/******************************************************************************* + * ETHERNET driver + *******************************************************************************/ +#if defined (BRS_ENABLE_ETHERNET_SUPPORT) + +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) +/* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */ +# if defined (BRS_EVA_BOARD_TI_AM2634_EVM) +BRSHW_PORT_PIN(BRSHW_PORT_ETH0_PHY_EN, /*CSL_MSS_IOMUX_PADCQ_CFG_REG*/0); /* GPIOA -> GPIO2 -> T16 */ +BRSHW_PORT_PIN(BRSHW_PORT_ETH0_PHY_N_RESET, /*CSL_MSS_IOMUX_PADBB_CFG_REG*/0); /* GPIOD -> GPIO28 -> R17 */ +# else + #error "Please choose the valid EvalBoard in vBRS setup or define pins for ETH_PHY_EN and ETH_PHY_N_RESET here manually." +# endif /* BRS_EVA_BOARD_x */ +# endif /* BRS_COMP_LLVMTEXASINSTRUMENTS */ +#endif /* BRS_ENABLE_ETHERNET_SUPPORT */ + +#endif /* _BRSHW_PORTS_H_ */ diff --git a/Source/include/BrsMain.h b/Source/include/BrsMain.h new file mode 100644 index 0000000..1b2476b --- /dev/null +++ b/Source/include/BrsMain.h @@ -0,0 +1,807 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsMain.h + * Project: Vector Basic Runtime System + * Module: BrsMain + * + * \brief Description: Main header of BRS contains + * - Main function (called from StartUpCode and calls stack entry EcuM_Init()) + * - Call of BrsHw HW initialization routines + * - 1ms handler, with support of cycle functions with several cycle times + * - Default_Init_Task, Main and Background Task which can be used by the operating system + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * ------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2018-03-20 visbwa Initial creation of new BRS code basis + * 2018-03-27 visbwa Renamed BrsAsrStartup into BrsStartup, added version check, reworked + * includes, added example code text in BrsMainStartup.c + * 2018-05-08 visbwa Introduced support for Generic Testsuite + * (BRS_ENABLE_TESTSUITE_SUPPORT), removed support for all other + * testsuites, introduced BRS_ENABLE_1MS_HANDLER and + * brsMain_CallCounter1sec + * 2018-05-16 visbwa Added extern declaration of brsHwZeroRamAreaSet and + * brsHwInitRamAreaSet in BrsMainStartup.c + * 01.00.01 2018-06-22 visbwa Added CAN stack exclusive area workaround from former + * BswInit_Callout_Stubs.c + * 01.00.02 2018-06-25 visbwa Added configuration check for OS_MS2TICKS_SystemTimer into BrsMain.h + * 01.00.03 2018-07-02 visces Removed outdated brsHwZeroRamAreaSet and brsHwInitRamAreaSet in + * BrsMainStartup.c + * 01.00.04 2018-07-18 visbwa Moved BrsHwDisableInterruptAtPowerOn() from BrsMainInit() into main() + * (OS specifies, this has to be called before Os_Init() and for every + * Core) + * 01.00.05 2018-07-26 visbwa No changes in sourcecode, only within ALM package + * 01.00.06 2018-07-30 visbwa Encapsuled call of BrsHwDisableInterruptAtPowerOn() with + * usecase != VTT + * 01.01.00 2018-08-16 visbwa Replaced include of RamInitSections.h by vLinkGen_RamInitSections.h in + * BrsMainStartup.c to support vLinkGen + * 01.02.00 2018-10-04 visbwa No changes in sourcecode, only within ALM package + * 01.03.00 2018-10-08 visbwa Changed include of BrsCfg.h into vBrsCfg.h (vBaseEnv 1.1.0) + * 01.03.01 2018-10-10 visbwa Moved BrsTestsuiteInit() from BrsMainInit() into Default_Init_Task(), + * removed usage of BRS_ENABLE_HLPTEST_SUPPORT + * (generic Testsuite concept!) + * 01.03.02 2018-11-05 visbwa Fixed include order (Can.h previous to BrsTestsuite.h) + * 01.03.03 2018-11-13 visbwa Implemented Default_Init_Tasks for projects with up to 6 Cores, + * fixed VTT support within IdleTasks (CANoeAPI_ConsumeTicks) + * 01.04.00 2018-11-21 visbwa Added testsuite callouts into every function + * 01.04.01 2018-11-30 visbwa Removed include of Rte_Main.h (Rte_Start() not called any more) + * 01.05.00 2018-12-21 visbwa Added call of new API Os_InitialEnableInterruptSources() within every + * core Default_Init_Task + * 01.05.01 2019-03-06 visbwa Added hint for DrvCan using infix, added wrapper for Can_30_Mcan + * 01.06.00 2019-05-06 visbwa Support for vLinkGen 1.04; renamed struct names of vlinkGen areas in + * BrsMainStartup.c + * - added support for zero init blocks + * - renamed Brs_RamZeroInit() to Brs_MemoryZeroInit() and + * Brs_RomToRamInit() to Brs_MemoryInit() + * - check for missing hard reset detection + * 01.06.01 2019-05-10 visbwa Changed include of vLinkGen header to support new vLinkGen file + * structure in BrsMainStartup.c + * 01.06.02 2019-06-13 vismaa Added additional Default_Init_Task_Core6 + * 01.06.03 2019-06-26 visbwa Moved call of BrsMainInit() previous to call of Os_Init() + * 01.07.00 2019-07-02 visbwa Enhanced FBL support (encapsulations, call of fblmain()) + * 01.07.01 2019-07-22 visbwa Added check for VLINKGEN_ZERO_INIT_BLOCK_COUNT_HARD_RESET in + * BrsMainStartup.c + * 01.07.02 2019-07-29 visbwa Added implementation of BrsMainExceptionStartup() for calls from + * assembly StartUpCode + * 01.08.00 2019-08-08 visbwa Implemented support for different FBL usecases Legacy, + * WithoutOSScheduling and OSScheduling, added BrsMainExceptionHandler + * module code for BrsMainStartup, changed FBL call from fblmain() to + * FblMain() for legacy mode, removed include of fbl_main.h, + * added InitPattern parameter to Brs_MemoryZeroInit() and added the + * new configuration values for the init pattern to the depending calls + * in BrsMainStartup.c, added sample implementation for Hard-reset blocks + * and areas in BrsMainStartup.c + * 01.09.00 2019-08-28 visbwa Changed encapsulation of task implementations (not used for FBL + * usecases Legacy and WithoutOSScheduling any more) + * 2019-10-07 visbwa Added support of platform individual ZeroInit function + * BrsHw_AsmMemoryZeroInitLoop() in Brs_MemoryZeroInit() in + * BrsMainStartup.c + * 2019-10-09 visbwa Enhanced support for VTT platform + * 01.09.01 2019-11-04 visbwa Changed include of Can.h into CanIf.h (get rid of DrvCan with infix + * (Can_30_Mcan.h)), enhanced MemMap + SchM exclusive area abstraction + * for Mcan driver (uses infixes) + * 01.09.02 2020-11-04 visbwa No changes in sourcecode, only within ALM package + * 01.10.00 2019-11-25 visbwa Implemented Default_Init_Task_Trusted and + * Default_Init_Task_Corex_Trusted to allow the SafeContext partitioning + * UseCase + * 2019-11-27 visbwa Changed include structure for vBrsCfg.h in BrsMain.h (does now also + * exist for VTT) + * 2019-11-29 visbwa Enhanced encapsulation with _MICROSOFT_C_VTT_ for DualTarget UseCase + * (no BrsHw!) + * 2019-12-04 visbwa Fixed encapsulation of DrvCan parts + * 01.11.00 2020-02-11 visbwa Support for UseCase HSM (BRS_ENABLE_HSM_SUPPORT, no EcuM), + * added filtering of MultiCore parts through + * C_BRSASR_USECASE_SINGLECORE_COMMENT, + * support for generated DrvCan macros to support modules with infix + * names, removed error directive at usage of BrsHwGetResetReason() in + * BrsMainStartup.c + * 01.12.00 2020-03-12 visbwa Encapsulation of SchM implementation with MemMap defines for UseCase + * FBL, encapsulation of struct brsMain_Cyclic_Callbacks with MemMap and + * 1ms-handler defines + * 01.12.01 2020-04-22 visbwa Added conditional call of BrsHwDisableEccErrorReporting() for FBL + * UseCase + * 02.00.00 2020-05-29 visbwa Major updates for vBaseEnv 2.0.0 + * - added BrsMainTogglePin() (moved from BrsHw.c BrsHwTogglePin()) + * - introduction of BrsMain_Callout_Stubs.c + * - updated vLinkGen define and struct names to new vLinkGen 2.0 naming + * schema, added version check for vLinkGen version in BrsMainStartup.c + * 02.01.00 2020-06-29 visbwa Added support for preferred PLL and Watchdog init in BrsMainInit() and + * BrsMain_MemoryInit_StageOne_Hook(), reduced calls of BrsHw_GetCore() + * inside Brs_PreMainStartup() of BrsMainStartup.c to a single call + * 02.01.01 2020-07-24 visbwa Soft increase for FBL_Legacy support + * 02.02.00 2020-08-10 visbwa Support for FBL Legacy UseCase w/o OS, usage of new FBL UseCase + * defines; + * MemMap encapsulation of BrsMainExceptionHandler(), enabled 1ms handler + * also for FBL, BrsMainCyclic1ms() usable from extern, removed usage of + * BrsAsrApplCanInterruptLockCtr for FBL (FBL is always in polling mode), + * added BrsMain_SoftwareResetECU_Hook() in BrsMain_Callout_Stubs.c, + * encapsuled memPtr in Brs_MemoryZeroInit() of BrsMainStartup.c + * (compiler warnings) + * 02.02.01 2020-10-29 visbwa No changes in sourcecode, only within ALM package + * 02.02.02 2020-10-29 visbwa No changes in sourcecode, only within ALM package + * 02.02.03 2020-10-30 visbwa Added include of Os.h for VTT (usage of ShutdownOS()), removed + * AUTHOR IDENTITY + * 02.02.04 2020-12-07 visbwa Increased for loop variable in Brs_MemoryZeroInit() and + * Brs_MemoryInit() from uint8 + * to uint32 (depending datatypes are increased in vLinkGen) in + * BrsMainStartup.c + * 02.02.05 2021-01-14 visbwa Adapted main() to also call Os_Init() for FBL with VTT + * 02.03.00 2021-03-17 visbwa Moved revision history of all .c and .h files into BrsMain.h, + * elimination of BrsMainStartup.h, added support for new OS + * UseCase INTERRUPT_ONLY and call of BrsMainExceptionHandler() at the + * end of main() for IllegalReturnFromMain + * 02.03.01 2021-03-22 visbwa Added definition of _BRSMAIN_C_ in BrsMain.c, to solve issues in + * vBrsCfg.h if DIO + * channels are used for TogglePin functionality + * 02.04.00 2021-04-07 visbwa Added implementation of BrsMainSuspendAllInterrupts() and + * BrsMainResumeAllInterrupts() for new OS UseCase INTERRUPT_ONLY + * 02.04.01 2021-04-13 visbwa Encapsulation of int main(void) declaration to not appear for VTT, as + * VTT expects void main(void) + * 02.05.00 2021-07-02 visbwa Added support for upcoming Brs_Template 1.03: + * - call of BrsHw_ExceptionTable_Init() in main() + * - introduction of BrsMain_Types.h + * - new MainExceptionHandler ErrorCode kBrsInvalidCoreConfig + * 02.05.01 2021-07-19 visbwa ESCAN00109765 Fixed VTT encapsulation in main() to solve compiler error + * 02.05.02 2021-08-02 visbwa Fixed BrsHw_ExceptionTable_Init() call in main() for FBL Ram exception + * table + * 02.05.03 2021-08-02 visbwa Fixed BRSMAIN_BUGFIX_VERSION in several files of the package + * 02.06.00 2021-08-05 visjhr HALBE-5072 In BrsMain_Types.h: Renamed StartupStackLabel -> StartupStackEndLabel, + * added StartupStackSize + * 2021-10-11 visbwa Introduction of Brs_ApplicationEntry(), BRS_FIRST_INSTANCE usage and + * MemMap concept in BrsMainStartup.c; brsMain_ResetReasonType in + * BrsMain_Types.h; + * moved BrsMainExceptionStartup() from BrsMain.c into BrsMainStartup.c + * and map it into StartupCode section; swap order of HardResetOnly and + * InitOne in BrsMainStartup.c, moved preferred PLL and Watchdog init + * from InitOne hook into HardResetOnly hook to fit with vLinkGen 2.04; + * several small adaptions to reduce compiler warnings; + * introduction of Brs_memMap.h + * 02.06.01 2021-10-20 visbwa Brs_memMap.h fix for GHS + * 02.06.02 2021-10-28 visbwa Encapsulation of _Brs_ExcVectRam_START extern declaration, for better + * VTT support + * 02.07.00 2021-11-09 visbwa Encapsulation of BrsHw_ExceptionTable_Init() in main() for FBL UseCase + * with new parameter BRS_FBL_EXCEPTIONTABLE_IN_RAM + * (vBRSFblSupportExceptionTableInRam); + * use DrvCan MemMap for mapping of BrsAsrApplCanInterruptLockCtr and + * module specific MemMap sections for exclusive area implementation in + * BrsMain.c (including CAN driver name infix wrapper, provided by vBRS + * generator in vBrsCfg.h) + * 02.07.01 2021-11-25 virjas Added missing function prototypes + * 02.07.02 2021-12-02 visbwa Added support for Arm6/TI and warning for GccGnu/Generic compiler in + * Brs_MemMap.h + * 02.08.00 2022-01-12 visbwa Changed call of BrsHw_ExceptionTable_Init() in main() for FBL UseCase + * (_Brs_ExcVectRam_START is now generated into BrsMain_CoreConfig), + * added a check for the vBrs generator version + * (BRS_GENERATED_HW_CONFIG_VERSION) + * 02.08.01 2022-02-04 visrgm Added support for Renesas compiler in Brs_MemMap.h + * 02.08.02 2022-02-18 visbwa Enhanced encapsulation of uint32 i in main() to prevent compiler + * warnings + * 02.08.03 2022-02-18 visbwa Added encapsulation to BrsMainExceptionStartup() (1st execution + * instance) + * 02.08.04 2022-03-23 visbpz Added support for Microchip compiler in Brs_MemMap.h + * 02.08.05 2022-03-23 visbpz Incrementing software version + * 02.08.06 2022-03-30 visbwa Added _BRSMAINSTARTUP_C_ to BrsMainStartup.c + * 02.08.07 2022-04-06 visjhr HALBE-6489 Added Default_Init_Task_Core0 and Default_Init_Task_Core0_Trusted + * 02.08.08 2022-05-12 visbwa Added functionality to override BRSMAIN_CYCLIC_MAX_CALLBACKS in + * BrsMain.c + * 02.09.00 2022-05-05 visbwa Added sections for mapping of exception table const/code in + * Brs_MemMap.h + * 2022-05-30 visbwa Added support for LlvmDiab/LlvmTI compiler and fixed support for + * GccGnu (to allow at least correct mapping for all brsExcVect) in + * Brs_MemMap.h + * 02.09.01 2022-05-31 visbwa Fixed LlvmDiab support in Brs_MemMap.h + * 02.09.02 2022-07-04 visbwa Removed call of BrsHwDisableEccErrorReporting() in BrsMainInit() + * (is called from FBL) + * 02.09.03 2022-07-07 visbwa Readded call of BrsHwDisableEccErrorReporting() and adapted + * encapsulation of BrsHw + * init function calls for FBL UseCases in BrsMainInit() + * 02.10.00 2022-07-14 visbwa Changes in ALM content settings only (usage type partly set to + * external) + * 02.10.01 2022-08-04 visbwa Added LlvmHightec support in Brs_MemMap.h + * 02.11.00 2022-12-07 visbwa Removed support for BrsHw packages with + * BRSHW_SOURCECODE_TEMPLATE_VERSION < 0x0103u; + * brsMain_ResetReason in Brs_PreMainStartup() only set by initCore; + * introduction of BrsMain_Appl.c, call of BrsMain_Appl_Init() from + * BrsMainInit(), moved UserDefined ExclusiveArea handling for CAN + * channels into BrsMain_Appl.c, implementation of FBL Instance Presence + * Pattern in BrsMain_Appl.c; + * support for Ansi/Gnu compiler with VTT/CANoeEmu in Brs_MemMap.h + * 2022-12-13 visdri Fixed LlvmTI compiler support in Brs_MemMap.h + * 02.11.01 2023-01-11 visbwa Fixed single core platform support in Brs_PreMainStartup() of + * BrsMainStartup.c + * 02.11.02 2023-01-11 visbwa Fixed MemMap defines for initialized variables in BrsMainTogglePin() + * 02.12.00 2023-02-16 visjhr HALBE-8511 Removed unused IdleTask{_CoreX},removed filtering ifdefs for + * C_BRSASR_USECASE_STARTAPPLICATION_COMMENT and C_BSWMODULE_ASR_* + * 2023-02-24 visbwa Introduction of BRS_MEMMAP_INLINE_ASSEMBLER_USED in Brs_MemMap.h for + * GHS compiler + * 2023-02-27 visbwa Added call to BrsHwApplicationInit() at beginning of + * Brs_ApplicationEntry() in + * BrsMainStartup.c, to support platform specific initialization per + * execution instance + * 2023-03-07 visbwa Added usage of BrsMain_Appl for UseCase VTT as well + * 02.13.00 2023-03-08 visjhr Added BRS_START/STOP_SEC_BRSAPPLENTRY_CODE for locating + * Brs_ApplicationEntry() to + * the new section "brsApplicationEntry" + * 02.13.01 2023-05-10 sgj Introduction of BRS_MEMMAP_INLINE_ASSEMBLER_USED in Brs_MemMap.h for + * DIAB compiler + * 02.13.02 2023-05-17 visbwa Fixed MemMap defines of brsMain_CallCounter1ms, + * brsMain_CallCounter1sec and brsMain_SuspendAllCounter + * 02.14.00 2023-05-17 visbwa Support of new execution instance HSM_Updater + * (BRS_ENABLE_HSM_UPDATER_SUPPORT) + * 02.14.01 2023-06-02 visbwa Added a check an valid Brs_Template version for USeCase HSM_Updater + * 02.15.00 2023-06-28 visbwa Changed implementation of BrsMainTask (from extended to basic task), + * setting of BrsCyclicAlarm_1ms moved into Default_Init_Task; small + * fixes for HSM-Updater support + * 2023-07-14 visbwa Fixed BRS_START_SEC_EXCVECTRAM_CONST in Brs_MemMap.h + * 02.15.01 2023-07-21 visjhr Added support for CCAC compiler (Brs_MemMap.h) + * 02.15.02 2023-09-13 visbwa Fixed include of CANoeApi.h, to support key sensitive environments (Linux) + * 02.16.00 2023-09-27 visbwa Support for new Can_30_Core and vCan drivers in BrsMain_Appl.c + * 02.16.01 2023-10-25 visbwa Fixed DrvCan header include encapsulation in BrsMain_Appl.c + * 02.16.02 2023-11-13 visbwa Fixed DrvCan header include encapsulation in BrsMain_Appl.c + * 02.16.03 2023-11-28 visbwa Introduction of BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING to + * disable CAN exclusive area handling in BrsMain_Appl.c + * visbwa BASEENV-10659 Added support for Can_30_Core_MemMap.h in BrsMain_Appl.c + * 02.17.00 2023-11-20 visjhr BASEENV-10133 Add support for multiple DrvCan instances in BrsMain_Appl.c + * 2023-11-21 visbwa Added "Change Id" to revision history + * 2023-12-05 visbwa BASEENV-11107 Added sample implementation of DrvCan HardwareCancelByAppl + * functionality to BrsMain_Appl.c as new default, as a replacement of + * the custom defined exclusive area handlings (still available as + * sample, but with danger notice) + * 02.17.01 2024-02-12 vissgj Fixed section pragma of brsSharedVar for DIAB (istring "" , + * ustring "uninitialised section") in Brs_MemMap.h + * 02.17.02 2024-02-23 vissgj Added pragmas ghs start/enddata of brsSharedVar for GHS in + * Brs_MemMap.h to force variables to data area bss + * (excludes data from a special data area sda) + * Added section encapsulation of extern volatile brsMain_ResetReasonType + * brsMain_ResetReason in BrsMain.c + * 02.17.03 2024-02-29 visjhr BASEENV-11377 Changed IAR pragma used for BRS_START/STOP_SEC_FBL_PP_CONST + * (FblPresencePatternSection) + * 02.17.04 2024-03-06 visbwa BASEENV-3450 Added support for QNX QCC compiler in Brs_MemMap.h + * 02.17.05 2024-04-16 visbwa BASEENV-11813 Added BRSMAIN_POSTBRSMAININIT_CALLOUT + * BrsTestsuite_BrsMain_PostBrsMainInit() + * 02.17.06 2024-04-24 vissgj Changed alignment for brsSharedVar section for GccHightec from 8 to 4 + * (else additional space is consumed) + * 02.18.00 2024-06-24 visbwa BASEENV-11442 Fixed Brs_MemoryInit() mechanism in BrsMainStartup.c, to better work + * with vLinkGenVarSectionGroupEndAlignment; + * BASEENV-11563 Enhanced Brs_MemoryZeroInit() mechanism in BrsMainStartup.c, to work + * with different ECC alignment values and implemented 8-Byte aligned + * initailization in Brs_MemoryInit(), encapsulated with + * BRSMAINSTARTUP_64BIT_MEMORYINIT; + * BASEENV-12149 Updated BrsMain_Appl.c for better FBL usage (Appl_30_CoreCanTimer* + * APIs already implemented by fbl_cw) + * 02.19.00 2024-07-08 kal BASEENV-11508 Replaced all _MICROSOFT_C_VTT_ defines with newer VVIRTUALTARGET, to + * also support VTT with GccGnu and CLANG compiler + * 02.19.01 2024-07-29 visbwa Introduced BRS_DUMMY_STATEMENT and usage in BrsMainExceptionHandler() + * 02.20.00 2024-08-06 mna BASEENV-12327 Updated main() for HypervisorMaster support + * 2024-08-19 mna BASEENV-12265 Update Brs_ApplicationEntry() for initialization of groups in new init + * stage POWER_ON + * 2024-08-21 mna BASEENV-12285 Update main() for support of non-Autosar Cores + * 02.20.01 2024-08-29 visbwa ESCAN00118129 Added workaround for vLinkGen Tasking linker issue of empty ROM blocks + * for ROM to RAM copy groups, which triggers error checks in + * Brs_MemoryInit() + * 02.20.02 2024-08-30 visbwa Fix for VTTonly in main(), as BrsMain_NonAsrCore_Hook() not available + * for VTTonly + * 02.21.00 2024-09-02 visbwa BASEENV-12323 Enhanced support for Hypervisor, introduction of BRS_DISABLE_OS_USAGE + * 2024-09-04 mna BASEENV-12291 Enhanced support for non-Autosar cores + * 2024-09-12 visbwa TAR-61084 Fixed RamConstSection for IAR compiler in Brs_MemMap.h + * 2024-09-13 visbwa Added support for new DrvCanGen3_Core@Implementation[4.00.00] + * (CAN_30_CORE_SW_MAJOR_VERSION) in BrsMain_Appl, introduction of + * BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP + * 2024-09-17 visbwa TAR-57340 Added workaround for usage of CanGen3 HW driver with CanGen2 VTT + * driver in Dualtarget setups in BrsMain_Appl + * 02.21.01 2024-10-23 visbwa TAR-62725 Fixed vCan header include in BrsMain_Appl.h + * 02.21.02 2024-11-28 kal TAR-68820 Added prototype for local function BrsHw_AsmMemoryZeroInitLoop_64bit() + * 02.22.00 2024-11-22 mna BASEENV-12737 MemoryInit to support 64bit addressing + * 2024-12-09 visrgm BASEENV-12889 Fixed MemMap encapsulation for BrsAsrApplCanTimerCount in + * BrsMain_Appl.c + * 2024-12-11 sgj BASEENV-12534 Removed workaround for ESCAN00118129 Tasking compiler (requires + * vLinkGen >= 15) + * 2025-01-10 visbwa BASEENV-9206 Introduction of BRSMAIN_MEMINIT_FUNC_PREFIX and BrsMain_Cfg.h, + * removed include of BrsHw.h in BrsMain_Callout_Stubs.c as its redundant + * 2025-01-15 mna BASEENV-13024 Hypervisor Multicore support in BrsMain_Appl_HypervisorApi(); + * Conditional presence and call of BrsHw_UnlockCores() with + * Brs_Template 1.03.13 + * 2025-01-23 visbwa BASEENV-13024 Introduction of BrsMain_Appl_HypervisorStartCoreApi() + * 02.22.01 2025-02-20 visbwa Fixed ALM compiler filter rule for Brs_MemMap.h with VTT DualTarget + * environments + * 02.22.02 2025-02-21 visbwa Fixed definition of BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP in + * BrsMain_Appl.h for newer DrvCanGen3_Core versions + * 02.23.00 2025-03-21 vismaa BASEENV-13397 Introduced BRS_DISABLE_MEMORY_INIT_GLOBALLY in Brs_ApplicationEntry() + * 02.23.01 2025-05-27 kal BASEENV-13873 Added support for ArmTfE compiler (Brs_MemMap.h) + * 02.24.00 2025-06-24 kal BASEENV-13740 Revision according to C coding guidelines and improved MISRA-C + * BASEENV-13830 compliance + * 2025-07-22 visbwa Removed outdated hint for ESCAN00078832 in Default_Init_Task() + * 02.24.01 2025-07-23 visbwa TAR-91131 Enhanced support for new Gen3 Vtt DrvCan in BrsMain_Appl.c + * 02.25.00 2025-08-29 visjhr BASEENV-14263 Introduction of BrsMain_Appl_SuspendAllInterrupts() and + * BrsMain_Appl_ResumeAllInterrupts() in BrsMain_Appl.c for changed + * functionality of vBrs generated SchM stub + * 02.26.00 2025-10-27 sgj BASEENV-14708 Added support for RiscV Tasking compiler (Brs_MemMap.h) + * 02.27.00 2025-11-20 visbwa BASEENV-14777 Added compiler check (DaVinci config to buildenvironment) in + * BrsMain_Appl.c + *********************************************************************************************************************/ + +#ifndef _BRSMAIN_H_ +#define _BRSMAIN_H_ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "Compiler.h" + +#include "vBrsCfg.h" + +#if !defined (VVIRTUALTARGET) + #include "BrsMain_Cfg.h" + + #include "BrsMain_Types.h" + + #include "BrsHw.h" +#endif + +#if defined (BRS_ENABLE_FBL_SUPPORT) || defined (BRS_ENABLE_HSM_UPDATER_SUPPORT) || \ + defined (BRS_ENABLE_HYPERVISOR_SUPPORT) + #define BRS_DISABLE_OS_USAGE +#else + #include "Os.h" +#endif + +#if defined (BRS_ENABLE_HSM_SUPPORT) || defined (BRS_ENABLE_HSM_UPDATER_SUPPORT) + #include "vHsm.h" +#elif defined (BRS_ENABLE_HYPERVISOR_SUPPORT) + #include "vHyp.h" +#else +# if !defined (BRS_FBL_NO_ECUMINIT) +/* Ecu State Manager has to be available in system (BSW module or BRS Stub) */ + #include "EcuM.h" +# endif +#endif + +/********************************************************************************************************************** + * MODULE VERSION + *********************************************************************************************************************/ +/* +* Description: This is the BrsMain major, minor and patch version. The version numbers are decimally encoded. +* E.g. a version of 02.23.01 is encoded with major 2u, minor 23u and patch version 1u. +* No leading zeroes shall be used, as they would be treated as octal numbers. +*/ +#define BRSMAIN_MAJOR_VERSION 2u +#define BRSMAIN_MINOR_VERSION 27u +#define BRSMAIN_PATCH_VERSION 0u + +#define BRSMAIN_VERSION_COMBINED ((BRSMAIN_MAJOR_VERSION) * 10000 + (BRSMAIN_MINOR_VERSION) * 100 + \ + (BRSMAIN_PATCH_VERSION)) + +/* +* Description: This is the legacy BrsMain main and bug fix version. The version numbers are BCD encoded. +* Nothing to do here, as the version numbers will be generated by macro. +*/ +#define BRSMAIN_VERSION (((BRSMAIN_MAJOR_VERSION / 10u) << 12u) | ((BRSMAIN_MAJOR_VERSION % 10u) << 8u) | \ + ((BRSMAIN_MINOR_VERSION / 10u) << 4u) | ((BRSMAIN_MINOR_VERSION % 10u))) +#define BRSMAIN_BUGFIX_VERSION (((BRSMAIN_PATCH_VERSION / 10u) << 4u) | (BRSMAIN_PATCH_VERSION % 10u)) + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL TYPE DEFINITIONS + *********************************************************************************************************************/ +#if defined (BRS_ENABLE_TESTSUITE_SUPPORT) || defined (BRS_ENABLE_SUPPORT_LEDS) || \ + defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN) || defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN) + #define BRS_ENABLE_1MS_HANDLER +#endif + +#if defined (BRS_ENABLE_1MS_HANDLER) +typedef enum +{ + BRSMAIN_CYCLETIME_BACKGROUND, + BRSMAIN_CYCLETIME_1MS, + BRSMAIN_CYCLETIME_10MS, + BRSMAIN_CYCLETIME_100MS, + BRSMAIN_CYCLETIME_250MS, + BRSMAIN_CYCLETIME_500MS, + BRSMAIN_CYCLETIME_1000MS +}brsMain_Cyclic_Cycletime; +#endif + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ +/* +* Expression that is used to determine whether the current core requires re-programming of the Exception Table. +* For application cores, Exception Table shall be re-programmed only for cores configured as AUTOSAR. +*/ +#if defined (BRS_DISABLE_OS_USAGE) + #define BRS_EXCEPTIONTABLE_INIT_NEEDED(i, coreID) (BrsMain_CoreConfig[(i)].PhysicalCoreId == (coreID)) +#else + #define BRS_EXCEPTIONTABLE_INIT_NEEDED(i, coreID) ((BrsMain_CoreConfig[(i)].CoreIsAsr == ASR) && \ + (BrsMain_CoreConfig[(i)].PhysicalCoreId == (coreID))) +#endif + +/* Expression that is used for dummy statements to avoid compile warnings about unused identifiers */ +#define BRS_DUMMY_STATEMENT(x) (void)(x) + +/******************************************************************************* + * ModuleCode for BrsMainExceptionHandler + ******************************************************************************/ +#define BRSERROR_MODULE_BRSHW 0x01u +#define BRSERROR_MODULE_BRSMAIN 0x02u +#define BRSERROR_MODULE_BRSSTARTUP 0x03u +#define BRSERROR_MODULE_BRSMAINSTARTUP 0x04u + +/******************************************************************************* + * ErrorCodes for BrsMainExceptionHandler + * 0x00 to 0x7f are assigned to the BRS + * 0x80 to 0xff are assigned to the application + ******************************************************************************/ +/* General error which is not assigned to a special error class */ +#define kBrsUndefinedError 0x00u + +/* No handler is installed in interrupt vector table for given interrupt */ +#define kBrsInterruptHandlerNotInstalled 0x01u + +/* A GenTool setting is different to the excepted value */ +#define kBrsWrongGenToolSettings 0x02u + +/* BrsHwRestoreInterrupt is called more often than BrsHwDisableInterrupt */ +#define kBrsIllegalInterruptRestoration 0x03u + +/* Hardware configuration like clock setting is wrong */ +#define kBrsIllegalHardwareConfiguration 0x04u + +/* Illegal parameter used like wrong channel parameter */ +#define kBrsIllegalParameter 0x05u + +/* Illegal TCC channel used */ +#define kBrsTccChannelOutOfRange 0x06u + +/* Interrupt from unknown source occurred */ +#define kBrsUnknownInterrupt 0x07u + +/* CAN1 and CAN2 interrupts cannot be distinguished from each other */ +#define kBrsAmbiguousInterruptSource 0x08u + +/* Execution of library version check in Common_SipVersionCheck failed */ +#define kBrsLibraryVersionCheckFailed 0x09u + +/* OS ErrorHook called */ +#define kBrsOsErrorHookCall 0x0Au + +/* BRS not properly initialized */ +#define kBrsConfigUninit 0x0Bu + +/* Application software returned to main */ +#define kBrsIllegalReturnFromMain 0x0Cu + +/* Assembler code reached, which should never be handled */ +#define kBrsIllegalAssemblerReached 0x0Du + +/* No Core config found for actual physical core */ +#define kBrsInvalidCoreConfig 0x0Eu + +/* Configuration is using a functionality, that is not supported yet */ +#define kBrsMissingFunctionality 0x0Fu + +/* A non-Autosar-Core could not be started although it is configured */ +#define kBrsFailedNonAsrCoreStart 0x10u + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ +#if !defined (VVIRTUALTARGET) +#define BRS_START_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +/*****************************************************************************/ +/* @brief Unified routine for Pre Main() Startup. + * @pre Stack pointer needs to be initilialized in StartUpCode before. + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from assembler startup code. + * Called by all cores from the booting execution instance. + * Through Brs_MemMap.h, the API is mapped into section + * brsMainStartup, which allows a fix memory allocation. + *****************************************************************************/ +void Brs_PreMainStartup(void); /* implemented in BrsMainStartup.c */ +#define BRS_STOP_SEC_STARTUP_CODE +#include "Brs_MemMap.h" + +#define BRS_START_SEC_BRSAPPLENTRY_CODE +#include "Brs_MemMap.h" +/*****************************************************************************/ +/* @brief Unified application entry for Pre Main() Startup. + * @pre Stack pointer needs to be initilialized in StartUpCode before, + * brsMain_ResetReason needs to be initialized by booting execution + * instance (see Brs_PreMainStartup()). + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from Brs_PreMainStartup() of the booting + * execution instance or is the direct application entry of + * non-booting execution instances (e.g. FBL, with a previously + * running BootManager). Through Brs_MemMap.h, the API is mapped + * into section brsApplicationEntry, which allows a fix memory + * allocation. All APIs are called with current Core ID. + *****************************************************************************/ +void Brs_ApplicationEntry(void); /* implemented in BrsMainStartup.c */ +#define BRS_STOP_SEC_BRSAPPLENTRY_CODE +#include "Brs_MemMap.h" + +# if defined (BRS_ENABLE_SUPPORT_LEDS) +void BrsMainWrapperTogglePinLED(void); /* implemented in BrsMain.c */ +# endif +# if defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN) +void BrsMainWrapperTogglePinWD(void); /* implemented in BrsMain.c */ +# endif +# if defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN) +void BrsMainWrapperTogglePinCustom(void); /* implemented in BrsMain.c */ +# endif +#endif /* !VVIRTUALTARGET */ + +/*****************************************************************************/ +/* @brief Main initialization routine. + * Contains configuration specific initialization of BrsHw parts + * and BrsMain specific mechanisms. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from main + *****************************************************************************/ +void BrsMainInit(void); + +#if !defined (VVIRTUALTARGET) +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage zero. + *****************************************************************************/ +void BrsMain_MemoryInit_StageZero_Hook(uint32 coreId); /* implemented in BrsMain_Callout_Stubs.c */ + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage hard reset. + *****************************************************************************/ +void BrsMain_MemoryInit_StageHardReset_Hook(uint32 coreId); /* implemented in BrsMain_Callout_Stubs.c */ + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage one. + *****************************************************************************/ +void BrsMain_MemoryInit_StageOne_Hook(uint32 coreId); /* implemented in BrsMain_Callout_Stubs.c */ + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage two. + *****************************************************************************/ +void BrsMain_MemoryInit_StageTwo_Hook(uint32 coreId); /* implemented in BrsMain_Callout_Stubs.c */ + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage three. + *****************************************************************************/ +void BrsMain_MemoryInit_StageThree_Hook(uint32 coreId); /* implemented in BrsMain_Callout_Stubs.c */ + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * previous to the memory initialization, stage Power_On. + *****************************************************************************/ +void BrsMain_MemoryInit_StagePowerOn_Hook(uint32 coreId); /* implemented in BrsMain_Callout_Stubs.c */ + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] coreID must declare the ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from Brs_ApplicationEntry() during StartUp, + * after the memory initialization was done. + *****************************************************************************/ +void BrsMain_PreMainHook(uint32 coreId); /* implemented in BrsMain_Callout_Stubs.c */ + +/*****************************************************************************/ +/* @brief This API is an optional callout + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from BrsHwSoftwareResetECU(), before a + * SW reset is triggered. Implement code here to also reset + * peripherals, if necessary for your UseCase. + *****************************************************************************/ +void BrsMain_SoftwareResetECU_Hook(void); /* implemented in BrsMain_Callout_Stubs.c */ + +/*****************************************************************************/ +/* @brief This API is mandatory callout, if non-ASR cores are configured in OS. + * Project specific implementation for non-ASR cores should be added here. + * @pre non-ASR cores are configured in OS + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from main() for non-Autosar-cores. + *****************************************************************************/ +void BrsMain_NonAsrCore_Hook(void); /* implemented in BrsMain_Callout_Stubs.c */ +#endif /* !VVIRTUALTARGET */ + +#if defined (BRS_ENABLE_1MS_HANDLER) +/*****************************************************************************/ +/* @brief Routine to register cyclic callbacks. + * @pre Initialization of BrsMain was done threw call of BrsMainInit(). + * @param[in] FunctionPointer has to be a pointer to a function of type + * void function(void). + * @param[in] Cycletime described the cycletime, the callback should be triggered. + * @param[out] - + * @return - + * @context Function is called from modules that need cyclic callbacks. + *****************************************************************************/ +void BrsMainRegisterCyclic(void (*FunctionPointer)(void), brsMain_Cyclic_Cycletime Cycletime); + +/*****************************************************************************/ +/* @brief One millisecond handler for BrsMain + * - Executes retransmission of BRS TCC messages + * - Toggling of LED (alive signal) + * - BRS Test code (1s cyclic negative TCC response message) + * @pre Initialization of BrsMain was done threw call of BrsMainInit(). + * @param[in] - + * @param[out] - + * @return - + * @context Function is called each millisecond either from the main loop + * or from the BRS main task (TASK(mainTask)) + *****************************************************************************/ +void BrsMainCyclic1ms(void); + +# if !defined (BRS_DISABLE_OS_USAGE) && (!defined (BRS_ENABLE_OS_INTERRUPT_ONLY)) +TASK(BrsMainTask); +TASK(BrsMainBackgroundTask); +# endif +#endif + +#if !defined (BRS_DISABLE_OS_USAGE) && (!defined (BRS_ENABLE_OS_INTERRUPT_ONLY)) +TASK(Default_Init_Task); +TASK(Default_Init_Task_Trusted); + +#endif /* !BRS_DISABLE_OS_USAGE && !BRS_ENABLE_OS_INTERRUPT_ONLY */ + +#if defined (BRS_ENABLE_SUPPORT_LEDS) || \ + defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN) || \ + defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN) +typedef enum +{ + BRSMAIN_TOGGLEPIN_LED, + BRSMAIN_TOGGLEPIN_WD, + BRSMAIN_TOGGLEPIN_CUSTOM +} brsMain_TogglePin; + +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_START_SEC_RAM_CODE + #include "Brs_MemMap.h" +# endif +/*****************************************************************************/ +/* @brief This API is used to toggle a PortPin. + * Per default, the following parameters are available: + * BRSMAIN_TOGGLEPIN_LED + * BRSMAIN_TOGGLEPIN_WD + * BRSMAIN_TOGGLEPIN_CUSTOM + * Depending pins must be configured and initialized within BrsHw. + * @pre - + * @param[in] Pin to be toggled + * @param[out] - + * @return - + * @context Function is called from all modules to set or clear a PortPin + *****************************************************************************/ +void BrsMainTogglePin(brsMain_TogglePin Pin); +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_STOP_SEC_RAM_CODE + #include "Brs_MemMap.h" +# endif +#endif /* BRS_ENABLE_SUPPORT_LEDS || BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN || BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN */ + +#if defined (BRS_ENABLE_FBL_SUPPORT) || defined (BRS_ENABLE_HSM_UPDATER_SUPPORT) + #define BRS_START_SEC_RAM_CODE + #include "Brs_MemMap.h" +#endif +void BrsMainExceptionHandler(uint8 ErrorCode, uint8 ModuleCode, uint16 LineNumber); +#if defined (BRS_ENABLE_FBL_SUPPORT) || defined (BRS_ENABLE_HSM_UPDATER_SUPPORT) + #define BRS_STOP_SEC_RAM_CODE + #include "Brs_MemMap.h" +#endif + +#if !defined (VVIRTUALTARGET) +# if defined (BRS_FIRST_EXECUTION_INSTANCE) +/* This code is only needed for the first instance in the system */ +#define BRS_START_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +/*****************************************************************************/ +/* @brief This is the central exeption/issue handler of BRS, in startup + * phase. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context This function implements an endless loop. The recommendation is + * to set a breakpoint on top of this function to see if any check + * has failed during the startup code execution. + *****************************************************************************/ +void BrsMainExceptionStartup(void); +#define BRS_STOP_SEC_STARTUP_CODE +#include "Brs_MemMap.h" +# endif /* BRS_FIRST_EXECUTION_INSTANCE */ + +/*****************************************************************************/ +/* @brief Get reset reason + * @pre BrsHwGetResetReasonStartup() is called first and the rest reason + * is saved in global variable brsMain_ResetReason. + * @param[in] - + * @param[out] - + * @return Reset reason + * @context This is a wrapper function for previous BrsHwGetResetReason(). + * This is to prevent multiple selection of reset reason + * registers, as this is not supported on all platforms. + * The HW registers for the reset reason are evaluated via a call + * of BrsHwGetResetReasonStartup() in Brs_PreMainStartup(). + * The result is stored by BrsMainStartup in the global variable + * brsMain_ResetReason. + *****************************************************************************/ +brsMain_ResetReasonType BrsMainGetResetReason(void); + +int main(void); +#endif /* !VVIRTUALTARGET */ + +#if defined (BRS_ENABLE_OS_INTERRUPT_ONLY) +void BrsMainSuspendAllInterrupts(void); +void BrsMainResumeAllInterrupts(void); +#endif + +#endif /* _BRSMAIN_H_ */ diff --git a/Source/include/BrsMain_Appl.h b/Source/include/BrsMain_Appl.h new file mode 100644 index 0000000..c4cdd1d --- /dev/null +++ b/Source/include/BrsMain_Appl.h @@ -0,0 +1,359 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsMain_Appl.h + * Project: Vector Basic Runtime System + * Module: BrsMain + * + * \brief Description: Header of additional, Application-specific, implementation + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to BrsMain.h. + *********************************************************************************************************************/ + +#ifndef _BRSMAIN_APPL_H_ +#define _BRSMAIN_APPL_H_ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ +#include "BrsMain.h" + +#if defined (BRS_ENABLE_TESTSUITE_SUPPORT) + #include "BrsTestsuite.h" +#endif + +#if !defined (BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING) +# if defined (BRS_ENABLE_CAN_SUPPORT) +# if defined (BRS_ENABLE_CAN_CORE_SUPPORT) + #include "Can_30_Core.h" + +# if defined (VVIRTUALTARGET) +# if defined (DRVCAN_CANOEEMUCANOEASR_VERSION) + /* + * Combination of CanGen3 HW driver with CanGen2 VTT driver detected. Special exclusive area handling should be + * disabled + */ + #define BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING +# endif +# else + #include BRS_DRVCAN_HEADER_FILENAME +# endif + +# elif defined (BRS_ENABLE_CAN_CLASSIC_SUPPORT) + /* Just a check to verify, if either CAN_Classic or CAN_Core is active with CAN support enabled */ + +# else + #error "Neither a classic DrvCan nor a Can_30_Core DrvCan was detected, but DrvCan support is enabled. There seems to be something seems wrong here!" +# endif /* BRS_ENABLE_CAN_X_SUPPORT */ +# endif /* BRS_ENABLE_CAN_SUPPORT */ +#endif /* BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING */ + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL TYPE DEFINITIONS + *********************************************************************************************************************/ +#if !defined (BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING) && defined (BRS_ENABLE_CAN_SUPPORT) && \ + defined (BRS_ENABLE_CAN_CORE_SUPPORT) +# if defined (CAN_30_CORE_COREVERSION) +# if (CAN_30_CORE_COREVERSION >= 0x0203u) + #define BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP /* include "Can_30_Core_MemMap.h" instead of "MemMap.h" */ +# endif +# elif defined (CAN_30_CORE_SW_MAJOR_VERSION) + #define BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP /* include "Can_30_Core_MemMap.h" instead of "MemMap.h" */ +# else + #error "Detection of Can_30_Core driver version was not possible. Please configure here manually the valid MemMap header of the module." +# endif +#endif + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ +/*****************************************************************************/ +/* @brief Main initialization routine. + * Contains configuration specific initialization of BrsHw parts + * and BrsMain specific mechanisms. + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is called from main + *****************************************************************************/ +void BrsMain_Appl_Init(void); + +#if defined (BRS_ENABLE_SCHM_STUB_GENERATION) +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_START_SEC_RAM_CODE + #include "Brs_MemMap.h" +# endif +/*****************************************************************************/ +/* @brief Suspend all interrupts via OS call + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is used for SchM_Enter_* defines in vBrs generated + * SchM stub module specific header files. This allows the user to + * add project specific code. As default, SuspendAllInterrupts() is + * defined empty within BrsMain provided Os.h stub for delieveries + * w/o OS (no interrupt locking needed in polling environments) + *****************************************************************************/ +void BrsMain_Appl_SuspendAllInterrupts(void); + +/*****************************************************************************/ +/* @brief Resume all interrupts via OS call + * @pre - + * @param[in] - + * @param[out] - + * @return - + * @context Function is used for SchM_Exit_* defines in vBrs generated + * SchM stub module specific header files. This allows the user to + * add project specific code. As default, ResumeAllInterrupts() is + * defined empty within BrsMain provided Os.h stub for delieveries + * w/o OS (no interrupt locking needed in polling environments) + *****************************************************************************/ +void BrsMain_Appl_ResumeAllInterrupts(void); +# if defined (BRS_ENABLE_FBL_SUPPORT) + #define BRS_STOP_SEC_RAM_CODE + #include "Brs_MemMap.h" +# endif +#endif /* BRS_ENABLE_SCHM_STUB_GENERATION */ + +#if defined (BRS_ENABLE_HYPERVISOR_SUPPORT) +/*****************************************************************************/ +/* @brief Callout to let the additional configured cores started by the + * boot core, if necessary. This is just an initial template and + * may need project specific adaptions. It's called by every core. + * @pre - + * @param[in] coreID is the physical core ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from main, previously to vHyp_Init() + *****************************************************************************/ +void BrsMain_Appl_HypervisorStartCoreApi(uint32 coreID); + +/*****************************************************************************/ +/* @brief Callout to implement user code previous to the call of + * vHyp_Start(). This is just an initial template and may need + * project specific adaptions. It's called by every core. + * @pre - + * @param[in] coreID is the physical core ID of the actual running core + * @param[out] - + * @return - + * @context Function is called from main, previously to vHyp_Start() + *****************************************************************************/ +void BrsMain_Appl_HypervisorApi(uint32 coreID); +#endif + +#if !defined (BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING) +# if defined (BRS_ENABLE_CAN_SUPPORT) +# if defined (BRS_ENABLE_CAN_CLASSIC_SUPPORT) +/********************************************************************************************************************** + * A classic (non-Gen3) DrvCan is part of the configuration. "Oldschool" implementation is needed + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * UserDefined ExclusiveArea handling for CAN channels, according to AN-ISC-8-1149_ErrorHook_E_OS_DISABLED_INT.pdf + *********************************************************************************************************************/ +/* Macro is generated in vBrsCfg.h, to support drivers with infix. + Sample w/o infix: void SchM_Enter_Can_CAN_EXCLUSIVE_AREA_0(void) + Can_DisableControllerInterrupts(0u); + Sample w/ infix: void SchM_Enter_Can_30_Mcan_CAN_30_MCAN_EXCLUSIVE_AREA_0(void) + Can_30_Mcan_DisableControllerInterrupts(0u);*/ + +#define CAN_START_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Enter, EXCLUSIVE_AREA_0); +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Exit, EXCLUSIVE_AREA_0); +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Enter, EXCLUSIVE_AREA_6); +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Exit, EXCLUSIVE_AREA_6); +#define CAN_STOP_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" + +# if !defined (BRS_ENABLE_FBL_SUPPORT) +#define CANIF_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_CanIf_CANIF_EXCLUSIVE_AREA_0(void); +void SchM_Exit_CanIf_CANIF_EXCLUSIVE_AREA_0(void); +#define CANIF_STOP_SEC_CODE +#include "MemMap.h" + +#define CANSM_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_CanSM_CANSM_EXCLUSIVE_AREA_4(void); +void SchM_Exit_CanSM_CANSM_EXCLUSIVE_AREA_4(void); +void SchM_Enter_CanSM_CANSM_EXCLUSIVE_AREA_1(void); +void SchM_Exit_CanSM_CANSM_EXCLUSIVE_AREA_1(void); +#define CANSM_STOP_SEC_CODE +#include "MemMap.h" + +#define COMM_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_ComM_COMM_EXCLUSIVE_AREA_1(void); +void SchM_Exit_ComM_COMM_EXCLUSIVE_AREA_1(void); +#define COMM_STOP_SEC_CODE +#include "MemMap.h" +# endif /* !BRS_ENABLE_FBL_SUPPORT */ +# endif /* BRS_ENABLE_CAN_CLASSIC_SUPPORT */ + +# if defined (BRS_ENABLE_CAN_CORE_SUPPORT) +/********************************************************************************************************************** + * A new (Gen3) DrvCan is part of the configuration. New implementation is needed + *********************************************************************************************************************/ +# if (Can_30_Core_IsHardwareCancelByApplOfGeneralFeature(0u) && Can_30_Core_IsHardwareLoopCheckOfGeneralFeature(0u)) + +# if !defined (BRS_ENABLE_FBL_SUPPORT) + /* Within a FBL project, depending APIs are already available within Fbl_cw.c */ +/********************************************************************************************************************** + * Hardware Loop Check / Timeout Monitoring for CAN Driver, according to TechnicalReference_Can_30_Core.pdf, + * chapter 2.8.2 + *********************************************************************************************************************/ +#define CAN_30_CORE_START_SEC_CODE +# if defined (BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP) + #include "Can_30_Core_MemMap.h" +# else + #include "MemMap.h" +# endif +void Appl_30_CoreCanTimerStart(uint8 Controller, uint8 source); +void Appl_30_CoreCanTimerEnd(uint8 Controller, uint8 source); +Can_ReturnType Appl_30_CoreCanTimerLoop(uint8 Controller, uint8 source); +#define CAN_30_CORE_STOP_SEC_CODE +# if defined (BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP) + #include "Can_30_Core_MemMap.h" +# else + #include "MemMap.h" +# endif +# endif /* !BRS_ENABLE_FBL_SUPPORT */ + +# else +/********************************************************************************************************************** + * UserDefined ExclusiveArea handling for CAN Driver Core, according to TechnicalReference_Can_30_Core.pdf, Note within + * chapter 3.2 + *********************************************************************************************************************/ +#define CAN_30_CORE_START_SEC_CODE +# if defined (BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP) + #include "Can_30_Core_MemMap.h" +# else + #include "MemMap.h" +# endif +void SchM_Enter_Can_30_Core_CAN_30_CORE_EXCLUSIVE_AREA_6(void); +void SchM_Exit_Can_30_Core_CAN_30_CORE_EXCLUSIVE_AREA_6(void); +#define CAN_30_CORE_STOP_SEC_CODE +# if defined (BRSMAIN_CAN_30_CORE_SPECIFIC_MEMMAP) + #include "Can_30_Core_MemMap.h" +# else + #include "MemMap.h" +# endif + +# if !defined (BRS_ENABLE_CAN_CLASSIC_SUPPORT) +/********************************************************************************************************************** + * UserDefined ExclusiveArea handling for vCAN Driver, according to TechnicalReference_vCan_30_Mcan.pdf, Note within + * chapter 3.2 + *********************************************************************************************************************/ +#define CAN_START_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Enter,EXCLUSIVE_AREA_0); +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Exit,EXCLUSIVE_AREA_0); +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Enter,EXCLUSIVE_AREA_1); +BRS_DRVCAN_EXCLUSIVE_AREA_INFIX(Exit,EXCLUSIVE_AREA_1); +#define CAN_STOP_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" +# endif /* !BRS_ENABLE_CAN_CLASSIC_SUPPORT */ + +# if defined (BRS_DRVCAN1_HEADER_FILENAME) + /* 2nd DrvCan instance detected */ +#define CAN1_START_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" +BRS_DRVCAN1_EXCLUSIVE_AREA_INFIX(Enter,EXCLUSIVE_AREA_0); +BRS_DRVCAN1_EXCLUSIVE_AREA_INFIX(Exit,EXCLUSIVE_AREA_0); +BRS_DRVCAN1_EXCLUSIVE_AREA_INFIX(Enter,EXCLUSIVE_AREA_1); +BRS_DRVCAN1_EXCLUSIVE_AREA_INFIX(Exit,EXCLUSIVE_AREA_1); +#define CAN1_STOP_SEC_CODE +/* +* to support CAN driver name infix, vBRS generator provides a wrapper +* for usage of the driver specific MemMap.h define in vBrsCfg.h +*/ +#include "vBrsCfg.h" +# endif /* BRS_DRVCAN1_HEADER_FILENAME */ + +# if !defined (BRS_ENABLE_FBL_SUPPORT) +# if !defined (BRS_ENABLE_CAN_CLASSIC_SUPPORT) +#define CANIF_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_CanIf_CANIF_EXCLUSIVE_AREA_0(void); +void SchM_Exit_CanIf_CANIF_EXCLUSIVE_AREA_0(void); +#define CANIF_STOP_SEC_CODE +#include "MemMap.h" + +#define CANSM_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_CanSM_CANSM_EXCLUSIVE_AREA_4(void); +void SchM_Exit_CanSM_CANSM_EXCLUSIVE_AREA_4(void); +void SchM_Enter_CanSM_CANSM_EXCLUSIVE_AREA_1(void); +void SchM_Exit_CanSM_CANSM_EXCLUSIVE_AREA_1(void); +#define CANSM_STOP_SEC_CODE +#include "MemMap.h" + +#define COMM_START_SEC_CODE +#include "MemMap.h" +void SchM_Enter_ComM_COMM_EXCLUSIVE_AREA_1(void); +void SchM_Exit_ComM_COMM_EXCLUSIVE_AREA_1(void); +#define COMM_STOP_SEC_CODE +#include "MemMap.h" +# endif /* !BRS_ENABLE_CAN_CLASSIC_SUPPORT */ +# endif /* !BRS_ENABLE_FBL_SUPPORT */ +# endif /* Can_30_Core_IsHardwareCancelByApplOfGeneralFeature(0u) && + Can_30_Core_IsHardwareLoopCheckOfGeneralFeature(0u) */ +# endif /* BRS_ENABLE_CAN_CORE_SUPPORT */ +# endif /* BRS_ENABLE_CAN_SUPPORT */ +#endif /* !BRSMAINAPPL_DISABLE_CAN_EXCLUSIVEAREA_HANDLING */ +#endif /* _BRSMAIN_APPL_H_ */ diff --git a/Source/include/BrsMain_Cfg.h b/Source/include/BrsMain_Cfg.h new file mode 100644 index 0000000..a25bb60 --- /dev/null +++ b/Source/include/BrsMain_Cfg.h @@ -0,0 +1,78 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsMain_Cfg.h + * Project: Vector Basic Runtime System + * Module: BrsMain + * + * \brief Description: Vector Basic Runtime System config header for BrsMain user optimizations. + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to BrsMain.h. + *********************************************************************************************************************/ + +#ifndef _BRSMAIN_CFG_H_ +#define _BRSMAIN_CFG_H_ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * MODULE VERSION + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL TYPE DEFINITIONS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ +#if !defined (BRSMAIN_MEMINIT_FUNC_PREFIX) +# if defined (BRS_COMP_LLVMHIGHTEC) + /* + * LlvmHighTec compiler is automatically inlining the memory init helper functions (Brs_MemoryZeroInit(), + * Brs_MemoryInit()). + * This is causing the section .brsApplicationEntry to increase a lot for this specific compiler. + * To prevent this, we add the attribute noinline to the function definitions + */ + #define BRSMAIN_MEMINIT_FUNC_PREFIX __attribute__((noinline)) + +# else + /* If no specific function prefix is defined, make it an empty definition */ + #define BRSMAIN_MEMINIT_FUNC_PREFIX +# endif +#endif + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#endif /* _BRSMAIN_CFG_H_ */ diff --git a/Source/include/BrsMain_Types.h b/Source/include/BrsMain_Types.h new file mode 100644 index 0000000..4b1192c --- /dev/null +++ b/Source/include/BrsMain_Types.h @@ -0,0 +1,108 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: BrsMain_Types.h + * Project: Vector Basic Runtime System + * Module: BrsMain + * + * \brief Description: Vector Basic Runtime System types header for vBrs generated structures. + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to BrsMain.h. + *********************************************************************************************************************/ + +#ifndef _BRSMAIN_TYPES_H_ +#define _BRSMAIN_TYPES_H_ + +/********************************************************************************************************************** + * INCLUDES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * MODULE VERSION + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL TYPE DEFINITIONS + *********************************************************************************************************************/ +typedef enum +{ + NON_ASR = 0, /* No Autosar OS is configured for this core */ + ASR = 4096 /* An Autosar OS is configured for this core */ +} brsCoreAsrType; + +/* Data type for readable addresses. */ +typedef P2CONST(void, TYPEDEF, AUTOMATIC) Brs_AddressOfConstType; + +#define BRS_DEFINE_ADDRESS_UNUSED (Brs_AddressOfConstType)0xFFFFFFFF + +/* Allocation of physical core to logical cores of a system. */ +typedef struct +{ + /* Logical Id of configured core. */ + uint32 LogicalCoreId; + + /* Phyiscal Id of configured core. */ + uint32 PhysicalCoreId; + + /* End label of the startup stack. */ + Brs_AddressOfConstType StartupStackEndLabel; + + /* startup stack size */ + uint32 StartupStackSize; + + /* Reflects if core is an AUTOSAR core. */ + brsCoreAsrType CoreIsAsr; + + /* Start label of the exception vector table. */ + Brs_AddressOfConstType ExcVecLabel; + + /* Start label of the interrupt vector table. */ + Brs_AddressOfConstType IntVecLabel; +} brsMain_CoreType; + +/* +* Reset reason, mainly used by BrsHwGetResetReason(). +* Necessary to e.g. identify hard reset during memory initialization in BrsMainStartup. +*/ +typedef enum +{ + BRSMAIN_RESET_SW, + BRSMAIN_RESET_OTHER +} brsMain_ResetReasonType; + +/********************************************************************************************************************** + * GLOBAL CONSTANT MACROS + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL VARIABLES + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + *********************************************************************************************************************/ + +#endif /* _BRSMAIN_TYPES_H_ */ diff --git a/Source/include/Brs_MemMap.h b/Source/include/Brs_MemMap.h new file mode 100644 index 0000000..81e1b3a --- /dev/null +++ b/Source/include/Brs_MemMap.h @@ -0,0 +1,350 @@ +/********************************************************************************************************************** + * COPYRIGHT + * ------------------------------------------------------------------------------------------------------------------- + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + * ------------------------------------------------------------------------------------------------------------------- + * FILE DESCRIPTION + * -----------------------------------------------------------------------------------------------------------------*/ +/** \file File: Brs_MemMap.h + * Project: Vector Basic Runtime System + * Module: BrsMain + * + * \brief Description: Module specific MemMap Header to allow linking of specific parts of BRS into specific + * memory sections. + * + * \attention Please note: + * The demo and example programs only show special aspects of the software. With regard to the fact + * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be + * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * REVISION HISTORY + * ------------------------------------------------------------------------------------------------------------------- + * Refer to BrsMain.h. + *********************************************************************************************************************/ + +#ifndef BRS_MEMMAP_ERROR + #define BRS_MEMMAP_ERROR +#endif + +#if defined (VVIRTUALTARGET) + /* + * VTT/CANoeEmu is supporting ANSI/GNU/CLANG as compiler values, but does not contain a Makefile which sets + * BRS_COMP_ + */ + /* + * The vVIRTUALtarget ANSI compiler options do not even support #warning: + * fatal error C1021: invalid preprocessor command 'warning' + * So no warnings show up for this compiler on this platform + */ +/* vVIRTUALtarget build settings: Windows x86/x64, Visual Studio */ +# if defined (_MICROSOFT_C_VTT_) + #define BRS_COMP_ANSI +/* vVIRTUALtarget build settings: Windows x86, CMake / MinGW-w64 */ +# elif defined (__MINGW32__) + #define BRS_COMP_GCCGNU +/* vVIRTUALtarget build settings: Linux, CMake / Clang */ +# elif defined (__clang__) + #define BRS_COMP_ARM6 +# endif +#endif + +/********************************************************************************************************************** + * CONFIGURATION CHECK + *********************************************************************************************************************/ +#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + +#else + #error "Unknown compiler specified! Pragmas for mapping into specific sections not yet implemented for your compiler." +#endif + +/********************************************************************************************************************** + * CODE sections + *********************************************************************************************************************/ + +/*****************************************************************************/ +/* StartupCode part, located in BrsMain, which is only used by first execution + * instance (e.g. Brs_PreMainStartup()) + *****************************************************************************/ +#ifdef BRS_START_SEC_STARTUP_CODE +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section text = ".brsMainStartup" + +# endif + + #undef BRS_START_SEC_STARTUP_CODE + #undef BRS_MEMMAP_ERROR +#endif + +#ifdef BRS_STOP_SEC_STARTUP_CODE +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section text = "" + +# endif + + #undef BRS_STOP_SEC_STARTUP_CODE + #undef BRS_MEMMAP_ERROR +#endif + +/*****************************************************************************/ +/* Brs_ApplicationEntry section, located in BrsMainStartup, which is used by + * every execution instance (Brs_ApplicationEntry()). This allows a fix + * address of application entry, needed by some bootloader use-cases. + *****************************************************************************/ +#ifdef BRS_START_SEC_BRSAPPLENTRY_CODE +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section text = ".brsApplicationEntry" + +# endif + + #undef BRS_START_SEC_BRSAPPLENTRY_CODE + #undef BRS_MEMMAP_ERROR +#endif + +#ifdef BRS_STOP_SEC_BRSAPPLENTRY_CODE +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section text = "" + +# endif + + #undef BRS_STOP_SEC_BRSAPPLENTRY_CODE + #undef BRS_MEMMAP_ERROR +#endif + +/*****************************************************************************/ +/* Code Exception table, configured during startup from first execution + * instance (on platforms, where exception table is code) + *****************************************************************************/ +#ifdef BRS_START_SEC_EXCVECT_CODE +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section text = ".brsExcVect" + +# endif + + #undef BRS_START_SEC_EXCVECT_CODE + #undef BRS_MEMMAP_ERROR +#endif + +#ifdef BRS_STOP_SEC_EXCVECT_CODE +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section text = "" + +# endif + + #undef BRS_STOP_SEC_EXCVECT_CODE + #undef BRS_MEMMAP_ERROR +#endif + +/*****************************************************************************/ +/* Code Exception table that is located in RAM, configured from FBL execution + * instance (on platforms, where exception table is code) + *****************************************************************************/ +#ifdef BRS_START_SEC_EXCVECTRAM_CODE +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section text = ".brsExcVectRam" + +# endif + + #undef BRS_START_SEC_EXCVECTRAM_CODE + #undef BRS_MEMMAP_ERROR +#endif + +#ifdef BRS_STOP_SEC_EXCVECTRAM_CODE +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section text = "" + +# endif + + #undef BRS_STOP_SEC_EXCVECTRAM_CODE + #undef BRS_MEMMAP_ERROR +#endif + +/*****************************************************************************/ +/* FBL/HSM_Updater specific section, to copy parts of BRS into RAM + * (everything, that is needed during re-flashing) + *****************************************************************************/ +#ifdef BRS_START_SEC_RAM_CODE +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section text = ".RamCodeSection" + +# endif + + #undef BRS_START_SEC_RAM_CODE + #undef BRS_MEMMAP_ERROR +#endif + +#ifdef BRS_STOP_SEC_RAM_CODE +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section text = "" + +# endif + + #undef BRS_STOP_SEC_RAM_CODE + #undef BRS_MEMMAP_ERROR +#endif + +/********************************************************************************************************************** + * CONST sections + *********************************************************************************************************************/ + +/*****************************************************************************/ +/* Constants, that are shared between several execution instances + *****************************************************************************/ +#ifdef BRS_START_SEC_SHARED_CONST +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section rodata = ".brsSharedConst" + +# endif + + #undef BRS_START_SEC_SHARED_CONST + #undef BRS_MEMMAP_ERROR +#endif + +#ifdef BRS_STOP_SEC_SHARED_CONST +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section rodata = "" + +# endif + + #undef BRS_STOP_SEC_SHARED_CONST + #undef BRS_MEMMAP_ERROR +#endif + +/*****************************************************************************/ +/* Const Exception table, configured during startup from first execution + * instance (on platforms, where exception table is const) + *****************************************************************************/ +#ifdef BRS_START_SEC_EXCVECT_CONST +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section rodata = ".brsExcVectConst" + +# endif + + #undef BRS_START_SEC_EXCVECT_CONST + #undef BRS_MEMMAP_ERROR +#endif + +#ifdef BRS_STOP_SEC_EXCVECT_CONST +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section rodata = "" + +# endif + + #undef BRS_STOP_SEC_EXCVECT_CONST + #undef BRS_MEMMAP_ERROR +#endif + +/*****************************************************************************/ +/* Const Exception table that is located in RAM, configured from FBL execution + * instance (on platforms, where exception table is const) + *****************************************************************************/ +#ifdef BRS_START_SEC_EXCVECTRAM_CONST +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section rodata = ".brsExcVectRamConst" + +# endif + + #undef BRS_START_SEC_EXCVECTRAM_CONST + #undef BRS_MEMMAP_ERROR +#endif + +#ifdef BRS_STOP_SEC_EXCVECTRAM_CONST +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section rodata = "" + +# endif + + #undef BRS_STOP_SEC_EXCVECTRAM_CONST + #undef BRS_MEMMAP_ERROR +#endif + +/*****************************************************************************/ +/* FBL/HSM_Updater specific section, to copy parts of BRS into RAM + * (everything, that is needed during re-flashing) + *****************************************************************************/ +#ifdef BRS_START_SEC_RAM_CONST +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section rodata = ".RamConstSection" + +# endif + + #undef BRS_START_SEC_RAM_CONST + #undef BRS_MEMMAP_ERROR +#endif + +#ifdef BRS_STOP_SEC_RAM_CONST +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section rodata = "" + +# endif + + #undef BRS_STOP_SEC_RAM_CONST + #undef BRS_MEMMAP_ERROR +#endif + +#if defined (BRS_ENABLE_FBL_SUPPORT) +# if defined (BRS_FBL_INSTANCE_FBL) +/*****************************************************************************/ +/* FBL specific section to store the FBL instance presence pattern into a + * dedicated section + *****************************************************************************/ +# ifdef BRS_START_SEC_FBL_PP_CONST +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section rodata = ".FblPresencePatternSection" + +# endif + + #undef BRS_START_SEC_FBL_PP_CONST + #undef BRS_MEMMAP_ERROR +# endif + +# ifdef BRS_STOP_SEC_FBL_PP_CONST +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section rodata = "" + +# endif + + #undef BRS_STOP_SEC_FBL_PP_CONST + #undef BRS_MEMMAP_ERROR +# endif +# endif /* BRS_FBL_INSTANCE_FBL */ +#endif /* BRS_ENABLE_FBL_SUPPORT */ + +/********************************************************************************************************************** + * VAR sections + *********************************************************************************************************************/ + +/*****************************************************************************/ +/* Variables, that are shared between several execution instances + * (e.g. brsMain_ResetReason) + *****************************************************************************/ +#ifdef BRS_START_SEC_SHARED_VAR +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section bss = ".brsSharedVar" + +# endif + + #undef BRS_START_SEC_SHARED_VAR + #undef BRS_MEMMAP_ERROR +# endif + +#ifdef BRS_STOP_SEC_SHARED_VAR +# if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) + #pragma clang section bss = "" + +# endif + + #undef BRS_STOP_SEC_SHARED_VAR + #undef BRS_MEMMAP_ERROR +#endif + +#if defined (BRS_MEMMAP_ERROR) + #error "Error in Brs_MemMap.h: MemMap section is not included!" +#endif diff --git a/Source/include/bm_ap.h b/Source/include/bm_ap.h new file mode 100644 index 0000000..01c5545 --- /dev/null +++ b/Source/include/bm_ap.h @@ -0,0 +1,203 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Application dependent routines + * + * \note Please note, that this file contains a collection of callback functions to be used with the + * Flash Bootloader. These functions may influence the behavior of the bootloader in principle. + * Therefore, great care must be taken to verify the correctness of the implementation. + * The contents of the originally delivered files are only examples resp. implementation proposals. + * With regard to the fact that these functions are meant for demonstration purposes only, Vector + * Informatik's liability shall be expressly excluded in cases of ordinary negligence, to the extent + * admissible by law or statute. + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2019-01-28 visrie - Initial version + * 01.01.00 2019-02-18 vismvi ESCAN00102171 No changes + * visrie ESCAN00102310 Added callout to check reprogramming flag + * 01.01.01 2019-03-07 visrie ESCAN00102386 No changes + * ESCAN00102399 No changes + * 02.00.00 2019-05-02 visrie ESCAN00102518 No changes + * ESCAN00102761 No changes + * ESCAN00103026 Provide BmHeader instead of StartAddress to ApplFblBmStartSoftware + * 03.00.00 2019-07-17 visrie ESCAN00103750 Removed target order list configuration + * 03.01.00 2019-08-14 visrie FBL-487 Exclude callouts if overwritten by OEM/HW layer + * 03.01.01 2019-09-04 visrcn ESCAN00103607 Memory qualifier mismatch + * 04.00.00 2019-12-04 visrie FBL-456 No changes + * ESCAN00105135 No changes + * 04.01.00 2020-01-16 visrie FBL-524 Added support for vHsm SecBoot library + * 05.00.00 2020-04-09 visrie FBL-1016 No changes + * 05.01.00 2020-04-29 vistmo FBL-1584 No changes + * 05.02.00 2020-08-13 vistmo FBL-1489 No changes + * 05.02.01 2021-03-17 vishor ESCAN00108386 No changes + * FBL-3018 Added/adapted MemMap sections + * 05.03.00 2021-08-11 visrie FBL-3394 Move default implementation of CheckReprogFlag into FblBm_Ap + * 05.04.00 2021-09-17 visjdn FBL-3865 No changes + * 05.04.01 2022-04-06 vismix FBL-4773 No changes + * 05.05.00 2022-04-07 vishor FBL-4822 No changes + * 05.05.01 2022-06-23 vismix ESCAN00111879 No changes + * 05.06.00 2022-07-13 vismix FBL-5391 Add callout for missing optional dependency + * 05.06.01 2022-11-29 vishor ESCAN00112986 Compiler error: Undefined symbols + * ApplFblPreMemDriver/ApplFblPostMemDriver + * 05.07.00 2023-06-29 vistbe FBL-7052 No changes + * 05.07.01 2023-12-18 visrie ESCAN00104829 No changes + * ESCAN00111036 No changes + * ESCAN00115752 No changes + * 05.08.00 2024-05-16 vishor FBL-8602 Add support for OEM updater solution + * 05.09.00 2025-05-23 dganesh FBL-9715 Extend presence pattern to connect validity information + **********************************************************************************************************************/ + +#ifndef BM_AP_H +#define BM_AP_H + +/*********************************************************************************************************************** + * VERSION + **********************************************************************************************************************/ + +/* ##V_CFG_MANAGEMENT ##CQProject : FblBm_Ap CQComponent : Implementation */ +#define FBLBM_AP_VERSION 0x0509u +#define FBLBM_AP_RELEASE_VERSION 0x00u + +/* Interface version */ +/** Major interface version identifies incompatible changes */ +#define FBLBM_AP_API_VERSION_MAJOR 0x03u +/** Minor interface version identifies backward compatible changes */ +#define FBLBM_AP_API_VERSION_MINOR 0x00u +/** Release interface version identifies cosmetic changes */ +#define FBLBM_AP_API_VERSION_RELEASE 0x00u + +/*********************************************************************************************************************** +* INCLUDES +**********************************************************************************************************************/ + +#include "FblBm_Cfg.h" +#include "bm_types.h" +#include "bm_hdr.h" + +#include "fbl_inc.h" + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +#if defined( FBLBM_ENABLE_STANDALONE_MODE ) +# define FblRealTimeSupport() FblLookForWatchdog() +#endif + +/*********************************************************************************************************************** + * FUNCTION PROTOTYPES + **********************************************************************************************************************/ + +#define FBLBMAP_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +void ApplFblBmPowerOnPre(void); +void ApplFblBmPowerOnPost(void); +void ApplFblBmInitPre(void); +void ApplFblBmInitPost(void); + +#if defined( FBLBM_AP_CALLOUT_RESET ) +void ApplFblBmReset(void); +#endif /* FBLBM_AP_CALLOUT_RESET */ + +#if defined( FBLBM_AP_CALLOUT_CHECK_TARGET_VALIDITY ) +tFblResult ApplFblBmCheckTargetValidity(tFblBmHdrTargetHandle targetHandle); +#endif /* FBLBM_AP_CALLOUT_CHECK_TARGET_VALIDITY */ +#if defined( FBLBM_AP_CALLOUT_IS_VALIDBLOCK ) +tFblResult ApplFblBmIsValidBlock(tFblBmHdrTargetHandle targetHandle, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * pLogicalBlock); +#endif /* FBLBM_AP_CALLOUT_IS_VALIDBLOCK */ +#if defined( FBLBM_AP_CALLOUT_IS_OPTIONALBLOCK ) +void ApplFblBmIsOptionalBlock(tFblBmHdrTargetHandle targetHandle, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * pLogicalBlock); +#endif /* FBLBM_AP_CALLOUT_IS_OPTIONALBLOCK */ +#if defined( FBLBM_AP_CALLOUT_START_SOFTWARE ) +void ApplFblBmStartSoftware(const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader); +#endif /* FBLBM_AP_CALLOUT_START_SOFTWARE* */ +#if defined( FBLBM_AP_CALLOUT_FAILSAFE_UPDATER_USER_CHECK ) && defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) +tFblResult ApplFblBmFailsafeUpdaterUserCheck(V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader); +#endif + +#if defined( FBLBM_ENABLE_SECURE_BOOT ) +# if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY ) +# if defined( FBLBM_AP_CALLOUT_GET_KEYEMPTY ) +tFblBmKeyEmptyResult ApplFblBmGetKeyEmpty( void ); +# endif /* FBLBM_AP_CALLOUT_GET_KEYEMPTY */ +# endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY */ +# if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) +# if defined( FBLBM_AP_CALLOUT_GET_FBL_CMACERASED ) +tFblBmMacEmptyResult ApplFblBmGetFblCmacErased( const tFblBmBlockInfo * fblBlockInfo ); +# endif /* FBLBM_AP_CALLOUT_GET_FBL_CMACERASED */ +# endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ +#endif /* FBLBM_ENABLE_SECURE_BOOT */ + +#if defined( FBLBM_AP_CALLOUT_CHECKREPROGFLAG ) +tFblResult ApplFblBmCheckReprogFlag( void ); +#endif /* FBLBM_AP_CALLOUT_CHECKREPROGFLAG */ + +#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) +# if defined( FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT ) +tFblResult ApplFblBmSearchUpdaterHeaderInit(void); +# endif /* FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT */ +# if defined( FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS ) +tFblResult ApplFblBmSearchUpdaterHeaderAddress(vuint32 * headerAddress); +# endif /* FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS */ +# if defined( FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT ) +tFblResult ApplFblBmSearchUpdaterHeaderNext(void); +# endif /* FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT */ +#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ + +#if defined( FBLBM_AP_CALLOUT_FATAL_ERROR ) +void ApplFblBmFatalError(tFblBmError error); +#endif /* FBLBM_AP_CALLOUT_FATAL_ERROR */ + +#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) +# if defined( FBLBM_AP_CALLOUT_GET_PP_SIGN_KEYEMPTY ) +tFblBmKeyEmptyResult ApplFblBmGetPresPattSignInitStatus( void ); +# endif /* FBLBM_AP_CALLOUT_GET_PP_SIGN_KEYEMPTY */ + +# if defined( FBLBM_AP_CALLOUT_IS_VALIDPATTERN ) +tFblResult ApplFblBmCheckPresencePattern(tFblBmHdrTargetHandle targetHandle, + const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * pLogicalBlock); +# endif /* FBLBM_AP_CALLOUT_IS_VALIDPATTERN */ +#endif + +/*-- Other callout functions -----------------------------------------------------------------------------------------*/ + +#if defined( FBLBM_ENABLE_STANDALONE_MODE ) +# if defined( FBL_ENABLE_ASSERTION ) +void ApplFblFatalError( FBL_DECL_ASSERT_EXTENDED_INFO(vuint8 errorCode) ); +# endif /* FBL_ENABLE_ASSERTION */ +# if defined( FBL_MIO_ENABLE_HOOKS ) +void ApplFblPreMemDriver( vuint8 device, vuint8 function ); +void ApplFblPostMemDriver( vuint8 device, vuint8 function ); +# endif /* FBL_MIO_ENABLE_HOOKS */ +#endif /* FBLBM_ENABLE_STANDALONE_MODE */ + +#define FBLBMAP_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* BM_AP_H */ + +/*********************************************************************************************************************** + * END OF FILE: BM_AP.H + **********************************************************************************************************************/ diff --git a/Source/include/bm_ap_cfg.h b/Source/include/bm_ap_cfg.h new file mode 100644 index 0000000..1a24eaa --- /dev/null +++ b/Source/include/bm_ap_cfg.h @@ -0,0 +1,307 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief Application dependent routines + * + * \note Please note, that this file contains a collection of callback functions to be used with the + * Flash Bootloader. These functions may influence the behavior of the bootloader in principle. + * Therefore, great care must be taken to verify the correctness of the implementation. + * The contents of the originally delivered files are only examples resp. implementation proposals. + * With regard to the fact that these functions are meant for demonstration purposes only, Vector + * Informatik's liability shall be expressly excluded in cases of ordinary negligence, to the extent + * admissible by law or statute. + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2019-01-28 visrie - Initial version + * 01.01.00 2019-02-18 vismvi ESCAN00102171 No changes + * visrie ESCAN00102310 Added callout to check reprogramming flag + * 01.01.01 2019-03-07 visrie ESCAN00102386 No changes + * ESCAN00102399 No changes + * 02.00.00 2019-05-02 visrie ESCAN00102518 No changes + * ESCAN00102761 No changes + * ESCAN00103026 No changes + * 03.00.00 2019-07-17 visrie ESCAN00103750 Removed target order list configuration + * 03.01.00 2019-08-14 visrie FBL-487 Exclude callouts if overwritten by OEM/HW layer + * 03.01.01 2019-09-04 visrcn ESCAN00103607 No changes + * 04.00.00 2019-12-04 visrie FBL-456 No changes + * ESCAN00105135 No changes + * 04.01.00 2020-01-16 visrie FBL-524 No changes + * 05.00.00 2020-04-09 visrie FBL-1016 No changes + * 05.01.00 2020-04-29 vistmo FBL-1584 No changes + * 05.02.00 2020-08-13 vistmo FBL-1489 No changes + * 05.02.01 2021-03-17 vishor ESCAN00108386 No changes + * FBL-3018 No changes + * 05.03.00 2021-08-11 visrie FBL-3394 Move default implementation of CheckReprogFlag into FblBm_Ap + * 05.04.00 2021-09-17 visjdn FBL-3865 No changes + * 05.04.01 2022-04-06 vismix FBL-4773 No changes + * 05.05.00 2022-04-07 vishor FBL-4822 No changes + * 05.05.01 2022-06-23 vismix ESCAN00111879 No changes + * 05.06.00 2022-07-13 vismix FBL-5391 Add callout for missing optional dependency + * 05.06.01 2022-11-29 vishor ESCAN00112986 No changes + * 05.07.00 2023-06-29 vistbe FBL-7052 No changes + * 05.07.01 2023-12-18 visrie ESCAN00104829 No changes + * ESCAN00111036 No changes + * ESCAN00115752 No changes + * 05.08.00 2024-05-16 vishor FBL-8602 Add support for OEM updater solution + * 05.09.00 2025-05-23 dganesh FBL-9715 Extend presence pattern to connect validity information + **********************************************************************************************************************/ + +#ifndef BM_AP_CFG_H +#define BM_AP_CFG_H + +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/*-- Processing hook functions ---------------------------------------------------------------------------------------*/ + +/*-- Callout functions -----------------------------------------------------------------------------------------------*/ + +/* Callout implementation is mandatory, but could be overwritten by OEM- or platform-specific variant */ + +/** HW specific initialization callout */ +#if !defined( FBLBM_CALLOUT_POWER_ON_PRE_HW) +# define FBLBM_CALLOUT_POWER_ON_PRE_HW() +#endif /* FBLBM_CALLOUT_POWER_ON_PRE_HW */ + +/** OEM specific initialization callout */ +#if !defined( FBLBM_CALLOUT_POWER_ON_PRE_OEM ) +# define FBLBM_CALLOUT_POWER_ON_PRE_OEM() +#endif /* FBLBM_CALLOUT_POWER_ON_PRE_OEM */ + +/** Initialization callout */ +#if !defined( FBLBM_CALLOUT_POWER_ON_PRE ) +# define FBLBM_CALLOUT_POWER_ON_PRE ApplFblBmPowerOnPre +#endif /* FBLBM_CALLOUT_POWER_ON_PRE */ + +/** HW specific initialization callout */ +#if !defined( FBLBM_CALLOUT_POWER_ON_POST_HW ) +# define FBLBM_CALLOUT_POWER_ON_POST_HW() +#endif /* FBLBM_CALLOUT_POWER_ON_POST_HW */ + +/** OEM specific initialization callout */ +#if !defined( FBLBM_CALLOUT_POWER_ON_POST_OEM ) +# define FBLBM_CALLOUT_POWER_ON_POST_OEM() +#endif /* FBLBM_CALLOUT_POWER_ON_POST_OEM */ + +/** Initialization callout */ +#if !defined( FBLBM_CALLOUT_POWER_ON_POST ) +# define FBLBM_CALLOUT_POWER_ON_POST ApplFblBmPowerOnPost +#endif /* FBLBM_CALLOUT_POWER_ON_POST */ + +/** HW specific initialization callout */ +#if !defined( FBLBM_CALLOUT_INIT_PRE_HW ) +# define FBLBM_CALLOUT_INIT_PRE_HW() +#endif /* FBLBM_CALLOUT_INIT_PRE_HW */ + +/** OEM specific initialization callout */ +#if !defined( FBLBM_CALLOUT_INIT_PRE_OEM ) +# define FBLBM_CALLOUT_INIT_PRE_OEM() +#endif /* FBLBM_CALLOUT_INIT_PRE_OEM */ + +/** Initialization callout */ +#if !defined( FBLBM_CALLOUT_INIT_PRE ) +# define FBLBM_CALLOUT_INIT_PRE ApplFblBmInitPre +#endif /* FBLBM_CALLOUT_INIT_PRE */ + +/** HW specific initialization callout */ +#if !defined( FBLBM_CALLOUT_INIT_POST_HW ) +# define FBLBM_CALLOUT_INIT_POST_HW() +#endif /* FBLBM_CALLOUT_INIT_POST_HW */ + +/** OEM specific initialization callout */ +#if !defined( FBLBM_CALLOUT_INIT_POST_OEM ) +# define FBLBM_CALLOUT_INIT_POST_OEM() +#endif /* FBLBM_CALLOUT_INIT_POST_OEM */ + +/** Initialization callout */ +#if !defined( FBLBM_CALLOUT_INIT_POST ) +# define FBLBM_CALLOUT_INIT_POST ApplFblBmInitPost +#endif /* FBLBM_CALLOUT_INIT_POST */ + +/** HW specific deinitialization callout */ +#if !defined( FBLBM_CALLOUT_DEINIT_PRE_HW ) +# define FBLBM_CALLOUT_DEINIT_PRE_HW() +#endif /* FBLBM_CALLOUT_DEINIT_PRE_HW */ + +/** OEM specific deinitialization callout */ +#if !defined( FBLBM_CALLOUT_DEINIT_PRE_OEM ) +# define FBLBM_CALLOUT_DEINIT_PRE_OEM() +#endif /* FBLBM_CALLOUT_DEINIT_PRE_OEM */ + +/** Denitialization callout */ +#if !defined( FBLBM_CALLOUT_DEINIT_PRE ) +# define FBLBM_CALLOUT_DEINIT_PRE() +#endif /* FBLBM_CALLOUT_DEINIT_PRE */ + +/** HW specific deinitialization callout */ +#if !defined( FBLBM_CALLOUT_DEINIT_POST_HW ) +# define FBLBM_CALLOUT_DEINIT_POST_HW() +#endif /* FBLBM_CALLOUT_DEINIT_HW */ + +/** OEM specific deinitialization callout */ +#if !defined( FBLBM_CALLOUT_DEINIT_POST_OEM ) +# define FBLBM_CALLOUT_DEINIT_POST_OEM() +#endif /* FBLBM_CALLOUT_DEINIT_POST_OEM */ + +/** Denitialization callout */ +#if !defined( FBLBM_CALLOUT_DEINIT_POST ) +# define FBLBM_CALLOUT_DEINIT_POST() +#endif /* FBLBM_CALLOUT_DEINIT_POST */ + +/** Callout to perform reset */ +#if !defined( FBLBM_CALLOUT_RESET ) +# define FBLBM_CALLOUT_RESET ApplFblBmReset +# define FBLBM_AP_CALLOUT_RESET +#endif /* FBLBM_CALLOUT_RESET */ + +/** Check appl validity callout */ +#if !defined( FBLBM_CALLOUT_CHECK_TARGET_VALIDITY ) +# define FBLBM_CALLOUT_CHECK_TARGET_VALIDITY ApplFblBmCheckTargetValidity +# define FBLBM_AP_CALLOUT_CHECK_TARGET_VALIDITY +#endif /* FBLBM_CALLOUT_CHECK_TARGET_VALIDITY */ + +/** Checks if the block is valid callout */ +#if !defined( FBLBM_CALLOUT_IS_VALIDBLOCK ) +# define FBLBM_CALLOUT_IS_VALIDBLOCK ApplFblBmIsValidBlock +# define FBLBM_AP_CALLOUT_IS_VALIDBLOCK +#endif /* FBLBM_CALLOUT_IS_VALIDBLOCK */ + +/** Callout when the block is optional */ +#if !defined( FBLBM_CALLOUT_IS_OPTIONALBLOCK ) +# define FBLBM_CALLOUT_IS_OPTIONALBLOCK ApplFblBmIsOptionalBlock +# define FBLBM_AP_CALLOUT_IS_OPTIONALBLOCK +#endif /* FBLBM_CALLOUT_IS_OPTIONALBLOCK */ + +/** Start the Application */ +#if !defined( FBLBM_CALLOUT_CALL_TARGET ) +# define FBLBM_CALLOUT_CALL_TARGET ApplFblBmStartSoftware +# if !defined( FBLBM_AP_CALLOUT_START_SOFTWARE ) +# define FBLBM_AP_CALLOUT_START_SOFTWARE +# endif /* FBLBM_AP_CALLOUT_START_SOFTWARE */ +#endif /* FBLBM_CALLOUT_CALL_TARGET */ + +/** Start the FBL */ +#if !defined( FBLBM_CALLOUT_CALL_FBL ) +# define FBLBM_CALLOUT_CALL_FBL ApplFblBmStartSoftware +# if !defined( FBLBM_AP_CALLOUT_START_SOFTWARE ) +# define FBLBM_AP_CALLOUT_START_SOFTWARE +# endif /* FBLBM_AP_CALLOUT_START_SOFTWARE */ +#endif /* FBLBM_CALLOUT_CALL_FBL */ + +/** Start the FBL to initialize the Key */ +#if !defined( FBLBM_CALLOUT_CALL_FBL_INIT_KEYS ) +# define FBLBM_CALLOUT_CALL_FBL_INIT_KEYS ApplFblBmStartSoftware +# if !defined( FBLBM_AP_CALLOUT_START_SOFTWARE ) +# define FBLBM_AP_CALLOUT_START_SOFTWARE +# endif /* FBLBM_AP_CALLOUT_START_SOFTWARE */ +#endif /* FBLBM_CALLOUT_CALL_FBL_INIT_KEYS */ + +/** Start the FBL to initialize its CMAC */ +#if !defined( FBLBM_CALLOUT_CALL_FBL_INIT_CMAC ) +# define FBLBM_CALLOUT_CALL_FBL_INIT_CMAC ApplFblBmStartSoftware +# if !defined( FBLBM_AP_CALLOUT_START_SOFTWARE ) +# define FBLBM_AP_CALLOUT_START_SOFTWARE +# endif /* FBLBM_AP_CALLOUT_START_SOFTWARE */ +#endif /* FBLBM_CALLOUT_CALL_FBL_INIT_CMAC */ + +/** Check if user updater is present */ +#if !defined( FBLBM_CALLOUT_FAILSAFE_UPDATER_USER_CHECK ) +# define FBLBM_CALLOUT_FAILSAFE_UPDATER_USER_CHECK(a) ApplFblBmFailsafeUpdaterUserCheck(a) +# define FBLBM_AP_CALLOUT_FAILSAFE_UPDATER_USER_CHECK +#endif /* FBLBM_CALLOUT_FAILSAFE_UPDATER_USER_CHECK */ + +/** Start the Updater */ +#if !defined( FBLBM_CALLOUT_CALL_FAILSAFE_UPDATER ) +# define FBLBM_CALLOUT_CALL_FAILSAFE_UPDATER ApplFblBmStartSoftware +# if !defined( FBLBM_AP_CALLOUT_START_SOFTWARE ) +# define FBLBM_AP_CALLOUT_START_SOFTWARE +# endif /* FBLBM_AP_CALLOUT_START_SOFTWARE */ +#endif /* FBLBM_CALLOUT_CALL_FAILSAFE_UPDATER */ + +/** Get information if Key is available for MAC verification */ +#if !defined( FBLBM_CALLOUT_GET_KEYEMPTY ) +# define FBLBM_CALLOUT_GET_KEYEMPTY ApplFblBmGetKeyEmpty +# define FBLBM_AP_CALLOUT_GET_KEYEMPTY +#endif /* FBLBM_CALLOUT_GET_KEYEMPTY */ + +/** Check if FBL MAC is available */ +#if !defined( FBLBM_CALLOUT_GET_FBL_CMACERASED ) +# define FBLBM_CALLOUT_GET_FBL_CMACERASED ApplFblBmGetFblCmacErased +# define FBLBM_AP_CALLOUT_GET_FBL_CMACERASED +#endif /* FBLBM_CALLOUT_GET_FBL_CMACERASED */ + +/** Check if the programming request flag is set */ +#if !defined( FBLBM_CALLOUT_CHECKREPROGFLAG ) +# define FBLBM_CALLOUT_CHECKREPROGFLAG ApplFblBmCheckReprogFlag +# define FBLBM_AP_CALLOUT_CHECKREPROGFLAG +#endif /* FBLBM_CALLOUT_CHECKREPROGFLAG */ + +/** Failsafe Updater */ +#if !defined( FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT ) +#define FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT ApplFblBmSearchUpdaterHeaderInit +# define FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT +#endif /* FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT */ + +/** Failsafe Updater */ +#if !defined( FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS ) +#define FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS ApplFblBmSearchUpdaterHeaderAddress +# define FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS +#endif /* FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS */ + +/** Failsafe Updater */ +#if !defined( FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT ) +#define FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT ApplFblBmSearchUpdaterHeaderNext +# define FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT +#endif /* FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT */ + +/** Fatal error callout */ +#if !defined( FBLBM_CALLOUT_FATAL_ERROR ) +# define FBLBM_CALLOUT_FATAL_ERROR ApplFblBmFatalError +# define FBLBM_AP_CALLOUT_FATAL_ERROR +#endif /* FBLBM_CALLOUT_FATAL_ERROR */ + +/** Check if Signed Presence pattern is empty */ +#if !defined( FBLBM_CALLOUT_GET_PP_SIGN_KEYEMPTY ) +#define FBLBM_CALLOUT_GET_PP_SIGN_KEYEMPTY ApplFblBmGetPresPattSignInitStatus +# define FBLBM_AP_CALLOUT_GET_PP_SIGN_KEYEMPTY +#endif /* FBLBM_CALLOUT_GET_PP_SIGN_KEYEMPTY */ + +/** Call for Presence pattern validation */ +#if !defined( FBLBM_CALLOUT_IS_VALIDPATTERN ) +#define FBLBM_CALLOUT_IS_VALIDPATTERN ApplFblBmCheckPresencePattern +# define FBLBM_AP_CALLOUT_IS_VALIDPATTERN +#endif /* FBLBM_CALLOUT_IS_VALIDPATTERN */ + +/** Callout to update signed presence pattern */ +#if !defined( FBLBM_CALLOUT_CALL_FBL_INIT_SIGNED_PRESENCEPATTERN ) +#define FBLBM_CALLOUT_CALL_FBL_INIT_SIGNED_PRESENCEPATTERN ApplFblBmStartSoftware +# if !defined( FBLBM_AP_CALLOUT_START_SOFTWARE ) +# define FBLBM_AP_CALLOUT_START_SOFTWARE +# endif /* FBLBM_AP_CALLOUT_START_SOFTWARE */ +#endif /* FBLBM_CALLOUT_CALL_FBL_INIT_SIGNED_PRESENCEPATTERN */ + +#endif /* BM_AP_CFG_H */ + +/*********************************************************************************************************************** + * END OF FILE: BM_AP_CFG.H + **********************************************************************************************************************/ diff --git a/Source/include/fbl_secboot_ap.h b/Source/include/fbl_secboot_ap.h new file mode 100644 index 0000000..c4ed5c4 --- /dev/null +++ b/Source/include/fbl_secboot_ap.h @@ -0,0 +1,81 @@ +/*********************************************************************************************************************** + * FILE DESCRIPTION + * ------------------------------------------------------------------------------------------------------------------*/ +/** \file + * \brief SecureBoot implementation callback file + * + * \note Please note, that this file contains a collection of callback functions to be used with the + * Flash Bootloader. These functions may influence the behavior of the bootloader in principle. + * Therefore, great care must be taken to verify the correctness of the implementation. + * The contents of the originally delivered files are only examples resp. implementation proposals. + * With regard to the fact that these functions are meant for demonstration purposes only, Vector + * Informatik's liability shall be expressly excluded in cases of ordinary negligence, to the extent + * admissible by law or statute. + * + * -------------------------------------------------------------------------------------------------------------------- + * COPYRIGHT + * -------------------------------------------------------------------------------------------------------------------- + * \par Copyright + * \verbatim + * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. + * + * This software is copyright protected and proprietary to Vector Informatik GmbH. + * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. + * All other rights remain with Vector Informatik GmbH. + * \endverbatim + */ +/**********************************************************************************************************************/ + +/*********************************************************************************************************************** + * REVISION HISTORY + * -------------------------------------------------------------------------------------------------------------------- + * Version Date Author Change Id Description + * -------------------------------------------------------------------------------------------------------------------- + * 01.00.00 2020-01-07 visrie FBL-524 Initial release + * 01.00.01 2020-04-27 visrie FBL-1773 No changes + * 02.00.00 2020-05-19 vistbe FBL-1016 No changes + * 02.01.00 2021-01-19 visrie FBL-2648 No changes + * FBL-2641 No changes + * 02.02.00 2021-09-03 visjdn FBL-3352 No changes + * 02.03.00 2023-06-21 vistbe FBL-4814 Add support for OTA + * 02.03.01 2024-05-16 viswmo ESCAN00117059 No changes + * 02.04.00 2024-11-18 vismix FBL-9654 No changes + * 02.05.00 2025-01-30 vikatya PIO-1340 No changes + * 02.06.00 2025-02-19 visrie FBL-10209 No changes + **********************************************************************************************************************/ + +#ifndef FBL_SECBOOT_AP_H +#define FBL_SECBOOT_AP_H + +/*********************************************************************************************************************** +* INCLUDES +**********************************************************************************************************************/ + +#include "bm_types.h" +#include "fbl_secboot.h" + +/*********************************************************************************************************************** + * FUNCTION PROTOTYPES + **********************************************************************************************************************/ +#define FBLSB_START_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +void ApplFblSbStartup(void); +#if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) +# if defined( FBLBM_INSTANCE_BOOTMANAGER ) +tFblResult ApplFblSbIsInitialStartup(void); +# endif +void ApplFblSbClrInitialStartup(void); +#endif +tFblResult ApplFblSbGetSignatureInfo(const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHdrHeader, vuint32 macId, + V_MEMRAM1 vuint32 V_MEMRAM2 V_MEMRAM3 * signatureAddress, + V_MEMRAM1 vuint32 V_MEMRAM2 V_MEMRAM3 * signatureLength); + +#define FBLSB_STOP_SEC_CODE +#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ + +#endif /* FBL_SECBOOT_AP_H */ + +/*********************************************************************************************************************** + * END OF FILE: FBL_SECBOOT_AP.H + **********************************************************************************************************************/ diff --git a/b.bat b/b.bat new file mode 100644 index 0000000..a28450c --- /dev/null +++ b/b.bat @@ -0,0 +1,2 @@ +@echo off +call j.bat rebuild %* diff --git a/config/Davinci/Config/AUTOSAR/MemMap_SwAddrMethods.arxml b/config/Davinci/Config/AUTOSAR/MemMap_SwAddrMethods.arxml new file mode 100644 index 0000000..00f5dba --- /dev/null +++ b/config/Davinci/Config/AUTOSAR/MemMap_SwAddrMethods.arxml @@ -0,0 +1,2151 @@ + + + + + + MICROSAR_MemMap + + + SwAddrMethods + + + + + CALLOUT_CODE + CODE + + + CALLOUT_CODE_QM + + + + CODE + + + CALLOUT_CODE_ASIL_A + + + + CODE + + + CALLOUT_CODE_ASIL_B + + + + CODE + + + CALLOUT_CODE_ASIL_C + + + + CODE + + + CALLOUT_CODE_ASIL_D + + + + CODE + + + CODE + CODE + + + CODE_QM + + + + CODE + + + CODE_ASIL_A + + + + CODE + + + CODE_ASIL_B + + + + CODE + + + CODE_ASIL_C + + + + CODE + + + CODE_ASIL_D + + + + CODE + + + CODE_FAST + CODE + + + CODE_FAST_QM + + + + CODE + + + CODE_FAST_ASIL_A + + + + CODE + + + CODE_FAST_ASIL_B + + + + CODE + + + CODE_FAST_ASIL_C + + + + CODE + + + CODE_FAST_ASIL_D + + + + CODE + + + CODE_ISR + CODE + + + CODE_ISR_QM + + + + CODE + + + CODE_ISR_ASIL_A + + + + CODE + + + CODE_ISR_ASIL_B + + + + CODE + + + CODE_ISR_ASIL_C + + + + CODE + + + CODE_ISR_ASIL_D + + + + CODE + + + CODE_SLOW + CODE + + + CODE_SLOW_QM + + + + CODE + + + CODE_SLOW_ASIL_A + + + + CODE + + + CODE_SLOW_ASIL_B + + + + CODE + + + CODE_SLOW_ASIL_C + + + + CODE + + + CODE_SLOW_ASIL_D + + + + CODE + + + + CONFIG_DATA_PREBUILD + + + + CONFIG-DATA + + + CONFIG_DATA_PREBUILD_QM + + + + + CONFIG-DATA + + + CONFIG_DATA_PREBUILD_ASIL_A + + + + + CONFIG-DATA + + + CONFIG_DATA_PREBUILD_ASIL_B + + + + + CONFIG-DATA + + + CONFIG_DATA_PREBUILD_ASIL_C + + + + + CONFIG-DATA + + + CONFIG_DATA_PREBUILD_ASIL_D + + + + + CONFIG-DATA + + + CONFIG_DATA_POSTBUILD + + + + CONFIG-DATA + + + CONFIG_DATA_POSTBUILD_QM + + + + + CONFIG-DATA + + + CONFIG_DATA_POSTBUILD_ASIL_A + + + + + CONFIG-DATA + + + CONFIG_DATA_POSTBUILD_ASIL_B + + + + + CONFIG-DATA + + + CONFIG_DATA_POSTBUILD_ASIL_C + + + + + CONFIG-DATA + + + CONFIG_DATA_POSTBUILD_ASIL_D + + + + + CONFIG-DATA + + + + CONST + CONST + + + CONST_QM + + + + CONST + + + CONST_ASIL_A + + + + CONST + + + CONST_ASIL_B + + + + CONST + + + CONST_ASIL_C + + + + CONST + + + CONST_ASIL_D + + + + CONST + + + CONST_SAVED_RECOVERY_ZONE + CONST + + + CONST_SAVED_RECOVERY_ZONE_QM + + + + CONST + + + CONST_SAVED_RECOVERY_ZONE_ASIL_A + + + + CONST + + + CONST_SAVED_RECOVERY_ZONE_ASIL_B + + + + CONST + + + CONST_SAVED_RECOVERY_ZONE_ASIL_C + + + + CONST + + + CONST_SAVED_RECOVERY_ZONE_ASIL_D + + + + CONST + + + + CONST_FAST + CONST + + + CONST_FAST_QM + + + + CONST + + + CONST_FAST_ASIL_A + + + + CONST + + + CONST_FAST_ASIL_B + + + + CONST + + + CONST_FAST_ASIL_C + + + + CONST + + + CONST_FAST_ASIL_D + + + + CONST + + + + + VAR_INIT + VAR + + + VAR_INIT_QM + + + + VAR + + + VAR_INIT_ASIL_A + + + + VAR + + + VAR_INIT_ASIL_B + + + + VAR + + + VAR_INIT_ASIL_C + + + + VAR + + + VAR_INIT_ASIL_D + + + + VAR + + + + VAR_NO_INIT + NO-INIT + VAR + + + VAR_NO_INIT_QM + + + + NO-INIT + VAR + + + VAR_NO_INIT_ASIL_A + + + + NO-INIT + VAR + + + VAR_NO_INIT_ASIL_B + + + + NO-INIT + VAR + + + VAR_NO_INIT_ASIL_C + + + + NO-INIT + VAR + + + VAR_NO_INIT_ASIL_D + + + + NO-INIT + VAR + + + + VAR_CLEARED + CLEARED + VAR + + + VAR_CLEARED_QM + + + + CLEARED + VAR + + + VAR_CLEARED_ASIL_A + + + + CLEARED + VAR + + + VAR_CLEARED_ASIL_B + + + + CLEARED + VAR + + + VAR_CLEARED_ASIL_C + + + + CLEARED + VAR + + + VAR_CLEARED_ASIL_D + + + + CLEARED + VAR + + + + VAR_POWER_ON_INIT + POWER-ON-INIT + VAR + + + VAR_POWER_ON_INIT_QM + + + + POWER-ON-INIT + VAR + + + VAR_POWER_ON_INIT_ASIL_A + + + + POWER-ON-INIT + VAR + + + VAR_POWER_ON_INIT_ASIL_B + + + + POWER-ON-INIT + VAR + + + VAR_POWER_ON_INIT_ASIL_C + + + + POWER-ON-INIT + VAR + + + VAR_POWER_ON_INIT_ASIL_D + + + + POWER-ON-INIT + VAR + + + + VAR_POWER_ON_CLEARED + POWER-ON-CLEARED + VAR + + + VAR_POWER_ON_CLEARED_QM + + + + POWER-ON-CLEARED + VAR + + + VAR_POWER_ON_CLEARED_ASIL_A + + + + POWER-ON-CLEARED + VAR + + + VAR_POWER_ON_CLEARED_ASIL_B + + + + POWER-ON-CLEARED + VAR + + + VAR_POWER_ON_CLEARED_ASIL_C + + + + POWER-ON-CLEARED + VAR + + + VAR_POWER_ON_CLEARED_ASIL_D + + + + POWER-ON-CLEARED + VAR + + + + VAR_FAST_INIT + VAR-FAST + + + VAR_FAST_INIT_QM + + + + VAR-FAST + + + VAR_FAST_INIT_ASIL_A + + + + VAR-FAST + + + VAR_FAST_INIT_ASIL_B + + + + VAR-FAST + + + VAR_FAST_INIT_ASIL_C + + + + VAR-FAST + + + VAR_FAST_INIT_ASIL_D + + + + VAR-FAST + + + + VAR_FAST_NO_INIT + NO-INIT + VAR-FAST + + + VAR_FAST_NO_INIT_QM + + + + NO-INIT + VAR-FAST + + + VAR_FAST_NO_INIT_ASIL_A + + + + NO-INIT + VAR-FAST + + + VAR_FAST_NO_INIT_ASIL_B + + + + NO-INIT + VAR-FAST + + + VAR_FAST_NO_INIT_ASIL_C + + + + NO-INIT + VAR-FAST + + + VAR_FAST_NO_INIT_ASIL_D + + + + NO-INIT + VAR-FAST + + + + VAR_FAST_CLEARED + CLEARED + VAR-FAST + + + VAR_FAST_CLEARED_QM + + + + CLEARED + VAR-FAST + + + VAR_FAST_CLEARED_ASIL_A + + + + CLEARED + VAR-FAST + + + VAR_FAST_CLEARED_ASIL_B + + + + CLEARED + VAR-FAST + + + VAR_FAST_CLEARED_ASIL_C + + + + CLEARED + VAR-FAST + + + VAR_FAST_CLEARED_ASIL_D + + + + CLEARED + VAR-FAST + + + + VAR_FAST_POWER_ON_INIT + POWER-ON-INIT + VAR-FAST + + + VAR_FAST_POWER_ON_INIT_QM + + + + POWER-ON-INIT + VAR-FAST + + + VAR_FAST_POWER_ON_INIT_ASIL_A + + + + POWER-ON-INIT + VAR-FAST + + + VAR_FAST_POWER_ON_INIT_ASIL_B + + + + POWER-ON-INIT + VAR-FAST + + + VAR_FAST_POWER_ON_INIT_ASIL_C + + + + POWER-ON-INIT + VAR-FAST + + + VAR_FAST_POWER_ON_INIT_ASIL_D + + + + POWER-ON-INIT + VAR-FAST + + + + VAR_FAST_POWER_ON_CLEARED + POWER-ON-CLEARED + VAR-FAST + + + VAR_FAST_POWER_ON_CLEARED_QM + + + + POWER-ON-CLEARED + VAR-FAST + + + VAR_FAST_POWER_ON_CLEARED_ASIL_A + + + + POWER-ON-CLEARED + VAR-FAST + + + VAR_FAST_POWER_ON_CLEARED_ASIL_B + + + + POWER-ON-CLEARED + VAR-FAST + + + VAR_FAST_POWER_ON_CLEARED_ASIL_C + + + + POWER-ON-CLEARED + VAR-FAST + + + VAR_FAST_POWER_ON_CLEARED_ASIL_D + + + + POWER-ON-CLEARED + VAR-FAST + + + + VAR_SAVED_ZONE + POWER-ON-CLEARED + VAR + + + VAR_SAVED_ZONE_QM + + + + POWER-ON-CLEARED + VAR + + + VAR_SAVED_ZONE_ASIL_A + + + + POWER-ON-CLEARED + VAR + + + VAR_SAVED_ZONE_ASIL_B + + + + POWER-ON-CLEARED + VAR + + + VAR_SAVED_ZONE_ASIL_C + + + + POWER-ON-CLEARED + VAR + + + VAR_SAVED_ZONE_ASIL_D + + + + POWER-ON-CLEARED + VAR + + + + VAR_SLOW_INIT + INIT + VAR + + + VAR_SLOW_INIT_QM + + + + INIT + VAR + + + VAR_SLOW_INIT_ASIL_A + + + + INIT + VAR + + + VAR_SLOW_INIT_ASIL_B + + + + INIT + VAR + + + VAR_SLOW_INIT_ASIL_C + + + + INIT + VAR + + + VAR_SLOW_INIT_ASIL_D + + + + INIT + VAR + + + + VAR_SLOW_NO_INIT + NO-INIT + VAR + + + VAR_SLOW_NO_INIT_QM + + + + NO-INIT + VAR + + + VAR_SLOW_NO_INIT_ASIL_A + + + + NO-INIT + VAR + + + VAR_SLOW_NO_INIT_ASIL_B + + + + NO-INIT + VAR + + + VAR_SLOW_NO_INIT_ASIL_C + + + + NO-INIT + VAR + + + VAR_SLOW_NO_INIT_ASIL_D + + + + NO-INIT + VAR + + + + VAR_SLOW_CLEARED + CLEARED + VAR + + + VAR_SLOW_CLEARED_QM + + + + CLEARED + VAR + + + VAR_SLOW_CLEARED_ASIL_A + + + + CLEARED + VAR + + + VAR_SLOW_CLEARED_ASIL_B + + + + CLEARED + VAR + + + VAR_SLOW_CLEARED_ASIL_C + + + + CLEARED + VAR + + + VAR_SLOW_CLEARED_ASIL_D + + + + CLEARED + VAR + + + + VAR_SLOW_POWER_ON_INIT + POWER-ON-INIT + VAR + + + VAR_SLOW_POWER_ON_INIT_QM + + + + POWER-ON-INIT + VAR + + + VAR_SLOW_POWER_ON_INIT_ASIL_A + + + + POWER-ON-INIT + VAR + + + VAR_SLOW_POWER_ON_INIT_ASIL_B + + + + POWER-ON-INIT + VAR + + + VAR_SLOW_POWER_ON_INIT_ASIL_C + + + + POWER-ON-INIT + VAR + + + VAR_SLOW_POWER_ON_INIT_ASIL_D + + + + POWER-ON-INIT + VAR + + + + VAR_SLOW_POWER_ON_CLEARED + POWER-ON-CLEARED + VAR + + + VAR_SLOW_POWER_ON_CLEARED_QM + + + + POWER-ON-CLEARED + VAR + + + VAR_SLOW_POWER_ON_CLEARED_ASIL_A + + + + POWER-ON-CLEARED + VAR + + + VAR_SLOW_POWER_ON_CLEARED_ASIL_B + + + + POWER-ON-CLEARED + VAR + + + VAR_SLOW_POWER_ON_CLEARED_ASIL_C + + + + POWER-ON-CLEARED + VAR + + + VAR_SLOW_POWER_ON_CLEARED_ASIL_D + + + + POWER-ON-CLEARED + VAR + + + + INTERNAL_VAR_INIT + INIT + VAR + + + INTERNAL_VAR_INIT_QM + + + + INIT + VAR + + + INTERNAL_VAR_INIT_ASIL_A + + + + INIT + VAR + + + INTERNAL_VAR_INIT_ASIL_B + + + + INIT + VAR + + + INTERNAL_VAR_INIT_ASIL_C + + + + INIT + VAR + + + INTERNAL_VAR_INIT_ASIL_D + + + + INIT + VAR + + + + INTERNAL_VAR_NO_INIT + NO-INIT + VAR + + + INTERNAL_VAR_NO_INIT_QM + + + + NO-INIT + VAR + + + INTERNAL_VAR_NO_INIT_ASIL_A + + + + NO-INIT + VAR + + + INTERNAL_VAR_NO_INIT_ASIL_B + + + + NO-INIT + VAR + + + INTERNAL_VAR_NO_INIT_ASIL_C + + + + NO-INIT + VAR + + + INTERNAL_VAR_NO_INIT_ASIL_D + + + + NO-INIT + VAR + + + + INTERNAL_VAR_CLEARED + CLEARED + VAR + + + INTERNAL_VAR_CLEARED_QM + + + + CLEARED + VAR + + + INTERNAL_VAR_CLEARED_ASIL_A + + + + CLEARED + VAR + + + INTERNAL_VAR_CLEARED_ASIL_B + + + + CLEARED + VAR + + + INTERNAL_VAR_CLEARED_ASIL_C + + + + CLEARED + VAR + + + INTERNAL_VAR_CLEARED_ASIL_D + + + + CLEARED + VAR + + + + INTERNAL_VAR_POWER_ON_INIT + POWER-ON-INIT + VAR + + + INTERNAL_VAR_POWER_ON_INIT_QM + + + + POWER-ON-INIT + VAR + + + INTERNAL_VAR_POWER_ON_INIT_ASIL_A + + + + POWER-ON-INIT + VAR + + + INTERNAL_VAR_POWER_ON_INIT_ASIL_B + + + + POWER-ON-INIT + VAR + + + INTERNAL_VAR_POWER_ON_INIT_ASIL_C + + + + POWER-ON-INIT + VAR + + + INTERNAL_VAR_POWER_ON_INIT_ASIL_D + + + + POWER-ON-INIT + VAR + + + + INTERNAL_VAR_POWER_ON_CLEARED + POWER-ON-CLEARED + VAR + + + INTERNAL_VAR_POWER_ON_CLEARED_QM + + + + POWER-ON-CLEARED + VAR + + + INTERNAL_VAR_POWER_ON_CLEARED_ASIL_A + + + + POWER-ON-CLEARED + VAR + + + INTERNAL_VAR_POWER_ON_CLEARED_ASIL_B + + + + POWER-ON-CLEARED + VAR + + + INTERNAL_VAR_POWER_ON_CLEARED_ASIL_C + + + + POWER-ON-CLEARED + VAR + + + INTERNAL_VAR_POWER_ON_CLEARED_ASIL_D + + + + POWER-ON-CLEARED + VAR + + + + CALIB + CALPRM + + + CALIB_QM + + + + CALPRM + + + CALIB_ASIL_A + + + + CALPRM + + + CALIB_ASIL_B + + + + CALPRM + + + CALIB_ASIL_C + + + + CALPRM + + + CALIB_ASIL_D + + + + CALPRM + + + + + + + CONST_BOOLEAN + CONST + + + + CONST_8 + CONST + + + + CONST_16 + CONST + + + + CONST_32 + CONST + + + + CONST_64 + CONST + + + + CONST_UNSPECIFIED + CONST + + + + + CONST_FAST_BOOLEAN + CONST + + + + CONST_FAST_8 + CONST + + + + CONST_FAST_16 + CONST + + + + CONST_FAST_32 + CONST + + + + CONST_FAST_64 + CONST + + + + CONST_FAST_UNSPECIFIED + CONST + + + + CONST_PBCFG + CONST + + + + PBCFG_GLOBALROOT + CONST + + + + CONFIG_DATA + CONFIG-DATA + + + + + VAR_PBCFG + VAR + + + + + VAR_SLOW + INIT + VAR + + + + INTERNAL_VAR + INIT + VAR + + + + VAR_INIT_BOOLEAN + VAR + + + + VAR_INIT_8 + VAR + + + + VAR_INIT_16 + VAR + + + + VAR_INIT_32 + VAR + + + + VAR_INIT_64 + VAR + + + + VAR_INIT_UNSPECIFIED + VAR + + + + + VAR_NO_INIT_BOOLEAN + NO-INIT + VAR + + + + VAR_NO_INIT_8 + NO-INIT + VAR + + + + VAR_NO_INIT_16 + NO-INIT + VAR + + + + VAR_NO_INIT_32 + NO-INIT + VAR + + + + VAR_NO_INIT_64 + NO-INIT + VAR + + + + VAR_NO_INIT_UNSPECIFIED + NO-INIT + VAR + + + + + VAR_NOINIT_BOOLEAN + NO-INIT + VAR + + + + VAR_NOINIT_8 + NO-INIT + VAR + + + + VAR_NOINIT_16 + NO-INIT + VAR + + + + VAR_NOINIT_32 + NO-INIT + VAR + + + + VAR_NOINIT_64 + NO-INIT + VAR + + + + VAR_NOINIT_UNSPECIFIED + NO-INIT + VAR + + + + + VAR_CLEARED_BOOLEAN + CLEARED + VAR + + + + VAR_CLEARED_8 + CLEARED + VAR + + + + VAR_CLEARED_16 + CLEARED + VAR + + + + VAR_CLEARED_32 + CLEARED + VAR + + + + VAR_CLEARED_64 + CLEARED + VAR + + + + VAR_CLEARED_UNSPECIFIED + CLEARED + VAR + + + + + VAR_ZERO_INIT + CLEARED + VAR + + + + VAR_ZERO_INIT_BOOLEAN + CLEARED + VAR + + + + VAR_ZERO_INIT_8 + CLEARED + VAR + + + + VAR_ZERO_INIT_16 + CLEARED + VAR + + + + VAR_ZERO_INIT_32 + CLEARED + VAR + + + + VAR_ZERO_INIT_64 + CLEARED + VAR + + + + VAR_ZERO_INIT_UNSPECIFIED + CLEARED + VAR + + + + + VAR_FAST_INIT_BOOLEAN + VAR-FAST + + + + VAR_FAST_INIT_8 + VAR-FAST + + + + VAR_FAST_INIT_16 + VAR-FAST + + + + VAR_FAST_INIT_32 + VAR-FAST + + + + VAR_FAST_INIT_64 + VAR-FAST + + + + VAR_FAST_INIT_UNSPECIFIED + VAR-FAST + + + + + VAR_FAST_NO_INIT_BOOLEAN + NO-INIT + VAR-FAST + + + + VAR_FAST_NO_INIT_8 + NO-INIT + VAR-FAST + + + + VAR_FAST_NO_INIT_16 + NO-INIT + VAR-FAST + + + + VAR_FAST_NO_INIT_32 + NO-INIT + VAR-FAST + + + + VAR_FAST_NO_INIT_64 + NO-INIT + VAR-FAST + + + + VAR_FAST_NO_INIT_UNSPECIFIED + NO-INIT + VAR-FAST + + + + + VAR_FAST_NOINIT_BOOLEAN + NO-INIT + VAR-FAST + + + + VAR_FAST_NOINIT_8 + NO-INIT + VAR-FAST + + + + VAR_FAST_NOINIT_16 + NO-INIT + VAR-FAST + + + + VAR_FAST_NOINIT_32 + NO-INIT + VAR-FAST + + + + VAR_FAST_NOINIT_64 + NO-INIT + VAR-FAST + + + + VAR_FAST_NOINIT_UNSPECIFIED + NO-INIT + VAR-FAST + + + + + VAR_FAST_CLEARED_BOOLEAN + CLEARED + VAR-FAST + + + + VAR_FAST_CLEARED_8 + CLEARED + VAR-FAST + + + + VAR_FAST_CLEARED_16 + CLEARED + VAR-FAST + + + + VAR_FAST_CLEARED_32 + CLEARED + VAR-FAST + + + + VAR_FAST_CLEARED_64 + CLEARED + VAR-FAST + + + + VAR_FAST_CLEARED_UNSPECIFIED + CLEARED + VAR-FAST + + + + + VAR_FAST_ZERO_INIT_BOOLEAN + CLEARED + VAR-FAST + + + + VAR_FAST_ZERO_INIT_8 + CLEARED + VAR-FAST + + + + VAR_FAST_ZERO_INIT_16 + CLEARED + VAR-FAST + + + + VAR_FAST_ZERO_INIT_32 + CLEARED + VAR-FAST + + + + VAR_FAST_ZERO_INIT_64 + CLEARED + VAR-FAST + + + + VAR_FAST_ZERO_INIT_UNSPECIFIED + CLEARED + VAR-FAST + + + + + VAR_NOCACHE_INIT_BOOLEAN + VAR + + + + VAR_NOCACHE_INIT_8 + VAR + + + + VAR_NOCACHE_INIT_16 + VAR + + + + VAR_NOCACHE_INIT_32 + VAR + + + + VAR_NOCACHE_INIT_64 + VAR + + + + VAR_NOCACHE_INIT_UNSPECIFIED + VAR + + + + + VAR_NOCACHE_NO_INIT_BOOLEAN + NO-INIT + VAR + + + + VAR_NOCACHE_NO_INIT_8 + NO-INIT + VAR + + + + VAR_NOCACHE_NO_INIT_16 + NO-INIT + VAR + + + + VAR_NOCACHE_NO_INIT_32 + NO-INIT + VAR + + + + VAR_NOCACHE_NO_INIT_64 + NO-INIT + VAR + + + + VAR_NOCACHE_NO_INIT_UNSPECIFIED + NO-INIT + VAR + + + + + VAR_NOCACHE_NOINIT_BOOLEAN + NO-INIT + VAR + + + + VAR_NOCACHE_NOINIT_8 + NO-INIT + VAR + + + + VAR_NOCACHE_NOINIT_16 + NO-INIT + VAR + + + + VAR_NOCACHE_NOINIT_32 + NO-INIT + VAR + + + + VAR_NOCACHE_NOINIT_64 + NO-INIT + VAR + + + + VAR_NOCACHE_NOINIT_UNSPECIFIED + NO-INIT + VAR + + + + + VAR_NOCACHE_CLEARED_BOOLEAN + CLEARED + VAR + + + + VAR_NOCACHE_CLEARED_8 + CLEARED + VAR + + + + VAR_NOCACHE_CLEARED_16 + CLEARED + VAR + + + + VAR_NOCACHE_CLEARED_32 + CLEARED + VAR + + + + VAR_NOCACHE_CLEARED_64 + CLEARED + VAR + + + + VAR_NOCACHE_CLEARED_UNSPECIFIED + CLEARED + VAR + + + + + VAR_NOCACHE_ZERO_INIT_BOOLEAN + CLEARED + VAR + + + + VAR_NOCACHE_ZERO_INIT_8 + CLEARED + VAR + + + + VAR_NOCACHE_ZERO_INIT_16 + CLEARED + VAR + + + + VAR_NOCACHE_ZERO_INIT_32 + CLEARED + VAR + + + + VAR_NOCACHE_ZERO_INIT_64 + CLEARED + VAR + + + + VAR_NOCACHE_ZERO_INIT_UNSPECIFIED + CLEARED + VAR + + + + + VAR_SAVED_ZONE_BOOLEAN + POWER-ON-CLEARED + VAR + + + + VAR_SAVED_ZONE_8 + POWER-ON-CLEARED + VAR + + + + VAR_SAVED_ZONE_16 + POWER-ON-CLEARED + VAR + + + + VAR_SAVED_ZONE_32 + POWER-ON-CLEARED + VAR + + + + VAR_SAVED_ZONE_64 + POWER-ON-CLEARED + VAR + + + + VAR_SAVED_ZONE_UNSPECIFIED + POWER-ON-CLEARED + VAR + + + + + VAR_NOCACHE_INIT + VAR + + + + + VAR_NOCACHE_NO_INIT + NO-INIT + VAR + + + + + VAR_NOCACHE_CLEARED + CLEARED + VAR + + + + + + + diff --git a/config/Davinci/Config/AUTOSAR/PlatformTypes_AR4.arxml b/config/Davinci/Config/AUTOSAR/PlatformTypes_AR4.arxml new file mode 100644 index 0000000..40d9a67 --- /dev/null +++ b/config/Davinci/Config/AUTOSAR/PlatformTypes_AR4.arxml @@ -0,0 +1,843 @@ + + + + + AUTOSAR_Platform + + + BaseTypes + + + dtRef_const_VOID + FIXED_LENGTH + 32 + VOID + void + + + dtRef_VOID + FIXED_LENGTH + 32 + VOID + void + + + boolean + FIXED_LENGTH + 8 + BOOLEAN + boolean + + + float32 + FIXED_LENGTH + 32 + IEEE754 + float32 + + + float64 + FIXED_LENGTH + 64 + IEEE754 + float64 + + + sint16 + FIXED_LENGTH + 16 + 2C + sint16 + + + sint16_least + FIXED_LENGTH + 64 + 2C + sint16_least + + + sint32 + FIXED_LENGTH + 32 + 2C + sint32 + + + sint32_least + FIXED_LENGTH + 64 + 2C + sint32_least + + + sint64 + FIXED_LENGTH + 64 + 2C + sint64 + + + sint8 + FIXED_LENGTH + 8 + 2C + sint8 + + + sint8_least + FIXED_LENGTH + 64 + 2C + sint8_least + + + uint16 + FIXED_LENGTH + 16 + NONE + uint16 + + + uint16_least + FIXED_LENGTH + 64 + NONE + uint16_least + + + uint32 + FIXED_LENGTH + 32 + NONE + uint32 + + + uint32_least + FIXED_LENGTH + 64 + NONE + uint32_least + + + uint64 + FIXED_LENGTH + 64 + NONE + uint64 + + + uint8 + FIXED_LENGTH + 8 + NONE + uint8 + + + uint8_least + FIXED_LENGTH + 64 + NONE + uint8_least + + + void + VOID + void + + + + + CompuMethods + + + boolean_CompuMethod + TEXTTABLE + + + + FALSE + 0 + 0 + + FALSE + + + + TRUE + 1 + 1 + + TRUE + + + + + + + + + DataConstrs + + + boolean_DataConstr + + + + 0 + 1 + + + + + + float32_DataConstr + + + + -INF + INF + + + + + + float64_DataConstr + + + + -INF + INF + + + + + + sint16_DataConstr + + + + -32768 + 32767 + + + + + + sint16_least_DataConstr + + + + -32768 + 32767 + + + + + + sint32_DataConstr + + + + -2147483648 + 2147483647 + + + + + + sint32_least_DataConstr + + + + -2147483648 + 2147483647 + + + + + + sint64_DataConstr + + + + -9223372036854775808 + 9223372036854775807 + + + + + + sint8_DataConstr + + + + -128 + 127 + + + + + + sint8_least_DataConstr + + + + -128 + 127 + + + + + + uint16_DataConstr + + + + 0 + 65535 + + + + + + uint16_least_DataConstr + + + + 0 + 65535 + + + + + + uint32_DataConstr + + + + 0 + 4294967295 + + + + + + uint32_least_DataConstr + + + + 0 + 4294967295 + + + + + + uint64_DataConstr + + + + 0 + 18446744073709551615 + + + + + + uint8_DataConstr + + + + 0 + 255 + + + + + + uint8_least_DataConstr + + + + 0 + 255 + + + + + + + + ImplementationDataTypes + + + dtRef_const_VOID + DATA_REFERENCE + + + + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/dtRef_const_VOID + CONST + + + + + + + + + + dtRef_VOID + DATA_REFERENCE + + + + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/dtRef_VOID + + + + + + + + + + boolean + + boolean has the value space required to support the mathematical concept of +binary-valued logic: {true, false}. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/boolean + NOT-ACCESSIBLE + /AUTOSAR_Platform/CompuMethods/boolean_CompuMethod + /AUTOSAR_Platform/DataConstrs/boolean_DataConstr + + + + Platform_Types.h + + + float32 + + float32 corresponds to the IEEE single-precision 32-bit floating point type +[IEEE 754-1985]. The basic value space of float32 consists of the values +m * 2^e, where m is an integer whose absolute value is less than 2^24, +and e is an integer between -149 and 104, inclusive. In addition to the basic +value space described above, the value space of float32 also contains the +following special values: positive and negative zero, positive and negative +infinity and not-a-number. The order-relation on float32 is: +x < y if y - x is positive. Positive zero is greater than negative zero. +Not-a-number equals itself and is greater than all float values including positive infinity. + +float32 values have a lexical representation consisting of a mantissa followed, +optionally, by the character "E" or "e", followed by an exponent. The exponent +must be an integer. The mantissa must be a decimal number. The representations +for exponent and mantissa must follow the lexical rules for integer and decimal. +If the "E" or "e" and the following exponent are omitted, an exponent value +of 0 is assumed. + +The special values positive and negative zero, positive and negative infinity +and not-a-number have lexical representations 0, -0, INF, -INF and NaN, +respectively. + +For example, -1E4, 1267.43233E12, 12.78e-2, 12 and INF are all legal literals +for float32. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/float32 + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/float32_DataConstr + + + + Platform_Types.h + + + float64 + + The float64 datatype corresponds to IEEE float64-precision 64-bit floating point +type [IEEE 754-1985]. The basic value space of float64 consists of the values +m * 2^e, where m is an integer whose absolute value is less than 2^53, and e is + an integer between -1075 and 970, inclusive. In addition to the basic value +space described above, the value space of float64 also contains the following +special values: positive and negative zero, positive and negative infinity +and not-a-number. +The order-relation on float64 is: x < y if y - x is positive. +Positive zero is greater than negative zero. Not-a-number equals itself and +is greater than all float64 values including positive infinity. + +float64 values have a lexical representation consisting of a mantissa followed, +optionally, by the character "E" or "e", followed by an exponent. +The exponent must be an integer. The mantissa must be a decimal number. +The representations for exponent and mantissa must follow the lexical rules +for integer and decimal. If the "E" or "e" and the following exponent are +omitted, an exponent value of 0 is assumed. + +The special values positive and negative zero, positive and negative infinity +and not-a-number have lexical representations 0, -0, INF, -INF and NaN, +respectively. + +For example, -1E4, 1267.43233E12, 12.78e-2, 12 and INF are all +legal literals for float64. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/float64 + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/float64_DataConstr + + + + Platform_Types.h + + + sint16 + + SInt16 represents integers with a minimum value of -32768 and a maximum value +of 32767. The order-relation on sint16 is: x < y if y - x is positive. +sint16 has a lexical representation consisting of an optional sign followed +by a finite-length sequence of decimal digits (#x30-#x39). If the sign is +omitted, "+" is assumed. + +For example: -1, 0, -12678, +10000, 2500 + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/sint16 + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/sint16_DataConstr + + + + Platform_Types.h + + + sint16_least + + sint16_least represents a signed integer with values defined by at least 16 bit. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/sint16_least + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/sint16_least_DataConstr + + + + Platform_Types.h + + + sint32 + + sint32 represents integers with a minimum value of -2147483648 and a maximum +value of 2147483647. The order-relation on sint32 is: x < y if y - x is +positive. sint32 has a lexical representation consisting of an optional sign +allowed by a finite-length sequence of decimal digits (#x30-#x39). If the +sign is omitted, "+" is assumed. + +For example: -1, 0, -12688778, +10000, 250098675. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/sint32 + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/sint32_DataConstr + + + + Platform_Types.h + + + sint32_least + + sint32_least represents a signed integer with values defined by at least 32 bit. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/sint32_least + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/sint32_least_DataConstr + + + + Platform_Types.h + + + sint64 + + sint64 represents integers with a minimum value of -9223372036854775808 and a maximum +value of 9223372036854775807. The order-relation on sint64 is: x < y if y - x is +positive. sint64 has a lexical representation consisting of an optional sign +allowed by a finite-length sequence of decimal digits (#x30-#x39). If the +sign is omitted, "+" is assumed. + +For example: -1, 0, -12688778, +10000, 250098675. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/sint64 + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/sint64_DataConstr + + + + Platform_Types.h + + + sint8 + + sint8 represents integers with a minimum value of -128 and a maximum value of 127. +The order-relation on sint8 is: x < y if y - x is positive. +sint8 has a lexical representation consisting of an optional sign followed +by a finite-length sequence of decimal digits (#x30-#x39). If the sign is +omitted, "+" is assumed. + +For example: -1, 0, 12678, +10000. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/sint8 + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/sint8_DataConstr + + + + Platform_Types.h + + + sint8_least + + sint8_least represents a signed integer with values defined by at least 8 bit. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/sint8_least + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/sint8_least_DataConstr + + + + Platform_Types.h + + + uint16 + + uint16 represents integers with a minimum value of 0 and a maximum value of 65535. +The order-relation on uint16 is: x < y if y - x is positive. +uint16 has a lexical representation consisting of a finite-length sequence +of decimal digits (#x30-#x39). + +For example: 1, 0, 1267, +10000. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/uint16 + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/uint16_DataConstr + + + + Platform_Types.h + + + uint16_least + + uint16_least represents an unsigned integer with values defined by at least 16 bit. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/uint16_least + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/uint16_least_DataConstr + + + + Platform_Types.h + + + uint32 + + uint32 represents integers with a minimum value of 0 and a maximum value +of 4294967295. The order-relation on uint32 is: x < y if y - x is positive. +uint32 has a lexical representation consisting of a finite-length sequence +of decimal digits (#x30-#x39). + +For example: 1, 0, 12234567, 104400. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/uint32 + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/uint32_DataConstr + + + + Platform_Types.h + + + uint32_least + + uint32_least represents an unsigned integer with values defined by at least 32 bit. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/uint32_least + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/uint32_least_DataConstr + + + + Platform_Types.h + + + uint64 + + uint64 represents integers with a minimum value of 0 and a maximum value +of 18446744073709551615. The order-relation on uint64 is: x < y if y - x is positive. +uint64 has a lexical representation consisting of a finite-length sequence +of decimal digits (#x30-#x39). + +For example: 1, 0, 12234567, 104400. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/uint64 + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/uint64_DataConstr + + + + Platform_Types.h + + + uint8 + + uint8 represents integers with a minimum value of 0 and a maximum value of 255. +The order-relation on uint8 is: x < y if y - x is positive. +uint8 has a lexical representation consisting of a finite-length sequence +of decimal digits (#x30-#x39). + +For example: 1, 0, 126, +10. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/uint8 + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/uint8_DataConstr + + + + Platform_Types.h + + + uint8_least + + uint8_least represents an unsigned integer with values defined by at least 8 bit. + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/uint8_least + NOT-ACCESSIBLE + /AUTOSAR_Platform/DataConstrs/uint8_least_DataConstr + + + + Platform_Types.h + + + VoidPtr + DATA_REFERENCE + + + + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/void + + + + + + + + Platform_Types.h + + + ConstVoidPtr + DATA_REFERENCE + + + + + VALUE + + + + /AUTOSAR_Platform/BaseTypes/void + CONST + + + + + + + + Platform_Types.h + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM.ecuc.Initial.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM.ecuc.Initial.arxml new file mode 100644 index 0000000..ee4910f --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM.ecuc.Initial.arxml @@ -0,0 +1,13 @@ + + + + + InitialEcuC + + + InitialEcuC + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM.ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM.ecuc.arxml new file mode 100644 index 0000000..df4aa7d --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM.ecuc.arxml @@ -0,0 +1,66 @@ + + + + + ActiveEcuC + + + ActiveEcuC + + + /ActiveEcuC/MemMap + + + /ActiveEcuC/Csm + + + /ActiveEcuC/FblSb + + + /ActiveEcuC/FblBm + + + /ActiveEcuC/Crypto + + + /ActiveEcuC/vBaseEnv + + + /ActiveEcuC/FblHal + + + /ActiveEcuC/Det + + + /ActiveEcuC/EcuC + + + /ActiveEcuC/Fbl + + + /ActiveEcuC/FblBmHdr + + + /ActiveEcuC/vLinkGen + + + /ActiveEcuC/vBRS + + + /ActiveEcuC/vSet + + + /ActiveEcuC/CryIf + + + /ActiveEcuC/Crypto_001 + + + /ActiveEcuC/FblAsrStubs + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_CryIf_CryIf_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_CryIf_CryIf_ecuc.arxml new file mode 100644 index 0000000..51eeaa1 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_CryIf_CryIf_ecuc.arxml @@ -0,0 +1,183 @@ + + + + + ActiveEcuC + + + CryIf + + + + false + + + + /MICROSAR/CryIf + VARIANT-PRE-COMPILE + /MICROSAR/CryIf_Impl + + + CryIfChannel + /MICROSAR/CryIf/CryIfChannel + + + /MICROSAR/CryIf/CryIfChannel/CryIfChannelId + 0 + + + + + /MICROSAR/CryIf/CryIfChannel/CryIfDriverObjectRef + /ActiveEcuC/Crypto/CryptoDriverObjects/Crypto_30_LibCv + + + + + CryIfCryptoModule + /MICROSAR/CryIf/CryIfCryptoModule + + + /MICROSAR/CryIf/CryIfCryptoModule/CryIfCancelJobApiUsesJobType + true + + + /MICROSAR/CryIf/CryIfCryptoModule/CryIfSupportsKeyElementCopyPartial + false + + + /MICROSAR/CryIf/CryIfCryptoModule/CryIfSupportsCertificateAPI + true + + + /MICROSAR/CryIf/CryIfCryptoModule/CryIfSupportsKeyStatusAPI + false + + + /MICROSAR/CryIf/CryIfCryptoModule/CryIfSupportsCustomSyncService + false + + + + + /MICROSAR/CryIf/CryIfCryptoModule/CryIfCryptoModuleRef + /ActiveEcuC/Crypto + + + + + CryIfKey_SmhKeyRSA + /MICROSAR/CryIf/CryIfKey + + + /MICROSAR/CryIf/CryIfKey/CryIfKeyId + 2 + + + + + /MICROSAR/CryIf/CryIfKey/CryIfKeyRef + /ActiveEcuC/Crypto/CryptoKeys/SmhKeyRSA + + + + + CryIfKey_Smh_Nist_800_90A + /MICROSAR/CryIf/CryIfKey + + + /MICROSAR/CryIf/CryIfKey/CryIfKeyId + 3 + + + + + /MICROSAR/CryIf/CryIfKey/CryIfKeyRef + /ActiveEcuC/Crypto/CryptoKeys/Smh_CryptoKey_Nist_800_90A + + + + + CryIfKeyDummy + /MICROSAR/CryIf/CryIfKey + + + /MICROSAR/CryIf/CryIfKey/CryIfKeyId + 0 + + + + + /MICROSAR/CryIf/CryIfKey/CryIfKeyRef + /ActiveEcuC/Crypto/CryptoKeys/SmhCryptoKeyDummy + + + + + CryIfChannel_CryptoCv_Fbl_MemDrvCmac + /MICROSAR/CryIf/CryIfChannel + + + /MICROSAR/CryIf/CryIfChannel/CryIfChannelId + 1 + + + + + /MICROSAR/CryIf/CryIfChannel/CryIfDriverObjectRef + /ActiveEcuC/Crypto/CryptoDriverObjects/Crypto_30_LibCv + + + + + CryIfKey_Fbl_MemDrv_Cmac + /MICROSAR/CryIf/CryIfKey + + + /MICROSAR/CryIf/CryIfKey/CryIfKeyId + 1 + + + + + /MICROSAR/CryIf/CryIfKey/CryIfKeyRef + /ActiveEcuC/Crypto/CryptoKeys/CryptoKey_Fbl_MemDrv_Cmac + + + + + CryIfGeneral + /MICROSAR/CryIf/CryIfGeneral + + + /MICROSAR/CryIf/CryIfGeneral/CryIfDevErrorDetect + true + + + /MICROSAR/CryIf/CryIfGeneral/CryIfVersionInfoApi + false + + + /MICROSAR/CryIf/CryIfGeneral/CryIfMaxNumberOfKeyElements + 10 + + + /MICROSAR/CryIf/CryIfGeneral/CryIfMaxSizeOfKeyElement + 32 + + + /MICROSAR/CryIf/CryIfGeneral/CryIfRedirection + false + + + /MICROSAR/CryIf/CryIfGeneral/CryIfSafeBswChecks + true + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_Crypto_Crypto_001_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_Crypto_Crypto_001_ecuc.arxml new file mode 100644 index 0000000..95117e2 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_Crypto_Crypto_001_ecuc.arxml @@ -0,0 +1,242 @@ + + + + + ActiveEcuC + + + Crypto_001 + /MICROSAR/Crypto_30_vHsm/Crypto + VARIANT-PRE-COMPILE + /MICROSAR/Crypto_30_vHsm/Crypto_Impl + + + CryptoGeneral + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoGeneral + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoGeneral/CryptoDevErrorDetect + true + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoGeneral/CryptoVersionInfoApi + false + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoGeneral/CryptoMainFunctionPeriod + 0.01 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoGeneral/CryptoSafeBswChecks + false + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoGeneral/CryptoMultiPartitionRuntimeChecks + false + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoGeneral/CryptoTimeoutCallout + false + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoGeneral/CryptoTimeoutRecovery + false + + + + + CryptoKeyElements + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoKeyElements + + + vHsmDummyKeyElement + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + true + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 0 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + + + + + CryptoKeyTypes + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoKeyTypes + + + vHsmDummyKeyType + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto_001/CryptoKeyElements/vHsmDummyKeyElement + + + + + + + CryptoDriverObjects + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoDriverObjects + + + CryptoDriverObject + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoDriverObjects/CryptoDriverObject + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoDriverObjectId + 0 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoDriverObjectQueueSize + 1 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoBufferSize + 128 + + + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoPrimitiveRef + + + + + + + CryptovHsm + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoKeyElementDeleteSupport + true + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoInterruptMode + true + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoIpcChannels + 4 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoIpcProtocolVersion + 3 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoRedirection + false + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoIpcMacJobOptimization + true + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoDetInstanceMask + 0 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoKeyDeriveJobSupport + true + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoHost2HsmAddress + 0 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoHsm2HostAddress + 0 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoIpcInstanceId + 0 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoIpcInitialization + true + + + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoManagementDriverObject + + + + + CryptoJobResponseInterrupt + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoJobResponseInterrupt + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoJobResponseInterrupt/CryptoJobResponseInterruptFlagClearAddress + 0 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoJobResponseInterrupt/CryptoJobResponseInterruptFlagClearMask + 1 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoJobResponseInterrupt/CryptoJobResponseInterruptFlagClearValue + 1 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoJobResponseInterrupt/CryptoJobResponseInterruptFlagClearing + true + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoJobResponseInterrupt/CryptoJobResponseInterruptFlagClearHandling + CRYPTO_CLEAR_INCLUSIVE_OR_ASSIGNMENT + + + + + CryptoJobRequestInterrupt + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoJobRequestInterrupt + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoJobRequestInterrupt/CryptoJobRequestInterruptFlagSetAddress + 0 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoJobRequestInterrupt/CryptoJobRequestInterruptFlagSetMask + 1 + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoJobRequestInterrupt/CryptoJobRequestInterruptFlagSetting + true + + + /MICROSAR/Crypto_30_vHsm/Crypto/CryptovHsm/CryptoJobRequestInterrupt/CryptoJobRequestInterruptFlagSetHandling + CRYPTO_SET_INCLUSIVE_OR_ASSIGNMENT + + + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_Crypto_Crypto_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_Crypto_Crypto_ecuc.arxml new file mode 100644 index 0000000..b990582 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_Crypto_Crypto_ecuc.arxml @@ -0,0 +1,14788 @@ + + + + + ActiveEcuC + + + Crypto + /MICROSAR/Crypto_30_LibCv/Crypto + VARIANT-PRE-COMPILE + /MICROSAR/Crypto_30_LibCv/Crypto_Impl + + + CryptoKeyElements + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements + + + Crypto_30_LibCv_Signature_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Seed + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 20 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyGenerate_Seed + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyGenerate_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_SharedValue + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_PrivKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 9 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Mac_Proof + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 48 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Salt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 13 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_OwnPubKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 10 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Base + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Password + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 64 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + true + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Cipher_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Cipher_IV + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Cipher_Proof + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 48 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 6 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Mac_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Hash_Result + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 20 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerive_Algorithm + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x00 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x00 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_X25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x00 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Algorithm_Fips186_Sha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x00 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Rsa_Modulus + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 160 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Rsa_Pub_Exponent + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 161 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Rsa_Priv_Exponent + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 162 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Rsa_Salt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 163 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Rsa_SaltLength + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 164 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_ANSIP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x01 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_PartnerPubKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 132 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + true + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3003 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_NIST80056A + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x03 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x04 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_SYM_NIST800108 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x01 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_ASM_NISTFIPS1864 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x02 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_AdditionalInfo + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 131 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_SCC_Contract_PubKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 132 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + true + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3013 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_SCC_IV_And_Encrypted_PrivKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + true + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3014 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Algorithm + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x01 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_AdditionalInput + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3016 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Nonce + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3017 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_PrivateString + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3015 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Reseed_Counter + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3018 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_DENIED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0 0 0 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Rsa_PrimeP + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3051 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Rsa_PrimeQ + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3052 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Rsa_ExponentDp + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3053 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Rsa_ExponentDq + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3054 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Rsa_InverseQi + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3055 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_SECP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x02 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_DENIED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Mac_Key_She + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ENCRYPTED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ENCRYPTED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Cipher_Key_She + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ENCRYPTED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ENCRYPTED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_She_UId + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3021 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_She_Counter + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0 0 0 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3019 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_DENIED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_She_BootProtection + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3056 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_She_DebuggerProtection + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3057 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_SCC_Contract_AAD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 34 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + true + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3060 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Label + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 130 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Smh_Crypto_30_LibCv_Rsa2048_Modulus + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 160 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Smh_Crypto_30_LibCv_Rsa_Pub_Exponent + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 161 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Smh_Crypto_30_LibCv_Rsa_Salt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 163 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Smh_Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x01 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Smh_Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_DENIED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Smh_Crypto_30_LibCv_Random_PrivateString + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3015 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Smh_Crypto_30_LibCv_Random_AdditionalInput + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3016 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Smh_Crypto_30_LibCv_Random_Reseed_Counter + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3018 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_DENIED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0 0 0 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Fbl_Decrypt_Aes128_Iv + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Fbl_Decrypt_Aes128_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Label + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3058 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_SECP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x04 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_KDF_X963_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x06 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Mac_Key_She_Ram + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ENCRYPTED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Cipher_Key_She_Ram + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ENCRYPTED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Cipher_2NDKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 7 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Symmetric_Generic + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Ansi_Nist_Sec_P256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Nist_Sec_P384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Iterations_PBKDF2 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 14 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_PBKDF2_HMAC_SHA1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x09 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_PBKDF2_HMAC_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0A + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_KDF_X963_SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x07 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Aead_ChaCha_Key + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Aead_ChaCha_Nonce + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES128_DF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_HASH_SHA2_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_HASH_SHA2_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_DENIED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 222 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES256Df + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_DENIED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 48 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_HMAC_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0B + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Iterations_HKDF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 14 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_Spake2Plus_P256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0C + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8_1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 6 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_W0 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3084 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_W1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3085 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_L + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3086 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Verification_Result + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3088 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_AdditionalInfo + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 131 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Verification + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3087 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Ed25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_PartnerPubKey_2 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3004 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_NISTP224R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_EcuId + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3007 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_NumEcu + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3006 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Intermediate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3005 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_Option1_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0D + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_SECP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x07 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_HMAC_SHA384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0E + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_Option1_SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x0F + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118_20 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x10 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_X448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 0x08 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp160r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 40 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp256r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 64 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp384r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 96 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp521r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 132 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EdDsa_Ed25519_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp160r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 20 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp256r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp384r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 48 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EcDsa_SECp521r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 66 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EdDsa_Ed25519_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EdDsa_Ed448_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 57 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_EdDsa_Ed448_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 57 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_EdDsa_Context + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3061 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_P256R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 9 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Nist_Sec_P521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_SlhDsaSha2_128s_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_Sm2_P256Sm2_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 32 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_Sm2Verify_P256Sm2_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 64 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_Sm2_ID + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3092 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_Signature_Sm2Generate_P256Sm2_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3093 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 64 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyGenerate_Algorithm_Sm2P256v1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 17 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Algorithm_NIST800108_CTR_CMAC_AES + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 15 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyDerivation_Context + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3061 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_SlhDsa_Context + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 3062 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyWrap_Aes_PlaintextKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyWrap_Aes_Kek + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 16 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + Crypto_30_LibCv_KeyExchange_Algorithm_P224R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementId + 12 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementInitValue + 10 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementSize + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementReadAccess + RA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementAllowPartialAccess + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementPersist + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteAccess + WA_ALLOWED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementFormat + CRYPTO_KE_FORMAT_BIN_OCTET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyElements/CryptoKeyElement/CryptoKeyElementWriteOnce + false + + + + + + + CryptoKeyTypes + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes + + + Smh_Signature_Rsa2048_Pss_Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Smh_Crypto_30_LibCv_Rsa2048_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Smh_Crypto_30_LibCv_Rsa_Pub_Exponent + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Smh_Crypto_30_LibCv_Rsa_Salt + + + + + Smh_Random_Nist_800_90A_DRBG_AES_NoDF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Smh_Crypto_30_LibCv_Random_AdditionalInput + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Smh_Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Smh_Crypto_30_LibCv_Random_Reseed_Counter + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Smh_Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES128 + + + + + CryptoKeyType_Fbl_Decrypt_Aes128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Fbl_Decrypt_Aes128_Iv + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Fbl_Decrypt_Aes128_Key + + + + + Cipher + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Cipher_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Cipher_IV + + + + + KeyExchange_X25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_X25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + KeyGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Seed + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + + + Signature + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_Key + + + + + Mac + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Mac_Key + + + + + KeyDerive + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerive_Algorithm + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Label + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Iterations_PBKDF2 + + + + + Random_Fips186_Sha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Fips186_Sha1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Seed + + + + + Hash + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Hash_Result + + + + + Signature_Rsa_Pkcs1_Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + + + Signature_Rsa_Pkcs1_Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Priv_Exponent + + + + + Signature_Rsa_Pss_Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_SaltLength + + + + + Signature_Rsa_Pss_Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Priv_Exponent + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Salt + + + + + Signature_Rsa_Pss_Verify_AutoSalt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + + + KeyExchange_ANSIP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_ANSIP256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + KeyDerive_NIST80056A + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_NIST80056A + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_AdditionalInfo + + + + + KeyDerive_ISO15118_ProvCert + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + + + KeyDerive_SYM_NIST800108 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_SYM_NIST800108 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Label + + + + + KeyDerive_ASM_NISTFIPS1864 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_ASM_NISTFIPS1864 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Label + + + + + KeyDerive_ISO15118_ContrCert + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_SCC_Contract_PubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_SCC_IV_And_Encrypted_PrivKey + + + + + CipherWithoutIv + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Cipher_Key + + + + + CipherShe + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Cipher_Key_She + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Cipher_IV + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Cipher_Proof + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_She_Counter + + + + + MacShe + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Mac_Key_She + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Mac_Proof + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_She_Counter + + + + + Random_Nist_800_90A_DRBG_AES_DF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES128_DF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_PrivateString + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_AdditionalInput + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Reseed_Counter + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Nonce + + + + + Random_Nist_800_90A_DRBG_AES_NoDF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_PrivateString + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_AdditionalInput + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Reseed_Counter + + + + + Signature_RsaCrt_Pkcs1_Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeQ + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDp + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDq + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_InverseQi + + + + + KeyExchange_SECP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_SECP256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + SheInfoKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_She_UId + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_She_BootProtection + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_She_DebuggerProtection + + + + + Cipher_Rsa_Oaep_Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + + + Cipher_Rsa_Oaep_Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Priv_Exponent + + + + + Cipher_RsaCrt_Oaep_Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeQ + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDp + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDq + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_InverseQi + + + + + Cipher_Rsa_Pkcs1_Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + + + Cipher_Rsa_Pkcs1_Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Priv_Exponent + + + + + Cipher_Rsa_Oaep_Encrypt_With_Label + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Label + + + + + Cipher_Rsa_Oaep_Decrypt_With_Label + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Priv_Exponent + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Label + + + + + Cipher_RsaCrt_Oaep_Decrypt_With_Label + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_PrimeQ + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDp + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_ExponentDq + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_InverseQi + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Label + + + + + KeyExchange_SECP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_SECP384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + Cipher_Rsa_Pkcs1_Decrypt_Pub + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Modulus + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Rsa_Pub_Exponent + + + + + KeyDerive_KDF_X963_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_KDF_X963_SHA256 + + + + + CipherSheRam + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Cipher_Key_She_Ram + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Cipher_IV + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Cipher_Proof + + + + + MacSheRam + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Mac_Key_She_Ram + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Mac_Proof + + + + + MacGmac + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Mac_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Cipher_IV + + + + + KeyGenerate_Symmetric_Generic + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Symmetric_Generic + + + + + KeyGenerate_Ansi_Nist_Sec_P256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Ansi_Nist_Sec_P256R1 + + + + + KeyGenerate_Nist_Sec_P384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Nist_Sec_P384R1 + + + + + KeyDerive_PBKDF2_HMAC_SHA1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Iterations_PBKDF2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_PBKDF2_HMAC_SHA1 + + + + + KeyDerive_PBKDF2_HMAC_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Iterations_PBKDF2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_PBKDF2_HMAC_SHA256 + + + + + KeyDerive_KDF_X963_SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_KDF_X963_SHA512 + + + + + AEAD_ChaCha20_Poly1305 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Aead_ChaCha_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Aead_ChaCha_Nonce + + + + + Random_Nist_800_90A_DRBG_HASH_SHA2_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_HASH_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_HASH_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_PrivateString + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_AdditionalInput + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Reseed_Counter + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Nonce + + + + + Random_Nist_800_90A_DRBG_AES256_NoDF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_PrivateString + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_AdditionalInput + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Reseed_Counter + + + + + Random_Nist_800_90A_DRBG_AES256_DF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Algorithm_Nist_800_90A_DRBG_AES256Df + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Seed_Nist_800_90A_DRBG_AES256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_PrivateString + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_AdditionalInput + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Reseed_Counter + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Random_Nonce + + + + + KeyDerive_HKDF_HMAC_SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Iterations_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_HMAC_SHA256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_AdditionalInfo + + + + + KeyDerive_Spake2Plus_P256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_Spake2Plus_P256R1 + + + + + KeyExchange_Spake2Plus_A_Suite8_1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8_1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_W0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_W1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Verification_Result + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Verification + + + + + KeyExchange_Spake2Plus_B_Suite8_1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8_1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_W0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_L + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Verification_Result + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Verification + + + + + KeyExchange_Spake2Plus_A_Suite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_W0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_W1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Verification_Result + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Verification + + + + + KeyExchange_Spake2Plus_B_Suite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_Spake2Plus_Suite8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_W0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_L + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Verification_Result + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Verification + + + + + KeyGenerate_ED25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Ed25519 + + + + + KeyExchange_NISTP224R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_NISTP224R1_BD + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_NumEcu + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_EcuId + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Intermediate + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey_2 + + + + + KeyDerive_Hkdf_Option1_Sha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_Option1_SHA256 + + + + + KeyExchange_SECP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_SECP521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + KeyDerive_HKDF_HMAC_SHA384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Salt + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Iterations_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_HMAC_SHA384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_AdditionalInfo + + + + + KeyDerive_Hkdf_Option1_Sha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_AdditionalInfo + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_HKDF_Option1_SHA512 + + + + + KeyDerive_ISO15118_20_ProvCert + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118_20 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + + + KeyDerive_ISO15118_20_ContrCert + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_ISO15118_20 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_SCC_Contract_PubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_SCC_IV_And_Encrypted_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_SCC_Contract_AAD + + + + + KeyExchange_X448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_X448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + Signature_EcDsa_SECp160r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp160r1_public + + + + + Signature_EcDsa_SECp256r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp256r1_public + + + + + Signature_EcDsa_SECp384r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp384r1_public + + + + + Signature_EcDsa_SECp521r1_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp521r1_public + + + + + Signature_EdDsa_Ed25519_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed25519_public + + + + + Signature_EcDsa_SECp160r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp160r1_private + + + + + Signature_EcDsa_SECp256r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp256r1_private + + + + + Signature_EcDsa_SECp384r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp384r1_private + + + + + Signature_EcDsa_SECp521r1_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EcDsa_SECp521r1_private + + + + + Signature_EdDsa_Ed25519_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed25519_private + + + + + Signature_EdDsa_Ed448_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed448_public + + + + + Signature_EdDsa_Ed448_private + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed448_private + + + + + Signature_EdDsa_Ed448_public_ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed448_public + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_EdDsa_Context + + + + + Signature_EdDsa_Ed448_private_ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed448_private + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_EdDsa_Context + + + + + Signature_EdDsa_Ed25519_public_ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed25519_public + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_EdDsa_Context + + + + + Signature_EdDsa_Ed25519_private_ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_EdDsa_Ed25519_private + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_EdDsa_Context + + + + + KeyExchange_P256R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_P256R1_BD + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_NumEcu + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_EcuId + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Intermediate + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PartnerPubKey_2 + + + + + KeyGenerate_Nist_Sec_P521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Nist_Sec_P521R1 + + + + + Signature_SlhDsaSha2_128s_public + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_SlhDsaSha2_128s_public + + + + + Signature_Sm2_P256Sm2_Generate_withoutID + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2_P256Sm2_private + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2Generate_P256Sm2_public + + + + + Signature_Sm2_P256Sm2_Verify_withoutID + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2Verify_P256Sm2_public + + + + + Signature_Sm2_P256Sm2_Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2_P256Sm2_private + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2Generate_P256Sm2_public + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2_ID + + + + + Signature_Sm2_P256Sm2_Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2Verify_P256Sm2_public + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_Sm2_ID + + + + + KeyGenerate_Sm2P256V1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Key + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyGenerate_Algorithm_Sm2P256v1 + + + + + KeyDerive_NIST800108_CTR_CMAC_AES + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Algorithm_NIST800108_CTR_CMAC_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Label + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Context + + + + + KeyDerive_NIST800108_CTR + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Password + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Label + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyDerivation_Context + + + + + Signature_SlhDsaSha2_128s_public_ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_Signature_SlhDsaSha2_128s_public + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_SlhDsa_Context + + + + + KeyWrap_Aes_PlaintextKey + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyWrap_Aes_PlaintextKey + + + + + KeyWrap_Aes_Kek + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyWrap_Aes_Kek + + + + + KeyExchange_P224R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_Algorithm_P224R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_OwnPubKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_PrivKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeyTypes/CryptoKeyType/CryptoKeyElementRef + /ActiveEcuC/Crypto/CryptoKeyElements/Crypto_30_LibCv_KeyExchange_SharedValue + + + + + + + CryptoDriverObjects + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects + + + Crypto_30_LibCv + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects/CryptoDriverObject + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoDriverObjectId + 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoDriverObjectQueueSize + 1 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoPrimitiveRef + /ActiveEcuC/Crypto/CryptoPrimitives/RsaPssSha256Verify + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoPrimitiveRef + /ActiveEcuC/Crypto/CryptoPrimitives/SHA256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoPrimitiveRef + /ActiveEcuC/Crypto/CryptoPrimitives/RngDrbgAes128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoDriverObjects/CryptoDriverObject/CryptoPrimitiveRef + /ActiveEcuC/Crypto/CryptoPrimitives/AesCmacGenerate + + + + + + + CryptoGeneral + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoUseVStdLib + true + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoWatchdogTriggerFunction + FblLookForWatchdogVoid + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoVersionInfoApi + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoMainFunctionPeriod + 0.01 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoDevErrorDetect + true + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoSafeBswChecks + true + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoKeyElementDelete + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoAlignKeyStorage + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoNvMEnableSetRamBlockStatus + true + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoRedirection + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoDefaultRandomMaxRetries + 10 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoNumberOfLongTermPrimitiveWorkspace + 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoStrictLengthCheckForKeyElementGet + true + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoEnableKeyLocking + true + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoMultiPartitionRuntimeChecks + false + + + + + CryptoKeyExchangePrimitives + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoKeyExchangePrimitives + + + CryptoKeyDerivePrimitives + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoKeyDerivePrimitives + + + CryptoMacPrimitives + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoMacPrimitives + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoMacPrimitives/CryptoCmacAesRoundkeyReuse + false + + + + + CryptoCipherPrimitives + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoCipherPrimitives + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoCipherPrimitives/CryptoEnableAES192 + false + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoCipherPrimitives/CryptoEnableAES256 + false + + + + + CryptoKeyGeneratePrimitives + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoKeyGeneratePrimitives + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoKeyGeneratePrimitives/CryptoKeyGenerateMaxLength + 32 + + + + + CryptoConfigurableCallouts + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoGeneral/CryptoConfigurableCallouts + + + + + CryptoKeys + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys + + + SmhKeyRSA + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyId + 0 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyDeriveIterations + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyNvId + 0 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyTypeRef + /ActiveEcuC/Crypto/CryptoKeyTypes/Smh_Signature_Rsa2048_Pss_Verify + + + + + Smh_CryptoKey_Nist_800_90A + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyId + 2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyDeriveIterations + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyNvId + 2 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyTypeRef + /ActiveEcuC/Crypto/CryptoKeyTypes/Smh_Random_Nist_800_90A_DRBG_AES_NoDF + + + + + SmhCryptoKeyDummy + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyId + 3 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyDeriveIterations + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyNvId + 3 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyTypeRef + /ActiveEcuC/Crypto/CryptoKeyTypes/Hash + + + + + CryptoKey_Fbl_MemDrv_Cmac + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyId + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyNvId + 7 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyDeriveIterations + 1 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyTypeRef + /ActiveEcuC/Crypto/CryptoKeyTypes/CryptoKeyType_Fbl_Decrypt_Aes128 + + + + + CryptoKey_Fbl_Decrypt_Aes128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyNvId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyId + 1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyDeriveIterations + 1 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoKeys/CryptoKey/CryptoKeyTypeRef + /ActiveEcuC/Crypto/CryptoKeyTypes/CryptoKeyType_Fbl_Decrypt_Aes128 + + + + + + + CryptoPrimitives + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives + + + AesGCMEncrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_GCM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + AesGCMDecrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_GCM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADDECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + AesEncrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_ECB + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_ENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CBC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_PADDING_PKCS7 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_PADDING_ONEWITHZEROS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CTR + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_PADDING_PKCS7 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_PaddingPKCS7 + + + + + AesDecrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_ECB + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CBC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_PADDING_PKCS7 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_PADDING_ONEWITHZEROS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CTR + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_PADDING_PKCS7 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_PaddingPKCS7 + + + + + SHA1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA1 + + + + + SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + AesCmacGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + AesCmacVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + RngFips186Sha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_FIPS186 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_FIPS186 + + + + + EcDsaEd25519Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + EcDsaEd25519Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + SipHashGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SIPHASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_SIPHASH_2_4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + SipHashVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SIPHASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_SIPHASH_2_4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + RsaPkcs1Sha1Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + RsaPkcs1Sha1Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + RsaPkcs1Sha256Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + RsaPkcs1Sha256Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + RsaPssSha1Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + RsaPssSha1Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + RsaPssSha256Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + RsaPssSha256Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + RsaPkcs1Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + RsaPkcs1Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_ENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_PKCS1_v1_5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + EccNistP256R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + HmacSha1Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + + + HmacSha1Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + + + HmacSha256Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + + + HmacSha256Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + + + EccNistP256R1GenerateSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1GenerateSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1VerifySha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1VerifySha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1GenerateSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1GenerateSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1VerifySha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1VerifySha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1GenerateSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1GenerateSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1VerifySha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1VerifySha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + RngFips186 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RNG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + RngDrbgAes128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_DRBG + + + + + RngDrbgAes128Df + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_USE_DF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_UseDF + + + + + RsaPkcs1CrtSha1Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_RSASSA_PKCS1_v1_5_CRT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_RSASSA_PKCS1_v1_5_CRT + + + + + RsaPkcs1CrtSha256Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_RSASSA_PKCS1_v1_5_CRT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_RSASSA_PKCS1_v1_5_CRT + + + + + EccNistP384R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + + + EccSecP384R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + + + EccNistP384R1GenerateSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1GenerateSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1VerifySha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1VerifySha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1GenerateSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1GenerateSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1VerifySha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1VerifySha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + RsaOaepSha1Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_OAEP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_ENCRYPT + + + + + RsaOaepSha1Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_OAEP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + + + RsaOaepSha256Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_OAEP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_ENCRYPT + + + + + RsaOaepSha256Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSAES_OAEP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + + + RsaOaepCrtSha1Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_RSAES_OAEP_CRT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_RSAES_OAEP_CRT + + + + + RsaOaepCrtSha256Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_RSAES_OAEP_CRT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_RSAES_OAEP_CRT + + + + + EccNistP256R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP384R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + SHA384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_384 + + + + + EccNistP256R1GenerateSha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP256R1VerifySha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1GenerateSha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccAnsiP256R1VerifySha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1GenerateSha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccSecP256R1VerifySha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + EccNistP384R1GenerateSha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccNistP384R1VerifySha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1GenerateSha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + EccSecP384R1VerifySha384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + GmacAesGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_GMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + GmacAesVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_GMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + + + HmacSha384Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + + + HmacSha384Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + + + KeySetValid + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_SET_VALID + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + KeyDeriveX963SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_KDFX963 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + KeyExchangeCalcPubValX25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_X25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_X25519 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_X25519 + + + + + KeyExchangeCalcSecretX25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_X25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_X25519 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_X25519 + + + + + KeyExchangeCalcPubValSecP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcPubValSecP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + KeyExchangeCalcSecretSecP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcSecretSecP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + KeyExchangeCalcPubValAnsiP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcSecretAnsiP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcPubValNistP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcSecretNistP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyExchangeCalcPubValNistP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + KeyExchangeCalcSecretNistP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + RandomSeedRngFips186Sha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_FIPS186 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + RandomSeedRngDrbgAes128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + + + RandomSeedRngDrbgAes128Df + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_USE_DF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_UseDF + + + + + KeyDeriveIso15118 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_ISO15118 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ISO15118 + + + + + KeyDeriveSymNist800108CntModeSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CTR + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + KeyDeriveAsymNistFips1864Erb + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_FIPS186 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + KeyDeriveNist80056AOnePassSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyGenerateSymmetricGeneric + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + KeyGenerateSecP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyGenerateSecP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + KeyGenerateNistP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + KeyGenerateNistP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P384R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + + + KeyGenerateAnsiP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + HmacRipemd160Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RIPEMD160 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + HmacRipemd160Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RIPEMD160 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + EccSecP160R1GenerateWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P160R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P160r1 + + + + + EccSecP160R1VerifyWithoutPreHashing + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P160R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P160r1 + + + + + HashRipemd160 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RIPEMD160 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + KeyDerivePbkdf2HmacSha1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_PBKDF2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA1 + + + + + KeyDerivePbkdf2HmacSha256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_PBKDF2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + KeyDeriveX963SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_KDFX963 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + AeadChaCha20Poly1305Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_20ROUNDS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CHACHA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_POLY_1305 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_POLY1305 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_POLY1305 + + + + + AeadChaCha20Poly1305Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADDECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_20ROUNDS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CHACHA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_POLY_1305 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_POLY1305 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_POLY1305 + + + + + RngHashDrbgSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + RandomSeedRngHashDrbgSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + SHA3_256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA3_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + RngDrbgAes256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + + + RngDrbgAes256Df + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_USE_DF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_UseDF + + + + + RandomSeedRngDrbgAes256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + + + RandomSeedRngDrbgAes256Df + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_RANDOM_SEED + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_USE_DF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_DRBG + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_UseDF + + + + + SheCmdGetId + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_CMD_GET_ID + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_CmdGetId + + + + + AesCCMEncrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_CCM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_CCM + + + + + AesCCMDecrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_CCM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_AEADDECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_CCM + + + + + KeyDeriveHkdfHmacSHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_HKDF + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_HKDF + + + + + KeyExchangeCalcPubValSpake2PlusCipherSuite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_SPAKE2_PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_MODE_1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_CIPHER_SUITE_8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_CipherSuite8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SPAKE2PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_Mode1 + + + + + KeyExchangeCalcSecretSpake2PlusCipherSuite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_SPAKE2_PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_MODE_1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_CIPHER_SUITE_8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_CipherSuite8 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SPAKE2PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_Mode1 + + + + + KeyDeriveSpake2PlusP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_SPAKE2_PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P256R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SPAKE2PLUS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + + + HashMD5 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_MD5 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_MD5 + + + + + KeyGenerateEd25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + Crypto_30_LibCv_PaddingPKCS7 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 133 + + + + + Crypto_30_LibCv_FIPS186 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 132 + + + + + Crypto_30_LibCv_ECCANSI + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 129 + + + + + Crypto_30_LibCv_ECCSEC + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 130 + + + + + Crypto_30_LibCv_DRBG + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 131 + + + + + Crypto_30_LibCv_X25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 135 + + + + + Crypto_30_LibCv_ISO15118 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 136 + + + + + Crypto_30_LibCv_POLY1305 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 137 + + + + + Crypto_30_LibCv_CmdGetId + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 140 + + + + + Crypto_30_LibCv_HKDF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 139 + + + + + Crypto_30_LibCv_SPAKE2PLUS + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 138 + + + + + Crypto_30_LibCv_CipherSuite8 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 157 + + + + + Crypto_30_LibCv_MD5 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 191 + + + + + Crypto_30_LibCv_CCM + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 147 + + + + + Crypto_30_LibCv_Mode1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 150 + + + + + Crypto_30_LibCv_P160r1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 146 + + + + + Crypto_30_LibCv_P256r1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 128 + + + + + Crypto_30_LibCv_P384r1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 131 + + + + + Crypto_30_LibCv_RSAES_OAEP_CRT + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 132 + + + + + Crypto_30_LibCv_RSASSA_PKCS1_v1_5_CRT + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 129 + + + + + Crypto_30_LibCv_UseDF + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 130 + + + + + KeyExchangeCalcPubValNistP224R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P224R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_BD + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P224r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_BD + + + + + KeyExchangeCalcSecretNistP224R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P224R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM_BD + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P224r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_BD + + + + + Crypto_30_LibCv_P224r1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 148 + + + + + Crypto_30_LibCv_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 141 + + + + + KeyDeriveHkdfOption1SHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_HKDF + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_HKDF + + + + + EccSecP521R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + Crypto_30_LibCv_P521r1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 134 + + + + + EccSecP521R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyExchangeCalcSecretSecP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyExchangeCalcPubValSecP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + SHA3_224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA3_224 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + SHA3_384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA3_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + SHA3_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA3_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + SHAKE128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHAKE128 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + SHAKE256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHAKE256 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + EccNistP521R1GenerateSha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + EccNistP521R1VerifySha512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyExchangeCalcSecretNistP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyExchangeCalcPubValNistP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM_P521R1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyDeriveHkdfHmacSHA384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_HKDF + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_HKDF + + + + + KeyDeriveHkdfOption1SHA512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_HKDF + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + KeyDeriveIso15118_20 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ISO15118_20 + + + + + Crypto_30_LibCv_ISO15118_20 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 193 + + + + + KeyExchangeCalcPubValX448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_X448 + + + + + KeyExchangeCalcSecretX448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_X448 + + + + + Crypto_30_LibCv_X448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 194 + + + + + Crypto_30_LibCv_ED448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 195 + + + + + Crypto_30_LibCv_EdDsaEd448Pure + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 199 + + + + + Crypto_30_LibCv_EdDsaEd448Ph + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 200 + + + + + Crypto_30_LibCv_EdDsaEd25519Pure + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 174 + + + + + Crypto_30_LibCv_EdDsaEd25519Ctx + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 175 + + + + + Crypto_30_LibCv_EdDsaEd25519Ph + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 176 + + + + + EdDsaEd448PhGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHAKE256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ED448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd448Ph + + + + + EdDsaEd448PhVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHAKE256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ED448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd448Ph + + + + + EdDsaEd25519PureVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Pure + + + + + EdDsaEd25519PhVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Ph + + + + + EdDsaEd25519CtxVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Ctx + + + + + EdDsaEd25519PhGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Ph + + + + + EdDsaEd25519CtxGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Ctx + + + + + EdDsaEd25519PureGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd25519Pure + + + + + EdDsaEd448PureGenerate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ED448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd448Pure + + + + + EdDsaEd448PureVerify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ED448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_EdDsaEd448Pure + + + + + HmacSha512Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_GENERATE + + + + + HmacSha512Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_512 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_MAC_VERIFY + + + + + Crypto_30_LibCv_HKDF_Expand + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 197 + + + + + KeyDeriveHkdfExpandHmacSHA256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_HKDF_Expand + + + + + KeyDeriveHkdfExpandHmacSHA384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_HMAC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_HKDF_Expand + + + + + Crypto_30_LibCv_IsPrivateKeyOnCurve + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 198 + + + + + Crypto_30_LibCv_IsPublicKeyOnCurve + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 196 + + + + + IsKeyOnCurveP160R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P160r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + IsKeyOnCurveP256R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + IsKeyOnCurveP384R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P384r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + IsKeyOnCurveP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + IsKeyOnCurveEd25519 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ED25519 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + IsKeyOnCurveEd448 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_ED448 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPrivateKeyOnCurve + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_IsPublicKeyOnCurve + + + + + KeyExchangeCalcPubValP256R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_BD + + + + + KeyExchangeCalcSecretP256R1_BD + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCANSI + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P256r1 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_BD + + + + + KeyGenerateSecP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + KeyGenerateNistP521R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P521r1 + + + + + SlhDsaSha2_128sVerifyPure + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + Crypto_30_LibCv_SLH_DSA + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 199 + + + + + Crypto_30_LibCv_SHA2_128S + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 201 + + + + + Crypto_30_LibCv_SM4 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 200 + + + + + Sm4Encrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_ENCRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CBC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_ECB + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SM4 + + + + + Sm4Decrypt + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_DECRYPT + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CBC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_ECB + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SM4 + + + + + Sm3 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SM3 + + + + + Sm2Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SM2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_Sm2P256v1 + + + + + Sm2Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SM2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_Sm2P256v1 + + + + + Crypto_30_LibCv_Sm2P256v1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmModeCustom/CryptoPrimitiveAlgorithmModeCustomId + 202 + + + + + KeyGenerate_SM2_Sm2P256V1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SM2 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_Sm2P256v1 + + + + + RsaPssSha384Generate + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_GENERATE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + + + RsaPssSha384Verify + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + + + KeySetInvalid + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEYSETINVALID + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + KeyDeriveNist800108CtrModeCmacAes + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_DERIVE + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CTR + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_NIST800108 + + + + + Crypto_30_LibCv_NIST800108 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitiveAlgorithmFamilyCustom/CryptoPrimitiveAlgorithmFamilyCustomId + 202 + + + + + SHA512_224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_512_224 + + + + + SHA512_256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_512_256 + + + + + SHA224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_HASH + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_224 + + + + + SlhDsaSha2_128sVerifyPhSha2_256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha2_384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_384 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha2_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha2_224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_224 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha2_512_224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512_224 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha2_512_256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_512_256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha3_224 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA3_224 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha3_384 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA3_384 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha3_512 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA3_512 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhShake128 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHAKE128 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhShake256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHAKE256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + SlhDsaSha2_128sVerifyPhSha3_256 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_SIGNATURE_VERIFY + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA3_256 + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamilyCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SLH_DSA + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_SHA2_128S + + + + + KeyWrapAes + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_AESKEYWRAP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEYWRAP + + + + + KeyUnwrapAes + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_AESKEYWRAP + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEYUNWRAP + + + + + KeyExchangeCalcPubValP224R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_PUBVAL + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P224r1 + + + + + KeyExchangeCalcSecretValP224R1 + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveService + CRYPTO_KEY_EXCHANGE_CALC_SECRET + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCNIST + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmFamily + CRYPTO_ALGOFAM_ECCSEC + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmMode + CRYPTO_ALGOMODE_CUSTOM + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoPrimitives/CryptoPrimitive/CryptoPrimitiveAlgorithmModeCustomRef + /ActiveEcuC/Crypto/CryptoPrimitives/Crypto_30_LibCv_P224r1 + + + + + + + CryptoNvStorage + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoNvStorage + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoNvStorage/CryptoNvManagementDataPerKey + 4 + + + /MICROSAR/Crypto_30_LibCv/Crypto/CryptoNvStorage/CryptoNvWriteBlockFctName + NvM_WriteBlock + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_Csm_Csm_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_Csm_Csm_ecuc.arxml new file mode 100644 index 0000000..4135edc --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_Csm_Csm_ecuc.arxml @@ -0,0 +1,661 @@ + + + + + ActiveEcuC + + + Csm + + + + false + + + + /MICROSAR/Csm + VARIANT-PRE-COMPILE + /MICROSAR/Csm_Impl + + + CsmJobs + /MICROSAR/Csm/CsmJobs + + + CsmJob_RandomGenerate + /MICROSAR/Csm/CsmJobs/CsmJob + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobPriority + 0 + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobId + 2 + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobUsePort + false + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobInterfaceUsePort + CRYPTO_USE_FNC + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmProcessingMode + CRYPTO_PROCESSING_SYNC + + + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobQueueRef + /ActiveEcuC/Csm/CsmQueues/CsmQueue_Standard + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobPrimitiveRef + /ActiveEcuC/Csm/CsmPrimitives_RandomGenerate + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobKeyRef + /ActiveEcuC/Csm/CsmKeys/CsmKey_Smh_Nist_800_90A + + + + + CsmJob_SigAsymVer_RsaPssSha256 + /MICROSAR/Csm/CsmJobs/CsmJob + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobPriority + 0 + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobId + 3 + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobUsePort + false + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobInterfaceUsePort + CRYPTO_USE_FNC + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmProcessingMode + CRYPTO_PROCESSING_SYNC + + + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobQueueRef + /ActiveEcuC/Csm/CsmQueues/CsmQueue_Standard + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobPrimitiveRef + /ActiveEcuC/Csm/CsmPrimitives_SigAsymVer_RsaPssSha256 + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobKeyRef + /ActiveEcuC/Csm/CsmKeys/CsmKey_SmhKeyRSA + + + + + CsmJob_HashSha256 + /MICROSAR/Csm/CsmJobs/CsmJob + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobId + 0 + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobPriority + 0 + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobUsePort + false + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobInterfaceUsePort + CRYPTO_USE_FNC + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmProcessingMode + CRYPTO_PROCESSING_SYNC + + + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobKeyRef + /ActiveEcuC/Csm/CsmKeys/CsmKey_Smh_HashSha256 + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobPrimitiveRef + /ActiveEcuC/Csm/CsmPrimitives_HashSha256 + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobQueueRef + /ActiveEcuC/Csm/CsmQueues/CsmQueue_Standard + + + + + CsmJob_MacGenerate_MemDrvCmac + /MICROSAR/Csm/CsmJobs/CsmJob + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobId + 1 + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobPriority + 0 + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmProcessingMode + CRYPTO_PROCESSING_SYNC + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobUsePort + false + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobInterfaceUsePort + CRYPTO_USE_FNC + + + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobKeyRef + /ActiveEcuC/Csm/CsmKeys/CsmKey_Fbl_MemDrv_Cmac + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobPrimitiveRef + /ActiveEcuC/Csm/CsmPrimitives_Cmac_Generate + + + /MICROSAR/Csm/CsmJobs/CsmJob/CsmJobQueueRef + /ActiveEcuC/Csm/CsmQueues/CsmQueue_Mac + + + + + + + CsmQueues + /MICROSAR/Csm/CsmQueues + + + CsmQueue_Standard + /MICROSAR/Csm/CsmQueues/CsmQueue + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmQueueSize + 1 + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmTriggerAsynchJobsInCallback + false + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmJobSharing + true + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmOperationModeLimitation + false + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmQueueProcessingMode + CRYPTO_PROCESSING_SYNC + + + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmChannelRef + /ActiveEcuC/CryIf/CryIfChannel + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmQueueMainFunctionRef + /ActiveEcuC/Csm/CsmMainFunction + + + + + CsmQueue_Mac + /MICROSAR/Csm/CsmQueues/CsmQueue + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmQueueSize + 1 + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmTriggerAsynchJobsInCallback + false + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmJobSharing + true + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmOperationModeLimitation + false + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmQueueProcessingMode + CRYPTO_PROCESSING_SYNC + + + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmChannelRef + /ActiveEcuC/CryIf/CryIfChannel_CryptoCv_Fbl_MemDrvCmac + + + /MICROSAR/Csm/CsmQueues/CsmQueue/CsmQueueMainFunctionRef + /ActiveEcuC/Csm/CsmMainFunction + + + + + + + CsmKeys + /MICROSAR/Csm/CsmKeys + + + CsmKey_Smh_HashSha256 + /MICROSAR/Csm/CsmKeys/CsmKey + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyId + 2 + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyUsePort + false + + + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyRef + /ActiveEcuC/CryIf/CryIfKeyDummy + + + + + CsmKey_SmhKeyRSA + /MICROSAR/Csm/CsmKeys/CsmKey + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyId + 1 + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyUsePort + false + + + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyRef + /ActiveEcuC/CryIf/CryIfKey_SmhKeyRSA + + + + + CsmKey_Smh_Nist_800_90A + /MICROSAR/Csm/CsmKeys/CsmKey + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyId + 3 + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyUsePort + false + + + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyRef + /ActiveEcuC/CryIf/CryIfKey_Smh_Nist_800_90A + + + + + CsmKey_Fbl_MemDrv_Cmac + /MICROSAR/Csm/CsmKeys/CsmKey + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyId + 0 + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyUsePort + false + + + + + /MICROSAR/Csm/CsmKeys/CsmKey/CsmKeyRef + /ActiveEcuC/CryIf/CryIfKey_Fbl_MemDrv_Cmac + + + + + + + CsmPrimitives_RandomGenerate + /MICROSAR/Csm/CsmPrimitives + + + CsmRandomGenerate + /MICROSAR/Csm/CsmPrimitives/CsmRandomGenerate + + + CsmPrimitives_RandomGenerate + /MICROSAR/Csm/CsmPrimitives/CsmRandomGenerate/CsmRandomGenerateConfig + + + /MICROSAR/Csm/CsmPrimitives/CsmRandomGenerate/CsmRandomGenerateConfig/CsmRandomGenerateAlgorithmFamiliy + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Csm/CsmPrimitives/CsmRandomGenerate/CsmRandomGenerateConfig/CsmRandomGenerateAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Csm/CsmPrimitives/CsmRandomGenerate/CsmRandomGenerateConfig/CsmRandomGenerateAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Csm/CsmPrimitives/CsmRandomGenerate/CsmRandomGenerateConfig/CsmRandomGenerateProcessing + CSM_SYNCHRONOUS + + + /MICROSAR/Csm/CsmPrimitives/CsmRandomGenerate/CsmRandomGenerateConfig/CsmRandomGenerateAlgorithmFamily + CRYPTO_ALGOFAM_CUSTOM + + + /MICROSAR/Csm/CsmPrimitives/CsmRandomGenerate/CsmRandomGenerateConfig/CsmRandomGenerateResultLength + 16 + + + /MICROSAR/Csm/CsmPrimitives/CsmRandomGenerate/CsmRandomGenerateConfig/CsmRandomGenerateAlgorithmFamilyCustom + CRYPTO_ALGOFAM_CUSTOM_DRBG + + + /MICROSAR/Csm/CsmPrimitives/CsmRandomGenerate/CsmRandomGenerateConfig/CsmRandomGenerateAlgorithmSecondaryFamilyCustom + CRYPTO_ALGOFAM_AES + + + + + + + + + CsmPrimitives_SigAsymVer_RsaPssSha256 + /MICROSAR/Csm/CsmPrimitives + + + CsmSignatureVerify + /MICROSAR/Csm/CsmPrimitives/CsmSignatureVerify + + + CsmPrimitives_SigAsymVer_RsaPssSha256 + /MICROSAR/Csm/CsmPrimitives/CsmSignatureVerify/CsmSignatureVerifyConfig + + + /MICROSAR/Csm/CsmPrimitives/CsmSignatureVerify/CsmSignatureVerifyConfig/CsmSignatureVerifyAlgorithmFamily + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Csm/CsmPrimitives/CsmSignatureVerify/CsmSignatureVerifyConfig/CsmSignatureVerifyAlgorithmMode + CRYPTO_ALGOMODE_RSASSA_PSS + + + /MICROSAR/Csm/CsmPrimitives/CsmSignatureVerify/CsmSignatureVerifyConfig/CsmSignatureVerifyAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Csm/CsmPrimitives/CsmSignatureVerify/CsmSignatureVerifyConfig/CsmSignatureVerifyProcessing + CSM_SYNCHRONOUS + + + /MICROSAR/Csm/CsmPrimitives/CsmSignatureVerify/CsmSignatureVerifyConfig/CsmSignatureVerifyCompareLength + 1 + + + /MICROSAR/Csm/CsmPrimitives/CsmSignatureVerify/CsmSignatureVerifyConfig/CsmSignatureVerifyAlgorithmFamiliy + CRYPTO_ALGOFAM_RSA + + + /MICROSAR/Csm/CsmPrimitives/CsmSignatureVerify/CsmSignatureVerifyConfig/CsmSignatureVerifyKeyLength + 32 + + + + + + + + + CsmGeneral + /MICROSAR/Csm/CsmGeneral + + + /MICROSAR/Csm/CsmGeneral/CsmAsymPrivateKeyMaxLength + 32 + + + /MICROSAR/Csm/CsmGeneral/CsmAsymPublicKeyMaxLength + 1024 + + + /MICROSAR/Csm/CsmGeneral/CsmDevErrorDetect + true + + + /MICROSAR/Csm/CsmGeneral/CsmSymKeyMaxLength + 16 + + + /MICROSAR/Csm/CsmGeneral/CsmUseDeprecated + false + + + /MICROSAR/Csm/CsmGeneral/CsmVersionInfoApi + false + + + /MICROSAR/Csm/CsmGeneral/CsmCallbackStartNotification + false + + + /MICROSAR/Csm/CsmGeneral/CsmCustomIncludeFiles + Crypto_30_LibCv_Custom.h + + + /MICROSAR/Csm/CsmGeneral/CsmCancelationDuringProcessing + false + + + /MICROSAR/Csm/CsmGeneral/CsmSafeBswChecks + true + + + /MICROSAR/Csm/CsmGeneral/CsmSwcMainInterfaceVersion + CSM_ASR_VERSION_R21_11 + + + /MICROSAR/Csm/CsmGeneral/CsmMultiPartitionRuntimeChecks + false + + + + + CsmJobTypeLayout + /MICROSAR/Csm/CsmGeneral/CsmJobTypeLayout + + + /MICROSAR/Csm/CsmGeneral/CsmJobTypeLayout/CsmJobTypeLayoutVarMembers + true + + + /MICROSAR/Csm/CsmGeneral/CsmJobTypeLayout/CsmJobTypeLayoutAsr430Compatibility + true + + + /MICROSAR/Csm/CsmGeneral/CsmJobTypeLayout/CsmJobTypeLayoutInput64 + false + + + /MICROSAR/Csm/CsmGeneral/CsmJobTypeLayout/CsmJobTypeLayoutOutput64Ptr + false + + + /MICROSAR/Csm/CsmGeneral/CsmJobTypeLayout/CsmJobTypeLayoutRedirectionInfoRef + true + + + /MICROSAR/Csm/CsmGeneral/CsmJobTypeLayout/CsmJobTypeLayoutJobInfoPtr + true + + + /MICROSAR/Csm/CsmGeneral/CsmJobTypeLayout/CsmJobTypeLayoutSecureCounterId + false + + + /MICROSAR/Csm/CsmGeneral/CsmJobTypeLayout/CsmJobTypeLayoutCallbackUpdateNotification + false + + + /MICROSAR/Csm/CsmGeneral/CsmJobTypeLayout/CsmJobTypeLayoutResultLength + false + + + /MICROSAR/Csm/CsmGeneral/CsmJobTypeLayout/CsmJobTypeLayoutFieldOrdering + CSM_ASR_VERSION_R21_11 + + + + + CsmBswApiCompatibility + /MICROSAR/Csm/CsmGeneral/CsmBswApiCompatibility + + + /MICROSAR/Csm/CsmGeneral/CsmBswApiCompatibility/CsmDefaultJobKeyApiVersion + CSM_ASR_VERSION_4_04 + + + + + + + CsmPrimitives_HashSha256 + /MICROSAR/Csm/CsmPrimitives + + + CsmHash + /MICROSAR/Csm/CsmPrimitives/CsmHash + + + CsmPrimitives_HashSha256 + /MICROSAR/Csm/CsmPrimitives/CsmHash/CsmHashConfig + + + /MICROSAR/Csm/CsmPrimitives/CsmHash/CsmHashConfig/CsmHashAlgorithmFamiliy + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Csm/CsmPrimitives/CsmHash/CsmHashConfig/CsmHashAlgorithmFamily + CRYPTO_ALGOFAM_SHA2_256 + + + /MICROSAR/Csm/CsmPrimitives/CsmHash/CsmHashConfig/CsmHashAlgorithmMode + CRYPTO_ALGOMODE_NOT_SET + + + /MICROSAR/Csm/CsmPrimitives/CsmHash/CsmHashConfig/CsmHashAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Csm/CsmPrimitives/CsmHash/CsmHashConfig/CsmHashProcessing + CSM_SYNCHRONOUS + + + /MICROSAR/Csm/CsmPrimitives/CsmHash/CsmHashConfig/CsmHashResultLength + 32 + + + + + + + + + CsmPrimitives_Cmac_Generate + /MICROSAR/Csm/CsmPrimitives + + + CsmMacGenerate + /MICROSAR/Csm/CsmPrimitives/CsmMacGenerate + + + CsmPrimitives_Cmac_Generate + /MICROSAR/Csm/CsmPrimitives/CsmMacGenerate/CsmMacGenerateConfig + + + /MICROSAR/Csm/CsmPrimitives/CsmMacGenerate/CsmMacGenerateConfig/CsmMacGenerateAlgorithmFamily + CRYPTO_ALGOFAM_AES + + + /MICROSAR/Csm/CsmPrimitives/CsmMacGenerate/CsmMacGenerateConfig/CsmMacGenerateAlgorithmKeyLength + 16 + + + /MICROSAR/Csm/CsmPrimitives/CsmMacGenerate/CsmMacGenerateConfig/CsmMacGenerateAlgorithmMode + CRYPTO_ALGOMODE_CMAC + + + /MICROSAR/Csm/CsmPrimitives/CsmMacGenerate/CsmMacGenerateConfig/CsmMacGenerateAlgorithmSecondaryFamily + CRYPTO_ALGOFAM_NOT_SET + + + /MICROSAR/Csm/CsmPrimitives/CsmMacGenerate/CsmMacGenerateConfig/CsmMacGenerateProcessing + CSM_SYNCHRONOUS + + + /MICROSAR/Csm/CsmPrimitives/CsmMacGenerate/CsmMacGenerateConfig/CsmMacGenerateResultLength + 16 + + + /MICROSAR/Csm/CsmPrimitives/CsmMacGenerate/CsmMacGenerateConfig/CsmMacGenerateAlgorithmFamiliy + CRYPTO_ALGOFAM_AES + + + + + + + + + CsmMainFunction + /MICROSAR/Csm/CsmMainFunction + + + /MICROSAR/Csm/CsmMainFunction/CsmMainFunctionPartitionRef + /ActiveEcuC/EcuC/EcucPartitionCollection/EcucPartition + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_Det_Det_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_Det_Det_ecuc.arxml new file mode 100644 index 0000000..ecfb383 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_Det_Det_ecuc.arxml @@ -0,0 +1,89 @@ + + + + + ActiveEcuC + + + Det + + + + false + + + + /MICROSAR/Det + VARIANT-PRE-COMPILE + /MICROSAR/Det_Impl + + + DetGeneral + /MICROSAR/Det/DetGeneral + + + /MICROSAR/Det/DetGeneral/DetEnableDet + true + + + /MICROSAR/Det/DetGeneral/DetVersionInfoApi + false + + + /MICROSAR/Det/DetGeneral/DetExtDebugSupport + false + + + /MICROSAR/Det/DetGeneral/DetGlobalFilterSize + 0 + + + /MICROSAR/Det/DetGeneral/DetBreakFilterSize + 0 + + + /MICROSAR/Det/DetGeneral/DetLogBufferSize + 0 + + + /MICROSAR/Det/DetGeneral/DetReportErrorRecursionLimit + 0 + + + /MICROSAR/Det/DetGeneral/DetReportRuntimeErrorRecursionLimit + 0 + + + /MICROSAR/Det/DetGeneral/DetReportTransientFaultRecursionLimit + 0 + + + /MICROSAR/Det/DetGeneral/DetDltFilterSize + 0 + + + + + DetNotification + /MICROSAR/Det/DetNotification + + + /MICROSAR/Det/DetNotification/DetErrorHook + ApplFbl_DetEntryHandler + + + /MICROSAR/Det/DetNotification/DetReportRuntimeErrorCallout + ApplFbl_DetEntryHandler + + + /MICROSAR/Det/DetNotification/DetReportTransientFaultCallout + ApplFbl_DetEntryHandler + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_EcuC_EcuC_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_EcuC_EcuC_ecuc.arxml new file mode 100644 index 0000000..b6f97e9 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_EcuC_EcuC_ecuc.arxml @@ -0,0 +1,691 @@ + + + + + ActiveEcuC + + + EcuC + + + + false + + + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/CryIf_InitMemory + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/CryIf_Init + + + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/Crypto_30_LibCv_InitMemory + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/Crypto_30_LibCv_Init + + + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/Crypto_30_vHsm_InitMemory + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/Crypto_30_vHsm_Init + + + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/Csm_InitMemory + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/Csm_Init + + + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/Det_Init + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/Det_Start + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/Det_InitMemory + + + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/Brs_Init + + + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/vBaseEnv_Init + + + + + /ActiveEcuC/EcuC/EcucGeneral/BswInitialization/vLinkGen_Init + + + + + + /MICROSAR/EcuC + VARIANT-PRE-COMPILE + /MICROSAR/EcuC_Impl + + + EcucGeneral + /MICROSAR/EcuC/EcucGeneral + + + /MICROSAR/EcuC/EcucGeneral/DummyFunction + false + + + /MICROSAR/EcuC/EcucGeneral/DummyStatement + true + + + /MICROSAR/EcuC/EcucGeneral/StructAlignment + Auto + + + /MICROSAR/EcuC/EcucGeneral/ArrayAlignment + Auto + + + /MICROSAR/EcuC/EcucGeneral/StructInArrayAlignment + Auto + + + /MICROSAR/EcuC/EcucGeneral/SizeOfEnum + Size32Bit + + + /MICROSAR/EcuC/EcucGeneral/SizeOfROMPointer + Size32Bit + + + /MICROSAR/EcuC/EcucGeneral/SizeOfRAMPointer + Size32Bit + + + /MICROSAR/EcuC/EcucGeneral/DummyStatementKind + SelfAssignment + + + /MICROSAR/EcuC/EcucGeneral/AtomicBitAccessInBitfield + false + + + /MICROSAR/EcuC/EcucGeneral/AtomicVariableAccess + Atomic32BitAccess + + + /MICROSAR/EcuC/EcucGeneral/CPUType + CPU32Bit + + + /MICROSAR/EcuC/EcucGeneral/SizeOfInt + Size32Bit + + + /MICROSAR/EcuC/EcucGeneral/ByteOrder + LITTLE_ENDIAN + + + /MICROSAR/EcuC/EcucGeneral/BitOrder + LSB_to_MSB + + + /MICROSAR/EcuC/EcucGeneral/BitFieldDataType + INT + + + /MICROSAR/EcuC/EcucGeneral/ConditionalGenerating + true + + + /MICROSAR/EcuC/EcucGeneral/EcucBswImplementationCodeType + EcuCSourceCode + + + /MICROSAR/EcuC/EcucGeneral/EcuCUseStdReturnTypeForRte + false + + + + + BswInitialization + /MICROSAR/EcuC/EcucGeneral/BswInitialization + + + CryIf_InitMemory + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes variables of the Crypto Interface +

    + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + CryIf.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + INIT_MEMORY + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/CryIf + + + + + CryIf_Init + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes the Crypto Interface +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + CryIf.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + INIT_TWO_IF + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/CryIf + + +
    + + Crypto_30_LibCv_InitMemory + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes variables of the Crypto Driver +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + Crypto_30_LibCv.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + INIT_MEMORY + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/Crypto + + +
    + + Crypto_30_LibCv_Init + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes the Crypto Driver +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + Crypto_30_LibCv.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + INIT_TWO_DRV + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/Crypto + + +
    + + Crypto_30_vHsm_InitMemory + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes variables of the Crypto Driver +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + Crypto_30_vHsm.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + INIT_MEMORY + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/Crypto_001 + + +
    + + Crypto_30_vHsm_Init + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes the Crypto Driver +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + Crypto_30_vHsm.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + INIT_TWO_DRV + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/Crypto_001 + + +
    + + Csm_InitMemory + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes variables of the Crypto Service Manager +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + Csm.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + INIT_MEMORY + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/Csm + + +
    + + Csm_Init + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes the Crypto Service Manager +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + Csm.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + INIT_TWO_SYS + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/Csm + + +
    + + Det_Init + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Init function description of Det in UnfilteredViewInInvariantProject (UnfilteredInvariantProjectModelView) . +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + Det.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + INIT_ZERO + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ConfigType + Det_ConfigType + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ConfigPtrClass + DET_INIT_DATA + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ConfigPtrName + Det_Config_Ptr + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/Det + + +
    + + Det_Start + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + PostInit function description of Det in UnfilteredViewInInvariantProject (UnfilteredInvariantProjectModelView) . +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + Det.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + INIT_ONE + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/Det + + +
    + + Det_InitMemory + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + InitMemory function description of Det in UnfilteredViewInInvariantProject (UnfilteredInvariantProjectModelView) . +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + Det.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + INIT_MEMORY + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/Det + + +
    + + Brs_Init + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Automatically generated by BswInitFctConfigurationService. +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + NO_INIT + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/vBRS + + +
    + + vBaseEnv_Init + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Created vBaseEnv_Init by Extended Init XML Service +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + NO_INIT + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/vBaseEnv + + +
    + + vLinkGen_Init + + + + DV:EcucBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Dummy initialization of the vLinkGen +

    +
    +
    +
    + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/Header + vLinkGen_Lcfg.h + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/InitPhase + NO_INIT + + + + + /MICROSAR/EcuC/EcucGeneral/BswInitialization/InitFunction/ModuleRef + /ActiveEcuC/vLinkGen + + +
    + + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_FblAsrStubs_FblAsrStubs_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_FblAsrStubs_FblAsrStubs_ecuc.arxml new file mode 100644 index 0000000..a405315 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_FblAsrStubs_FblAsrStubs_ecuc.arxml @@ -0,0 +1,36 @@ + + + + + ActiveEcuC + + + FblAsrStubs + /MICROSAR/FblAsrStubs + VARIANT-LINK-TIME + /MICROSAR/FblAsrStubs_Impl + + + FblAsrStubsModuleConfigDefines + /MICROSAR/FblAsrStubs/FblAsrStubsModuleConfigDefines + + + /MICROSAR/FblAsrStubs/FblAsrStubsModuleConfigDefines/FblAsrStubsCreateGptConfigDefines + false + + + /MICROSAR/FblAsrStubs/FblAsrStubsModuleConfigDefines/FblAsrStubsCreateDemConfigDefines + false + + + /MICROSAR/FblAsrStubs/FblAsrStubsModuleConfigDefines/FblAsrStubsCreateComConfigDefines + false + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_FblBmHdr_FblBmHdr_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_FblBmHdr_FblBmHdr_ecuc.arxml new file mode 100644 index 0000000..e3d1cdb --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_FblBmHdr_FblBmHdr_ecuc.arxml @@ -0,0 +1,121 @@ + + + + + ActiveEcuC + + + FblBmHdr + + + + false + + + + /MICROSAR/FblBmHdr + VARIANT-PRE-COMPILE + /MICROSAR/FblBmHdr_Impl + + + FblBmHdrHeader + /MICROSAR/FblBmHdr/FblBmHdrHeader + + + /MICROSAR/FblBmHdr/FblBmHdrHeader/FblBmHdrBlockStartAddress + 0 + + + /MICROSAR/FblBmHdr/FblBmHdrHeader/FblBmHdrBlockLength + 1 + + + + + /MICROSAR/FblBmHdr/FblBmHdrHeader/FblBmHdrTargetRef + /ActiveEcuC/FblBmHdr/Fbl + + + + + FblBmHdrVariant + /MICROSAR/FblBmHdr/FblBmHdrHeader/FblBmHdrVariant + + + FblBmHdrAuthenticationHeader + /MICROSAR/FblBmHdr/FblBmHdrHeader/FblBmHdrVariant/FblBmHdrAuthenticationHeader + + + /MICROSAR/FblBmHdr/FblBmHdrHeader/FblBmHdrVariant/FblBmHdrAuthenticationHeader/FblBmHdrAuthenticationHeaderAddress + 0 + + + + + + + + + Appl + /MICROSAR/FblBmHdr/FblBmHdrTarget + + + /MICROSAR/FblBmHdr/FblBmHdrTarget/FblBmHdrTargetId + 2 + + + + + Data + /MICROSAR/FblBmHdr/FblBmHdrTarget + + + /MICROSAR/FblBmHdr/FblBmHdrTarget/FblBmHdrTargetId + 3 + + + + + Fbl + /MICROSAR/FblBmHdr/FblBmHdrTarget + + + /MICROSAR/FblBmHdr/FblBmHdrTarget/FblBmHdrTargetId + 0 + + + + + FblUpdater + /MICROSAR/FblBmHdr/FblBmHdrTarget + + + /MICROSAR/FblBmHdr/FblBmHdrTarget/FblBmHdrTargetId + 1 + + + + + FblBmHdrGeneral + /MICROSAR/FblBmHdr/FblBmHdrGeneral + + + /MICROSAR/FblBmHdr/FblBmHdrGeneral/FblBmHdrMaxVerificationEntries + 1 + + + /MICROSAR/FblBmHdr/FblBmHdrGeneral/FblBmHdrSbVerificationList + false + + + /MICROSAR/FblBmHdr/FblBmHdrGeneral/FblBmHdrAllowTargetsWithoutMacOperation + false + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_FblBm_FblBm_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_FblBm_FblBm_ecuc.arxml new file mode 100644 index 0000000..86ebc35 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_FblBm_FblBm_ecuc.arxml @@ -0,0 +1,71 @@ + + + + + ActiveEcuC + + + FblBm + + + + false + + + + /MICROSAR/FblBm + VARIANT-PRE-COMPILE + /MICROSAR/FblBm_Impl + + + FblBmGeneral + /MICROSAR/FblBm/FblBmGeneral + + + /MICROSAR/FblBm/FblBmGeneral/FblBmFailsafeUpdater + false + + + /MICROSAR/FblBm/FblBmGeneral/FblBmIncludeHardwareConfiguration + false + + + /MICROSAR/FblBm/FblBmGeneral/FblBmInitializeKeys + true + + + /MICROSAR/FblBm/FblBmGeneral/FblBmSecureBoot + true + + + /MICROSAR/FblBm/FblBmGeneral/FblBmStandaloneMode + true + + + /MICROSAR/FblBm/FblBmGeneral/FblBmInitializeMacOfBootloader + false + + + /MICROSAR/FblBm/FblBmGeneral/FblBmIncludeOemConfiguration + false + + + /MICROSAR/FblBm/FblBmGeneral/FblBmHeaderAddress + 0 + + + /MICROSAR/FblBm/FblBmGeneral/FblBmExecutionInstance + BootManager + + + /MICROSAR/FblBm/FblBmGeneral/FblBmFailsafeUpdaterUser + false + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_FblHal_FblHal_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_FblHal_FblHal_ecuc.arxml new file mode 100644 index 0000000..3f83e81 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_FblHal_FblHal_ecuc.arxml @@ -0,0 +1,72 @@ + + + + + ActiveEcuC + + + FblHal + /MICROSAR/FblHal + VARIANT-LINK-TIME + /MICROSAR/FblHal_Impl + + + FblHalGeneral + /MICROSAR/FblHal/FblHalGeneral + + + /MICROSAR/FblHal/FblHalGeneral/FblHalFlashCodeBufferSize + 2048 + + + /MICROSAR/FblHal/FblHalGeneral/FblHalDerivativeSpecificDefines + #define V_COMP_LLVMTI + + + /MICROSAR/FblHal/FblHalGeneral/FblHalDerivativeSpecificDefines + #define V_COMP_LLVMTI_SITARA + + + /MICROSAR/FblHal/FblHalGeneral/FblHalDerivativeSpecificDefines + #define V_CPU_SITARA + + + /MICROSAR/FblHal/FblHalGeneral/FblHalDerivativeSpecificDefines + #define C_CPUTYPE_32BIT + + + /MICROSAR/FblHal/FblHalGeneral/FblHalDerivativeSpecificDefines + #define V_SUPPRESS_EXTENDED_VERSION_CHECK + + + /MICROSAR/FblHal/FblHalGeneral/FblHalDerivativeSpecificDefines + #define VGEN_ENABLE_CANFBL + + + /MICROSAR/FblHal/FblHalGeneral/FblHalDerivativeSpecificDefines + #define FBL_RTI_BASE 0x52180000uL /**< RTI0 base address */ + + + /MICROSAR/FblHal/FblHalGeneral/FblHalDerivativeSpecificDefines + #define FBL_SFR_BASE_ADRESSES_PRECONFIGURED + + + /MICROSAR/FblHal/FblHalGeneral/FblHalDerivativeSpecificDefines + #define V_ENABLE_CAN_ASR_ABSTRACTION + + + /MICROSAR/FblHal/FblHalGeneral/FblHalECCSafeRead + false + + + /MICROSAR/FblHal/FblHalGeneral/FblHalTimerClockFreq + 0 + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_FblSb_FblSb_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_FblSb_FblSb_ecuc.arxml new file mode 100644 index 0000000..e50dd00 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_FblSb_FblSb_ecuc.arxml @@ -0,0 +1,84 @@ + + + + + ActiveEcuC + + + FblSb + + + + false + + + + /MICROSAR/FblSb + VARIANT-PRE-COMPILE + /MICROSAR/FblSb_Impl + + + FblSbGeneral + /MICROSAR/FblSb/FblSbGeneral + + + /MICROSAR/FblSb/FblSbGeneral/FblSbHeaderVerification + false + + + /MICROSAR/FblSb/FblSbGeneral/FblSbVerificationList + false + + + /MICROSAR/FblSb/FblSbGeneral/FblSbCopyFlashDriver + false + + + /MICROSAR/FblSb/FblSbGeneral/FblSbFblLbtVerification + false + + + + + FblSbMacOperation + /MICROSAR/FblSb/FblSbMacOperation + + + /MICROSAR/FblSb/FblSbMacOperation/FblSbMacOperationId + 0 + + + /MICROSAR/FblSb/FblSbMacOperation/FblSbGroupId + 0 + + + /MICROSAR/FblSb/FblSbMacOperation/FblSbVerifyForceSequential + false + + + /MICROSAR/FblSb/FblSbMacOperation/FblSbVerificationMethod + + + /MICROSAR/FblSb/FblSbMacOperation/FblSbSecureBootUpdateSignatureAlgorithm + ED25519 + + + /MICROSAR/FblSb/FblSbMacOperation/FblSbSecureBootUpdateSignatureLength + 64 + + + /MICROSAR/FblSb/FblSbMacOperation/FblSbSecureBootUpdateSignaturePosition + BeforeSegmentList + + + /MICROSAR/FblSb/FblSbMacOperation/FblSbConfirmationMode + false + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_Fbl_Fbl_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_Fbl_Fbl_ecuc.arxml new file mode 100644 index 0000000..2ff8fe3 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_Fbl_Fbl_ecuc.arxml @@ -0,0 +1,428 @@ + + + + + ActiveEcuC + + + Fbl + /MICROSAR/Fbl + VARIANT-LINK-TIME + /MICROSAR/Fbl_Impl + + + FblMemoryDeviceTable + /MICROSAR/Fbl/FblMemoryDeviceTable + + + Ram + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdErasedValue + 255 + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdSegmentSize + 1 + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdIndex + 0 + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdInitHook + false + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdDeinitHook + false + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdReadHook + false + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdEraseHook + false + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdWriteHook + false + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdVerifyHook + false + + + + + Flash + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdIndex + 1 + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdSegmentSize + 1 + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdErasedValue + 255 + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdInitHook + false + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdDeinitHook + false + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdReadHook + false + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdEraseHook + false + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdWriteHook + false + + + /MICROSAR/Fbl/FblMemoryDeviceTable/FblMemoryDevice/FblMdVerifyHook + false + + + + + + + FblGeneral + /MICROSAR/Fbl/FblGeneral + + + /MICROSAR/Fbl/FblGeneral/FblApplicationStateTask + false + + + /MICROSAR/Fbl/FblGeneral/FblStayInBoot + true + + + /MICROSAR/Fbl/FblGeneral/FblPresencePattern + true + + + /MICROSAR/Fbl/FblGeneral/FblCompressionMode + true + + + /MICROSAR/Fbl/FblGeneral/FblCommonData + true + + + /MICROSAR/Fbl/FblGeneral/FblWriteSegmentation + 256 + + + /MICROSAR/Fbl/FblGeneral/FblWatchdogService + true + + + /MICROSAR/Fbl/FblGeneral/FblVerificationSegmentation + 256 + + + /MICROSAR/Fbl/FblGeneral/FblUnalignedDataTransfer + true + + + /MICROSAR/Fbl/FblGeneral/FblStartFunction + true + + + /MICROSAR/Fbl/FblGeneral/FblPipelinedProgramming + true + + + /MICROSAR/Fbl/FblGeneral/FblPipelinedVerification + false + + + /MICROSAR/Fbl/FblGeneral/FblMaximumNumberOfSegments + 16 + + + /MICROSAR/Fbl/FblGeneral/FblInternalMemoryCopy + true + + + /MICROSAR/Fbl/FblGeneral/FblDiagnosticBufferSize + 2050 + + + /MICROSAR/Fbl/FblGeneral/FblDataProcessingBufferSize + 256 + + + /MICROSAR/Fbl/FblGeneral/FblVerificationFunction + false + + + /MICROSAR/Fbl/FblGeneral/FblUserConfigFile + $(DpaProjectFolder)\Config\Fbl_Usr.cfg + + + /MICROSAR/Fbl/FblGeneral/FblGapFilling + false + + + /MICROSAR/Fbl/FblGeneral/FblAdaptiveDataTransferRcrrp + false + + + /MICROSAR/Fbl/FblGeneral/FblGatewaySupport + false + + + /MICROSAR/Fbl/FblGeneral/FblInputVerification + false + + + /MICROSAR/Fbl/FblGeneral/FblP2Server + 25 + + + /MICROSAR/Fbl/FblGeneral/FblS3ServerExtendedSession + 0 + + + /MICROSAR/Fbl/FblGeneral/FblResponseAfterReset + false + + + /MICROSAR/Fbl/FblGeneral/FblSuspendDriverOperation + false + + + /MICROSAR/Fbl/FblGeneral/FblSleepMode + false + + + /MICROSAR/Fbl/FblGeneral/FblSleepTime + 0 + + + /MICROSAR/Fbl/FblGeneral/FblProcessedVerification + false + + + /MICROSAR/Fbl/FblGeneral/FblOutputVerification + true + + + /MICROSAR/Fbl/FblGeneral/FblEncryptionMode + false + + + /MICROSAR/Fbl/FblGeneral/FblFlashDriverUsage + DOWNLOAD_DRIVER + + + /MICROSAR/Fbl/FblGeneral/FblReprogrammableLbt + false + + + /MICROSAR/Fbl/FblGeneral/FblOta + false + + + /MICROSAR/Fbl/FblGeneral/FblHardwareSwap + false + + + /MICROSAR/Fbl/FblGeneral/FblProjectState + INTEGRATION + + + /MICROSAR/Fbl/FblGeneral/FblApplicationTimerTask + false + + + /MICROSAR/Fbl/FblGeneral/FblHeaderAddress + 0 + + + /MICROSAR/Fbl/FblGeneral/FblP2StarServer + 5000 + + + /MICROSAR/Fbl/FblGeneral/FblS3ServerProgrammingSession + 5000 + + + /MICROSAR/Fbl/FblGeneral/FblFillCode + 255 + + + /MICROSAR/Fbl/FblGeneral/FblUserSubfunction + false + + + /MICROSAR/Fbl/FblGeneral/FblUserService + false + + + /MICROSAR/Fbl/FblGeneral/FblUserRoutine + false + + + /MICROSAR/Fbl/FblGeneral/FblWatchdogTriggerCycle + 1 + + + /MICROSAR/Fbl/FblGeneral/FblMaximumAmountOfLogicalBlocks + 8 + + + /MICROSAR/Fbl/FblGeneral/FblBlockStartAddress + 0 + + + /MICROSAR/Fbl/FblGeneral/FblBlockLength + 0 + + + /MICROSAR/Fbl/FblGeneral/FblOneStepUpdater + false + + + /MICROSAR/Fbl/FblGeneral/FblXcpSupport + false + + + + + FblLogicalBlockTable + /MICROSAR/Fbl/FblLogicalBlockTable + + + SBL + /MICROSAR/Fbl/FblLogicalBlockTable/FblLogicalBlock + + + /MICROSAR/Fbl/FblLogicalBlockTable/FblLogicalBlock/FblLbBlockType + SBL + + + /MICROSAR/Fbl/FblLogicalBlockTable/FblLogicalBlock/FblLbDisposability + OPTIONAL + + + /MICROSAR/Fbl/FblLogicalBlockTable/FblLogicalBlock/FblLbOutputVerification + SecM_Default + + + /MICROSAR/Fbl/FblLogicalBlockTable/FblLogicalBlock/FblLbBlockIndex + 0 + + + /MICROSAR/Fbl/FblLogicalBlockTable/FblLogicalBlock/FblLbStartAddress + 0 + + + /MICROSAR/Fbl/FblLogicalBlockTable/FblLogicalBlock/FblLbEndAddress + 0 + + + /MICROSAR/Fbl/FblLogicalBlockTable/FblLogicalBlock/FblLbHeaderAddress + 0 + + + /MICROSAR/Fbl/FblLogicalBlockTable/FblLogicalBlock/FblLbDescription + + + + /MICROSAR/Fbl/FblLogicalBlockTable/FblLogicalBlock/FblLbBmHeaderAddress + 0 + + + + + + + FblFord + /MICROSAR/Fbl/FblFord + + + /MICROSAR/Fbl/FblFord/FblValidationStructure + true + + + /MICROSAR/Fbl/FblFord/FblSigningSolutionKey + SINGLE_KEY + + + /MICROSAR/Fbl/FblFord/FblWriteDataByIdentifierService + true + + + /MICROSAR/Fbl/FblFord/FblRequestUploadService + true + + + /MICROSAR/Fbl/FblFord/FblValidationStructureBeginTag + 1961616914 + + + /MICROSAR/Fbl/FblFord/FblValidationStructureEndTag + 4046069293 + + + /MICROSAR/Fbl/FblFord/FblFlashErasedDetection + false + + + /MICROSAR/Fbl/FblFord/FblFlashErasedDetectionPatternSize + 16 + + + /MICROSAR/Fbl/FblFord/FblSeedKeyModule + true + + + /MICROSAR/Fbl/FblFord/FblSecretKey + FFFFFFFFFFFFFFFFFFFFFFFF + + + /MICROSAR/Fbl/FblFord/FblSecretKeyUpdate + false + + + /MICROSAR/Fbl/FblFord/FblMaximumReadableDataIdentifiers + 5 + + + /MICROSAR/Fbl/FblFord/FblKeyExpLength + 256 + + + /MICROSAR/Fbl/FblFord/FblTokenDownloadHandling + true + + + + + FblFlashBlockTable + /MICROSAR/Fbl/FblFlashBlockTable + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_MemMap_MemMap_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_MemMap_MemMap_ecuc.arxml new file mode 100644 index 0000000..f100632 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_MemMap_MemMap_ecuc.arxml @@ -0,0 +1,5441 @@ + + + + + ActiveEcuC + + + MemMap + + + + false + + + + /MICROSAR/MemMap + VARIANT-PRE-COMPILE + /MICROSAR/MemMap_Impl + + + vHsmGlobalRamBuffer + /MICROSAR/MemMap/MemMapAddressingModeSet + + + vHsmGlobalRamBuffer + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vHsmGlobalRamBuffer + + + + + + + vHsmIpcMemory + /MICROSAR/MemMap/MemMapAddressingModeSet + + + vHsmIpcMemory + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vHsmIpcMemory + + + + + + + vHsm_Generic + /MICROSAR/MemMap/MemMapAllocation + + + vHsmGlobalRamBuffer + /MICROSAR/MemMap/MemMapAllocation/MemMapSectionSpecificMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapSectionSpecificMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/vHsmGlobalRamBuffer + + + /MICROSAR/MemMap/MemMapAllocation/MemMapSectionSpecificMapping/MemMapMemorySectionRef + /MICROSAR/Crypto_30_vHsm/Crypto_Impl/ResourceConsumption/CRYPTO_30_VHSM_GLOBAL_VAR_NOINIT_32BIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapSectionSpecificMapping/MemMapMemorySectionRef + /MICROSAR/Crypto_30_vHsm/Crypto_Impl/ResourceConsumption/CRYPTO_30_VHSM_GLOBAL_VAR_NOINIT_UNSPECIFIED + + + + + vHsmIpcMemory + /MICROSAR/MemMap/MemMapAllocation/MemMapSectionSpecificMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapSectionSpecificMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/vHsmIpcMemory + + + /MICROSAR/MemMap/MemMapAllocation/MemMapSectionSpecificMapping/MemMapMemorySectionRef + /MICROSAR/Crypto_30_vHsm/Crypto_Impl/ResourceConsumption/CRYPTO_30_VHSM_IPC_MEMORY_VAR_NOINIT_32BIT + + + + + vHsmRamCode + /MICROSAR/MemMap/MemMapAllocation/MemMapSectionSpecificMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapSectionSpecificMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/vHsmRamCode + + + /MICROSAR/MemMap/MemMapAllocation/MemMapSectionSpecificMapping/MemMapMemorySectionRef + /MICROSAR/Crypto_30_vHsm/Crypto_Impl/ResourceConsumption/CRYPTO_30_VHSM_RAMCODE + + + + + + + vHsmRamCode + /MICROSAR/MemMap/MemMapAddressingModeSet + + + vHsmRamCode + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + + + + + MemMap_Common + /MICROSAR/MemMap/MemMapModule + + + /MICROSAR/MemMap/MemMapModule/MemMapGenerateAdditionalMemorySections + true + + + + + CODE + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CODE + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE + + + + + CODE_FAST + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CODE_FAST + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_FAST + + + + + CODE_ISR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CODE_ISR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_ISR + + + + + CONST + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + + + CONST_8BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_8BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + + + CONST_16BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_16BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + + + CONST_32BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_32BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + + + CONST_64BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_64BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + + + CONST_8 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_8 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + + + CONST_16 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_16 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + + + CONST_32 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_32 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + + + CONST_64 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_64 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + + + CONST_PTR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + PTR + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_PTR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + + + CONST_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + + + CONST_FAST_8BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_FAST_8BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST + + + + + CONST_FAST_16BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_FAST_16BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST + + + + + CONST_FAST_32BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_FAST_32BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST + + + + + CONST_FAST_64BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_FAST_64BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST + + + + + CONST_FAST_8 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_FAST_8 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST + + + + + CONST_FAST_16 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_FAST_16 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST + + + + + CONST_FAST_32 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_FAST_32 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST + + + + + CONST_FAST_64 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_FAST_64 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST + + + + + CONST_FAST_PTR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + PTR + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_FAST_PTR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST + + + + + CONST_FAST_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_FAST_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST + + + + + CONST_PBCFG + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + CONST_PBCFG + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_PBCFG + + + + + PBCFG_GLOBALROOT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + PBCFG_GLOBALROOT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/PBCFG_GLOBALROOT + + + + + VAR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + + + VAR_INIT_8BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_INIT_8BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + + + VAR_INIT_16BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_INIT_16BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + + + VAR_INIT_32BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_INIT_32BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + + + VAR_INIT_64BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_INIT_64BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + + + VAR_INIT_8 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_INIT_8 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + + + VAR_INIT_16 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_INIT_16 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + + + VAR_INIT_32 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_INIT_32 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + + + VAR_INIT_64 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_INIT_64 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + + + VAR_INIT_PTR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + PTR + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_INIT_PTR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + + + VAR_INIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_INIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + + + VAR_NOINIT_8BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOINIT_8BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + + + VAR_NOINIT_16BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOINIT_16BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + + + VAR_NOINIT_32BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOINIT_32BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + + + VAR_NOINIT_64BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOINIT_64BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + + + VAR_NOINIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOINIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + + + VAR_NO_INIT_8 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NO_INIT_8 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + + + VAR_NO_INIT_16 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NO_INIT_16 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + + + VAR_NO_INIT_32 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NO_INIT_32 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + + + VAR_NO_INIT_64 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NO_INIT_64 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + + + VAR_NO_INIT_PTR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + PTR + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NO_INIT_PTR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + + + VAR_NO_INIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NO_INIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + + + VAR_ZERO_INIT_8BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_ZERO_INIT_8BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + + + VAR_ZERO_INIT_16BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_ZERO_INIT_16BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + + + VAR_ZERO_INIT_32BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_ZERO_INIT_32BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + + + VAR_ZERO_INIT_64BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_ZERO_INIT_64BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + + + VAR_CLEARED_8 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_CLEARED_8 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + + + VAR_CLEARED_16 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_CLEARED_16 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + + + VAR_CLEARED_32 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_CLEARED_32 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + + + VAR_CLEARED_64 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_CLEARED_64 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + + + VAR_CLEARED_PTR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + PTR + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_CLEARED_PTR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + + + VAR_CLEARED_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_CLEARED_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + + + VAR_ZERO_INIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_ZERO_INIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + + + VAR_FAST_INIT_8BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_INIT_8BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT + + + + + VAR_FAST_INIT_16BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_INIT_16BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT + + + + + VAR_FAST_INIT_32BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_INIT_32BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT + + + + + VAR_FAST_INIT_64BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_INIT_64BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT + + + + + VAR_FAST_INIT_8 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_INIT_8 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT + + + + + VAR_FAST_INIT_16 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_INIT_16 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT + + + + + VAR_FAST_INIT_32 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_INIT_32 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT + + + + + VAR_FAST_INIT_64 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_INIT_64 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT + + + + + VAR_FAST_INIT_PTR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + PTR + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_INIT_PTR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT + + + + + VAR_FAST_INIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_INIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT + + + + + VAR_FAST_NOINIT_8BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_NOINIT_8BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + + + VAR_FAST_NOINIT_16BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_NOINIT_16BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + + + VAR_FAST_NOINIT_32BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_NOINIT_32BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + + + VAR_FAST_NOINIT_64BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_NOINIT_64BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + + + VAR_FAST_NOINIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_NOINIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + + + VAR_FAST_NO_INIT_8 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_NO_INIT_8 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + + + VAR_FAST_NO_INIT_16 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_NO_INIT_16 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + + + VAR_FAST_NO_INIT_32 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_NO_INIT_32 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + + + VAR_FAST_NO_INIT_64 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_NO_INIT_64 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + + + VAR_FAST_NO_INIT_PTR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + PTR + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_NO_INIT_PTR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + + + VAR_FAST_NO_INIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_NO_INIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + + + VAR_FAST_ZERO_INIT_8BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_ZERO_INIT_8BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + + + VAR_FAST_ZERO_INIT_16BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_ZERO_INIT_16BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + + + VAR_FAST_ZERO_INIT_32BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_ZERO_INIT_32BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + + + VAR_FAST_ZERO_INIT_64BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_ZERO_INIT_64BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + + + VAR_FAST_ZERO_INIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_ZERO_INIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + + + VAR_FAST_CLEARED_8 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_CLEARED_8 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + + + VAR_FAST_CLEARED_16 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_CLEARED_16 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + + + VAR_FAST_CLEARED_32 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_CLEARED_32 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + + + VAR_FAST_CLEARED_64 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_CLEARED_64 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + + + VAR_FAST_CLEARED_PTR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + PTR + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_CLEARED_PTR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + + + VAR_FAST_CLEARED_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_FAST_CLEARED_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + + + VAR_NOCACHE_INIT_8BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_INIT_8BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT + + + + + VAR_NOCACHE_INIT_16BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_INIT_16BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT + + + + + VAR_NOCACHE_INIT_32BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_INIT_32BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT + + + + + VAR_NOCACHE_INIT_64BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_INIT_64BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT + + + + + VAR_NOCACHE_INIT_8 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_INIT_8 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT + + + + + VAR_NOCACHE_INIT_16 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_INIT_16 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT + + + + + VAR_NOCACHE_INIT_32 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_INIT_32 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT + + + + + VAR_NOCACHE_INIT_64 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_INIT_64 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT + + + + + VAR_NOCACHE_INIT_PTR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + PTR + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_INIT_PTR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT + + + + + VAR_NOCACHE_INIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_INIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT + + + + + VAR_NOCACHE_NOINIT_8BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_NOINIT_8BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + + + VAR_NOCACHE_NOINIT_16BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_NOINIT_16BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + + + VAR_NOCACHE_NOINIT_32BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_NOINIT_32BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + + + VAR_NOCACHE_NOINIT_64BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_NOINIT_64BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + + + VAR_NOCACHE_NOINIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_NOINIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + + + VAR_NOCACHE_NO_INIT_8 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_NO_INIT_8 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + + + VAR_NOCACHE_NO_INIT_16 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_NO_INIT_16 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + + + VAR_NOCACHE_NO_INIT_32 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_NO_INIT_32 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + + + VAR_NOCACHE_NO_INIT_64 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_NO_INIT_64 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + + + VAR_NOCACHE_NO_INIT_PTR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + PTR + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_NO_INIT_PTR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + + + VAR_NOCACHE_NO_INIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_NO_INIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + + + VAR_NOCACHE_ZERO_INIT_8BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_ZERO_INIT_8BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + + + VAR_NOCACHE_ZERO_INIT_16BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_ZERO_INIT_16BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + + + VAR_NOCACHE_ZERO_INIT_32BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_ZERO_INIT_32BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + + + VAR_NOCACHE_ZERO_INIT_64BIT + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_ZERO_INIT_64BIT + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + + + VAR_NOCACHE_ZERO_INIT_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_ZERO_INIT_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + + + VAR_NOCACHE_CLEARED_8 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 8 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_CLEARED_8 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + + + VAR_NOCACHE_CLEARED_16 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 16 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_CLEARED_16 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + + + VAR_NOCACHE_CLEARED_32 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 32 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_CLEARED_32 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + + + VAR_NOCACHE_CLEARED_64 + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + 64 + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_CLEARED_64 + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + + + VAR_NOCACHE_CLEARED_PTR + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + PTR + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_CLEARED_PTR + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + + + VAR_NOCACHE_CLEARED_UNSPECIFIED + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_NOCACHE_CLEARED_UNSPECIFIED + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + + + VAR_PBCFG + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionAlignment + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionFileName + MemMap_Common.h + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionPrefix + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSymbol + VAR_PBCFG + + + + + /MICROSAR/MemMap/MemMapModule/MemMapAdditionalMemorySection/MemMapMemorySectionSwAddrMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_PBCFG + + + + + + + MemMapGeneral + /MICROSAR/MemMap/MemMapGeneral + + + /MICROSAR/MemMap/MemMapGeneral/MemMapGeneratePragmasForNearAddressing + false + + + /MICROSAR/MemMap/MemMapGeneral/MemMapGeneration + FULL + + + /MICROSAR/MemMap/MemMapGeneral/MemMapCompatibilityGeneration + FULL + + + /MICROSAR/MemMap/MemMapGeneral/MemMapTypedPragmas + true + + + /MICROSAR/MemMap/MemMapGeneral/MemMapGeneratePragmas + true + + + /MICROSAR/MemMap/MemMapGeneral/MemMapErrorChecks + ALL + + + + + MSR_Generic + /MICROSAR/MemMap/MemMapAllocation + + + MSR_CODE + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALLOUT_CODE + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALLOUT_CODE_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALLOUT_CODE_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALLOUT_CODE_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALLOUT_CODE_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALLOUT_CODE_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_FAST + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_FAST_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_FAST_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_FAST_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_FAST_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_FAST_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_ISR + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_ISR_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_ISR_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_ISR_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_ISR_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_ISR_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_SLOW + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_SLOW_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_SLOW_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_SLOW_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_SLOW_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CODE_SLOW_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/MSR_CODE + + + + + MSR_CONST + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/MSR_CONST + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_PREBUILD + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_PREBUILD_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_PREBUILD_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_PREBUILD_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_PREBUILD_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_PREBUILD_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_POSTBUILD + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_POSTBUILD_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_POSTBUILD_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_POSTBUILD_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_POSTBUILD_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONFIG_DATA_POSTBUILD_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_FAST_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALIB + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALIB_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALIB_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALIB_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALIB_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CALIB_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_SAVED_RECOVERY_ZONE + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_SAVED_RECOVERY_ZONE_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_SAVED_RECOVERY_ZONE_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_SAVED_RECOVERY_ZONE_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_SAVED_RECOVERY_ZONE_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_SAVED_RECOVERY_ZONE_ASIL_D + + + + + MSR_PBCFG_CONST + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/CONST_PBCFG + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/MSR_PBCFG_CONST + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/PBCFG_GLOBALROOT + + + + + MSR_PBCFG_VAR + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_PBCFG + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/MSR_PBCFG_VAR + + + + + MSR_VAR_CLEARED + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_ZERO_INIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_ZERO_INIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_ZERO_INIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_ZERO_INIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_ZERO_INIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/MSR_VAR_CLEARED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_ZERO_INIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_ZERO_INIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_ZERO_INIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_ZERO_INIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_ZERO_INIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_ZERO_INIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_ZERO_INIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_ZERO_INIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_ZERO_INIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_ZERO_INIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_ZERO_INIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_ZERO_INIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_ZERO_INIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_CLEARED_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_CLEARED_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_CLEARED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_ZERO_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_CLEARED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_CLEARED_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_CLEARED_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_CLEARED_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_CLEARED_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_CLEARED_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_CLEARED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_CLEARED_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_CLEARED_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_CLEARED_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_CLEARED_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_CLEARED_ASIL_D + + + + + MSR_VAR_INIT + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/MSR_VAR_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_INIT_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_INIT_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_INIT_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_INIT_ASIL_D + + + + + MSR_VAR_NO_INIT + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/MSR_VAR_NO_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NOINIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NOINIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NOINIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NOINIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NOINIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOINIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOINIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOINIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOINIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOINIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOINIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NOINIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NOINIT_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NOINIT_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NOINIT_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NOINIT_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NOINIT_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NOINIT_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NO_INIT_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_NO_INIT_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_NOCACHE_NO_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_NO_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_NO_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_NO_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_NO_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_NO_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_NO_INIT_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_NO_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_NO_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_NO_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_NO_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_NO_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_NO_INIT_ASIL_D + + + + + MSR_VAR_POWER_ON_CLEARED + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/MSR_VAR_POWER_ON_CLEARED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_CLEARED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_CLEARED_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_CLEARED_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_CLEARED_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_CLEARED_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_CLEARED_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_CLEARED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_CLEARED_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_CLEARED_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_CLEARED_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_CLEARED_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_CLEARED_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_CLEARED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_CLEARED_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_CLEARED_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_CLEARED_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_CLEARED_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_CLEARED_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_CLEARED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_CLEARED_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_CLEARED_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_CLEARED_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_CLEARED_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_CLEARED_ASIL_D + + + + + MSR_VAR_POWER_ON_INIT + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/MSR_VAR_POWER_ON_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_POWER_ON_INIT_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_FAST_POWER_ON_INIT_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SLOW_POWER_ON_INIT_ASIL_D + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_INIT + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_INIT_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_INIT_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_INIT_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_INIT_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/INTERNAL_VAR_POWER_ON_INIT_ASIL_D + + + + + MSR_VAR_SAVED_ZONE + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapAddressingModeSetRef + /ActiveEcuC/MemMap/MSR_VAR_SAVED_ZONE + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE_BOOLEAN + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE_8 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE_16 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE_32 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE_64 + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE_UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE_QM + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE_ASIL_A + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE_ASIL_B + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE_ASIL_C + + + /MICROSAR/MemMap/MemMapAllocation/MemMapGenericMapping/MemMapSwAddressMethodRef + /MICROSAR_MemMap/SwAddrMethods/VAR_SAVED_ZONE_ASIL_D + + + + + + + MSR_CODE + /MICROSAR/MemMap/MemMapAddressingModeSet + + + MSR_CODE + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 8 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 16 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 64 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + BOOLEAN + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + PTR + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/MSR_CODE + + + + + + + MSR_CONST + /MICROSAR/MemMap/MemMapAddressingModeSet + + + MSR_CONST + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 8 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 16 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 64 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + BOOLEAN + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + PTR + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/MSR_CONST + + + + + + + MSR_PBCFG_CONST + /MICROSAR/MemMap/MemMapAddressingModeSet + + + MSR_PBCFG_CONST + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 8 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 16 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 64 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + BOOLEAN + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + PTR + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/MSR_PBCFG_CONST + + + + + + + MSR_PBCFG_VAR + /MICROSAR/MemMap/MemMapAddressingModeSet + + + MSR_PBCFG_VAR + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 8 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 16 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 64 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + BOOLEAN + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + PTR + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/MSR_PBCFG_VAR + + + + + + + MSR_VAR_CLEARED + /MICROSAR/MemMap/MemMapAddressingModeSet + + + MSR_VAR_CLEARED + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 8 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 16 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 64 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + BOOLEAN + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + PTR + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/MSR_VAR + + + + + + + MSR_VAR_INIT + /MICROSAR/MemMap/MemMapAddressingModeSet + + + MSR_VAR_INIT + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 8 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 16 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 64 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + BOOLEAN + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + PTR + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/MSR_VAR + + + + + + + MSR_VAR_NO_INIT + /MICROSAR/MemMap/MemMapAddressingModeSet + + + MSR_VAR_NO_INIT + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 8 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 16 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 64 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + BOOLEAN + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + PTR + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/MSR_VAR + + + + + + + MSR_VAR_POWER_ON_CLEARED + /MICROSAR/MemMap/MemMapAddressingModeSet + + + MSR_VAR_POWER_ON_CLEARED + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 8 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 16 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 64 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + BOOLEAN + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + PTR + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/MSR_VAR + + + + + + + MSR_VAR_POWER_ON_INIT + /MICROSAR/MemMap/MemMapAddressingModeSet + + + MSR_VAR_POWER_ON_INIT + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 8 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 16 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 64 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + BOOLEAN + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + PTR + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/MSR_VAR + + + + + + + MSR_VAR_SAVED_ZONE + /MICROSAR/MemMap/MemMapAddressingModeSet + + + MSR_VAR_SAVED_ZONE + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + UNSPECIFIED + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 8 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 16 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 32 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + 64 + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + BOOLEAN + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapAlignmentSelector + PTR + + + + + /MICROSAR/MemMap/MemMapAddressingModeSet/MemMapAddressingMode/MemMapLinkerLogicalGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/MSR_VAR_SAVED_ZONE + + + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_vBRS_vBRS_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_vBRS_vBRS_ecuc.arxml new file mode 100644 index 0000000..c1b8f60 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_vBRS_vBRS_ecuc.arxml @@ -0,0 +1,216 @@ + + + + + ActiveEcuC + + + vBRS + /MICROSAR/vBRS + VARIANT-PRE-COMPILE + /MICROSAR/vBRS_Impl + + + vBRSGeneral + /MICROSAR/vBRS/vBRSGeneral + + + /MICROSAR/vBRS/vBRSGeneral/vBRSEnableEcuMStubGeneration + false + + + /MICROSAR/vBRS/vBRSGeneral/vBRSEnableSchmStubGeneration + true + + + /MICROSAR/vBRS/vBRSGeneral/vBRSExecutionInstance + FBL + + + /MICROSAR/vBRS/vBRSGeneral/vBRSFblSupportExceptionTableInRam + true + + + /MICROSAR/vBRS/vBRSGeneral/vBRSEnableCoreSpecificVLinkGenConfig + true + + + /MICROSAR/vBRS/vBRSGeneral/vBRSEnableSupportLEDs + false + + + /MICROSAR/vBRS/vBRSGeneral/vBRSEnableSafeContextSupport + false + + + /MICROSAR/vBRS/vBRSGeneral/vBRSEnableMultiCoreSupport + false + + + /MICROSAR/vBRS/vBRSGeneral/vBRSEnableSupportToggleWdPin + false + + + /MICROSAR/vBRS/vBRSGeneral/vBRSEnableSupportToggleCustomPin + false + + + /MICROSAR/vBRS/vBRSGeneral/vBRSDisableSetupSupport + false + + + /MICROSAR/vBRS/vBRSGeneral/vBRSEnableSchmStubSupportDrvCanAN + false + + + /MICROSAR/vBRS/vBRSGeneral/vBRSFirstInstance + true + + + /MICROSAR/vBRS/vBRSGeneral/vBRSFblSupportEcuMInit + false + + + /MICROSAR/vBRS/vBRSGeneral/vBRSEnableSmallDevicesOptimization + false + + + /MICROSAR/vBRS/vBRSGeneral/vBRSHypervisorGuest + false + + + + + vBRSHwConfig + /MICROSAR/vBRS/vBRSHwConfig + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSEnablePLLClocksHandling + true + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSEnablePortHandling + true + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSEnableWatchdogHandling + true + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSPreferPLLWatchdogInit + false + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSMakefileUserCode + ADDITIONAL_INCLUDES += LlvmTi + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSMakefileUserCode + ADDITIONAL_LDFLAGS_FROM_VBRS = -L LlvmTi/drivers/lib + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSMakefileUserCode + ADDITIONAL_LDFLAGS_FROM_VBRS += -L LlvmTi/kernel/lib + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSMakefileUserCode + ADDITIONAL_LDFLAGS_FROM_VBRS += -Xlinker --library=drivers.am263x.r5f.ti_arm_clang.debug.lib + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSMakefileUserCode + ADDITIONAL_LDFLAGS_FROM_VBRS += -Xlinker --library=nortos.am263x.r5f.ti_arm_clang.debug.lib + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSMakefileUserCode + ADDITIONAL_LDFLAGS_FROM_VBRS += -Xlinker --retain='*(.brsExcVect1*)' + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSMakefileUserCode + ADDITIONAL_LDFLAGS_FROM_VBRS += -Xlinker --retain='*(.brsExcVect2*)' + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSMakefileUserCode + ADDITIONAL_LDFLAGS_FROM_VBRS += -Xlinker --retain='*(.brsExcVect3*)' + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSOscClock + 25000000 + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSPeriphClock + 12500000 + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSTimebaseClock + 400000000 + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSCompilerInstructionSet + ARM + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSCompilerEnableFPU + true + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSPeriphClockDescription + SBL powers up the timers and clock sources. RTI1 Timer: 12.5MHz + + + + + TI_AM2634_EVM + /MICROSAR/vBRS/vBRSHwConfig/vBRSEvalBoardInfo + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSEvalBoardInfo/vBRSEvalBoard + TI_AM2634_EVM + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSEvalBoardInfo/vBRSEvalBoardDescription + User LEDs -> GPIO1 (on unused QSPI0_CSn1) + + + /MICROSAR/vBRS/vBRSHwConfig/vBRSEvalBoardInfo/vBRSEvalBoardOscClock + 25000000 + + + + + + + vBRSMemoryInit + /MICROSAR/vBRS/vBRSMemoryInit + + + /MICROSAR/vBRS/vBRSMemoryInit/vBRSInitPatternBlocks + 0 + + + /MICROSAR/vBRS/vBRSMemoryInit/vBRSInitPatternHardResetBlocks + 0 + + + /MICROSAR/vBRS/vBRSMemoryInit/vBRSInitPatternAreas + 0 + + + /MICROSAR/vBRS/vBRSMemoryInit/vBRSInitPatternHardResetAreas + 0 + + + /MICROSAR/vBRS/vBRSMemoryInit/vBRSInitEnable64BitInitPattern + false + + + /MICROSAR/vBRS/vBRSMemoryInit/vBRSDisableMemoryInitGlobally + false + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_vBaseEnv_vBaseEnv_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_vBaseEnv_vBaseEnv_ecuc.arxml new file mode 100644 index 0000000..82911f0 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_vBaseEnv_vBaseEnv_ecuc.arxml @@ -0,0 +1,255 @@ + + + + + ActiveEcuC + + + vBaseEnv + /MICROSAR/vBaseEnv + VARIANT-PRE-COMPILE + /MICROSAR/vBaseEnv_Impl + + + vBaseEnvGeneral + /MICROSAR/vBaseEnv/vBaseEnvGeneral + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvTestedDerivativeRef + + + + + AM2634 + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvAvailableChannels_Can + 4 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvAvailableChannels_Lin + 5 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvAvailableChannels_Ethernet + 2 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvAvailableChannels_Flexray + 0 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvCpuCore + CORTEX_R5F + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvCpuCoreAmount + 4 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvCpuInitCore + 0 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvCpuMaxFrequency + 400000000 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvTestedDerivative + AM2634 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvTestedDerivativeDescription + TI AM2634 Grade O, Device Rev B (SR1.0A) (Infos accord. to AM263x__DS__2022_02_04__SPRSP74.pdf) + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvAvailableChannels_I2c + 4 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvAvailableChannels_Spi + 5 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvAvailableChannels_Hyperbus + 0 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvAvailableChannels_EthernetSwitch + 0 + + + + + OCSRAM + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionStartAddress + 1879048192 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionSize + 2097152 + + + + + R5SS0_CORE0_TCMA + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionStartAddress + 0 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionSize + 32768 + + + + + R5SS0_CORE0_TCMB + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionStartAddress + 524288 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionSize + 32768 + + + + + R5SS0_CORE1_TCMA + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionStartAddress + 2015363072 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionSize + 32768 + + + + + R5SS0_CORE1_TCMB + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionStartAddress + 2016411648 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionSize + 32768 + + + + + R5SS1_CORE0_TCMA + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionStartAddress + 2017460224 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionSize + 32768 + + + + + R5SS1_CORE0_TCMB + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionStartAddress + 2018508800 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionSize + 32768 + + + + + R5SS1_CORE1_TCMA + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionStartAddress + 2019557376 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionSize + 32768 + + + + + R5SS1_CORE1_TCMB + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionStartAddress + 2020605952 + + + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvDerivativeInformation/vBaseEnvMemLayoutHwRegion/vBaseEnvHwRegionSize + 32768 + + + + + + + OCSRAM + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvMemLayoutHwRegion + + + R5SS0_CORE0_TCMA + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvMemLayoutHwRegion + + + R5SS0_CORE0_TCMB + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvMemLayoutHwRegion + + + R5SS0_CORE1_TCMA + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvMemLayoutHwRegion + + + R5SS0_CORE1_TCMB + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvMemLayoutHwRegion + + + R5SS1_CORE0_TCMA + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvMemLayoutHwRegion + + + R5SS1_CORE0_TCMB + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvMemLayoutHwRegion + + + R5SS1_CORE1_TCMA + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvMemLayoutHwRegion + + + R5SS1_CORE1_TCMB + /MICROSAR/vBaseEnv/vBaseEnvGeneral/vBaseEnvMemLayoutHwRegion + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_vLinkGen_vLinkGen_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_vLinkGen_vLinkGen_ecuc.arxml new file mode 100644 index 0000000..c17711c --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_vLinkGen_vLinkGen_ecuc.arxml @@ -0,0 +1,6505 @@ + + + + + ActiveEcuC + + + vLinkGen + + + + false + + + + /MICROSAR/vLinkGen + VARIANT-PRE-COMPILE + /MICROSAR/vLinkGen_Impl + + + vLinkGenMemLayout + /MICROSAR/vLinkGen/vLinkGenMemLayout + + + vHsm + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 16384 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + + + + + vGlobalRamBuffer + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 15104 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/vHsmGlobalRamBuffer + + + + + vHsmIpcMemory + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 1280 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/vHsmIpcMemory + + + + + + + vLinkGenLinkerSections + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections + + + vHsmGlobalRamBuffer + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + vHsmGlobalRamBuffer + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + vHsmIpcMemory + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + vHsmIpcMemory + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + svHsmGlobalRamBuffer + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + svHsmGlobalRamBuffer + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + svHsmIpcMemory + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + svHsmIpcMemory + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + vHsmGlobalRamBuffer_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + vHsmGlobalRamBuffer_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + vHsmGlobalRamBuffer_INIT_FAST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + vHsmGlobalRamBuffer_INIT_FAST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + + + vHsmGlobalRamBuffer_NO_INIT_FAST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + vHsmGlobalRamBuffer_NO_INIT_FAST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + + + vHsmIpcMemory_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + vHsmIpcMemory_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + vHsmIpcMemory_INIT_FAST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + vHsmIpcMemory_INIT_FAST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + + + vHsmIpcMemory_NO_INIT_FAST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + vHsmIpcMemory_NO_INIT_FAST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + + + RamCodeSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + RamCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionAlignment + 0 + + + + + EepDummySection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + EepDummySection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionAlignment + 0 + + + + + BmHeaderSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + BmHeaderSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionAlignment + 0 + + + + + RamConstSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + RamConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionAlignment + 0 + + + + + FblHeaderSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + FblHeaderSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionAlignment + 0 + + + + + BmHdrHeaderSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + BmHdrHeaderSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionAlignment + 0 + + + + + MagicFlagSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MagicFlagSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionAlignment + 0 + + + + + FblPresencePatternSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + FblPresencePatternSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + ApplVectSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + ApplVectSection + + + + + FblFlashDrvSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + FblFlashDrvSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionAlignment + 0 + + + + + FlashDrvHeaderSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + FlashDrvHeaderSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + FlashDrvFooterSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + FlashDrvFooterSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + MSR_CODE + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + MSR_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + MSR_CONST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + MSR_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + MSR_PBCFG_CONST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + MSR_PBCFG_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + MSR_PBCFG_VAR + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_PBCFG_VAR + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MSR_VAR_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_CLEARED + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MSR_VAR_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MSR_VAR_NO_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_NO_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MSR_CONST_FAST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + true + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + MSR_CONST_FAST + + + + + MSR_VAR_FAST_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_FAST_CLEARED + + + + + MSR_VAR_FAST_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_FAST_INIT + + + + + MSR_VAR_FAST_NO_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_FAST_NO_INIT + + + + + MSR_PBCFG_CONST_FAST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + true + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + MSR_PBCFG_CONST_FAST + + + + + MSR_PBCFG_VAR_FAST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_PBCFG_VAR_FAST + + + + + MSR_PBCFG_VAR_FAST_NO_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_PBCFG_VAR_FAST_NO_INIT + + + + + MSR_PBCFG_VAR_NO_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_PBCFG_VAR_NO_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MSR_VAR_SAVED_ZONE_POWER_ON_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_SAVED_ZONE_POWER_ON_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MSR_VAR_SAVED_ZONE_POWER_ON_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_SAVED_ZONE_POWER_ON_CLEARED + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MSR_VAR_SAVED_ZONE_FAST_POWER_ON_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_SAVED_ZONE_FAST_POWER_ON_INIT + + + + + MSR_VAR_SAVED_ZONE_FAST_POWER_ON_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_SAVED_ZONE_FAST_POWER_ON_CLEARED + + + + + MSR_PBCFG_VAR_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_PBCFG_VAR_CLEARED + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MSR_PBCFG_VAR_FAST_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_PBCFG_VAR_FAST_CLEARED + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + true + + + + + MSR_VAR_POWER_ON_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_POWER_ON_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MSR_VAR_FAST_POWER_ON_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_FAST_POWER_ON_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MSR_VAR_POWER_ON_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_POWER_ON_CLEARED + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MSR_VAR_FAST_POWER_ON_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + MSR_VAR_FAST_POWER_ON_CLEARED + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + brsStartup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + brsStartup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + startupCode + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + startupCode + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + brsExcVect1 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + brsExcVect1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + brsExcVect2 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + brsExcVect2 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + brsExcVect3 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + brsExcVect3 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + startupData + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + startupData + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + DMSC_INTERNAL_const + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + const.devgroup.DMSC_INTERNAL + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + MAIN_const + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + const.devgroup.MAIN + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + MCU_WAKEUP_const + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + const.devgroup.MCU_WAKEUP + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + brsExcVect1Const + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + brsExcVect1Const + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + brsExcVect2Const + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + brsExcVect2Const + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + brsExcVect3Const + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + brsExcVect3Const + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + BOARDCFG_DATA + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + boardcfg_data + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + DATA_USER + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + data_user + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + DMSC_INTERNAL_var + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + bss.devgroup.DMSC_INTERNAL + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MAIN_var + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + bss.devgroup.MAIN + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + MCU_WAKEUP_var + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + bss.devgroup.MCU_WAKEUP + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + brsExcVectRamConst + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + brsExcVectRamConst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + brsExcVectRam + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + brsExcVectRam + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + brsExcVect + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + brsExcVect + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + brsMainStartup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + brsMainStartup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + brsSharedConst + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + brsSharedConst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + brsApplicationEntry + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + brsApplicationEntry + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + brsExcVectConst + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + brsExcVectConst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + brsSharedVar + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + brsSharedVar + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + text + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionName + text + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerCodeSection/vLinkGenLinkerCodeSectionFast + false + + + + + rodata + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionName + rodata + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerConstSection/vLinkGenLinkerConstSectionFast + false + + + + + rodata_const + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerSpecSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerSpecSection/vLinkGenLinkerSpecSectionValue + .const + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerSpecSection/vLinkGenLinkerSpecSectionPad + 0 + + + + + data + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + data + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + bss + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + bss + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + stack + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + stack + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + heap + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionName + heap + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vLinkGenLinkerVarSection/vLinkGenLinkerVarSectionFast + false + + + + + + + vHsmIpcMemory + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupInitCore + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vHsm/vHsmIpcMemory + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/vHsmIpcMemory + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + + + vHsmIpcMemory + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 64 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vHsmIpcMemory + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/svHsmIpcMemory + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vHsmIpcMemory_NO_INIT_FAST + + + + + vHsmIpcMemory_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 64 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vHsmIpcMemory_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vHsmIpcMemory_INIT_FAST + + + + + + + vHsmGlobalRamBuffer + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupInitCore + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vHsm/vGlobalRamBuffer + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/vHsmGlobalRamBuffer + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + + + vHsmGlobalRamBuffer + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vHsmGlobalRamBuffer + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/svHsmGlobalRamBuffer + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vHsmGlobalRamBuffer_NO_INIT_FAST + + + + + vHsmGlobalRamBuffer_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vHsmGlobalRamBuffer_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/vHsmGlobalRamBuffer_INIT_FAST + + + + + + + Var_EepDummyArea + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 256 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + + + + + EepDummy + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 256 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + + + + + Var_MagicFlagArea + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 8 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + + + + + MagicFlag + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 8 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + + + + + Const_BmHeader + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + + + + + BmHeader + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + UPPER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 32 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + + + Const_FlashBootloader + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + + + + + FblHeader + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 512 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + FblBmHdrHeader + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 512 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + FblApplicationEntry + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 2 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 256 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + FblRomArea + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 3 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + FblReserved + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + UPPER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 4096 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + FblBlockValPresencePattern + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + UPPER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + + + Const_ApplicationOrUpdater + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + + + + + ApplStartupCode_FirstExecInst + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 1504 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + ApplCoreExceptions_FirstExecInst + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 2 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 512 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + ApplVect + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 3 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 8 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + ApplApplicationEntry + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 256 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + ApplRomArea + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 5 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + ApplBmHdrHeader + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 512 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + ApplReserved + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + UPPER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 4096 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + + + Data_Default + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupInitCore + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 1000 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_DATA + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + vLinkGenVarGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificRomRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificRomRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + data + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/data + + + + + bss + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + ZERO_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/bss + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/stack + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/heap + + + + + + + MSR_PBCFG_VAR + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupInitCore + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_DATA + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + vLinkGenVarGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificRomRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificRomRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + MSR_PBCFG_VAR_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_PBCFG_VAR + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_PBCFG_VAR_FAST + + + + + MSR_PBCFG_VAR_NO_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_PBCFG_VAR_NO_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_PBCFG_VAR_FAST_NO_INIT + + + + + MSR_PBCFG_VAR_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + ZERO_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_PBCFG_VAR_CLEARED + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_PBCFG_VAR_FAST_CLEARED + + + + + + + MSR_VAR + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupInitCore + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_DATA + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + vLinkGenVarGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificRomRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificRomRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + MSR_VAR_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + ZERO_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_CLEARED + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_FAST_CLEARED + + + + + MSR_VAR_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_FAST_INIT + + + + + MSR_VAR_NO_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_NO_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_FAST_NO_INIT + + + + + MSR_VAR_POWER_ON_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + ZERO_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + POWER_ON + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_POWER_ON_CLEARED + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_FAST_POWER_ON_CLEARED + + + + + MSR_VAR_POWER_ON_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + POWER_ON + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_POWER_ON_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_FAST_POWER_ON_INIT + + + + + + + MSR_VAR_SAVED_ZONE + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupInitCore + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/RETENTION_DATA + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + vLinkGenVarGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificRomRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificRomRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariantHandling/vLinkGenVarGroupVariantSpecifics/vLinkGenVarGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + MSR_VAR_SAVED_ZONE_POWER_ON_INIT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + POWER_ON + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_SAVED_ZONE_POWER_ON_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_SAVED_ZONE_FAST_POWER_ON_INIT + + + + + MSR_VAR_SAVED_ZONE_POWER_ON_CLEARED + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + ZERO_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + POWER_ON + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_SAVED_ZONE_POWER_ON_CLEARED + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_VAR_SAVED_ZONE_FAST_POWER_ON_CLEARED + + + + + + + Brs_Startup_Code + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 1 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/STARTUP_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/StartupCode_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + + + vLinkGenConstGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling + + + DemoUpd + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplStartupCode_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + + + + + Brs_Startup_Code + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsStartup + + + + + BrsMain_Startup_Code + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsMainStartup + + + + + + + Brs_Shared_Var + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/SHARED_DATA + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/Variables_Shared + + + + + Brs_Shared_Var + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsSharedVar + + + + + + + Brs_Shared_Const + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + Brs_Shared_Const + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsSharedConst + + + + + + + Brs_ExcVect + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 1 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/R5SS0_CORE1_TCMA/CoreExceptions_R5SS0_CORE1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + + + vLinkGenConstGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling + + + DemoUpd + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplCoreExceptions_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + + + + + Brs_ExcVect + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsExcVect + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsExcVectConst + + + + + + + Brs_ExcVectRam + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupInitCore + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/RAM_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + vLinkGenConstGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + Brs_ExcVectRam + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + COPY_TO_RAM + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsExcVectRam + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsExcVectRamConst + + + + + + + Brs_ApplicationEntry + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 1 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/APPLICATION_ENTRY + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/ApplicationEntry + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + vLinkGenConstGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblApplicationEntry + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplApplicationEntry + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + Brs_ApplicationEntry + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsApplicationEntry + + + + + + + Const_Default + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 1000 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + vLinkGenConstGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + text + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/text + + + + + rodata + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/rodata + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/rodata_const + + + + + + + MSR_CODE + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + vLinkGenConstGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + MSR_CODE + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_CODE + + + + + + + MSR_CONST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + vLinkGenConstGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + MSR_CONST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_CONST_FAST + + + + + + + MSR_PBCFG_CONST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + vLinkGenConstGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + MSR_PBCFG_CONST + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_PBCFG_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MSR_PBCFG_CONST_FAST + + + + + + + Fbl_EepDummy_Shared + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupInitCore + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Var_EepDummyArea/EepDummy + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + + + EepDummySection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + ZERO_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + HARD_RESET_ONLY + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/EepDummySection + + + + + + + Fbl_MagicFlag_Shared + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupInitCore + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Var_MagicFlagArea/MagicFlag + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + + + MagicFlagSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + ZERO_INIT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + HARD_RESET_ONLY + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MagicFlagSection + + + + + + + Fbl_EepDummy_SharedNoinit + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Var_EepDummyArea/EepDummy + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + EepDummySectionNoinit + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/EepDummySection + + + + + + + Fbl_MagicFlag_SharedNoinit + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Var_MagicFlagArea/MagicFlag + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + MagicFlagSectionNoinit + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MagicFlagSection + + + + + + + Fbl_FblHeader + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblHeader + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + FblHeaderSectionGroup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/FblHeaderSection + + + + + + + FblAppl_BmHdrHeader + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblBmHdrHeader + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + FblBmHdrHeaderGroup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/BmHdrHeaderSection + + + + + vLinkGenConstGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblBmHdrHeader + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplBmHdrHeader + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + + + Fbl_PresencePattern + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblBlockValPresencePattern + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + Fbl_PP + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/FblPresencePatternSection + + + + + + + Appl_ApplVect + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplVect + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + + + APPLVECT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupSize + 8 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/ApplVectSection + + + + + + + Bm_BmHeader + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_BmHeader/BmHeader + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + + + BmHeaderSectionGroup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/BmHeaderSection + + + + + + + FblUpd_RamCode + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupInitCore + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/RAM_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + RamCodeSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + COPY_TO_RAM + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/RamCodeSection + + + + + vLinkGenConstGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + + + FblUpd_RamConst + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupInitCore + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/RAM_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + RamConstSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + COPY_TO_RAM + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/RamConstSection + + + + + vMemHeaderSectionGroup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 100 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/FlashDrvHeaderSection + + + + + vMemFooterSectionGroup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 100 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/FlashDrvFooterSection + + + + + vLinkGenConstGroupVariantHandling + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling + + + DemoFbl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_FlashBootloader/FblRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + + + DemoUpd_DemoAppl + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Const_ApplicationOrUpdater/ApplRomArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariantHandling/vLinkGenConstGroupVariantSpecifics/vLinkGenConstGroupSpecificVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + + + + + Startup_Labels_NoFirstExec + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenSymbolGroupPosition + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenSymbolGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenSymbolGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenSymbolGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + + + Startup_Label_NoFirstExec + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolName + brsStartupEntry + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolValue + Brs_ApplicationEntry + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolPosition + 0 + + + + + + + ApplVectSymbols + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenSymbolGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenSymbolGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenSymbolGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenSymbolGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenSymbolGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + + + RESETVECT + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolName + RESETVECT + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolValue + brsStartupEntry + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolPosition + 0 + + + + + RESETVECT_1 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolName + _START + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolValue + brsStartupEntry + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolPosition + 0 + + + + + RESETVECT_2 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolName + Startup_Handler + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolValue + brsStartupEntry + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolPosition + 0 + + + + + + + FlashDrv_CodeConst + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 1000 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Var_FlashDrvArea/FlashDrvArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FlashDrv + + + + + text + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 500 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/text + + + + + rodata + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 500 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/rodata + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/rodata_const + + + + + FlashDrv_RamCodeSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 500 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/RamCodeSection + + + + + FlashDrv_RamConstSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 500 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/RamConstSection + + + + + + + FlashDrv_Data + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 250 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Var_FlashDrvArea/FlashDrvArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FlashDrv + + + + + data + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 500 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/data + + + + + bss + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 500 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/bss + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/stack + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/heap + + + + + + + Var_FlashDrvArea + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + + + + + FlashDrvArea + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitCore + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + HARD_RESET_ONLY + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + + + + + FlashDrv_Header + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FlashDrv + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Var_FlashDrvArea/FlashDrvArea + + + + + FlashDrvHeaderSectionGroup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/FlashDrvHeaderSection + + + + + + + FlashDrv_Footer + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 2000 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FlashDrv + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Var_FlashDrvArea/FlashDrvArea + + + + + FlashDrvFooterSectionGroup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/FlashDrvFooterSection + + + + + + + FblUpd_FlashDrv + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 0 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/Var_FlashDrvArea/FlashDrvArea + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoFbl + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoUpd + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FirstExecInst + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_DemoAppl + + + + + FblFlashDrvSection + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/FblFlashDrvSection + + + + + + + FlashDrvSymbols + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenSymbolGroupPosition + 3 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenSymbolGroupVariant + /ActiveEcuC/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant_FlashDrv + + + + + StartupEntry + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolName + brsStartupEntry + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalSymbolGroup/vLinkGenLinkerSymbol/vLinkGenLinkerSymbolValue + 0 + + + + + + + OCSRAM + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + /ActiveEcuC/vBaseEnv/vBaseEnvGeneral/OCSRAM + + + + + StartupCode_FirstExecInst + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 1024 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/STARTUP_CODE + + + + + ApplicationEntry + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 256 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/APPLICATION_ENTRY + + + + + OCSRAM + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 2 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/LOCAL_INTVEC_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/LOCAL_INTVEC_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_INTVEC_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_INTVEC_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/LOCAL_EXCVEC_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/LOCAL_EXCVEC_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/LOCAL_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/LOCAL_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/RAM_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/RAM_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_DATA + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/STACKS + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/LOCAL_DATA + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/RAM_CODE_COPY + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/RAM_CONST_COPY + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/RETENTION_DATA + + + + + Variables_Shared + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 16 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + UPPER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/SHARED_DATA + + + + + StartupStack_Shared + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 4096 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + UPPER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/STARTUP_STACK + + + + + + + R5SS0_CORE0_TCMA + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + /ActiveEcuC/vBaseEnv/vBaseEnvGeneral/R5SS0_CORE0_TCMA + + + + + CoreExceptions_R5SS0_CORE0 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 96 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockCore + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CONST + + + + + + + R5SS0_CORE1_TCMA + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + /ActiveEcuC/vBaseEnv/vBaseEnvGeneral/R5SS0_CORE1_TCMA + + + + + CoreExceptions_R5SS0_CORE1 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 96 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockCore + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CONST + + + + + + + R5SS1_CORE0_TCMA + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + /ActiveEcuC/vBaseEnv/vBaseEnvGeneral/R5SS1_CORE0_TCMA + + + + + CoreExceptions_R5SS1_CORE0 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 96 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockCore + 2 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CONST + + + + + + + R5SS1_CORE1_TCMA + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddrOffset + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionSize + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionAvailable + true + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionHwRegion + /ActiveEcuC/vBaseEnv/vBaseEnvGeneral/R5SS1_CORE1_TCMA + + + + + CoreExceptions_R5SS1_CORE1 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockSize + 96 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockCore + 3 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockAddress + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockBoundary + LOWER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockInitStage + NONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CODE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenMemoryRegion/vLinkGenMemoryRegionBlock/vLinkGenMemoryRegionBlockContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CONST + + + + + + + Brs_ExcVect1 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupCore + 1 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/R5SS0_CORE1_TCMA/CoreExceptions_R5SS0_CORE1 + + + + + Brs_ExcVect1 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsExcVect1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsExcVect1Const + + + + + + + Brs_ExcVect2 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupCore + 2 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/R5SS0_CORE1_TCMA/CoreExceptions_R5SS0_CORE1 + + + + + Brs_ExcVect2 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsExcVect2 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsExcVect2Const + + + + + + + Brs_ExcVect3 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 1 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupCore + 3 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupContentType + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_EXCVEC_CONST + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/R5SS0_CORE1_TCMA/CoreExceptions_R5SS0_CORE1 + + + + + Brs_ExcVect3 + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsExcVect3 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsExcVect3Const + + + + + + + R5F_Startup_Code + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + R5F_Startup_Code + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/startupCode + + + + + + + R5F_Startup_Data + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + R5F_Startup_Data + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/startupData + + + + + + + TI_sysfw_sections_const_devgroup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + TI_sysfw_sections_const_devgroup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupEndAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/DMSC_INTERNAL_const + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MAIN_const + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MCU_WAKEUP_const + + + + + + + TI_sysfw_sections_bss_devgroup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarGroupRegion + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/OCSRAM/OCSRAM + + + + + TI_sysfw_sections_bss_devgroup + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupEndAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInit + NONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupInitStage + ONE + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/BOARDCFG_DATA + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/DATA_USER + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/DMSC_INTERNAL_var + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MAIN_var + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalVarGroup/vLinkGenVarSectionGroup/vLinkGenVarSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/MCU_WAKEUP_var + + + + + + + Brs_ExcVectRamConst + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupPosition + 5 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstGroupRegion + + + + + Brs_ExcVectRamConst + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInit + COPY_TO_RAM + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupInitStage + ONE + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupPosition + 0 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupAlignment + 4 + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupEndAlignment + 4 + + + + + /MICROSAR/vLinkGen/vLinkGenMemLayout/vLinkGenLogicalConstGroup/vLinkGenConstSectionGroup/vLinkGenConstSectionGroupRef + /ActiveEcuC/vLinkGen/vLinkGenMemLayout/vLinkGenLinkerSections/brsExcVectRamConst + + + + + + + + + vLinkGenContentTypes + /MICROSAR/vLinkGen/vLinkGenContentTypes + + + vHsmGlobalRamBuffer + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeLocal + false + + + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeCopyRef + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_CONST + + + + + vHsmIpcMemory + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeLocal + false + + + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeCopyRef + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_CONST + + + + + RAM_CODE + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + false + + + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeCopyRef + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/RAM_CODE_COPY + + + + + RAM_CONST + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + false + + + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeCopyRef + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/RAM_CONST_COPY + + + + + GLOBAL_DATA + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeLocal + false + + + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeCopyRef + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_CONST + + + + + LOCAL_DATA + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeLocal + true + + + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeCopyRef + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/LOCAL_CONST + + + + + RETENTION_DATA + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeLocal + false + + + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeCopyRef + /ActiveEcuC/vLinkGen/vLinkGenContentTypes/GLOBAL_CONST + + + + + GLOBAL_CODE + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + false + + + + + LOCAL_CODE + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + true + + + + + GLOBAL_CONST + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + false + + + + + LOCAL_CONST + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + true + + + + + GLOBAL_EXCVEC_CODE + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + false + + + + + LOCAL_EXCVEC_CODE + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + true + + + + + GLOBAL_EXCVEC_CONST + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + false + + + + + LOCAL_EXCVEC_CONST + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + true + + + + + GLOBAL_INTVEC_CODE + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + false + + + + + LOCAL_INTVEC_CODE + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + true + + + + + GLOBAL_INTVEC_CONST + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + false + + + + + LOCAL_INTVEC_CONST + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + true + + + + + STARTUP_CODE + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + false + + + + + STARTUP_STACK + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeLocal + true + + + + + STACKS + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeLocal + true + + + + + RAM_CODE_COPY + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeLocal + false + + + + + RAM_CONST_COPY + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeLocal + false + + + + + SHARED_DATA + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenVarContentType/vLinkGenVarContentTypeLocal + false + + + + + APPLICATION_ENTRY + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType + + + /MICROSAR/vLinkGen/vLinkGenContentTypes/vLinkGenConstContentType/vLinkGenConstContentTypeLocal + false + + + + + + + vLinkGenGeneral + /MICROSAR/vLinkGen/vLinkGenGeneral + + + /MICROSAR/vLinkGen/vLinkGenGeneral/vLinkGenFileGeneration + ONE_FILE_PER_VARIANT + + + /MICROSAR/vLinkGen/vLinkGenGeneral/vLinkGen64BitMemoryMode + false + + + + + vLinkGenVariantHandling + /MICROSAR/vLinkGen/vLinkGenVariantHandling + + + vLinkGenVariant_FirstExecInst + /MICROSAR/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant + + + /MICROSAR/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant/vLinkGenVariant_isFirstExec + true + + + + + vLinkGenVariant_DemoFbl + /MICROSAR/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant + + + /MICROSAR/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant/vLinkGenVariant_isStandardAppl + true + + + + + vLinkGenVariant_DemoAppl + /MICROSAR/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant + + + /MICROSAR/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant/vLinkGenVariant_isStandardAppl + true + + + + + vLinkGenVariant_DemoUpd + /MICROSAR/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant + + + /MICROSAR/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant/vLinkGenVariant_isStandardAppl + true + + + + + vLinkGenVariant_FlashDrv + /MICROSAR/vLinkGen/vLinkGenVariantHandling/vLinkGenVariant + + + + + vLinkGenPublishedInformation + /MICROSAR/vLinkGen/vLinkGenPublishedInformation + + + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenGeneration + 2 + + + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenDuplicatedLabels + false + + + + + vLinkGenRegionBlockFlags + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenRegionBlockFlags + + + EXECUTE + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenRegionBlockFlags/vLinkGenRegionBlockFlag + + + READ + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenRegionBlockFlags/vLinkGenRegionBlockFlag + + + WRITE + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenRegionBlockFlags/vLinkGenRegionBlockFlag + + + INIT + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenRegionBlockFlags/vLinkGenRegionBlockFlag + + + + + vLinkGenConstGroupFlags + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenConstGroupFlags + + + NOLOAD + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenConstGroupFlags/vLinkGenConstGroupFlag + + + PALIGN_BLOCK + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenConstGroupFlags/vLinkGenConstGroupFlag + + + + + vLinkGenVarGroupFlags + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenVarGroupFlags + + + NOLOAD + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenVarGroupFlags/vLinkGenVarGroupFlag + + + PALIGN_BLOCK + /MICROSAR/vLinkGen/vLinkGenPublishedInformation/vLinkGenVarGroupFlags/vLinkGenVarGroupFlag + + + + + + + + + + + diff --git a/config/Davinci/Config/ECUC/FLex_OBC_BM_vSet_vSet_ecuc.arxml b/config/Davinci/Config/ECUC/FLex_OBC_BM_vSet_vSet_ecuc.arxml new file mode 100644 index 0000000..823b4d6 --- /dev/null +++ b/config/Davinci/Config/ECUC/FLex_OBC_BM_vSet_vSet_ecuc.arxml @@ -0,0 +1,837 @@ + + + + + ActiveEcuC + + + vSet + + + + false + + + + + /ActiveEcuC/vSet/vSetBswInitialization/CryIf_InitMemory + + + /ActiveEcuC/vSet/vSetBswInitialization/CryIf_Init + + + + + /ActiveEcuC/vSet/vSetBswInitialization/CryIf_InitMemory/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/CryIf_Init/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Crypto_30_LibCv_InitMemory + + + /ActiveEcuC/vSet/vSetBswInitialization/Crypto_30_LibCv_Init + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Crypto_30_LibCv_InitMemory/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Crypto_30_LibCv_Init/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Crypto_30_vHsm_InitMemory + + + /ActiveEcuC/vSet/vSetBswInitialization/Crypto_30_vHsm_Init + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Crypto_30_vHsm_InitMemory/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Crypto_30_vHsm_Init/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Csm_InitMemory + + + /ActiveEcuC/vSet/vSetBswInitialization/Csm_Init + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Csm_InitMemory/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Csm_Init/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Det_Init + + + /ActiveEcuC/vSet/vSetBswInitialization/Det_Start + + + /ActiveEcuC/vSet/vSetBswInitialization/Det_InitMemory + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Det_Init/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Det_Start/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Det_InitMemory/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Brs_Init + + + + + /ActiveEcuC/vSet/vSetBswInitialization/Brs_Init/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/vBaseEnv_Init + + + + + /ActiveEcuC/vSet/vSetBswInitialization/vBaseEnv_Init/vSetInitFunctionInstance + + + + + /ActiveEcuC/vSet/vSetBswInitialization/vLinkGen_Init + + + + + /ActiveEcuC/vSet/vSetBswInitialization/vLinkGen_Init/vSetInitFunctionInstance + + + + + + /MICROSAR/vSet + VARIANT-PRE-COMPILE + /MICROSAR/vSet_Impl + + + vSetGeneral + /MICROSAR/vSet/vSetGeneral + + + /MICROSAR/vSet/vSetGeneral/vSetDummyStatementKind + SelfAssignment + + + + + vSetPlatform + /MICROSAR/vSet/vSetPlatform + + + /MICROSAR/vSet/vSetPlatform/vSetSizeOfRAMPointer + Size32Bit + + + /MICROSAR/vSet/vSetPlatform/vSetSizeOfEnum + Size32Bit + + + /MICROSAR/vSet/vSetPlatform/vSetBitOrder + LSB_to_MSB + + + /MICROSAR/vSet/vSetPlatform/vSetSizeOfInt + Size32Bit + + + /MICROSAR/vSet/vSetPlatform/vSetCPUType + CPU32Bit + + + /MICROSAR/vSet/vSetPlatform/vSetSizeOfROMPointer + Size32Bit + + + /MICROSAR/vSet/vSetPlatform/vSetByteOrder + LITTLE_ENDIAN + + + + + vSetCalibration + /MICROSAR/vSet/vSetCalibration + + + vSetBswInitialization + /MICROSAR/vSet/vSetBswInitialization + + + CryIf_InitMemory + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes variables of the Crypto Interface +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + CryIf.h + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/CryIf + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + INIT_MEMORY + + + + +
    + + CryIf_Init + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes the Crypto Interface +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + CryIf.h + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/CryIf + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + INIT_TWO_IF + + + + +
    + + Crypto_30_LibCv_InitMemory + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes variables of the Crypto Driver +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + Crypto_30_LibCv.h + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/Crypto + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + INIT_MEMORY + + + + +
    + + Crypto_30_LibCv_Init + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes the Crypto Driver +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + Crypto_30_LibCv.h + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/Crypto + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + INIT_TWO_DRV + + + + +
    + + Crypto_30_vHsm_InitMemory + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes variables of the Crypto Driver +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + Crypto_30_vHsm.h + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/Crypto_001 + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + INIT_MEMORY + + + + +
    + + Crypto_30_vHsm_Init + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes the Crypto Driver +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + Crypto_30_vHsm.h + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/Crypto_001 + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + INIT_TWO_DRV + + + + +
    + + Csm_InitMemory + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes variables of the Crypto Service Manager +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + Csm.h + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/Csm + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + INIT_MEMORY + + + + +
    + + Csm_Init + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Initializes the Crypto Service Manager +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + Csm.h + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/Csm + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + INIT_TWO_SYS + + + + +
    + + Det_Init + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Init function description of Det in UnfilteredViewInInvariantProject (UnfilteredInvariantProjectModelView) . +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + Det.h + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetConfigType + Det_ConfigType + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetConfigPtrClass + DET_INIT_DATA + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/Det + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + INIT_ZERO + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetConfigPtrName + Det_Config_Ptr + + + + +
    + + Det_Start + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + PostInit function description of Det in UnfilteredViewInInvariantProject (UnfilteredInvariantProjectModelView) . +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + Det.h + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/Det + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + INIT_ONE + + + + +
    + + Det_InitMemory + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + InitMemory function description of Det in UnfilteredViewInInvariantProject (UnfilteredInvariantProjectModelView) . +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + Det.h + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/Det + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + INIT_MEMORY + + + + +
    + + Brs_Init + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Automatically generated by BswInitFctConfigurationService. +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/vBRS + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + NO_INIT + + + + +
    + + vBaseEnv_Init + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Created vBaseEnv_Init by Extended Init XML Service +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/vBaseEnv + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + NO_INIT + + + + +
    + + vLinkGen_Init + + + + DV:vSetBswInitFunction + +

    + PLAIN_TEXT +

    +

    + Dummy initialization of the vLinkGen +

    +
    +
    +
    + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetHeader + vLinkGen_Lcfg.h + + + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetModuleRef + /ActiveEcuC/vLinkGen + + + + + vSetInitFunctionInstance + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance + + + /MICROSAR/vSet/vSetBswInitialization/vSetInitFunction/vSetInitFunctionInstance/vSetInitPhase + NO_INIT + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    diff --git a/config/Davinci/Config/InternalBehavior/Crypto_30_LibCv_ib_bswmd.arxml b/config/Davinci/Config/InternalBehavior/Crypto_30_LibCv_ib_bswmd.arxml new file mode 100644 index 0000000..5d8ded0 --- /dev/null +++ b/config/Davinci/Config/InternalBehavior/Crypto_30_LibCv_ib_bswmd.arxml @@ -0,0 +1,76 @@ + + + + + MICROSAR + + + Crypto_30_LibCv_ib_bswmd + + + BswModuleDescriptions + + + Crypto + + + /MICROSAR/Crypto_30_LibCv_ib_bswmd/BswModuleDescriptions/Crypto_30_LibCv_MainFunction + + + + + Crypto_30_LibCv + + + CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0 + + This critical section protects workspace locking resources, the job queue and the NvBlock state. Furthermore, it ensures the consistency of the global RAM variables for the last job and default random source data.Therefore the critical section enclosed with CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0 should never be interrupted by any other API. For more details, see DocTechRef. + + + + CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1 + + This critical section protects key locking resources and ensures the consistency of the key data. If the CRYPTO is accessed by multiple partitions, either key locking has to be disabled (then this critical section implementation can be configured as None) or this critical section implementation has to be configured as Spinlock.Therefore the critical section enclosed with CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1 should never be interrupted by any other API. For more details, see DocTechRef. + + + + CRYPTO_30_LIBCV_EXCLUSIVE_AREA_2 + + This critical section protects long-term workspace locking resources. If the CRYPTO is accessed by multiple partitions, either the services which use a long-term workspace have only to be used on one partition or this critical section implementation has to be configured as Spinlock. Therefore the critical section enclosed with CRYPTO_30_LIBCV_EXCLUSIVE_AREA_2 should never be interrupted by any other API. For more details, see DocTechRef. + + + + + + Crypto_30_LibCv_MainFunction + + /MICROSAR/Crypto_30_LibCv_ib_bswmd/BswModuleDescriptions/Crypto/Crypto_30_LibCv/CRYPTO_30_LIBCV_EXCLUSIVE_AREA_0 + /MICROSAR/Crypto_30_LibCv_ib_bswmd/BswModuleDescriptions/Crypto/Crypto_30_LibCv/CRYPTO_30_LIBCV_EXCLUSIVE_AREA_1 + /MICROSAR/Crypto_30_LibCv_ib_bswmd/BswModuleDescriptions/Crypto/Crypto_30_LibCv/CRYPTO_30_LIBCV_EXCLUSIVE_AREA_2 + + /MICROSAR/Crypto_30_LibCv_ib_bswmd/BswModuleDescriptions/Crypto_30_LibCv_MainFunction + + + + + Crypto_30_LibCv_MainFunctionTimingEvent0 + /MICROSAR/Crypto_30_LibCv_ib_bswmd/BswModuleDescriptions/Crypto/Crypto_30_LibCv/Crypto_30_LibCv_MainFunction + 0.01 + + + + + + + Crypto_30_LibCv_MainFunction + SCHEDULED + TASK + + + + + + + + + diff --git a/config/Davinci/Config/InternalBehavior/Crypto_30_vHsm_ib_bswmd.arxml b/config/Davinci/Config/InternalBehavior/Crypto_30_vHsm_ib_bswmd.arxml new file mode 100644 index 0000000..55d8d03 --- /dev/null +++ b/config/Davinci/Config/InternalBehavior/Crypto_30_vHsm_ib_bswmd.arxml @@ -0,0 +1,90 @@ + + + + + MICROSAR + + + Crypto_30_vHsm_ib_bswmd + + + BswModuleDescriptions + + + Crypto + + + /MICROSAR/Crypto_30_vHsm_ib_bswmd/BswModuleDescriptions/Crypto_30_vHsm_MainFunction + + + + + Crypto_30_vHsm + + + CRYPTO_30_VHSM_EXCLUSIVE_AREA_0 + + This critical section protects workspace locking resources. Therefore the critical section enclosed with CRYPTO_30_VHSM_EXCLUSIVE_AREA_0 should never be interrupted by any other API. For more details, see DocTechRef. + + + + CRYPTO_30_VHSM_EXCLUSIVE_AREA_1 + + This critical section ensures that a forwarded DET from the vHsm is processed only once (Flag is located in the IPC memory).Therefore the critical section enclosed with CRYPTO_30_VHSM_EXCLUSIVE_AREA_1 should ensure that the Crypto_30_vHsm_MainFuncion does not interrupt an ongoing Job Processing. Otherwise, a DET could be notified twice. + + + + CRYPTO_30_VHSM_EXCLUSIVE_AREA_2 + + This critical section protects workspace locking resources when it can not be ensured that uint32 write access is atomic.The critical section enclosed with CRYPTO_30_VHSM_EXCLUSIVE_AREA_2 does not need to be protected against interruption by other API calls when the combination of hardware and compiler can guarantee atomic uint32 write operations.The critical section can therefore be empty in this case. If atomic uint32 write access can not be guaranteed, the critical sections enclosed with CRYPTO_30_VHSM_EXCLUSIVE_AREA_2 should ensure that they should never be interrupted by any other API + + + + CRYPTO_30_VHSM_EXCLUSIVE_AREA_3 + + This critical section protects workspace locking resources when it can not be ensured that uint32 write access is atomic.The critical section enclosed with CRYPTO_30_VHSM_EXCLUSIVE_AREA_3 does not need to be protected against interruption by other API calls when the combination of hardware and compiler can guarantee atomic uint32 write operations.The critical section can therefore be empty in this case. If atomic uint32 write access can not be guaranteed, the critical sections enclosed with CRYPTO_30_VHSM_EXCLUSIVE_AREA_3 should ensure that they should never be interrupted by any other API. If interrupt mode of the driver is used and ISRs can not be interrupted by other interrupts, this critical section does not need to be protected. + + + + CRYPTO_30_VHSM_EXCLUSIVE_AREA_4 + + This critical section protects HOST2HSM register via a spinlock if multiple partitions are configured because multiple cores need to write to the register._EXCLUSIVE_AREA_4 should ensure that write access does not happen from two partitions at the same time. If only one partition is configured, this critical section does not need to be protected + + + + + + Crypto_30_vHsm_MainFunction + + /MICROSAR/Crypto_30_vHsm_ib_bswmd/BswModuleDescriptions/Crypto/Crypto_30_vHsm/CRYPTO_30_VHSM_EXCLUSIVE_AREA_0 + /MICROSAR/Crypto_30_vHsm_ib_bswmd/BswModuleDescriptions/Crypto/Crypto_30_vHsm/CRYPTO_30_VHSM_EXCLUSIVE_AREA_1 + /MICROSAR/Crypto_30_vHsm_ib_bswmd/BswModuleDescriptions/Crypto/Crypto_30_vHsm/CRYPTO_30_VHSM_EXCLUSIVE_AREA_2 + /MICROSAR/Crypto_30_vHsm_ib_bswmd/BswModuleDescriptions/Crypto/Crypto_30_vHsm/CRYPTO_30_VHSM_EXCLUSIVE_AREA_3 + /MICROSAR/Crypto_30_vHsm_ib_bswmd/BswModuleDescriptions/Crypto/Crypto_30_vHsm/CRYPTO_30_VHSM_EXCLUSIVE_AREA_4 + + /MICROSAR/Crypto_30_vHsm_ib_bswmd/BswModuleDescriptions/Crypto_30_vHsm_MainFunction + + + + + Crypto_30_vHsm_MainFunctionTimingEvent0 + /MICROSAR/Crypto_30_vHsm_ib_bswmd/BswModuleDescriptions/Crypto/Crypto_30_vHsm/Crypto_30_vHsm_MainFunction + 0.01 + + + + + + + Crypto_30_vHsm_MainFunction + SCHEDULED + TASK + + + + + + + + + diff --git a/config/Davinci/Config/InternalBehavior/Csm_ib_bswmd.arxml b/config/Davinci/Config/InternalBehavior/Csm_ib_bswmd.arxml new file mode 100644 index 0000000..ace0a53 --- /dev/null +++ b/config/Davinci/Config/InternalBehavior/Csm_ib_bswmd.arxml @@ -0,0 +1,55 @@ + + + + + MICROSAR + + + Csm_ib_bswmd + + + BswModuleDescriptions + + + Csm + + + /MICROSAR/Csm_ib_bswmd/BswModuleDescriptions/Csm_Virtual + + + + + Behavior + + + CSM_EXCLUSIVE_AREA_0 + + This critical section protects queuing resources that can be accessed from various contexts. Therefore the critical section enclosed with CSM_EXCLUSIVE_AREA_0 should never be interrupted by any Csm API which accesses queuing resources. For more details, see DocTechRef. + + + + + + Csm_Virtual + + /MICROSAR/Csm_ib_bswmd/BswModuleDescriptions/Csm/Behavior/CSM_EXCLUSIVE_AREA_0 + + /MICROSAR/Csm_ib_bswmd/BswModuleDescriptions/Csm_Virtual + + + + + + + Csm_Virtual + REGULAR + TASK + + + + + + + + + diff --git a/config/Davinci/Config/InternalBehavior/Det_ib_bswmd.arxml b/config/Davinci/Config/InternalBehavior/Det_ib_bswmd.arxml new file mode 100644 index 0000000..5843542 --- /dev/null +++ b/config/Davinci/Config/InternalBehavior/Det_ib_bswmd.arxml @@ -0,0 +1,55 @@ + + + + + MICROSAR + + + Det_ib_bswmd + + + BswModuleDescriptions + + + Det + + + /MICROSAR/Det_ib_bswmd/BswModuleDescriptions/Det_Virtual + + + + + DetBehavior + + + DET_EXCLUSIVE_AREA_0 + + Critical section to guarantee atomic handling of log buffer, requires global interrupt disabling. + + + + + + Det_Virtual + + /MICROSAR/Det_ib_bswmd/BswModuleDescriptions/Det/DetBehavior/DET_EXCLUSIVE_AREA_0 + + /MICROSAR/Det_ib_bswmd/BswModuleDescriptions/Det_Virtual + + + + + + + Det_Virtual + REGULAR + TASK + + + + + + + + + diff --git a/config/Davinci/FLex_OBC_BM.JidhinAngadithazha.silent.dcusr b/config/Davinci/FLex_OBC_BM.JidhinAngadithazha.silent.dcusr new file mode 100644 index 0000000..31dadc5 --- /dev/null +++ b/config/Davinci/FLex_OBC_BM.JidhinAngadithazha.silent.dcusr @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/Davinci/FLex_OBC_BM.dpa b/config/Davinci/FLex_OBC_BM.dpa new file mode 100644 index 0000000..aa5a36a --- /dev/null +++ b/config/Davinci/FLex_OBC_BM.dpa @@ -0,0 +1,309 @@ + + + + FLex_OBC_BM + 1.0 + JidhinAngadithazha + + + + AM263P4 + LlvmTexasInstruments + + CBD2501331_D00 + + Real Target + + + + false + false + + + Standard + + + bootmanager + + + .\Config\ECUC + ..\..\Source\GenData + .\Appl\GenDataVtt + ..\..\Source + .\Config\ServiceComponents + .\Log + .\..\..\..\..\vector\CBD2501331_D00_fbl-2 + + + .\Config\ApplicationComponents + + + .\Config\TimingExtensions + + .\Config\InternalBehavior + .\Config\McData + .\DefRestrict + .\Config\AUTOSAR + + + + + false + false + false + true + false + + + + + .\Config\ECUC\FLex_OBC_BM.ecuc.arxml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + true + + + .\Config\ECUC\FLex_OBC_BM.ecuc.arxml + + + + All + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + false + false + + + diff --git a/config/Davinci/Log/automationScriptRunHistory.log b/config/Davinci/Log/automationScriptRunHistory.log new file mode 100644 index 0000000..e69de29 diff --git a/j.bat b/j.bat new file mode 100644 index 0000000..25b451a --- /dev/null +++ b/j.bat @@ -0,0 +1,2 @@ +@echo off +call m.bat -j %NUMBER_OF_PROCESSORS% %* diff --git a/m.bat b/m.bat new file mode 100644 index 0000000..74670f7 --- /dev/null +++ b/m.bat @@ -0,0 +1,80 @@ +@echo off + +rem ***************************************************************************** +rem * This is a template batch file. The path might be adapted +rem ***************************************************************************** + +rem ***************************************************************************** +rem * MAKESUPPORT_DIR has to be set to MakeSupport root directory +rem * There MUST NOT be any blanks between the '=' sign and the path string +rem * Example: +rem * set MAKESUPPORT_DIR=..\..\MakeSupport +rem ***************************************************************************** + +set MAKESUPPORT_DIR=$$MAKESUPPORT_DIR + +rem Check if SWCP was used to set MAKESUPPORT_DIR +rem If not, its value is set to "" +set VAR_NAME=MAKESUPPORT_DIR +if %MAKESUPPORT_DIR% == $$%VAR_NAME% set MAKESUPPORT_DIR= + +rem ***************************************************************************** +rem * DO NOT EDIT ANYTHING BELOW THIS +rem * +rem * %~dp0 is the location where this file is started from. +rem ***************************************************************************** + +if "%MAKESUPPORT_DIR% "==" " goto ErrorNotSet +if not exist %MAKESUPPORT_DIR% goto ErrorWrongPath + +set PATH_OLD=%PATH% +call %~dp0%MAKESUPPORT_DIR%\set_cygwin_path.bat + +rem Replace GNU make help with MakeSupport help when 'm -h' is executed +if ["%~1"]==["-h"] ( + make help + goto Skip +) + +rem ***************************************************************************** +rem * Run make and store its return value afterwards. +rem * The return value is passed to the caller of m.bat at the end of the file. +rem ***************************************************************************** +make -Otarget %* + +:Skip + +SET GNU_MAKE_RETURN_CODE=%ERRORLEVEL% +set PATH=%PATH_OLD% +set PATH_OLD= + +if "%GNU_MAKE_RETURN_CODE%" NEQ "0" goto ErrorGnuMake +set RETURN_CODE=0 + +goto End + +:ErrorNotSet +set RETURN_CODE=1 +echo ******************************************************************************** +echo Error: MAKESUPPORT_DIR has to be set to MakeSupport\cygwin_root\cmd directory! +echo Please correct setting in this batch file and try again! +echo ******************************************************************************** +goto End + +:ErrorWrongPath +set RETURN_CODE=1 +echo ******************************************************************************** +echo Error: %MAKESUPPORT_DIR% does not exist +echo Please correct setting in this batch file and try again! +echo ******************************************************************************** +goto End + +:ErrorGnuMake +set RETURN_CODE=1 +echo ******************************************************************************** +echo Error: GNU make returned code "%GNU_MAKE_RETURN_CODE%" +echo ******************************************************************************** + +:End +set MAKESUPPORT_DIR= +exit /b %RETURN_CODE%

    l9ph6K%oCO5E!7s_ugsQG2hRhm+vnZS6hp>_5urlU)#iG&%Th~ zDOIR{sN;Iz<#AgusuEJzvYt{nBJ{MtM3xpn(vRTkOZe(w3*T~;X8d(+z$FRG314x_ zm)2UoWhzzP_4j7?-~LYzS~MRG-p-A|PkKEYG6W@-i!)!w#K-+s&riF@#Xr-Z6JOE~ z5+}0&Vwm2*9r%NJQxVf`PN<*fTOJ)>g1Lz>E(NU#f-V57;UFWI){vqtSG5n(>qP!(;|GoVS`gZ4p^CPLj1UB>93E#MCp zjZjRU-u_HX)SeA33+jfeF7JT>*}8_v$vI(adginPjrxrVFUeYRGsCgdpJNO&x@QJF zWLv7!z%ybB1UbD;fa)}oK88P#iW0lWAxas1yl|26%K6Dm!QxZ$ce7(?E`1KI4i0?; z&~@=ZKNokckl6%d*c3J|VN;p7w#Ik<|YC_5qSlLXYr(GeWmC=^!iXAKIHbn*laW3eI+)JsLZ1Kk8<=XS+^h|pnDWz}gw8(eX4Qpdv=oWK1`f09HTu^8zlH;zM-$cI9TPqIrwLbzJ+rAbUs@fT!FL`JiQHlPIt=T z0S1~i-mkS1Y2eIc1eGZ1NDn_t1u83k^eh38(jf5Xd0RO;NXMRHl)QnG%4~7~-bAdr z(Ktz!GMJ?RpCE|**Ln1;^4Yx!{22mrw zil^4}qeI>(BJP+>Mn*=LiXZmw3)?OasRBP7FOnb^y7DsJJaf1zMX6??#C2z5JC`jr zV+fY#&=o&(12`7J%Wc%$thKjI!%EmZW=*%+tQ~gdC3DBunm-{lU9*sXjNC;7!D=5^ zk_dMCrHFQvX_Q%fA?PiiN{+M&z1VgID0XK61Q^#edtugqN`S3)fo|pf6ADY$$`jnu8uDF+Kx?t#k7HwLo||=^^Qy z^dUGS@n001+x5NUL0y+E;*YUMdTEusuGc(T@+?%g>qd%Ru%7GL%k5j%)yWSbt!Af5 zhT@G3iMzT9A~x;Z(9p7D1MqO332KpuU452kcpoKc0bph^8B~=WIb^CrOhfL=EX3 zE&uc%9jF+`-xgpd)s*ocDc}K}0W?UlVh%v@r4Z@TA@0vlThKx{Org@)HyJZ}6YDGdEmD+VndkdcIj+DcP>6UrQND zGt&VZkPNo$$jnM(1KEL-N>3jAy5%$|F(o%%YCjTJBwM%NXm%Dp zG0_Wc?I;>BB0a?Oo@=%r`eLYY7Y$0fB&Oa<7U+)aLCACr8K(!Wme;t16Se?dXhvm@ zh0>s@q$wWvA`RJBTFW{Vk&?^(28xs3dU#`jr{t6H#1<~?nS+(N9a&PpF?*cA)>V*C z3Msw0h`4uUJA|qSGw_~Tcpxt4Q;X7;tfu`Mx?chq$rm)SZDQ}><#x&tp}TqN!6WZW zq(K?a*AmQh6>lg<>qCZ&Fi_3i1dLo3S8^=X$cI~Z@U!ahZ_r4)6{0)ty#yEu#9_RS zBei*p;~8~{)sCn$gjr*$`YtVdh(+;OVlLeCjY>}5ypv?KDZhiqp!mFW1=it4_Xyrz z?h9o@+?Xr*U&!i#cM$!yMX$kiY~ygdX>y(f!fJsF#|nw+$xvOLi@}y=BM8}C=&kZG zmGp*Yg~6h))J)jT>6(2PZY80PufbLLAcFZ2BacG)+{=F?&j8OhAA?tu($|uDE2%Q` zW0=10+qN&f`DpAr3h6q1X)U2sAyOCQv|)G|!EHXIwaBA}e;P{kL!8-Y4zF+=4|AsN z<7RFn!d$?WcJfpix-cE=T%Kk<-O5Y2egHcd(VFI}z_e%7+A>Z0HL~MI^%`v^rn{Wn zhu$XqH4&6IIWW>As2@gv$aQ)XG!NwHysX6a9AhZ;dSSF4{+a_lxeO+uqS{LY35b2z zwLSN=J;U1D%`6_|7H*O16y$rgY5WFRG!|Hoy=~V_xmS-GfX+X#EOB3s_31NK5Sjgh#M2;KpC*P%2-V2zOVH`#?{RQ`kIUPp5_XP2Uz6MV_^2}^}DzOoJ2DP>yMSaH2UAOmR$BDCc z)g*Z^iQL_Jc<8xpD>3^D9=W{5ClntjJ&`Cp|FY*$1s*d!2jw2X>X=3g!bcNCG=|*) z@dZnK@}chGnv10S9~4Zebr6O?6bA=BMIgM6%kw@4FMp`}6}hpp!+r}XG(|kUfBLs5@HwA#@kz>MN{QoZyROCo zJ(M?=fQgoao_BK%!+gz^sy~lp_wYt4nu%1>gh%sAkTHNSRsC);fXKVMR*6@}Oz!w?^u6l}OKv&#TiWcVbo zRh`w0+$GOoJ`0SW+R7B7QybR7(3k3JeGEZQ)WIvxevsrF zTiG>E*ab)zmx%B0Sw~$O0XQc>U=h>(w6>*#G1n4C)BC%#CMBoo12%2Y(XW%y-2G4+>G(;lVy7$S} zR;$uz)T|QTv3_F$&zAON@VM0cX52EeIDv8Nc>3EBC-j&5Czxvg=&MOXH)oAEHoKcQ z0WSZstudAA;c@nxU3KmaJlC5Aj zmu2~gTTNnX3El_w&H#(YR~-@18Q_Lk5tKQk%A}CVc@^qZvn(nWapNvEU&BWSo8XvE z3B{a9FnN@cHY9?4si)1nG@nc3)tFU|7mZ=8Pi;$OabQQHE}qb%I;f_oHyNa~fH0zV z>GyC*tG=1du>EplO&O_Arj(tOsGjMXdza5)luI8@j2JZvK9{dg^LcKW^JO+vgUw)_ zaenq**taC(xxK!-dPEs%&{uPMT{SzXo|@Bj@Po!j{d8;V7nI6%azapz+-iu0hEZPr z^k|Qm4qTBY1w$)5OX%Fv@LH4wwe(^WaZ83ysa8>pS*a?Y{SvD#OTil9TY$_!KsZlg z!tO+4vr_9+jq^7P-Zl?mS!e{K812zg$IMD&E)df;t;dTeGwYK({i*K{Ike1zcVEGL}w;iUalj|N^@O*G2>U7T`{BQbFGP) z>=y4N6=^V8^rlY)VIq;fI7|kTMq{oCQU504UARUob3x;Z#72SS7=}y0e z1?YB!*}0@#1E$CILWTv9{ET!^s;E>{_C6&2^M+4c+>b+KKyMv`k{H7t3%0RFXVs+@ zRiPCeRO(XQ_u?hlD6hNWxhY&)EI3Bw%|e;X|3P}Ft#03}sNOeI(FlTU zh>0f~{^$`&`hui|O+;>D7-3S8BR0xNqPqImkHi(G-nn=#XmbR{YONvfvYPc)6Lha0Q*Qo5mD_2_$?4YY;KR#a*Z$9z<%Vymi z>mc|&Po7H=9Omp7J=nC`&M5-i-~_^o(>fjMAIy<=j6-XUemh`3*;}S~ZV-U93pC|I zPIyv{CwYGYGVK0@{>gYbu6)``|9WC!hT?>q1fRFieT=L+Gw#j8*t1NPvA`Sl!H_`| z&&)(LkuY0cy>_f7ZZ2N7bDh0SN4%%g24AOttG!>q(Y)&3l!3v{m|;z=RlH1`%8VuU z9?%?l%yYxz0Sxu?u!B{nFV?$?_948CI0*3M#<0HLhw!tw@n`R8=l(zJ(X{B!y}~3 zj(|aDpu=o_;*41UkyediQzUbuvD0AaC^OMORO*YyL;;ZkX4<%NEFj_p?as%@ujDan!R%s58O4~$vro9gKrdb1xUu~K zfd!vinU(2^);Z_11h?27&Qs*dTP1a?+@yb%vgPY)TQba<>vI^@L|1 zz<}@4q8B4!;CT;19ZIZU5SUnaUB*#(E%)t%|CQsrDCHeK$?dZ<6pAC|8jpWDsN%gA z2lGdE1gcGFLzokAh11l3BZq`wSr>k)H&CsZ49^3KL|niEjp!;MhI%l7b}mlhfo7hk zD~cpqq){vp%op;B||&rY$G#QiC!N+&zgK@V?y{Mfa{~P#ahc*s^tcNe0>Cifx87SZXu2a zUBgeIB=Um=2mnb+r62lw2mAn+jazs-^X1p}HKC>USp)QIF^Dd|4t*>=PK=sb^w5 z*C{2w$6A za;dP2Y74HG-$aS#WN~5yetgSvh)tQ=Ddy65eMB>2)pZ}$5oifW6&Awg5&EgKxtZ_+ zV_bO=)KU@J=a-dy5-rYT6$dDoV|bACcBs#2L9QceaNod$pEu`TxLgQ}qK==fQaaG9 z`F&tFIh1pd5w76~<+WC>D$kzi=}3r|v0D5M`GGfW5MB2V91%8e%p~QZ>q=rCYvZcT z)T%T3Mais3s1UqN^mF*Nw`RKq@9DNQL+w;FV$Rr0HfR^n_~8MfX<^lD>}X<|AY`($ zdy~4k*H(|i_2-SQPrlS;4?rMr9N~O)*au)m#U2cIx9_G#S9n5&iEAqtN2QG z6Uwd_95qG01^}!E$Ig{VQ4QA$S0$`*DkW_!rEMrBZH+~u%?X>qteN;q|MpW~VD@Hu z=cYS(tEFnl1)((*|sfO~q$ZivErIekgZ&&Vinc;JyI;?sud1BT>lLgP?o-u-}u89ARpeBD*7 zqY*DpYxFMi>jt|g?$Pb;Rm8zj4PO*m?_RS%PwWgu)Qi&1h`tR(H;|ZB8Lbg8mEDV5 zDF#YDgb`@vZJX5OL}V|2C0v37HzGti>bPC_2>h5;vy#MNPd!S zuyBa2(HYJFIM5z22Vj^`pmhS0Y{slNfM(s(`*EGk5|CLEf||xvV)ud&j~j+eY&Vij zeP;nmQEu7LcRhu@<`TP%sq6Kka}_%4tfo5 z_9w`w*FJ;xpg!y-=5+{bb{s3sF?OwSn5f{ngxAX~*_3Gb1Y25-eF|cb?vT-kJk69| zOs1x17Be>=b!;>tmBqayXWl?gw!aJVqQGTe!W6_aJpLrbe<{%SY}hD!<=!|-GDK4Y!u8)?fH*W1EIWU(@6W{(! z)t-7D{1H@zg^)JB_g6y(XNW39*Yy^ZRi%kjiVarm(vxrJno65vjfrhjle6Uqy;R10 z2fwauD5tDycNzS#1cScAsoAF!UpPOnL)!i4`=Y0!cQ%(`<5QIZCmgin* zc_g>T;xARoZlzPTnMi$?xwiAkdQ@AL!_nWOW%tA5R<||q;(Y-o3RlUGA593f&go$r zf)yfZVIepwmYNr15?k?UtrHI|Guc(EFVxJY=>5hqgHRV+>twrx5zX;~_2uDhJJ5!c zBInqDSl@$k0DOAQhc)TmBBU7y`|WC&?uc=`mDcy`M5l^!CQx2?p#K9 z?BAw`X^kM#`j0em8$CAwJ3z$0CNpj#$PMN%6Z*A^`DTUa!E2&ch2l)!qvd%svmbIQ z8p$e3NfyVaY^?sAL~JU)m#@2W&Gm*?d$fW3%kyvNfmD{i#0KfyouH;PR7jO<-11-* zT3vn^SI*u;o~3FVhl2y2G;UO=L|YExUC2EoM(J%M{FlRFxd{{8VsO0W5M_J6*T)9-Fq=Qg%x{7rj&sqs(njL=Id*F!_$8KCHVIzCw)5coGfq~0T{s9GU9BVn9UnpM(6EW(~7Dxi( zK4+Wep&grFcVp{Cit;IJ)LEeWZy%&8{3o32aHI~q$j|KlQbM&9g(!RtJTo8?Qsg=Qr1 zLWNNLN@l_$bgw&vGLQnr<4$_5`ba2&7wK>YF=T#0+Ed(d{n z+;Ef|iV7<;GWEq?>edEpS&6-4acPBAMTO=3s&j9Wx3sh{PINT3b7NIP)d&f# zbaXVipZZs}LdcyJW9^1yq4CJWJl5tntS#h`5&I~`(|J+6Iju#1c`lM@i`o#$}>L=}XP**Q9y#G22=H(f4P zlo?9suaz`fi>N85i4**LCuroXf2RRTXx~wJO_!p^!b`p9Dnie)_{&@e zx$qY8K_THuB`V!qDo<(^gg#J{&**KXGZzj^D)(P$af8T#VRB;v1$%05T$FUkKeAR4 ziPDxeiBn!{Nk08-DQGXSumXHyQJxbwOugS#(;x9}j?>jShK^OraN2Xo5SU81w>rgb zJ{2N~*6Y_8F!LLXY3Y;Woen7(MYtq;%5Q8_2qjz>&XG^8#mud?rwyW!?!c zM&OQb3kQ&4=R{N^8)5LC)gs!V)KsyT=Jr5n()n z6I|gaSG~hyK0u5NSd&J1rl07=c%VV6(T<~0+z%xd-Ol4xKBZV6bYQTR1pS#qg>w^? zZ8qJE8)$hp$B0Ufw5otMs5}URpv!Q2M@aIe#Hfk!=#nv2kg=|L%!||#iD1b4?yriV z+Z=+6;=<}EA>)8`O4`N~U4vjIrRvHsR&i_it$&y#khVu$udoS0w?4#`z7)!|PLbEr zH_3eYxOa_r*g@ECeuvAuF180-Mj>byi=!`@Pa6p}VbpP*~~;~=dGL$8t85|aN+r#ZepEwQmbnK?CV z<8`bb8YSA5?Q0LHt7>VwgJH`=*o6p$!SaFu>(!;?W*}wVPM%8};544vE`;j%NXELy zy%X(}1d#8whTUoNOj$ zzxfxSGML4xiZu!Rpo$j^vIZ`YRVZ`k`oc?EQiKzP?Z-mQM}I0*gL=I1E>*`KveqPc zJ?&t1o4b}=gt4*~=w<-?CC;^R4E=Q};{k-O(+B*N=O*O9d}@o!!*c)@xg;Fp3?vWd z8s5c0L!`bWIFOLx`m5;qJ5!F=!17S?9<}QkM)ItR)_5gW8cv?JbH8Hpz95D3Bb66; z3YYqkhqzY}E#M+>eA|cdxj!NR`V~uD(m*}GrXN}}8CSE9ZK&ZupTS_!Bn1! zSk48|`e`;BHLM*V#A_oKSPZN=8CpMZp4gtHdO%op&9iH#VaL+=W7= z8uqpzD0QX`Ma!pA1H=>>3XpXsuy!wyRA@e1Zbzh3j8+J8W=+}WII>QC%HInqI}-i2 zIJFj{0s*;dcW7z;uEioc18@%t(a>d^Cz>(2QGfLhhWYR;A{OH#>K2ArrMP zI7J}5R}G0IWK_~TG5##PCXJ;vc{S=DeZtTzvXsA4NF+B&>HdDVcoh<1L$y18#b=#) zIIAvXP{Vnei>Yn!emuKaB@te=n9z_=lmhLz{XYN&K>ELiP-s*|$%XZ(=NsAFD!|4? zQ{fV5A!8&Z_&&A`B$c`KC`4;z(bgG>;4sQn$tBg1O1D8CIU3$y1;g?B*-`tepygG< zb9}Y?OUZ`EonjKXee9)$8>oUJn7WZl8L!2toH4 zAvxw*+|xa^2uoCSx>BkfmYT1~G|g5KEG=@vHLSx3uby##8g7?GGZj~TDeU?w`Ta(` zlJ>4BY&o{)sGs{e<}rV4i!>X~{SuITAg{<_s{4IH>IpewZSY~Fzd_Ud2DM209h}%I z;4us;tjjcvkQU;8coPd@nf1H%i?nw?5!O?74UzbYCdlKbZLV>iEz~voMlEqCmz)j_ zGK<$Ltk)`nYQ~kz?3H$>P5GM=3nk;H+k2kS)n5esOyVt&sg#l zPwK=^DqynKg+0wW=d8jP7K_E1AQlBdn4Nle-NAQ@LcwKTyw>}>{Rd~;r1M>z!&oVU zhv+RWUR&}eqf{rd1^ljMARP`&c5=_06R7f8PCYt~J>m6kKjGH^E!s8QwR6HBACH$D z?+VG*`eo*y=J4BcP$B&v|6H@ILEt;uTBc8un#>f!*X>8&=B6-q8txZZNm%ooFcJ#I zGy3Jvrm!mW=MRP%#gx{M0hJU+x5E)n;pM>hEK$q*VMdSpc> zq=!5Catxfs+;0W#WJWZ3o#FLh#V*<9Bo)_4@!QcK*kd)+$h_CPG0a4_vS-`L9iP0t zA6tDYm~-a{4tv9SqzTQ=@>xa|9 zyKaV6O_2R^_h^&W^NwxJQE@-88IE%S4?f2Q)Ef1zXF3lLaB=x(6=QQz0vR+ns`%{H zp$O}4xAgC9QVx;SCTrAA;q>R+S2zUE43-J zTY#!Fg*{xeo{lK+YU^~p{u?MYVRopWqqL4Ua(6iK4 zzZ%a5rB`xJ%(G&5|KXKs9-i;W!UP4Hw_+CKuB>`IU7qujhLh(J6swem7d0OG0OK@q2$c0U2wC|#bomi9} z%ECT!>a0ZqQF2{y405XTK!*J)J)+y&{4GQr=*@ zMQ!&aJ>h9A(1K%QBa?undtgk)tI`NxccRkJ3c1Pck#>Iv>Wrp+C`+o2_z1&*CC*5r zY_3MTn@RDLW&3b$xDG_ZN~L5K=|U&(0uPFPgU9|#_t;qC^&zwSRXX6)Vha091c%kU zUL|(lb+&y~(xbDINH<<prU%D>4odhqzFQxv+sG^EVNuv#6D`Y~Q0O8@*5;oG3MC zpmHzOv|K)$K{6(VVy9+uDw(1-g>)K)Vq>(j7HCP7KA=&@!22_s^$5%N8^>boGMm`J zG3*mH`kpqf!QhepFQ+e~H(b`8j_vT~)YEMPT)>|0JKE_KFIR*|$I0J}TQt0`S2&BY zT`rODnS~cCDuF$-8A0mspI*sAaMVeui^$G%OxiLJDHfOzlJlfpu~^=CnEPWV>Qs## zW}@zDWGn7s+EAo5X(Tlsq$pWvR`l`B*~}H1?Wa@Q}Csm`0)7P~Y=&H&YU2sNCvcElDN z(ir-GWJU(FMNdB1GW2vL0OGjhlvt8)?M`9hyK?*}zIHgBcDzzE@kN1+@0d5H_*{}}L^$~ZAP8jrkG6)-7^Yk;Pb)Bx?o3`7w+83c!2YN#N4*t&%F!&5LQ&e%RafdPQ z<9&y(xlJ;e6x1pk2hB;{KF%|be7DElr&ol3zhBXQ<+PXPM-^<=hc~0xx3?AnzyS2X zCha8xoW`aa?o;+g)LMJ^k?G{riCDyv@GG{q<{ohYp0|1O5gykc%%%C61wEjpM!enF z!v2|BX}nrBP3$Qy_@Gqc#)_7Dj0vow2aCk0vO5Q;7C$-LF)xp_ZqC>gs+U;#2J5{= z+oqatGTmF_Paje@57Pmxll2ZG_1@pfRvDeFrNhtX9i~5KMM&a?!+>sSSj_=|%$_3w zfuFO~(GnN5fm6i1WX(L%vn`r2C9tVX&C_}%QD&Mm^(4UU1#Wo85Sn);;MTG+ggUk6 zc)iaG5skVD0?;{e^>U38hQxaDN`(Qq;_T$L+T6Uh6o~@i29H3_+M^kt?yDL-j!ij! zwa_GbzI33(S8B))90BZAdEzNBflC?%@sgGbIc?%a8f49f;!6BqS``}YJomTH<^i5YkQhkHK7Qp zv)7BD5!)(~ZjgbmZm(ma=jF$}>eUDVtlGy;TyGCP{3h*ckUchE+9D$N`yG?QOZ>b9 zFJXQU8Eu8uFkJpfL)?Kb-eEdlj$1TnKNFK&#@n2LZfNOKK6jQdrl_Vn`gS7M%CYciBM^dQ-+!p=Ehp; zo|w)cD#$;qcfFtdvT%%vE?OZrrJYiqzuhwJHGDNS zv19Ql&pvP%LtK}B5pxdySsBi520N~bD~coGU{&o*a^Aem6%|HAuiSZmg%D;BBo68~ zG9i>xwvk2#6f1f?2&L$LCOnjdhxyJ6Q>6k!;Wumf0SX=Z%5PW*_T+5Y@dmB@lefB{O?kk8(O60S5uWj@~KaDHc}Yc@(ka z+AO)qTyfrAcYYpJ>eS5>xC;Kr6%&-gpt;p1?WRXkI;o0pV8~yKe5w|8(?X)R&!T5+ z`qR3g&0DYo(kO~kw=2rei|4&^I1**n1E8{P6+OEvB0 zPZDyx{JXx9tVJ4?<1HkZtxH>7rRc~SC)^Lq%NUlmkiMi#2!xaRy{(*Ulw5C3M?YUD zSSfF&s+q~u9l*P!s(*sFU9#hgXb1W84pTs2$q_D3VWl4GoAUf4x^;6`Y}2s>NngY? zjk+%8yLQY?amg%Vp|I_J`4x6w8@}FENie*}$`hpnD5VdfTR6)y{jT zaVS4-w0%bjJcpJlE9z7nP*=W#z1tL)@5ZEoJV)USD^{d-^LFu`X0e`jO-&ih27G|^ zgZCm9#THa+(77dD+7Bx|DQnTY=*X$jRT)!O&A_&t=*b2AW>sHazTi}!uSD;tD0O3e zIw-VgpT?h7O^Pexm(3JkZ*9L`;SWPGZYN+$*LQmL-^9%<(z2$o^TE_|i;bF|<4(zC zC@uqxIJ;q5W6Q02wN&nSG{++7>v~G2QR~y(DQ6S2D8RF=x^S7a#X~EAzqCb_=oO!; zS7sJDCkml5J|yxaZAOhqu-P;KE?wJ!ByCZCJ_ZCgVYfuBXb%j_JLVP znZ_GOsjjyk2n^QxOI_M2%DU(l-iYcIO6pQJ?ru5n!(CR)*cd4l2C}+pOkpn(<}C>) zMWrO?`A?~GF%#mWr4e{x_eG2OEgJqs%43ew;uA5g#H+1L0>$9Gm15Ff&PUmKc`_n3 z@Uwo`?V6kiu=YekkB9`v_0=%JsaHOu!m;jH#UN4#8QG9@05b=VQSNP6Ze`~i5A-eZ zDB}66EimW=SgSBz#@UF%h|+G&XyK+30YTpvqLMM1^byKt!J@#IRJ8`3xYda$GLB2d z70X;Hr8f`5UIL^6v=x%NJ(VdIUBCuqXx=3-whlYlSPo;?>ylC`%}BqUfmHiNlrMlz z`(+s2*|pk+qp^bMhP<`Dp6+5$0)G1uV|Mmm(AO0BY&leqUPLWO7CsU-x5$=7N z+B6h>QUmg~Pf^3@87_d|N1!=2kl(gVbZTC!n&^IB+o3x!+PPj|cQ9+gpOFD=nPc4> z_ZImWdS^Iaa7ID2C-|mleyy&3A?))^#WnWkm)#d)D|&3Kt;vx&)ib)ZE0L&PZHoy} zv)C_psl&wVCizGDg=+41MG8x zt_b^`WLwYhen!4`@K}Q(h9tjy4-OvyXHoWtCy4fT%i|a04Jq1$2AC8<+#q>d1FHPr zN<_H}Bp?AEP^XvoyHE$zp}wE=7xdYvkt40lXoh=GR{4D^=b;9qM~}1pGh|{;PjU$F zsyu}XishU@cVIM8GaJNDOvGTt^#@|0Pe|l78XW;-SKus|xHb=7A{T1Nx53zDn*Wa9 z6VksbZ+k}?W+Fep6UGdbwp!eBq}O2;Kh)07(r!zU)-o?MF(}qw zT8@qE9jfQJ(v^-au13jS8Wiv3{b2TPAGhPLaNB4V*vya}nnvf;qwiK#R~%9ls8zVs zR^~j^UXv|DPiAsOukWw7&8@00)1VV9+Vqa<+NvEN+m_mP!j9rutQ}_BX;ZIlW=@vg zm(&EQG(H^p|IL!K)+&ghI@%ni9It^3W(?K!eh=%AcS$yySc{YR7c7qfgBi@O7g@`qo_kOja(j37L*;-tbHY|wTd^x zg}rqA$yN!^fl6VUEpJ-W#q{hf7f-GSy+xZiWq)EFN9)m&><3v|ByWlGoE8Tm2Cb`f zc-_J0V(Wv@;3;7@1X50(ZA%?uoJ@k^&%y@qC88q=Zl)B=@OUmM5^3ZM!;L7#&d?#` zvwhB$S8YvAT@5|6_s*~C)U%xvNvmXZ>^np3rB@(@r?-dZnxr=>j6Ev|({<(QSk~ip z)cM9MTBE9MfStgWA04_1QBjyB;1~8A6anA*ti#tfqmzinCm^|Mj$s8S#O65-9Yz_X zFh^lgGUvMg7V{BMA7dg4en2A|(r0@m=(MhYj*8~_nRmM4$7UH2qs?ygWa^#KqD4DEQB zvm0u8VyQs!TcB+%fw8b`ILgsxzsbQ$v6K}9J#?*6{Q7;Ek?FJ0nAS~&%}`Bnnug&i z1UX?3>k7b(j3xqsQ-P%baGWrz8wJ0< zaMSp3uH%8OfM@j-8@O_QsQy)Upw=yp6v@1OA4SDaMz&>!;jlM7l|xllK67f2t&bNW z28ightxBveh18*XBoeJT7c4quFNl;X`s1 z(j77WPrWOqYAI>ca*%y*IQXY1kKJR?+kAFEo7cO@^2WRqwW+CNy|GraRWBmz61(6$ z*$7dG@kK{TI*V6Qhs{iVoxkxuNMC`X43#|;=ZUBu=)Q6adlI9?Xc@uY-GSDb@!wJV zg8J0CS0F7V`nY!+EOlyP(fOVL6`e?gB~<*1KEy1J8{|62i)cL^B_Y;L$@hf%;l7I9 z0po$|-o59p^6uDeO|ufbepJP1xcqq^h@a=V(Jx{``@Tb#cO+ilT3H{+$BuJ z9?RoKqD~tGacDCn{MbsTiio{&U#J!Cza<(<_d-O zX)1tH^;ORS6>O*1OEK2PvdboURGrj zhuR^1w_GNtO8-s*hu(Op*p%MWplEX?Nx#jJK81KqvFJ~=sUm9k4XjQq8?11$gUya# zFBgwZ(~a3!bZ=uoX!=I7F{%baEW`0&KLK9~pFE%aH&6rV6KF)=PzP!0f9sUv$sMr7 ze{@RWe?&{C|0-GvTe*r`nc13(8o3&&dO4c?PaFR$t-?W8{BNydD=n2Zf>?7O+RmO9 zBm&!$Z^rM=aaCLM#9&u)(&F%i?{@|#SCZeVJglPnB=ILrRH+ZZ7`Q=ej4o2F{cv-2 zmF+N-eapfdAo%sA0Fv~|6N4Cr&|_SYrRzZ(SD7|pov~?MX{?38tL3s%-g0F9F219w zv1+rcDORO?RGK;8v(ywV0JOWYEakCl*9y)WZa%RNy{+u7AdNu=KK+7uiUPiD)>+4y zSFi#$o5mV#RBgjS1yQAegLf?^o-ZWyNw>XXSGk|g>*Q% zd&V_fiL*^2Ec%*w_mlqGkV$rqcqVHA-8)RGInpZK%&L9#c26#4M)g2W!Hb#dYKe)2cqD;&$>=%p!JJ2FJPFxP*GgHKgjpsg;7}_I{>}neRhDV*4l#lV5w# zJd-%~22E}dl`%Y+*$snp(w53p`c@*tckj4d4V;fol~QH2u-xo`G`kF~)pXr%nbW=g z2KIoep+Ne61V`KRjA^nUGI|uLOC*en?EJRt?Qd z2a`ZP8E>_iw2$*qP+k!&={5ZPKZ<2d@P8~c);aH>J=tNR{NsA%m zMOWAUq2`;!64JGP+5-}j%w*bnJ|M)(#6YI6gBYqP%kjx4s_NF|)7ig?znzcJP48j+ z>gJDpbgEyY;#Os%$^H-8?lHQur{5EJ+`)-$+wR!5ZL?#$Pi%H<+jeqd+Z}b#v6GIb z|M$)_Yi8E0XU&Uy-<(yes$TB%{q0Xx?Y+6Ll#l+3CGkbcc!r2@{73$Hc8C(|tdqBS z9!0=TJeMac4XBg1m;Bnpjgr?}r=v3P>mZr$$fI2S5}FDX0g>*;#=3J*>nGm7PHX@X)}YO3`6&U_Rn=4e)PqatrKJ0NlqVSDI)DVT`nK3=%G zJKm>u&fskjx!^4-*yu1{>tut`NPbUao&2MD^(9|}4Xe;MkmC^r((IsYHmsGkIs76u z0-CphQP!_n5U=haB)ggz`zEaUXS|$vi&*Q<;HEfFh$qYW>>azxRpF}_$0I(Ir?KN3 ztIvpMf9nUBUgXGMA9%21_yQ<-F$zhw_*gME$b`#^omFae${w(6mI)wf(1U$B3Pe)4 zC|btys_7-$*4H`s|^XJ)}D|vaAlfw?Ma|))I*SjekW1y_ZvGQ zGBJIHo%}N3xO*3rp@|emfdpOfiGBO0B+t|69pRr0z9^qw`}J2W1nB=RgI)f6Gg#vP z9l||YzJJw%@o4}_@sC=tnx*GAPzErK955?j!HX!AA+?ume@s(WQ+3sMiJW$=Z0Nq$ z*JW(X+@n8-gEVdU+~2y03-U@9Pdm8n05Sx>0g&ul$KH8AbA4}D`}%~y>XCoGG(?dW z>FKzqoz+@Y{V~^7a88=DRQkx6gMEPEjYnpm;@BjY>E6>$BZZhWg)n-h z6_idMz=uylqS6c5;#W~#*1*5PLMh`5(}TK6wlf;-wNUJ}l<8qZz`KQcXi#uUyB*a~ zFjn2co0A82PMM(HVI!6up-HQ)wAroG`4cAU)qI@53$?ZwW2nV<-sqhFp| zS(hJ5>>OcZ(r7CLJC^}OZ4ENJ$UI8L2g026C<$N-2O!knnjj#=k^xUcB`?#|ELoZN znz}PB1k;*4lx!fvZLU&-A+}{Nd!Uhr>mYQJd%1&!Gukly$;|<*n32S*mCIJ{WZeU8 zt&?>P+%PoStdmKHsYVKk zjsp^Anfys9u!gh(BoBa`EY2Z4DG9Xp;pv$mCvng@1(fO1v(+hDBWZ*#tS#lTLLG1?sRA0P8Y=*d28QCphAqk=304mOj(hAy+WIx7P&S`4F zya7xQQJxgGyH)U=PG2J^B;WJ3OwQ22RanB*096c?V6XI*I&`U`tL-6+U&T_jvYgsw zlsB*pGw0)1D+D#=`TMF}Wsdwy=B0caQ;bS=b#a-M%*nfJ(jsH+77gcXII|n1O0J$8 z_pX}DC264vC|WaYBlu@mcLF92mn>Mabp*G5VETZE(L%!@E!>e10ZEubc*#N*H&jib zsTd}R@<=1^ zAe4+{UAskP9YQglN<-SNJw6;#wA9b!h?SX2S;k?L}mU_DAz7!@kV* z{))h&)Tk^ho&j!Zwtq+1C-*xaZ2?7Ox$5U?T*K8aN|mp-a+T>Vx&jj6^P@GsMnx)K z%ZBD!gI|jrwH}+lBx}yBc=wT_?I@R;{V+E6(jIKzk6-%~+eZ%+ zO)Qd~qVRVaB^2s4S-ZPuJAGwH@+nTH%Z~r3+7nu!@$n2g(*1_yFRaaSssaU{94 zC@+9nqh)fjK{cPesH^;~U$WCCe_J7m_G9J)oQr7V5JA9|Siy6ip^Z_a;P}uZYfI3G zaD%kXq$73-=rQ3C{;9O_dNiL+P?tH{dg%4QKRAAq>Fq{wCHk(TJ11j?Zfk8%jjY~i z$DMiF4C(6x^J;^kzMmJc?zKWlURPzUNygW=@?5R>x-O_dOYtX@=%%=J0;km0*I>L4VqE`1Hr0CA7n?i z@g17?G(>lTg;<^g(h-dLucX=)KvxO0kP|U=*^^N)6~g3ZR$7}R8em?*7(`rNp@|nb z^%a0=w}lUla`3q6P`GUPdqloO8M~XU+ER9*bSOXLgSb1=apY@kH|NrLPDxG}-0UBM z`DichOAKC{xr0Ps>9(Ikp?c-Doflncp@pi{`s@Ho{=%#P+v~d`$A`wC&&I)EvD^n=juG)i1vlL}ICH5$~HqXH`bo|H&Qn zju!k*4C^D5#3+QhzNA}UfqAuSu+W`*?ya}d(ZOcs#wXZ6g))aF0Xp(8R?7Y@R!sh@3#F2axrNLBYWxc)21=WnH~~md zqW#JzT)M3-c5Mry5bjc^E1b0WK;fp)cxc%#@5UoMGTR$SF7~Z5XBU?qJ;V+88!{4l zB~ewj8{aA`dya?w7#g&d6{s0i)Ta0Bo{Kb7abq<%$`bDUeHj(v*v#gpWR9(Me4Cu{X3Kfa%0i$uM`lPgiOZGu zP|bPCU~5NJ#@*4#v~_^9zZ1BYc}x4rgL0U^QJq|5(zVsFY_Dm^+4LJLWICelfK5&` z+6=O|wCS|*!q&VlnLs~kpJFJ79M;3qY9-FHyK0xPd-VEuZ2NQ_f1maz`RXNoMRNt} zDrUyvrGL?&)06aMbivSuE838KyJFcTbr)J0Ct#8EvCAgn$>`^i-QaJeRejr$ z;}7ak?_#)xU<8~P(;!lHE7}P1fjPB($J{K8IMI>AG{9-RyNS(KB6l-is~xhnL1PZyd;N)U&!CgW0HvQi2mJ#FF=vXvX9`iK$r6z+mv}2n3_&i;MfojZ z3xAkm1|j=K=T=+cb4t|jdbElu+Jw6R1tw%*M$+q%OoI>wroKefIns)Ya*4Re=FK#D z!N{B(5y=lPD(X;)qQeV6KE=?zxaMYm(Sc)W_F}vifglv`zZkjs6GIa{c35JI6@YI$ zb=C(ce$jzedrse;-u6y<6Xh%iOTpPtC1FI>EOsEf~NiW1B4oN@Ol8&>zM-&rHQ#>bdWUg2F zkswD2cfY99Rq95#C5eJuU{!s-S;>I6K=bl!pgbE*TbJ9Xhxlo-g|S6B7G1H!Ve;UI`_gg4KdGg zbtAUE0PJ~kaW)3$TBP@(Q@o6TY5Mk(M&`+2(@7&XHcg6;SYx(vL@5#d{;Jj}CE-aM z)*8VSP&|C({?wKs3D?>}l1>@sxrIaPG_k1qiNGwwLh2|b!+rA<6#3$4B|q^UNQWCn z{mqewX}mTc)izawgRaoXCB**tZ)S~HpEM{+5-34^4YBAg&v_6x>MVjEyfs)Nksx%v zbU2jjCX6{fgJ%3y9MGFx{iX9fmA}fnU~1a4+Myk&KIfhc)`0;$0rZ_@Dcx^u_aBO2 z$bA{8-OmD3nEWE98XhwD*-CKr?C$yW?Vo^sJlwBZ_$v|He;cr-|2+XK@qZ?4kJjct z`z4=*5Ql^CTy$71QC>E%6F%SQF@B+;Dgl_qRm`|<$OnY&al%6Bsopxs&@o<)6|A{8{Pr%<=aIrO7!EIRB zQZ=I&5VFO^vug2Hn6{CWjKvM@CVl`2Xf*#W1<9oXkRmUNGE07S4Ap$UY!@n9=MtmI zJbj+nHOt8r!>YaBXEpu-cz; zBW}(EtVAarx(h<)L+FDijCBErAUH|!D<}epg3$$q8;Ev zU?X-!p!IIx#nkxiuJ=R*K{c$5smTSL?u^_8Iy$Ur$)wLHsG2S899rxn8ruaVKp2;q zjBzwIJhm-dz3hXqskKLG-Ef$mXpT^+}fXqHh=x#PzA@j ze5Lp>QQ=ITrRD_ljpe+wT))sb(v^DqL{GlBOiHy0YL=x-rGZu^f`8kfgchxnRzv}) zOE=8YF0v7sW7sKm#I-=reSo_-b@+9eE769tWL=*yakGWM28pT(SIiY2>*ek(P;INH zL;swVD_5+J`1sVXuRld4`m8i@2L8J}wEu~fG6j3Mf>nFMBr5@vz#h}_3d&FxS_xh0 zE>2uHO9ZJ96Wh5SH5fe89-COK4E39v2IpCc;)yH`&Il}~G^2&<_i|T~#@>A5D;76R z1rDRRj;*7diM5GzhF=JP(aO7nP}AW$Mz%yahZ*|Hfog#U)eR;GoS(H(zwdHGWb`f8 z_DWY-&0{xU~)hv-I#CBt!1dS4GJaeKgOc@*;N!kYP2yvM`JD)gGT2MT>n+ zr8vnF#N6*3dw6tAJRhXw<~3*qo*PxSQw<+bR3R-{&ZJtC_|JA}+u?W>f^nxG;i(PY z(Pos5O=o&u57Cw%ZxI%vAz35qrcI%7R}o+`Sd7#cx*uK2HrL5d`X$Aqljt;5R9mE9 zsro8KwTDLo{F>8DqFaaV-~|WD+)g+q7qHx29TQ1)L(RoBO2dZFrYdho*6%%m$VL&i zK3&ypo!G9NzI3&}l@}PadHWJD;T#xDJ)>d)auyI-0l4qnl0DaDFg(QoTp+X5*5d)u zP~?x%Vpq)&pO3E^bj0tg1($x&UUZO4FcQ)AUVW;Y5TUxfzDso?2P+2qHS+H$7w~5I zHTGrmh=VAB)E`h;fUE1!ti0W2sWtL&U%R2#L#M!PBaTOb;oL*>3$b%0!NFi7ic8Xp zhO}O(F(gcdeWsF-0PWhSz(2UVr=8MV(K)isX0zzsL;`>C3#({io8hx11Uknq9V6!$ zSTP2Xr0IWc>iYy>Xx zhWk?DS$j>p!MGwi&!RUHX=VHic2y2V)C>Ka46y0Y2=Rsbv6nHi)F%9zoxnhH7V{5) z;b2hJ5BG*L!z|S0t1MFW2(MBT)%1+Yl4Ghk-MNiTvB4FY%z{}hC!7!|ON`lIQ?Kx= zM7JIcf$7QoObHv)=m--REsp^ z2?jdqLP{mxKPvcke!u8IC%-H4R8~U!)4R0U{VfhK*lj#+MI`AKN@*e)`Q8mLr}@hd!+5^yAoQ52H)#r$;2H1d z(w9%@e+pKW*PuM1b)5CbpEE|12p7^i4caGn`b_EK&K6rv1v=`;a?zQfvv@kk)#Z}>gk~H^Q(_AJj zMsq9M@i}xK-3|g)rtDrOR)2}E(>lq?;Ro1$8c#WAb#;~~2wguH>g_r@6q5|Hpf&>c z+TZd)3fs$*8~PiMljf7`gjofyR03IYvuyg~D>~(-ZbQ4NQ67`a+}z$KzrYDCy;w)1 z;lfTDbsF7gJ$cN~rGV5!$3GB20>xK6nA^)=d6*-yy;QPh2}t@VE|Xe@Rpc?fKu*&N z!PIv2Z}_vTH5%Ku-ekT?KNmRV+T=DGk25_g2Au2;($XmqyOP2zHcGk2=L9*rCs1S( zQ)v`;i$e^udcA+dau+}vO#5GE0viSHZ!CsBxFt& z6KpPy8*#ICSMD+lbsrOlkcE(IG zkw|~AK7=$ZZK8xM?CZlO+LOyxVGzaw7V~6&z$QxiQAu}!R(ZC>Yss0D10E=)8SC!J z+ORNdW*_Nig2Ts)xS{=v-PRXCZ5}Xn zmgVxKdJUestiq^Tphof|q*5Q>)Voy3|XF4g_l2(A)H&^kJ*}MM=PHG}}6US?1sJiWXs1 z$AlfcTfRv)*Tx#iKrhN7Qxd`|(hKoQ>+R2+*0yzP3Bkl#k?08=o9j7$t{t#axQW{C z>bter;~zqv*8cW3Z1+58+rpF#*Da&iy!ga46!aXE-z2K#a1tW>Ndrt4a63lJ0V#Py zJy_kpQ&9Jak1Dv-$jyH~#|3Y2PN!FpsUKxNo++ z?nQWfXxj5Np1b(nP@kmI!Q~!nhiXEl`}=@#4soQJa&*J4#4jLp1xt^Ofk0Iy?9W@AO|5jO_EJBeP!jaLgIy zG!w7Vfd1K`P%AWoDTRTgBWxHQTh21^J(WP&FcT%A4;LxtgHG7P`^y5Hs_?%oxJyV~ zK?w=(v>jLxtrkIuZzjF3pC#jIYT}%-EFB!0A zLT!Lywd^KGaK zg^rBb!y3SB1#8co(Z|X6t;5zdwbv*n;zsr@O|xIM#4UhW_Kob)BM$bektxxgc%QIb zIv@ARqf}d%1Jl=fOFQpN7hfZrt-M8oaMC4g;_QeLnEf8wFuTZD_oC>%RB=CZ3RLqacC;KEGLJjBaRQEsH~?gn661MKn+4 z%GRG&`)h<_6UB@NHv}2gM4M0S?>(LD1|J4+PWYo^5hk&ebaFd!pMl$Ar&WBT%0kgz zHYNEi4_yX7)AX6Pk&U%v?3i86P>H@ht!SOD3}D_~v^i33r(K#E6MwDeDAF#hZE%5~ zvx^e92P7WFg{jo_E9$>6t*BFSednFE?wlc%Qi!SmIY7q0_*hV{%f@q$%??TSN;dfd z`o$kAM<9ACZN!?9ftQ(0>J^sp5Tz&~d#G|%DW5c_Kx<33Bug4L;J%=E{)8sT(UohM z>XO@1Z6BvrfZm}=%^6-L=F*i$K0VN!$jRAeoGcXB#{t^LpB^FFKd`y~;~X~g>>7jH z+Tp08fI`Is|7UJCU)r&hfm>tj7Y>qo?k(C`n#x}wVA7ZFvcv&dBHD?MaXji!A)t?) zg9}Cq)dC7DGh33V-6%1OS;XB{v)tNc4%hK@^ycC{ae1psGk-4p1BA)7{l7qH!$H!r z8gm5=Q&OpAELrvp;&Eg*fNnhkwsAaVmhzr3V-C=Um@4sHdex0)bsrn$a`tZju=;DT zVw<-Y?n1gPV3I@yz@pE+wU5->{IY~jo}=}BgCSioXlTJh9V_VUPzCX{PF()}mfl#U z>T@ko(y8UUEGCVZJ`zJbVtZR1T(--5!U0{%IZB^%50T(h3W3m6@~Xt7;%?+EjXuu92V1BMLn!_32*D zw@5}b1J)ukPsWhjxYR0KkQPVsU^mxp)8)mbCM4c9xF%1pXYH2CGW>I1sDETg&wuZT z+Uo+@=Df>3LAIs^DVDaroS60a4*U zXPmeN8NM%1RxF~4(=z&!#Kh=hXb8-Ao-jw$Vi1+1)ZPKVFLWhcJO581^v_!v)1%g^ zlK`)=cG6(W#`^GXmCpU8$Q0(0_N=~k2IWTI<7)S>hetwF5KR!!rwp067}KtJXSP^- zq!oG;k*S&}$&p|9AloDn(ds1MqeBeQjPRc!G#d?fm57}b&w|YFS(%9aVyd20v|jt4 zgh%ZAfLItE3O||0V)@phy4J#cRUPc$inH^vY`_T3$wb3cHOLWRgWkV81azv0!gZg2 zq;UMwn@wqr`$(>~g5Y6&5u|Hl3Q44`j?G;3#hB+vO&h%cRVe;%K zZrUK6a;W3by^zK2B(>!_T^THT5^@W|>J`{V_Ul}C#s+eKQ;|l!F`jEXqXL8tGW|SO z?6=s|arcZI9;Oky!7wACY9&t2KT^h+MhCGQ{TX)+Tqw%%#}L&ossCp=jRthe-c1lIQeqzVz7B( z?bIHgV|x2cJr4#MLh=}EjPoqIv;C}1FD*hF%QVY6);K*Twc{$Xt^!D}^Hu@(j>YE#x``nqfqk%iQQuqBsDNFx{ zbhz39b}@GO+K&s1L^t(GQD}{@$UDX0f`EYc+^AvWj%c|m-^e<1-o2G1ib2W#1MT7T z0@A6uPB2ZH6P@DO0H7uok0^7}Q_3UWxQ3mPu}0tif(f3hj@c=?&*n3b%p2dLU>TgCDq>Xj(RXn;D7my=z5&%93`xNB!2HpTtfXVY0kLROb(xK_K`)m+h0jE&&4s z7})K<{fvp;f7fOEuNN(Q`>AO>e&%u{Q28t8pTmmk09%zk5(Et3+y+{M^0gQ5Tc9?Y zsc4nwMZT!0pgI%cw#_>)C8}6EfU68|tBm^RIqO?)5xS4O#2&;6R(H}C|KMQ=i=(Y?*(BwwUj}{8%paeQ z#_9kKK=QvtW*!%fNPW&9#*FS-zS$ozb@C}I14nl;XRDf;EiLxft1sC*@);tld_6N8 zvK@3ya}DwsI-iwbFh|^N_0B^BA$U;4a)HK)LT5=chDuXP3VS*~*3vkkc^CkZjm3Wt{gKOTs{P_|L2#LHJ-2wgZPb`_=~5tg%}zZ| zv!ip(4k%+08-@f8f0vzNe`aEIS1f@T6d%9I2vQ>2kb9{?$QI3kqd+br1;G%kCkgTU77r4;4r+yw5axCi5%G=*os(@=u-U) zM5N%r`Y$`U+~uua62ii$<<&IG(N$JSoA&*5Fx)~(Vk2!ynR0xoCXiDC@P z0J02TOd=j*(pC1(9M@Spt*T=!@zCdBa&CS3y>Fdwv3E|MS8glGkEGH>O|F)Wos4@+ z7@gC*>uX7=nnnw7lP8>@_pw5pb-L5%bo?*{CpCEkVnVrcH8q&h!ZXs4e2rTtShpSA zPgVxz0x>8NCuSKZ7#pyyPvbFx7HB^CWhnY&19Y-LG!dpB3B^g1(B73mLptwD5~bvX z>ZCHbTL7HD#w|dEm$JCLSS=wH4W`_@grtfRpgL|VQk%>oPPq!#s5!`zT8(Mm1Kgw2 znI%^P$Nzzz55KNgI-<}Q!b^#H+X-DGaL%K|e!+QQ=A0AoG(3Mq#+lx(Q}Db}d-&aX zJvhC7Fbv8*Wp|WnaNwY@AZ^Chm-j}5RNti)s3MJ7;z|*tAt#i~V#t_7O=`gSu0Kf8 z;uZ{~wLKMuTU=fMp;=ax$WctG$o-H>uS;Y4Q7_GCKuW5|Xh2JfT(M>IX1C3+SaV)z zKoCc<>;f!&?u<<4)pGJ>q9!6Tu`n=PKRtf_JTJp}G&n4x*b2&GXir4ZnnH6NVdU4) znEXKN2&>V}&?B#Mec?e}iQOjRmvW-UC_-Nx;fl=G#%PJ6Uvci~;EMau1Fg-I1bylb zUOXdKokpwQZKa2hr1)+H-2l_n@tdg%MqwIsDdjKPRkx-kj7aZQ$%^N6>Hv3GZ*eRg zMO$7b)G6v#mL^j@XpbhWq|20OsrJ-A&xvx&b&NbI@t0IIC=g&3zZI45FzgAcY#(i& zJa(Ef$PudZ-l;W7$H|boM4erD6sUkb(Ue+m{m2c zcpcD?4kDnDQ5)lOvVh??u*iPZr)-Q(E(Fn;q%UdE@e*-h4R@wZTuWp7!@*shBL0k) zL+D-;A=Kmzo@Cg`P67c+UZ2$LEcjq?qbNDkab968B|~sc>C2xaq+dG7D)W9^hn!f* z7_N`xN}@j!Zt|D%siBL_ z;QrW?h8llGJ0ELoApfA_UH&2tCzPSM%(<>;Ke?V_Obpwt)v|AfTAPQm;&ytbkD8k& z^Gpz^2C3*h$@n@1S^I(maoH}RC+zv~&-i;dMgeTs1%CQ zk=?6uN46aBiWe1jr$nzN2G>6^8sLjd-F^H{_t+g&u^AZqw+>4-KQ2M zJRX+zv6F_V!;73rx{eLHX6%6TU%GNehvz)3J+$a8~Ziiw#d9vb`y zz7zCyl~1cMpwRGh%*VsO=Z+GO>Nn!*ambZ$SiJr!ye7(buw_Q-{kf7S(f9gc3F@{SfW^ zVgxBkR0EBBYY`~g0?iG}!h510te^D#qVTLuq<$V$Nil@~e1-D`=6$P+t>cOF88jde zhZQ306|ChYxFC2<2*M>puKIQfVK*G0-y>v)#X5*)In31}l`XkCavs6x%4&I)eBC&f z9u_5Vb`3u%Ah;6bq^VznI%(OfTq9AaxiO30l6gPINpD`)HNp7DQFC-Q(I!$GKfXi8 zEdfdABw#Sa?0{k(@}6XNTQN`R5e7LEWBDZ-&-N>0C&h?Z#6>POkFF;1Vq_5J{@B<% z#4~CnQK=N{kVZ)hWHOS`x^Bms+9J+Z;f}U5H!b@$Xe*{yd}y{~vW8L+2;T13;av@( z1NzP67}F&sLQ24GvG`MxeZkMs)@E3^UtH6S_W%=%x8~K1>dI}(;G6p|bePjWB?^ClxYOWUc$FeAT>eNiuxdptP@AH5^B&>S+6SQ! z2>!TcX>dSaX0@GaHg@J6(9~VsbszV3oOgdciD8pD86B@48Z!5Y#p(4+hcGOGzzHYa z59gQHNoONXw5f_~Wz8ur0>wM}oSy8+Q=gp(%0Dg7zo#qC&%b979CE*h{m70;l=a3?O?|bFQMokZ^dV4Gy*%LbfmlfK?Ub}KE_BH&p3g|H z-YT=cSC?12T;%kDv7~#_!4trzrhnqW6TrSpdG(7m3<{m_Pn6tDEZJ(}pO|Yd z);(@4WG4KRJUVGlO*cB87%?*nd8it=u+V%@g<*9*8rBTN;)t5Gbmr00Z;hCI*>BX) zZ;hOk*l#q@XTtnJxZkLz?*W~v-#-tn3rCMA`VB7%121lX18vBLLscdlE+Ysq(T_1P zET0+G!2ua<4emlqEO(+Vv6oos(+;mi->N^M*`wKTrm7!qR8K))JL-ryqZnp(^t#r3 z|NXfHE)-XZg!KT{`igX}vibh~Swm$*{Nu6}N`7k+6CFb$ypd4EE>YT1x*5s80%oWj zt7yE4Cb5(aM96?AD-&@{nCt9Mtktnq1@8N>Wf222413gR-*iI<9eGhK~6YNbE=ss{_QClLrJuX{H8Pf z&mW5=@cY5C#np3Dxs@cn(Uh=m-;FZN2nSvZjx z(a#@q$uI`A7>A#GMtEc56!tcdj|%F>Sw-Nlo)q<;t-D{q?OpBrb1jW$S?Z5**P;RE z7BG+SkiN0OJp=ta=EmPx>$!2)Hgh1UcDyCQJsdHN#ZmjmwnVYO&$rfsdM5jK%#4Xy z>f>?Nr~&6{FpoTtuOY$yEmo84Y7gkUXWiV+XHj$t}tKeIW=TN}U-_nCJ zDAE;r63l-`o2$Y9$%0|24+hw?K;lpIhq2b9XpmV`{iQ7R6##p9$gFu8W3xhtO)SKcJxh7+bPz2G%fmbh)*x#r}qXgE) z!DVd4UOx@6M}XwZ3wE$D#%8HUz+D3Y?D-(OfWZz{#(cbR_Re5yuGxd|#?W~6gk6aa zUq$jtzzKJ_1b_a>bX+8*hb75E5#~}3p9%whtCt2@V&R|Twer3ACf*#ET$G_%#G-0DxS5uq zwFS>7fs+$3t%0VY0*t1DY8n%yLG8#D78vN2wizIW^7USwlK zR7tLjcGXX3yn?F2;Tp}l2kaUL$zy(se4meby@!+?HAzqso)-PZQKoDv=yVh7=OaJ!c!}EtjBiWSXwUDzULn~Sa zt7-2pA;E5$(p>XnrEkazeUsYt!)gzLW-WTV6+D;^ z5!!G7;!gK;!UKw{z8{gni5y{T2|QQ}7rr|a8mn!g`*)mfFr#}^euvxK1^;~`D01O_D8p}B{=;VM(Bn@m zIC_a(I4kSj*tg5S9Y~#ve zg`vpe&X4yls;zohY=43~wZ%&JSzqp55ueVS(`#v4icX2qgmo-=T>!e>d?X;Hqk54D z*0?>B2n-{4RQHl@(=Y5FFA%G$XP0*0YH7%uov;`U(iw({-ys25jpAgEa?&k((VCtE z8ojZPoVT?BcSyteX4L)N00_A`IQrcjK7y z9lzY^dkEiK39e;1-VSn(jz}Eoz!GF(|MPvnQYyP@EFXdNhj0@aiooU^ILF4Q6&#M2 z_8h8g&OqC_!=@7jw9{|*`sU~jJCQqw2t!l~Dp^hdzY6`n!ajP!m=hbC!2f(My|t>9 z&Jzm^Ov?J-t$&yNm#%*+e{*#+b+@rMm;YvBZenV0!7SrwZsTEN?rviL&zR`{KBn-^ z-2MM&#(%D)|I+dH!&oN#6!aLkPl^Y@1&0Ma_{f|;R~~Ay!Z5DW zfxMB&{sH>Wg5JTr7n|(}L`|Z+>m#ZSJG$jW1axPTO&7BnsBo_smGh6OB}qzzu3okE zNW^$c=~m05IfvR55~5-7E|k1v5-s}=>W5~u)(lywjSznuJ`3^lBlAHnhDK`Tg@sNR z_cPgG&>p`%Qa5U3`l*|-!2}KgN0D9Y-Mr~z9oJv<$ad8P15K<{OHm$WLYVWs0{J(D z;4>PMZOAcMDken8EryFM1M>xzD8mo?gy?R2MY>9_2;7eGY6VmbCk^MZHopPjO zA_S`7mcvkfljH#INkh`z3WGKBT?eX6)u}-O#3pFbE1mUeMX(b0>{ztmKgv>a<2_EvTtXVO~ycuWl8gFARjW&3SR;Fl63pE4>q7YHCy z_soYQ9&l*o0=kkZCk>p5su?8>I$o$aDzQcdU{{#5zSB`>r==ULslgy0ou!AzBLD(P z2s&w}r$fr5;B9`~xu29L6d}0FOFGm$f5Cgc#(u#_@7 z+Dyyh9*sK563i^%U7GG=z67UEV`Rq-qrp1oMEN?L45Ct|%5bwSRkv)4!%~M|66eZH zoSud;8i10cd1)zBw=VA+N+H9kxNv!uC3JA{)$ysakm7pOKGNhNTyW;pgi~KMI#J|_ zcGM1DQ;DX(I8T)k^k|BwhhpFwdpiq6zTD$0sRVowM zYZy*?P{nUi8ab2#UP?;F;(9LJY-vW6p;G3b*~=C zFXi@HrCjSQ+W_avX>S?-R3K2DLLOHf1{8K^a5=*nMpTTN#ADuW_Gh?IQg>Bk&5pM5 zz&^^OnoN|GguI*3InZ*mAJ7D!mTepPa&hsSrMUpG>6{#f4{aHH;ix!bS}Yq!b2+^> z;ASC<5*aF$v;mR1;QMV^C5jEPE#9X>7pYV=EF{_9-*6QBT0*mtLqKC5IdzZAPe${W z*|n3axnAn>wK9&+85`L#?ScY2c>N$EY|9(om-}+r3Auw#fBD9JOR5>p6@R@J50qa> zy(w)!2+8IvKqG!E#pK)5hYh}vgnaf4LsU=^OQZCs$rgdJ-syYuUJ);m+Dym1wC9}u z0weM24OA~Bi$HR|wq_qMI3JU?TGmxCG}HJIg|DoM?cE5*?jCZ3ATHDaGh{1roFVLe z_Q}VIx}TEap?p&#W42b8k)9K$V6gKUbo5qv9-Cnx zJj4bpzS)2xGw6m?y2-LaWr+hAonF!nkF6G0-q0uJNao)pN9~?#x+(ApIMAyVqHPf} zXb)#C#3@r(-QS3q?}QckctH&Ilw5L$fpa&m9fc1(o9j%9QKt&Hx?c`Y>e!-aKcB&Jf+s*w>C%TuB$1GPn=h``iT7@3P-N^b1n{oWcnCIf!l zl@*D`dYh|Uo&NUaeVP%b^qe_dmGGMs+8|QDka%!xxgijgTM|V%uEc%G3cu6OKik!i zSARKs%gvC&NeRDest-=c!fbs(V!%rHx>SyZfZ0O#tWpM5 zF-rDhMPQihM*pM^e*~m9XZXqH_dt%)g(Oz}v`RSKi1bNTYj8ABXs~snGJLEGwo5hP z!~RhJ9qs4D%chf{qn7+LVX-xdO?e`P!c|#%tahz9%@Fl?;TQV$%kN&;>>Pek^aIt8 zJ4Zh-N=F016h8dhjj1KSo(jJQNPARzmW5Uu(Bog|G(t0t(^hkQe+-4RABPmzOE$;i z4trNshIC*j%Z#|wX?sPw^;5aAywe;9Sz&;;qg~DTxS{PW8fh;}oDx%$9jZqpxwCS` zMcsq@GekCtPEVl@Vw03Pto_!1;)%g3w+PL{1lMD6&9^+H2iA<33~)RB6)fvO&k5FZ z7n<%BHkCi*%QYI&(W}avdWCDKOZ}+6yC!Lgek8U3{k}{mlEO?z83}?b@RE9aQtrH@ z_}O7FV3aem>9cG7{a5V}AI0&W`=Fs&aiFUw(Xc1wv}Pqwr$%s zGmtyu|5u$lXVq?N-_)+%_Gxu9=hw!(n0LL8XY_Bpk6Ix?Hi5Q>)JIh!X(S=qMnykGo<-Vke1MWwDfz^=>7^I1K&y@sd~eav!tZ*OW&skf z{^7R(gCA&X4syC^rnKEJ4wtG*FjxbuM8i>@`0C`gGM_rIFSJ+%0sNWnb z!%a)VheWyBM5@_-M*rULeyzP8-$d%h!|u6rzcv^Ry5=2JLGy{R9kFED(apwgYNoAp z2W&s^AU$&B@tMxFimq2HhoOFP8!#A0m82J?o`4#$NFK)a=?MDSOrQ=eyO6jm5h(_$ zZ3BUpIsU;k5PY%d-$DtjEt9ccLq)CYEQ*YUV$swm5(%q2Bf+}5jYOanLT_@-tynIA zGGrS5h`n;uYE@y!JSPpY$5mEX_QP@{+{kxRA6wfOz6*9q`QsEwM_X0&v`aA%#LZBu zCF*M>nLfyz5MHRTgA@G}$zk5+M+h&!)VEQcMH1&6%i0p5_aiUQ@EJs5_{S$Czc*vX z7#256;FvBPw4l7Eh2zY>_tr*`eUYKiKtS(=|7vgD^?!VC{r8u+jk%M#zLmL$zLUAF zjiQr-v!Ro-!~f#ff4sk3#cC9tVKGIsg~yJB#f~dYSQvc znHe9>5}Hk!87B3&Tf?fh@}tZ~4Wq<$+qOq?5ob-W(C(sEk_U_C>cz|PtI{+aiA}&K ztK7(kZeyOC+c?U&(t5p5=6$={0(#u507`tv6 zw~qpFZ?NMu#m5@ikQ$m`&q;`SM0ly*=-;cWk1fo_@{=8r+_|hqd~Yown^Pf9V!1G1 z8$UB|S>*7g*-3G~ByTrRU#okl_f~nbBKv;c;@&sb##@KU*TGj0?bSzc!c~82ZpuA2 zA@VDCB;)85uykO=y+LZ{54gVE-?b5+{<$)M<%;662SV$+`+TjZoVm7+o!7Xmj*a8ne<8Ke6ukdmr0 zX?HTz z!Qp_{kU%!_ZnAFFe65I4BZp*!L=8aR_xgwg^R$Wb1iANu<#fRPoiURn;tJUpPNq!b zlD-pKQ&m%5qI-Bqxmv$m$g(;;hqbS1h1VP&DOpXDgXzXo6R74NZI#{|zO;YyB>zi%pZS>r;?}fGIeTUhfF3dbN#hIFDRTJl)kytFO-@0oLltP%c{y zusp$qdFZ}C-*vUaW;TG(0EUF2F4bnKHz?{Jg&M=EoxRUkiEm^q&F0nJ=~=a&q@2o6 zT8P?OxX^KDCRYO)QCwfbH9!?LqFE(J*~-(Wdqgm)L_BOs1HRC>3@=2F&Kr~(NduNF zdT`1r@VV;cuhAOuLRPEHrO%NqF(mS1b&-ZSAcc>^hcPWO@{I+L7-EWrmhXDd8aTq%z)+(l_hh69a`uJ8pNj!TiP0y(^I)=wplAhLW=6 zBt?MTV+SM%jQ8$qxiWP*U5!H|fc<=ct=4?83ZiGcQnwAzc;p#krWO=C9EXCF9mckC zs=#(vV+;jxlhAWMfo5bp;baQFtRJC81yRN|`ur_~JrqbD{CM{0@v>$kyS9H2 zu+zlQSPjitrA^e*CAUCfAe)xg6c5)f@>=LwjOnHDe{W#8m28>92U1xOWTX1ogsje# z*m^5qDZ8(|ps7@m#b)oR04-xayq%gxQ-DkjAtdaWi1JJde=~c`VU>A)9@LFVNIBrC zpA=_ue06J%f}e!d%RD)}X($Xobz`tbaX=n!Lt(O-gymvs9XG%MN4G7!(j_acuCAzO z>PQkJVZ{T9l1gXk2IlSpdat)LyeE8DZ}jmUE=voF7-r3#cq?YEY?fD@!$TWDc;S$( zBAb}W3+$UjmeI4Rw>;7YSg;&Bt$6@|uaMN}e+xYW`d}UQWaQ_XH&n_u+QtyMISm zz`V=wF=g%?^A$vg=y9p#7MvlY=w>swWm5!elb>u;5bvW`=FA&*8|0DUYEBf7GIELH zD)Pl-tCX2X3`(Kxq4+nh_57u1E%KMi+Z!W69I#Ak$~AuQS;?Gh;|SGek6_TpV!tw6#J_kgF`3aOfUWu-%`Bpsr^4`9r^}Wh1dGSxWe&t5M#m`JQYrXw zM@Osd_m$tjoIkvPj+i>27LD0^F-7yJ<(vAb=D3>dB+dD1CT2bK7x{*@kt|NAGI+l+ zW<@rYb9zEe;aTS#=_&+DK3j*LP-0XWuml*urS)s9(=1Nhoto(K!CT&VzJ1xPEasy0 zl3(*GmK^yNeZW4TWe^`UWQr2EWFs^i&8tk{zSl~OovE6~<_rAU<>y;MJ6^znfV$EC zRhM`C-`wT@!^%IdN~)W?As^uU?l_NIAx83t@6J|>2+&7TR_2B-i;C=b1rl9L7^YcJ# z0(fQ!`h48;{pt=!=jG~-4p=Rs%RB`i9)`@opT=Zah8SdLvy<;9#y4gXgBqcBg2eT1 z`6BBewjbqLe6kjn)QFNo<7U|;88)L_y%i?wQkXM*qJ+jz`4wiw3G{>_vh(A*GutR; z=)p$pvCMT8#YHGh6GmLqtJCqd@gmDM68+YFgbe<%-sS;p| zB#|FJOtTG{(I$1Skt>>Xa_i;~190CnnS;%^WUmYIenty>{J@`cAv7iiAw`+9C5}|< zKZmOa`@SFZ_GDs&-}&o~AC*CICx5|KGnD^B{pg{W~LceRP#T>RMkPORhVYlc-6b_*}I*71xz8gm<#FY8VizMYD>YmUE6F zLM2kltm&%dIC%q(d1x9#BE!}AoX3ub0j4qf$XoBraqH+*M_7e2ce-0;XV6TokjQTo zh3jvp&0p{c(@VTquPBE(L=5oQdQ$Er4f|G+QE_QqX|d#81LFL zM~xX1i!TO9QT&EDBnwAYF&4BD5088%!VkxWCpDfb_fbo z4i`BS^k{`G9M4yaWZ&%8oE-ORkP11h?y%zZgzGyBNh$<5t5xj~0b35y{Wgkpo)55| z`Kt$UJ#cCS^Ua-B72?Qw%<<{8`J3+k#!zi0Jz5G+fZ4Qm zQT4ZNez>+_<&VlJx*dYt$n>>gmjQTi6tYxQJtW-Nmt%Q?r1q)1neUF4Nsp@)dsNGU zftUz7p+(9^XYQLcvkI?H=c=^LGhz*MTcN%$u(e1RhS9qn?cr4+|(^4+A!O%cX(X-im&xa>z=O%4^ zUtnHOA%w)9qKf~G_mj`tC3j9nx?xcJc$7eiyTw7&%+z3i%kg7H#`SqF!(@QO| zj%mcq1^3Ds@f?lQCscQ2O7#8RB*WRr$C>BG%SWr1()dkd$kHt|SyN+}f{TEvQ=Ra4 zMHJo$PQ?(%B>1H@!#h9tBoxQ5_;G|OC~6AkAcsl?VBgr}2HQFXXVTe`>XzQPO$KgR zC>Ua1H8G%Xexbz)cp4mY?CC&wzE)L?cM2a)2_+0w5U1Sg6J&Si$O(7*N|Tj;wpTMz z*}LSF-^v1$Z`AWyllB}M2z~49f?=Gn+QUMjeJ2o<7PI;x-m>%~@l zt*y?ANk?v6`AU5l$39<-d57Ep{VbmcS~B33yhv*h>vs5T30|!SylSBvP~`%@J8d5F z@R1g;wto3@s^g41#Ww_kJM38s8t6Q`+?DUKSg|_(%yp0QF+L8eD-hY47>*?_|6~KX z4p%Y}lH{3Q{az2_$s69*APj)jG8Z$msXm!czwv=&c8}M$;5jp>597;rgNDiX!_VNm z(jB8ogc@%DsUr2^M;gD^J-f~4Q5Oh#>@}9f)bNqM0>!|@+jruHhtYtixTn``o@r%UoZl zs(xC>`gke2Mwb^4R>twuDH7LKwos?^^z-E>5l^hhQT-xo|H$l`mE#4`a!Z|fjg7ho zAL*S!$sPb7MHpeYJl@^Nu}QJg2cvW!?gnpq4T-Tf@xxPFHSX8~o-51ShK?J<)t zzn}0M{Q&vq)={W@JXmFQ>_}eWD~BnJ{b+I8K5r-pC9876A^35bSEop$j%iGma_-63 z6sojtwi_C>1K_{Uxdb^%cCXZ{H({xn(qS}@KF_)EH;xwh%drOKbKCEJ2ED1G;&KQ6 z;8+}}8y?sr$`TA@Pa7NRs@wL)a5FiR-d3T@>8Yz;jXF_ktU6Zz*?^a49*C-Q4hG1U1qzR#kDZNih z_Dq!Qok~HqMn6w#8^&j($Z#Ug%Ht|=ZAj?i-qnk4Zhyr;ix(HZ6_H)vIkV({lwxLd z+X52Lj`cvGwxYy)@oTcEamF1&Uy7TycAntlv5ZVl0V zcsp^#&^FP*_NQ#2dS}#Gex3cD7s#5Rt7QNU1SCc9ueQJ@|EXJGMRN~hSrcI!XKOm) ze}Ddu7uQiRQNmTjlmz*b!wVYm!5Hu*J|nFxo$Ig#=vRU#zX0HuH9OseC|gmjARse~Q2V0;coqb^Uscs9#?XqgG=l=C4Z) z>cuVvV_iW7Ljd;WS%|KD8w?bK5+WWPZ?tf49dluq0>e&mNntN75!sLf!w+I8sDx6` znE?jJQv+FvkHGZeggCZ@u;*fCK;34T>k^g)c`SdKIYqM3RfpK#Eo|pVPCqL{D4(oo zJu9hUBEqC31CeorsWma9A-*t21VZE`AQOcaUPZL;Zpsy?DyJ`e2}1_0!JT%jLb&Mj z{yOE)d8bTMMhhjW2Tnz92a9o;LS(01;y#_QadqevIRb5t2K3Af%%~}NuD)@T0Wvy@ zT1cn;qLBhelAJ>rhI`vM7l2>-?as=?{pg5CFEbK_42hhPW~3!X<=3$bjZq37D8afq z)R()bB#KL~53h4V5s~RDVLZWi#c_<9W*f|SaeXC`9t>D|^0-XFLhc0V0`#v(T_<0! z7GwG{5uML70$kcL`H=f`U>UI2@gbo_u1N($#ch942`^YB@Z?Yx>LD8{ZP&X2u!MdJ z=0t*Zuus{Qo7KJqOdha4O+=JOj3{(=Pitim$)XTNS;vn=Sk&3rKaer)QITAp7usJ2 z6!TqCHb+o7QOa$^+{r{8XI`dht#bIEf-SPX@p{w%m9iwkR;A_YWv zgRR1NeOFu+7|N7t*kF?bRSHy#w_hq?gh6YSXmD-BmG2m_PFS$ACp;zr7E?27^7{L{S}zmi&u?bW(dh`n&ubvuo~{cMBWjV zR4x$M%umC$zgNerxXc`5>WAw7#?wRUv5>WUBAQqWbnegfQ*sl-|hST*4dp*oTwsccIh>dJDLM zfLgBsLdPQCE;vb^9wqWARzIB`$@agvxF=~1uQ#_DH(SZXv*p5uM*KxmT@d&KO-#*Q zqH;|Rgei|LR%F^X2SLSk?aD(vp!~mTw(n{DEO;l}WQi0Y3W<3iX6i=jgZckTZkxS_-86%3{7cv+NB zq1#e8&+-BOOQ185dp^hD9ke|}y1<>)TXyHoU(M%-*%Q&qtzwq6Ge`Pq$U98FI|P`O z{HhaoGHT6Z78Yr)GR>FH=x^)j4e^Lylskd|p^jPCd!aHn0z%xL$v66n`i<&QcL5|# zS`pXKk^vEjo^6nlDhFK1N;9v$a8t?1m_67%{#7^DEx&m`+ZrHx)FEG_hjJHJq$sXXx(O=%C?r2ky+LgIhfYTWZCXeJg%Pcyn>ScZz#U_0tc?j0y6 z>`2y(asZ!kxMim}nro}O!HKpdsRskbIuT4k4k9D7*h_~I+TV$}c6d9r$S;Ysixd{D z660Uv-2BlNUZg-?NNy6!2fi7Wc9*qUTS0NDYwm2ZSDI9s7mn?%c&;`Urllz>I7V5k z6`=NIMrnDaDV<9m7wTh7G7GvISw#}W5Pv7g=$3;IgiS>wjV%|~QMN)Tog|Xq7xVYKC#9j)oDSe|ybr7MOTtc4Ej*z+|Me7U!u3zf@fP)iPEh6S!r6;lLw5-h5>` zI^3JEa+?!zzv(wMgt8=jJxdiX6bnFK!H?KpS_TO-}ThHBXLkda1CZ^ynb> z7UuG0Aw;j5_ZtO6$W zwp2+NoesO;U^w}wE2jG+%F2qndIFy2AE%1Cs2@yk^HDF0in?PfWp}euLpR_rGtxtP z00jHWY|EI-)@g{~4+2PDh~p8G)-c^`h6G*s5B0B{($-a843WwENH;~9qafBXH9*=B zc{M|j(XttwNXtE9IBRqWl1?ESNzZ21%sPD>94q*fd(P&*@Ms|x$>$xRO(71DwubZR zM+EX$IcGx5k5sfS`uYanyph`UqJ1DVqX!3F>3xXc*8&l7pr&KSHqfEC2>F`w?R9>Y z$9I9eCF4B_hw zpg=&$|Anbne-~HrPl@3F^Z0M@VEt+0@S**J_>Vl?=UMm!6uDJsVFW@Eq-;1n`7#^U zWOykTd)Gic-HOJ>xz9jcyyFNw>PCsRlD#7tUxlJMN82R$IQDsr7z~%IP0vZk%`DH$ z3EkfxAF$o_UVFkQeaai-rT@spRkR4hI?Ya-`R1L1wLZ&e!R4JEEh7pm3Wo;JQDR~qx4277n~6xkWOY!dv%vU8wY(r5j+TxQ z1$o0TFff)o;e#SSR<;cHGdO&7d>HEJ1JxBY@YAq`6cx zClaphyeX-<9_FJSuQr}$wi0E^5T}XX<6&leR<*}C?IS{}35*As3AM}MZ)<IWyD24r5FWOrDw3YhbC=*(vxE~cO%v-NeX7Hdz1Jxy$^I*T(6Q;E9y4Gr1*H9k3) zg`rvLzSyQ!8!+!F1-U7yG;xWny{VUd6jrU;TA+2}C`nLmaG1xDaDhk>h7WX-3enF? zD~DAabB>{U7RiHzN8%=DD(<6vX~9V0!Iyw|Bm#I9+cgu_g=m|M>s|IfIpJvA!{&w* zyfY@PuAca`O2;)7LjwzXUKac!(hMgN{%@NG%hK)~vL}e?GT;s-3`rTd(&LC+edi*^ zMa9GpmQSc?;>(4IEQl60h<(@K>P7Fzs9sJsM0ul2T*hf7utkHU78Rt->1BBeT4Vd3 z5~I@@8NxSj@1w9!)~r~sq0vS3+XLpSdvtatB$|JKfss5eov4s0 zZp;Y%E85j9*V&@nA7H4UEZ;`wd`B1Q4|jxpT@?2ZxNGi~GoGd8m7f{+7(i+?fEJ;b zn2?rS)?&T`>3KluaEs2#Gbs7P3k4}{bbVA?`xLr*>?)}QbV@`3>)3(_b4MG)3dyy2 zs*8&^0K;Y6F)to@N-qhZW1eN-tFtSMrGn)Ld*4B%p@%xtUujo@PSXhZX`OgW+3xn4 z`j#ct0iaH$xLx8QPAcccLZHyaCOljAtz&PMUZxa5lnp<0Rm!TkN__-MhhR-Q#FFDp zak#+P_}WI;@>Xol@(p!+F`%W!52koqgf=?vW1Q~zq;@UK)I~RT-;Q8hMt2OGfmW2b8RMR7=tLMsTK4o z2`^1#g3~9dnx);YTaJreC0Y$X+$#6wSNt!c(>WxMOy_coBg?jN1mg5dg!WJ}KEtl) z-g@{MC=ddvhv{rQ?SJN+9Wa=;q2y#;<^v9Leq+vO*r2kR_-#7xM*206&bDDdcbLP> zHbcW{x`tXZMZOcGbhB!#$mps<3BEbMe_=&g-hpD~9yp7x5%syO_)#EEjRSw(J4PWP%o zD)N|SDD0sc_iAmdn8nk^3!ZnVK)=uW*d6PUK2~X;HxuKk)44 zb7wt~9+H3pprl$ikHmEL+gh}j^M?l1j-hDr+ylzK$tk{1-^m@G$9#re2~N?GN3<>b zdoG8*&RR+0=F4T9oB&xH5emdfD3joP!a=4Er&2IXJN!qz(}Ctv;^O00jDee(M3 zGumw2PuB%TQQO_B&#jG@f04nLtKUWVf5;&Czc3E>-#gYnHLQ(44GT;8Ps956INacW zi^H9bnKpBam7_EZPoI!(y|@IdobQe;SNYsQJY&5noJnCg59+^7+rLR?MjdTZgT~{) z&dHgMOI>bmbWF8OxleLDUA~{4RCR%*^jm}Bz&1sMRao2il{KfyQ(78dnw5lEt7fE@ zw()ng7hyd)nDA36b=8Nv6b#eQSU;C^45sXTb#;~;OW(R4P*}V<0=PicvQ=r-t@ZtZ#Hv4BP++VhK`(S? zvNFTHbr2zqgO~-2XNxA;Cbm_k~7`Ze$c>#sI9tI9>xdxUQIaJ&6~@V)2pWmW?g#*2DON- zC5(XBLE0XV>s$sr|2H-iQVGMIktHXtD-KP1qUuJexL~#Wjf;qh#G1hha7l|*>8=~+ z%NePNDoTb)vp4b=*(+zynb2hA_8?XCEFQF-fL|~YkGzPky7~pwna!1BLQj_|%792B zT1Eg*8!b|wfTwYhvRtK1#vuK8gSb8=eeEa?ossqjTLYA3v(}TDJkM`lib*1wSRSqJ z;s69d<6nWeeSE2&W1oSzbEr+ma$VNYQfCS}OJz!v1}_D#cGhX1fw(ZP=32SQNw4-b z&~VU0EGWs>tTW}TbM0FSA8&IWYuI@txt5aqFn#?y=F^juTQjvoc2b8!?VS{^bYNHV z>NtypD4bvp6vd+ru`Z+sojwBR2v8`=vBX_{rX0m8$kT;hdt${5uyMe|p|fhYh*Wt~6Z2~lQYm$EVuj1gMeHO6`cG!1bdz45_@ONY0KeqH9C zoMII{UrNuTB8i*M6llzNhdbOvPg7cxRUGX;1%yS{4D+R{Y+PigiKgQ*6c3~U^SgDj zd&I%IBV=&Qv=Q9i3(mArgd811E?NxE3aHYl>FaCHzrMnDyo6n0av6rno_}JJ(i{Xqk@KWH$3!J*DO zxyxeSg?AKU@#DP1pDok@*;b!D1(x|K$rONo3t$fw*x?e<}OEGv|mWT#8%7H$V{+3~zFjWFCJ8;_6Fn z-0Epg-$iqL;(1hFc~Wd_XOS zV$|q>7Xm;iwQEGxY?%98=ECvohl2Q2z6MO6BJ+uy1%+M^mE(f8MaT-8XnaSH<3bMl z_&M@;mwjpT{udf7g<>`=|3L%)e~AYFxyru3%c}yvw4ANEjnii??mw^m^OOOx*CRX( ztfIlfI%IcLcokX!fhZU1Z)M*BJX)Og@<#S@TSMcb&bf7ABhx$Bzvbh;BK^|j%gpR%{Z1P`B|2kkqOxhrrAA|^Z2kf>+X60Cdc(NQ5RYtL zLfMHTl%W)kBdy6$-6H!`u|4-vyzRY?jf3V`F~uGuUJCn4CU!mS+(9EIoeorPoc=>T zYgq}#gjAV5Q!-p`T25I6N~`gmKtYH1?sK+@rMisT_YQYi5l3tQW=?6#d-V=uN@(JJ zNuTQGENSAHz2(@ReOnXmsG3RZPbt$7Vq8)DgH=E(X~gvOv0i)EcMMat1;f;+vee6v zq>&r=MTT-J`7t@HD?FJ?>=PN-Aw}55)Wk>5`4UsuIlDG=;F&=Lz$k72ECIRzx1h7* zE2{$+EMNkZ=jOt*b^G~zwbPrV)`Qtw5sLMh{R33Aai3Ui9>$%#sy3n7Nx`OoP``( zI59&F5vtv@g@=b$w?|hfit8=4>*s_nS$vEkpbJrCDXeCW8;nD6`q_Eecp$K0MiyNM zk4KCc0PSFu?!9fo+-J$$>yE-~B#1sSefAInN@Gb-p&m#X1|>D6FOSK}bxM@MmGWRk z_5kRgtcP~-#q~t3^?LBOa^BSGZa(5iw<*692k|CG6nsK0%-uV=4 zGVjJF4}UbZXgzs}0t$&U>1uQDRRcXw?-0M1=6Ey5(1AMG&uvccpfqbs$5s~ZA$Tgm z)=oxA@7)d8g7I{-fi0XbUZkZLN5YA7ZNplCaB&xsr_GLhOdaD)L+Wp})J8bfn6pp{PZ@1@6qe*#lRaf@{tPHH}$e z9s(u&Smgq&bxhgZ?h{iM*{_^rc z{@V^o!g+C6FuF0dkk}AF$OaYrb{?zzRPi^V#m$jG<*@=As9d)-9!Nn^9i<21GJ~${ z4z*`9f4f9FEuu~GPCKkjRL>o?Ae!tm0yT!-7T_TID12IksN7^3oOsh$;#ts4cpni1 z7vdG_IS1KGgo5CpefT4f0Gdi1paUpQ?rG_Vh*s_uxAaGxe`Zq*;!kU#c9b) z>IvqEm&K#w_7K;1o1Az|Zj81c_gS7P?ZKs^YyNADCKHGnF{gqSRRT(bk<9?rHoVIsJ2_vgA z>he8z@Exi*I4}Hz53!~XWwp8IX5ob!#8uqkgVB`dY~j zivnTx>0wS(7GytegiDw#5yo=6UzulE-Nfx*QM*GS+y>%7@&>jE`Xh!dK%Fspbnl;j zzQ3Y&_ts9+{+_od=5<54{K1dt|3aDgf9Q(;^QQR!9#RkxSd0BNr0|1VNr+>OgrZ?! zwYQ{ifTFk$NP1XasYbKxNY|Nff2`=r`{tcff;_KM>K0b|5%LlD*Oa2TgHVJ)sFdVt za&pr3@cR~rsmak5S=VnUJw#pMnV#yL?@1ofXIXot9xb^l%@u{%V-Dx3X>B4ExkV>f z9ERH3Ro>Q#)J6T$EETUMMQGkpYwHVA4Q5_LcL%-WZ@GrcxUT7(xgqpgP^ogRTAfQi z%8o3OnUZUr!b#kHH5jd?bEyJZeU;1@Jmch~MdCAA6dTM|ed#90*cjR-A^F25utRoSVLpI! zMzr!JA+1WPGV_r%UM3s$PDH1(x$y}R9u2&tcqV9j6(jw=a#~g?8 zUcD`sfx4azvfgU+;L{}D!g?Y-@M#hcrrw{L&8lu4V~JL|8Tl=~gKOS^hb9zu$f$ALQn_VH_=X2% zg`Y-YMG+q@5K|k&+%)XcoNVADR>=-Uao_cs`c+v5x!!w=6WIbbFds;KH$8)t8Vkku zh=_UaD~H1D6Baa&P?&zH@|GZEEVMZQYicT_HbhIO(p0~pg2DGOIVgds3_mdX#50m~ zYr|kb)Ty?!Ud+KgnNsvldUV`Z!1D20tP@BY71=9*t1mc~I}X&DcXfRrJK^*c)W1GD zjZsiO$X=%2CiLw?tlkEO&B5u`l4Z`^f1SojUthT#36K6B6=!R~eGne+rU(;C3-KQ& zakBA3$IYEEmdt*veRVRNffG9-89JxvSw#qs>}g)`9e2D3t^BrUVLZMU6p*fAe!7{4 zPb?X$6@4?Wg5fJOq851iaNGR?J~$|w6=kJwhV}(ypV6mNU5NM?DmTeItj1U4-C{w2UzLp!md+^}n&?<_9@* zn*R6CiAA*lzT_*v*%ui6ytY4BB1nA&(H1r(V4|^t$LNd?`OcfXL>JKddaL_cfDyi` z`tAO~60HA1llVXCt?Ylm650Rzu!JM#zp>=MvE;w8>1KUl)^J$~)~5SGaP zGnUByUx_6GK0Y%HR?%(JIPya1l|fR)-)XljyGmQq3MLDzw+P3wc9uUUB~k>L`pp@Z z)pA2-t&^544~=EYW$pF%G}<9$ zV!I?dDo1sm!*pRfwMkqdC5TlgmGUTVwT=B_5^OLVccht|q9SOSgcOXJ0EXrgw@b(wd~AJk3~gyTW2TFs zv0g6v6xwQKrb4i=WGGId@Ztm!7{AK3XV6hsu|PFg4;%)~Vf(bw?+bT{ z%GMtRP;X7mWz{wg(nQOi_kZWxMKkOFvO~y|kD#wt<^r=PMhB-{r?QLhRg_3yk0bc# zq>!qB@l-66F9{D$%j!$CNK%;{t=cNEAJJJw9~^*YA;(rl(Hi_NRJSN~=OejtuX|?g z7?BiR=}G8`PWn|Qu+iWpDoF@n$f$YPP`ZAU>-ID3JR7y-oFXQiKe95So=NzrKHlKB z7-e%9#qD>mq<2a(=+#bJ9B38*zk(m}jkF9>Qe;@y9YUJ3h%3=z-X*;OwZ7Lhe-UDP0cP5r@F2NaZ9^oV%`g>@gZ*x zi>Dj0t{*83G!K8)PVX?Tct9(j^`(KFgtK!1->Rr|Y7TiXJDEn4kdH61MpG~r2j@#e z+DSd%C2DJRHRWRHH*}BisH;;h!;t7_#Yj+EC}DIT3*)#$B$GLgE4zU-nO(Ts^7yD- zr)GpAv{uoR5)f{=W4yrY_Gk~9?_D?}glOJLc`jHo%D zzFapzAclKnvZ9Uj_2CzZA;O&1D8xKEc#%tXDl&`Fj&9nkS3~Z(s|1?1yEM7jeQW4n z4_{J?U1z+xvYz44IIHPDAi4L}^wNF(D*BNOHPPEp#km3y@xrEKBs0;&tPrymXW7ZT z7e}@b-6t6Qpb?q{kuZhK1r^fEW$~f-8z&_%ge2h+!{7{oui_@^oHR1>EkRX@ccO;S zLv}lc*pWy;k<5|df5uGl$$G&oHQIaE@vG=gR?H89*3!q$5;1rDX0&_z9|@A40<{NB379I*zol}*2Yvh;J455&@P48DEWnD2_-+4d zEV28~Ex><8f$&?Io7z|#|Mfc6|99b^p@cOEg@rOKSz?A#$nHR+OiVZenM4n(Uu11{ z!XaeF2+f6!ykk|xx~yZ%`up5e=1t&0X?-TA&n4Y)^oi52tU5_pg0Id1{vX^&+{s5B ze?G~4-(O$7fpD60vLkjf^o<)RY?_lQF!m^D2Ba&dMonnymTIQt=q^tOUwWJrBstM) z4b?3pOzVqd&>seEv|$l$rg~B!-PGX(nUcx>JMMj9-8QAkFbtLZz`2Q-Sb=mI^)q49<_7cD5r8*wmf_M-yJbMC3v%1a30eF4u2>aLa_Ahj|nK7UMR zW~Fs<*V~bsGef!X5eN>@gIDI~8j-7M%GxCxY$_>6+{?jtfp@W7S{KR-i%BW|YJetP z-!vgzUtEleWC8DKmRpv`b0S?|B8Pz7@fF3gI!XUPZ*^a=#VT%%$b*rn&IrT9M5$>` zASsXlv|9D~5mwNeBAE-~u}sY$6FStBRT{ZM#@^M)BOsme#S$xBqCl4#bDT*i6)_bL z*R**~Ekl*gex=5~t7z_vos;HXLN~)Dx{F7zv}PeH7Wxj_Muwe#^&=Y%8Lz;xpi+-M zppT^D=eWJ+>KT@4i+xt~37`i@G(0qi$F^AYYo^^C28!tPRCTCm3*5Xr>AEbtg^hZqrB$7s1#j9n?C*BrnYF5_z|&Js?d zaO|NzK*cU7EGx@-+q%5i{44^-*>@RdeuM@`oBU$R%t;ns@J85|HEZR*&uXv+ow}I9 zvxBx?TF=C(`WQuv@hTIl;iMvrd30=%15G&8(dyY>d&EtHE<=ZNhKB6U4?b#x>O_zf zK86np6Aw*#>_Mkf-V3gcljs!(Us6|zj36^}!G56p^AXG?*+={jq_n-_xvD-1RCz#_ zV4~fm1)K!$tAol8oVf+!BAGf5(dFHz#Ms%ExM3x?d&*e$rg>h_p2`&KO-zH>Q@bW?!+^W* zJ=c58%k!NVn&%b*$-U%jO1`wjy8Jaw2LKN*{;SEC(;gK{>o32`_^$Ob-8w+#RbH%z zZOh(OP-uF0W2LNdR1_pL@_jH=s#eKy_vg{t7ITtJ7US=k^uvAQef>y!v4D5rp5$Dy zH1nGqxU}d7z$t91AbCj!G8L>!VMX(osRuSB)Zz^+uVv#vn3fS`6Q;5WvWioBCf#x! zz$b2k7y}odt?PdiPMqdnA?>42OX)^RZ3;S2X-orb>J5Rl?{&+Oeed^%*j_oHB{>=_ zjFt{P-8g3*AYO3^7pJN1fD(^$wz;SfEJy$n#r!ALZ!`pfo_;Fs#WeGb79cwdO}Bc9 z4#zQ|@*U=QK?wKjDid282rnqFVQf!mR+ZOms-a8aT`hqs;Vp8+<0kgUU;bcADsT|I zJ1;&$)Gm4jW`d<5qIrf2ByV4=I&5bC)G)P(E!^a8fo7aY@0sd|zl=CCLJt&XgZX@p zSu`hn9;ZulMT8`ZP!0!V&7qsMY2 z1!0gp&LL8}H`Dpi8C^;8a_R0^j$rrr+g@uMFZ`t~RKzQ#O8mnt_5YGtZ2z~m%>QY} z{CCN@fS#meh1~q&FMb#(Cn|*s>99hA{2BNdP|D{X>hyRgeb+uK7x}*==de}nCC-Hr zoO^Z)_HR%hNisuE8Ps6$IGBZBOvj}rvo^S=JhSfF@l2<5Wqn^kx{*7f^8$OO%aU3r zoSROI{{bweNy-iJET)kjV5)O$j)SeOII;Z$3-y-;Su7rawe=aPhHcKQOH%1P z1I=|8tgAjq2CZ)?GF6;!*$*@mGt?~cjojhqts)C1$64Z2w1uV^l?RyA^9*T~cN)?i zXJ(q3?MiP+X&5>>`v>fT`Fya_QLOjN!{@cgue$Lm>t!bxN)bf&DQ?H6>_WPMAE*YqrPY6la=^s=|0wVbHLip!H70}WUAn9puvM#sM}73KN;PT z({!2ZO8sn|!s37M_D(^X{N1*0*|u%lwr$(CyQ{0}E!(zj+f`k*ZCl+{yZisG6(`nS z=X@6@_SzAd7x}x$tBg7Fi8;rZ7ZjzO?G+4cu5ivbf|m-fKfmzcRjQfM%xza0JnjDA zisn?6t#}>x9S5~&sr|Hlpc+MH#d?jzh5Nqgq;ZzzDpwDb6er)QIHiH|EsKGqQ*o1lr{9 zz~H~UCr~v!+m2P9a(?BKT|on632Th#qLcwGGNnWjSc5_#ospYlCrR@Ztwlk-wk|3c z4cl`zNyi0Z3;uNqQv)(O4;Q#>4BN801HokqK_+_@KWx21t(G&aw;icdKJB~hVGHNy zn(0kKjqgv{tYA}a%J5jS66#q>?Z@#MqF$(nV{GCRa`4)BEl($`ctIb91R0)V+J4|l z&2|J?a??2uJcwiyxVluTC*5u#rU^H%i-9InvH=o<<`Cn8T=}06`x->|$U=9L) zz`|A*2>A8Q>X!M$Ok2X=tp(H=e^!bh00?!{3*Wfb+{$f>M^GEgb;H&RY4l zY1cfnpdp{gVdgJ$iL`F$y|_gx_GQDf&=>tUaFJ?oOK?ED}PI7RD6l?n!laa@{F2lFApPLtReCfF~Uwo$78 z)kTT@+eIlU;!w~1$M=!&AHI+NzrGL5Q!6fUd#Dxiy%W0D-u+j0G$Z2LEm`_!x;x1Ju%i(y{^NQ&Br2aa=Adr4Ak zEkW%-pn_7MK~KUnzi^0izrlD=P*+qr+6qx%OBOR(B8c0q}BssR;wVFlZyB4Te) z%GnVbzcH=C`(ZFGOzg!C#S=Y#>9rWXdcPd~GejF%BEj5CZfQ<6h3-E@ zxM6_O`KV}FTJGsx^(e{ZJ%Eg?p7%KCT5!z%#Q#mplP%E6ZStLI5xb=C&?9%tKj5S5 z*Y#Sr;OE;B@OO+&6{R62V=Zg@EZiD%+Yu)bStr$thI#ABOQ*}m#mJ5h=NeAzmHp|E zN2PU~eQJ6;vkn);!pzLgWmTQUW>&z4smE%Iz*@Wv#ZNX)eR@4FJz-|i;WB|5Tk0)2 zD`VC~4W)@$gFceM2Jar=Eq;?X=&j|2&76<#)90X^svbvM* zh7HoNvzkH4#(4x?O|NoWO2;}UiNFlzOE?_TB9#IC;}LO4A^3xb#2A3CpK{jLafWbS z4);PjRu=%Qi#0LmPf5xP!Rw<4D1=L$rnA)gWiLTvO|j(xVQ9ZabW{6Nc2;16GJ-_cpGM!M7De1DdBroFbie_TSt1mV?cx#o1Rk@Oc zh+^XRsyynHJS!?Z&BSo<`KUpLm3?};l}i2qqYpjJvJw5@#CFm62g?~(E99e>OvyCM z<6@ozWe6Q4=&f<@?UglPLWIE_pR3FSoQ8_*S}H+HFK73A@@ZQgQrltXeKZQMyoASPHI^r z*Z`79n!%nQ8+0ie^((S81|!-uVLqGjkdx2r!|3RzaK11J-xaa+7#_A)Z=>W=?x6wQ zA?=NMIL?kCaxP+o4-wAV^VnI`;iD;0k)`71ILh%uRQSAViich;6ok!}+MK8WR@oPX zpS(a|*i@a?v&PzV2oXSZS(;2EbvD-~=p3h7)JG@K@jMqW$a`$rSqE!6i+nTJ1DN$$ zl`5Sd&duw`zDo*HM`?ZH;E508jZirevR=syIHVm1=;|F-Qf(`0T``;umL*vQ9fB`L zPy0f0`;CoUu~CuWL2_6#_A1;TDng|llCz|;e|_ki5eYu+Ee_Z>p1@t9xG*&{7CS`; z_e~Kmcfj3o9kWbT%rbUmK)}8*a8F^r`%@qWov^yan%noUqXu$ zs}O=2Xkx2feG0z8ID@&ai>Xg-AC6i2x1iB_n!a-Dx_>c-T)+Ac#%v$*Ee=Mj!TLYa z27WmuzoG$^(LbzzUrF(;rqKZ#j?P@CsVYjblKo9mWzej=d0o!fw49&t7i0L1BYPiu ze+>V?_3MX!QFh1tgE7@yTJ*y>)Ynwd0@TC$Dpj=bfFdo%VSX8q3e%8_dCG3RnHes1ZTv zFYRq1C~Hhzq5*%k?MJ8>f)g+hC>e&%28$;`y-v+FBNZ$Yo{v&t$U`S6XXb=BS3ze3 z+8m{0==7A0r&W%3o7u@I#1$^HlNrE@%tg}SBB0)CKRE-n>A-ZtND;^tY4Yz%kJre0j79G4&8wdJ9 zrYr_FYPDFR99pn%I)H`{zO@hxal&EIXzOs?19ZX#sw5$k;T92hr3TGGc1NQ>G z0|g3|h5Kc+n3|JM)yCs13Kp)lE}kb9n_z&(NYyzpTw$w^En?zB1Nr7o}s33ari@a=hwncq&{a-$jPJQ)1nv zE6BM)H|pJ=kVzn61t1re2>)FNBujAib{l@_e;#te>c@~y%5@9gLqq?8`BzLQ2%DMm z|8NY;zZFye{~KcZ@3eI5A1%cTzyKk3Dp5z&6DmEF-$vX z7+UCrb!`_tJ6#F5Fq~&BV`Z_o$M>wek0j5fWiuDk|ar3q!lG|Cf9P07v_&g8kvQ;vEA z4Y@-F^_Fap-6LCTdttgwzdPU7)GGAo+%js3atpmf=hr<~6w=_)_wlEQLC=}y3hs>J z64e&VIl3C?a~ekUmGbmMTJIhd(=fEKz+)c- zOS|Lmw_dkil}!!NkDD^;u4)PmQv2jR1qzlP@ww=K(B_ip5871lj#T_bo8B9r4DQ-= zf>`q#E8D+lqYY)hdc-prdNj8RR=$C}@)vEO0n7dQ-TFR2yLw;6Z6{dz0I{D&vPNOM2JRGWyJ{ zZ8O@AxOwKG?yoxjYsS6Uej?@x1-KVOU!$TQxt;~+jREAq_K$DyDaOJ0w)fP$%lnZy}!REw_zvHq#^nDgQhZ&}#NcC$COF;$>r4 zmd+e4E7R-#%Q&*HVOAO!)&h1^4WHKC*06;Q^DPu4;l`J{Y*s6O7)Ol-FEO6Ax_Y9U zDN2!g55Xp028i2bd1fV~-vV$^6Cig<%M7lGRO${n(_n}ZBCPvs(>8x(Ru(3XEN9$$ z0KM?i{#&O4yJ$?2-UmE*F6lUuquUj5uv7@zV6>*Cn6j8`PObP}P|5o*BST!3jHn;f ze!@GRVrG`O7(09QI_dFZmUt5+Q>@f7Uoby+28sQKbdJ#c!m$AlL7heSwu4H)Ng;~W zRHrHmHS_ZP!r~__q*M&ym}?EXN($5F!9OM!(7}!N z{M(UzD<^n7VVA>qJ78Ma~K}+NDn^R!eyNRH%U)Z27`T*D^K-|M*u7dKVQQ z!HDx$fktkb*Z5>57o2TG+vuQM`6Lywa`{Hjn26J$=yG4vx*&N9GTS;rY;k?fo(?x< z?4uZAQH2SmFn$^n<;;@7Iw_G-(f!$ppQzdhvkJutT@aC<#3 zH6S`}rWb@a9!Y$ilYLj!I#NJ9pccCY-vBJ1o)Ji86H(-7DirPtiK0c3xtH(~rUxO- z+W4E)FCnD&Z=@TJzq>xJ9sic)A5eG}mwy;1@86bX%l{)~S;@>@)X~oF&pWIg9sc{t ze?+xwdmEuGVgC(;9j8D=k&==Ul2Ilm8={hE3M3(hHa169ffBZ|?O2mbAoq1gBwDU) zX>QJ`))cR-mYiE|fkFw>DptRN%6sBSK`D|9M--x$1B{aLn zAhffvg0yLRojNP+L6X2ie9fulI37^o>c-~SP@ihs z^ksIEZ)5G?3&FO^HDxnKRC0hl76GZm5LUm=u_%;b6^*2p9 z$oWiOJd}&4SRpC{l_M5eq?%rg`>T^jTQd)G8eNI z@PLH;`~%IQR-oTtPkh~m>XB3EfZiIf8O=Dg zq$udyLUe}XcN|7-3Vz*(5bzlJVQ(uKn~p}{?+V{>S=^n3a0Hn&vAYnx5;|$bnY3o ztA+-*yvUjDXDYGi3`GFSw>s(V>Lt;oGPAyP`?b1VEA(V838URSDJuz`#u6-i`XcEV z_4rUfZ}+SSkb`qC^x=`E6SX9g+#2+2=TI;`NaB@+XFv_eR3R)KEc1$yu%;jmmWr09 zk}Ke>-Vr|{#s}##If#distglL{kJ-u2q~&^D~3UdcbJo9kmSR8|6>zb(ZVPIIYn1$ z1cTaF#xG&8fnj+*hTYG>fx|OI|N2*9(Y~x2*Q^+`=(tHvPKqd*3L*P&8iGq#kQGdn zHfyuT@HV>s@ zvp@;=#KkpP-gAwGe8n!@^Z2M{6R9BR z#$q~p-_l-ja?{cXgf=iW7Kii82%2`P^c5)%Cj>S(+EWy*wy#CC$G#~dDQVrG9YZ~W zCKPJ4Fg}T-LhnsbwnK&E0ZUu>%;#TrUVECmvdjKp$x#vDP*9iLWlLmWvhpxU;N=}y!TmwNgXGn06=!>=%a&cX>Oqpng&{^3 z)Usk&qh6=%=gYYTIO*H4f`VW1Ugc`mI!HgsFZU-?r{8& zhwGai=;;T_qIr*XGA&j`n8sWGINa6CD&6e_F-5&8<08a_qPkWJ;zYV$&<$N$YlGTR zb*k?R?k|N5Ea=!7C5OYy&?70YvtpFpr{+IpK@UmG+l?qIJ#DoO5-#mgh;T2CfNzW7 zCKq#@d)sJq<_@58J!j8iXq>T2ocS#^9P5m~f#IotaEq8Uym)s33sO&^qEYnkI zLh3-Go!gRQf+<0LN`NPOX1Q0&BJ@jcw^@`z2ycvrVZB8r>s!q}<|{e;-lf?nPd*)X zZh9s8Kx@TnRi{EM>!KV}@xo?_3GMsZyM&+F`Sm<6*Pw7oGW=64S*S5e?9u@otVV2) z(-QDP3PRGV%`|K{PJRDbl1!&8U@A%8f04oEW|JC_4!2w_%%ly_it`AhmRj+oQRO}~B z-muYWi|~deZqm)z1HI4ObDsU((lPjI_Ze47m9h!)M}kpw`VGMqu&BRT$ZHRlp3l&E zNe@SQaodCAsYpA>3*oaz;BX+#Gy~< zWwS^or=B_PkP>lhJ&&s-ahQ*2#1PRBh=+%K5<0fG z*|QMj)>2hii%2+TiD$ON#$XaA(^=z^k^S>UvQKuGbb0hO63HG&L@+kO$oq)~v*Ypm zv?y~al=ccNS}xc`GA0{;Y1Uz@w(Qf&$JX=dzHBHm<#ePb!y73vIQJP|j(fOf4N zQ^aC_^!wKq0F@&zJhk%m1Ld0`Hjrl!LrdYl02-y-%}~bGE!PCC$9|J z1!?1T!l>>zIV9yBW5p7l4@_N1!_Elr@5j^tMnJj0t2Dp{Gd?fWNw$_$MYLUN%C3Wr zGvZNi=KS?MJHtHuhQ)w@{7PF0UXjOeT~8>EO=~Jy$bdG%vZYSj;bK|CJ`YU%aA++@ za&{wds#vo7ERZ2;+=Tr|Iw;ph0j^9o`}Z3tz3|QZt2QTEhOIDiUZ*!2g)bo^+!}}D zrDhOzQw|fG@ibsPM&~)3Ds=MYtG0HE#s)H1pjI=Z;;wdSqrvUcN!nIZSZV3LW4mCT zLa8d5B(5=rLqe#8U^{G1#9JoG*xTvC#T(~ozCdg*l%-eJey<3jO8}_iV2I`HWFGSI z6Sfz^2~$#5XsQ#l!AP+exaO@Ny1~+3RxR)95=B-B)OpQNU$_SiN8lK@mm_a2T@kN> zCnIh7hE*DHP4^aC_}#CV)d%sCL3Pp#e>K`NRi_$zMoy&?l4z39Uo%=xpiJJ3&=4f$(J#tkDHlM+Loz zeTwtDaCli7Cnsm2LvX^R7yPioJZqPaE`Bg2kU6OQaB`Ya3l{j=;9EoMx*I^U4;Fcopm! zC(#ncR1nWXA5&O3a>|68>1L7X)*yA#p6z8^hDYyw(P(mE7&VUE`{@YHf_0&&(Ef?8 zXH?^PM^|V}u=17d!#5lIZF9eFvw(4IZ{SF9;<(YGYQ@m1IR)d`RFvCu;VV<38yOBzL%c)bW4=}cI>1VmFsMJ1 z@JURUIE>xZ(87KO#5Xq-bQzYti}#MvI2tV6i*}v0!F@E<3Ax%k)kdv8o-3&{{ii{d}E1Hxp&T^9+;qRM^ zv(yPSdA2fRV@-}I&1#dA@Ts!X{4{|dY1CI>k%rrlmV7M=0A7S~O9F1i)0`fe*W|sD z=EOg{z?$-^vG&$iSZBRzasxl_@b!6le1zG=rxlqT&rBg_O&<%hRgfEd-5%_6n;arY zw?froGK(#iXS|Rh);XryHVE*i$w`a<>7y{>Mw-Bo#-z`Ro*FLo%}oh@Trj>h(97Nx zIC3)TXdQJu^YEPn(b$dt7}@$waet)V9*BjD4bKaY7DO z@DdQ(tDkugVI}r69Es13ECfr!9El+N%7I3m!*v_m9Dx}nPlF)M`oTKihqX|I3WXj! zsxKzMSxk-ofRRYh)(662f;BLh0~?c}Jm-* zN{An>B#6_&672cQRC_w@*bWJ+tY&c4t4aj)q6Xk7wd_)S#*F&ygOOra5Tn?qO41d` zIIu#;J`Wrh3?o+BF;;HA_AaML?hN2rG}N2y8>}A(p3eiGJLy~8KEAnKnDv$yXs<<9H-eM8oX?Qh8pGB~a^HO5X2r%#lnh0K<~dGLo6(q4 z6=K=Aw(sUEQb3nw0RyPgcOeVW-{vM@s1GDqZCk)*mswr%spcn=XoU#OE_5Jyi0I|E z^GfINmWB-Qt`Y{Woa}X_!GV^kN@JT%T|teKPPH{2V0I_wKV#+oc)ThI2jzzRaZa!V!W=7ifFNji8#n zs2cbzrnrFxbYB@Xb)l%j zaJT|Q&^OveO{`oHzl>0#Zu8I%y}_k4XN^ucO=)lHAQ==HQkHqA9WcW; z@K6qXTkR3Eo1JSfvBD2dbG*bYu%&axr?rr#l6Wr24-M;ZEbdhoWx zgL2&M?6j@hOXAR@?n&{@AFkepsVi+l zp6yOZy}TRHgD9dmvJXVCo7vK}5O9>pV!`EyaJ9$id?Eel+Lqm`@ae;71SyDvex>#B zq7^Xw$mS6c(y!I#jq@>WLZ&A>>K_r8u(NX?-H}t0;&ZwC6{W6=&9n>e@-5LZCVtSF z=SIKd0!-&lfaebQ{T6wKfY20EU~l@9+0;!%*RL>UyYA+heSN=rF|SHDW_{AC*!>%d z3K-YqA!_XY^q`cs;HG#%mHSd{E(wCr=92@vXXhV7*tsM5CIo^r z35dr>+Qa6D+172t_q|EUmMgbMxw|&Q?n~ry*MhN@CR5QfIfL=>77~Acr?^5jVe+DB z42Mm?#7S|6P&Ua@rX$X2426*u-#gXk=ehf*1=ZtNOlM6rsnNr{;zca|K;(2n?EN$ z{EtviDSN0>pIY<^lQ1lK5PP7=6$cJkD2mRy&ivWV=l#$C#|yb{KM1S-mFW2y{F$Oq zdc)lryoq-Xhib9Pe{%UDaC60d!~J%#vy%(T75E|0#Du0+NX2MfVV~B(lbPt6!5|rJ zGB+zp_rMW7-%_wGeaPxE@?MrkkE2~pG`gtL^h=4dp}0($3Q1yn);wdlF_9KlM~)Hw zNNZ^^R09y>Z7v-T8L6WHoO>3Fz${`j0I{Ya{$DR}(Kv+SSF1xBAQmtl!wLx|PC*1n$05%gldGLFd@gWS3JFkH^ zccE4WAHz^Gh&Dpe1Gj#?EXDAH=K>reXKJQpc=pYH7UH7lyTSf?aCtc(XUdgLcECG| zN$N*A^`JsB3^*Vt8NYAO2wi!Te7mCn1wj;n1i(zlz;d}kM2x~fJUwfo1j)5F`%|L$ zu%$*yibxt>bzCb$L5&A#TWc=V888SBTT5S=f#m9GZD+5LV>1aSiSuw&Y%|nKUr;A) z-f!O#*u~zx{LbKr^Hp=_z(&7EBVe>D%P&^N+x=2ttdacyx563w;vSuoxR()pfmL)6 zNC+joIb=`hz-(8Io^nf!R*};p73LOmX(bkH>xQZA@;-CN(~E0pJCP4_Rj;{(Qxkhm zN8D_R;VN)=KHdnN6U=vf2EtUT~t`~7>Ny;AUXR`fpV)B8H;;uI*ebY+bRJ~pQe zM0=eY$Gp1#tLljpG*1WiT0sGfs@meP)3?MM9bvy{gRC9p!=1*I)PPeo@xn?bMsaI^B;#j|KRtb$*^YL?(R#>|}!F-3@ z94mRZPJSmI=Zvl<=2-hj`JYj)el_;-6VbKIyT<*Bn+qrXB@rQTm;ANh2)(jQexEKY z6CcPwb8B%pTMJcN=r*gl3%AZB7JvvF%n(RSOhR%%N`M>d_x+N)Ec8^qS8o^EosTA{ zIlR~vM9f8?lPC&pSY3#=N!?Z+8V&^9@Y;!LeT|ta^V8woWG)7adAC zYhVLpk8PW{oK?g_ifAeUES42bd-zt}M^9_`v~Y-qK@f#Kr3^p~W5mBAuETES9@x;L z6<;1_TO3qGaZ6y`d*hY(hzuf%lUVaYo^bMZO|Z*x#+)3*H~e!~b<+#T@j`S)G`0oI*0)kx8<#us*J@pfq!E>>0xqz zx@f<0PRgUsRfGcBPedmcs+t9hy7P~Grqkw(J)|4=z$fHvRchf>Rddj~<}@CvVv;tD zBp?+I1T23izwjaOqn7a8dfY5D;}sn5PP%v80Qmy`D_KVv9)qZVB}ajgD3 z$@+g$tSwFbzm8RYPzcl2I4*nQCi#qj|8%V4>zKef+XhW)!u%GR^trUty3x7NUzeG( z-FfGIpG{>;{;@8DuBg03IA@3=-py(NvPx@%mMPVIxRt)e{gT7|vYnpYoBR1m`CZx% zUjlM4#UXXczNWLK@O(HyXFnyQVbXjfqlO1}QOAYdpVro{B6G=cBBViowL1)m%u<&w@$3%sTCoeR!t~qfUQ5g-U3>r;^9p*1OSy!J@ z=9VT7$MjO3GDnD;i7Yjvcg9l%H(0_iBw?R2PkC#tDNV1;IJ*;j&S|MGFR@5oBwt~! zQVH7gkYHvOk9a0?U#NrgjQCfwXA(&!a@N2Z(>pfHj69WkVsFJRTn9G911l|VdV2Ix zv!4$se{aG@*^ww1oF%$jICE(uVECl_p29PwSw3+gv#J_)2~YI#cj%UM?wcX0aK{p5 zVHZxyB);sF*`Yq`NgMeOTVC!v4;>1{$$<^9@^-n27QN`>3o;4KL9S7w7EZ|d(2nlY zp-LEoep@(2MKOt9q2Cz+!YYJiU4OH5+|xg<^$RDI1m|c{`QuBp0 zjZd-+?QjN{dmH}^{&%leQWexHm#`+U4w>?0W0;f09c1qHQs+^vm#Bov6439B5x!wRX-HK9D!6b8*P>{R}B35!9F3WlUo3< zh+@JhP1P1dW{q@tS4IO9)Z$Wo#fA+bg`F_L%FWG)L+*I9;MRi9Qe1@4isl!LCfcBl z4+0fWVhzy!8>JIj(xo#wEraW_SH=iOEh*7YCy;-`<0AeCNqq5x zQDeFS>`A~JEbN8J)N5S6=lC;T_6*K_(q|xy;-xo9BjMD+I{{k z%UBA}`jnu=;GY~F5aufZAD8q$f)D_8q$&0-KFFZJw$+b0B=rdOt`vS2vO2LIY3sxE zE;KAAIu{@A%E*dvgBIDFXOLdTuZjbw_MppcITqGSbp2*j{2#;Wo_zscKQGqv?_Y9@ zou>i>kzW8={4~OEQ8{<|b&%h_R}b%-@?v!&M+gE?aAD@+XtS|k_=*1J=m<}1m%d?G zE#oOCh4tyXSRobDOWQXb|IN|SPx^mybVxH#&Vab3SCDF?2k;e<;17ONa$!<{p>iLh z=EnKwQMUY({GX?wq4=(0W9p}!Hg*E^>yg3Y{O$$xP7NFQb)yrjYV->!td!>dj?=mc zN`?$$N0_0nFLu69$bPo5O@it;H!wRL!?xPdX0>!4-8XpHht-a;8%m^89mwpB3aZ*b zz|1X|sop<$snBTU&ii|5b0P7#sqpDnNLRqw%9iHWKf819&E9AB!2Te^za5Y8`Jbu3 za^?<}ZdU&V8~*Fje~y3uCpusb&~VV8)uJ_v2(9?q=c7dd7edcM)LB(;*`*+DUJhIX zWN((%BR{_{Pd^gA_M22TW$OrfytBUZ{*$JI0unBoZ7gHa;Je*;;=jGoc*Fg1BG}6Z z>;&T(RA%g?)<`sCQ(>ypz!U!m9*9SOiuAL++g4uIs4Q0Q2BzxaXcOTWO*wGo$vStLbagX*W|szDOrz8C{b(B< zo%XvxFhhYVEg4}~wu?O4QMch1>|cf9{qc=(jpI{cm661K_*?-axLJJtNb~ZfoKn*) zVhOa&rTDathf<_$ECP6hm$JjyEkkmH9%zHus*eR20~{*lO#@1Vgn07!co(uUBMWe@ znw+$&O05+q(OnCJySBE3re)E{ZczP524+H7aGhkABLp&%t*v#{)hy8A6XnnKJoDR> z#9>NM?s{I*BKVjCdR$byR#nI0wl879K2m70tm%{*ODAlhq4r@k*H*T*8j?L!+BEJ?DXC6YKlWZ)nva|x z4966_NQ+O?T1>`qmWV6YDw124rxMtbJmvcr|KBR>%>2a)6SvAVv4&mZhBdW(mP1*|*k2>50 zEU6Uc3cNnwci=o75hQ)Xiv7dDonv?gS@rN**p}EDykl%+xe#sI5{xeM&fqZIvvs7s zC7s&aBAB+(ZfrqO6n4$9p!Hz(Nd`aNQAmly(L|%A@%P-+Suc{4HgFP{qBzSlX|Q!! z!&D&Gmo?#jaD*4CL+4FZW@sIESKpbZ^DP}?$Ecr7u`Y#q>WT%bPBg6qU)(>hy3lsD z8S`}wbk3tgYu+JTp)AS{b!|j`$lESK2kxDZ-1QdRxw3T8?(xLTdGvFJF`<(dd#%18@k5{s>CdT5Xipz{p>?C?J|3)xvh6f0H=dG33#ao3bs5|w&N`#~@iEpuNL zM41m{qGY8~-wlu{1qJ4$H-<>*)Qpf^d{}WPGav|)UO%VNh;!~Xi-T<>CylN|1YP9j z`;oH~W~ZziLQQinqWeLCKQ{0RLsmfca#;3FGJaW_uz&@RIx@l7F$V z%jflfnrnlA-|)B->nYG?vYwBWfL4SAil1B8p0rMdFQ_q z+T~2}k6g_psMQyf_1WwV13e4ndJJOnNUMnkX-mvXn)`0L8hUVA8oSF;|Ksb7cGz_v z1YBL#lX|`Wgn7MCGC<@6W?sVw#*O&91I(3s;4Bpr86G>?-oP%XFi5z}FAQ)et)y(r z*}OIDjO_d>ZS(X9FO8P@3goDS=d=rX8Yw8a)Vr1w|M=wxKTc1lOgC&ral$>F6VfhE z#LxAQo(~dBTJj$06#J96Z-DQrIB4P?brOxhQp(#SeDQ;>$s2#cmgnK*i@88^il0pgd?=k` zX)t<-Vq34*UuWuV0Jx!6_(K+X zt`F9nd5Rbo`g0=qe+1U?M=@0rAC$%TNzk!YL3`6Hel$Nd{ zI>y~sJk+|?G$uDy5Jf*yy?{~(Z5Dh+TnSIdDp9oaFv@z zuUuW&xkTojC>_>X0N(yt0j{PYB$uj&T^^R?S@o!53{m9wR=E-QEU_A3{2f#xj^0~4Ph2KVoxr-xs`WIL(R(yF92v@D35?u8S(*-{oPk800Drem$k*lJ4V z`3GzO;w_RbYV2{E*3IuIUxoriRo6~a#qT++ftX%teF+K>Haj6$SdL$HmX&&AWebxlTW z5m3YR**9?vr)>)dvqs`O5MD!ru)kZ6Uobl*HJ759Ib`!5r}FL0tzD>&qo#ImE8I0D z!$z4pM-mD{lV;xZ_Le}?Z#pd2aTDPCp=EVEDLRp$%oMG7#v3bjX+QoMfVD-=eW7Gw zog*Fp;c28m$iIfVNL9PbV1Zo&cbzy^iz*te4<}P!l5(>Q7w-Al^eFq zU!O&nO`SOfMpNZ0F07@6%zi`)xc1&~brY};6BRZD4YC!%`GXqi#do*sPQiQxOBDNF zktwSRr2&8dXSxF4w4C)>@Q_brC}^Lu6Pm4I#$Q+yjA5U2kli9H3U4MLwG#w)rBm~e z)p37N!`E~$78xI#-L#U2IZP|(8=On{g1V{x9am<9G= z+yti$R-t8k!t+S?TW;uL|58o<{mn^ArGJc7f98oSII!H zi3FfuKM|&v4tf!XR3+YCH~yK##@&|q!y1V5LWcIUu)PvvCx2N3?P>MzB=%Vtf4^Qg zb_=cnSbjD=P=gavFii#`_ByGYU9Qm?(W<;30n@^Lf80<$(c_nhLGR+8z(#hl} zKGRSCum<4YvWCe2&vLBj`mgI>b#+SX!xv2xJ3z6)jAMM(2_7CTQq5+SjBZ$MgA6_x zX+BwA1RAWLB>U$yh3GSir6=^_w*5u1jP8a^@neNlbD7X2`7lOPL`16LujXDKZ-Otd z>en3B#3>8Ud|U>Bsl;q<*Xg(Go0n|I?#K-m6NrJX)0Hg$qw#Z5t*y}wa?^f{hOF@|q2#1;6JN#V3I2M&XPG7?b!Hq+mj=F9 zfAr)Iyds@O?V&%RKp^>poi!?56+ic}qz^7-60W|@=3S;0o8P+xPinp!pJ%y1!if5!gS%kDSCRx}0^^rb(@KH__OwB}e|8K*dp8Zc zMd{QY@CHue!WPf9gj8M(6iJ^;9y>5^VDu9?ao*$4q_ovM(kKGV4*qy6MF%t-Sa1dE z!hAi8`3M1gT<6&D*DRS%hRDOUHBf2=gs^OO7^^P&9kDiWyRtYfFpH@+y)pKy*CVkV zCGgMS3N}~U(n*-I_15HaDfZHq8~4AKt8rfTX>mNDHksVTM-?_H^VZ61Uafp;ZHiko zjggSyOZt9|Z)J~bMX8h{PcI;2_HB+IA&fGkWvkJa zkRtGmrJDSpe#@s>#YzsjsLZNCq$iB~pkj}P+YsQr`k|fY5iuLbsc1S{r#VPqquy3= z5a1VWhq_Eq!SDDZ$fl^9q+m}tuvrtY+ODhuYBAIu>^7{gSAhBCoGhW{nyuUIg`w~% zEvELs8L$vmr=M$RczSfSVV;$@87Fn>FFV?Lhh`|m0v*v*Sds2w+|ndK zXbxVNSbW;a^E}R@d!vD|Sz&A8ng|p|4M<+&);O`u? zQ=uaUzc68Z8DFXPTF-WVWYZPH>HZ5zkR;;pP49AHB4d9*=BBn7HTLusIzYpPt%LDS zgk@!26t5Hpr>2lcqflbd`PqQHuJt)BMZ|-qO=FrS)l*&$CP|x*oJUsq@jk2Uj;^EG z@f+St2!T)UoW9a4G%Ba|sE&%PDnv;g z_bxcg)K~>wdvIu`9z9Azcjh*Xyil^nSXZ~2$Irj3(2^lL9K^VM@8x+r11RF;PVAn< z{+51j&k)3C<*wOVhwoyk@q4GcxmVqos~6MywG#IVAWG{yG8nHk*iLfAjW4zmvgsA?_Y zTJ7t&a%aTQXv*}%o&oO~^IRaGe^FUHEE)!nI>Y8D$$;sVv;`I9OQ^8bM+~>2(yN&u z(>th7v^Z}e-Vy#>cEZ%uQ1nvi>Q@)kM1)WACq6Zn3@b$RIMpT^^_{C#lyV3jR~ z{z%5N+ZoRg;}zHfLSc|AFn@5>3F4VUAr?x6c5M<_d5PtKDP?gAYt$jo)hlm!Md^e$ zI#h=y^ZGX+gMd@xsNMMQh8WD=hbFi z)Z@F3SVcwGBW;}r5XUQ_lb5 z?X6<#TDEP`#4&r?F*7qW+c7gUGcz;BG|kM+cFfG|X=Y|-W{M$xd#!V}j_%df`grf{ z`!h!Ml7=)snp$x8GP3-P#hT{{_wSz!Qh-+jEzJf;!z3R@yAlF>;Z(Y*oI%{IF%`ykd-KoNwDa8l7 zM~c;Vlphl<>QlRqKCky&4}WY@ZY3U0GJm{M1Mg=z5$%y+@GJM-%Z(B%@o_Xwa)r9a+wiFl~9T(%QqD zCu6fPacD!Ol)t}oEWU&lMy64XLB~a=(Rg4w`V>-5*ZJm`s%4(1`w>GkQ^|Y#tqAHC zy+%$O_^eZ9!Ej7?UXxDQ+2%cbU)Uj?lIK?cEie(HKVdx2pWAQc>{Gjfa#XtQ7t1d& zaTbRcL1C4SQIBQfOT@2dR8XB5oNb7dAe>6Ndm?Z3aQt7@I?o`hGbNZWUleiv6W22T z?ZF8;IM`Sk8~z&FMwPcq&* z#@<>QmlJ#`r1KH9s^;~Sv8q$X1*<_3?;_hFoz9v!*%r$fA%=wZ z6E{DND%}AlEYy2k$5(Y*_byKXQgk3@MCplG0jfP@f+6MBv+OAom&$dd__)aJhPvN- z;I3_(JnlUYpbZ=AxQ}tKx4$-8Fp7Jmu$NIo4qoiMJE11Ama4GI?qaYVop)t7K6lF7 zfL<0Fl=-Jst6WJ4vQT6-Z2%r_8LRnC=wOH3253kh%v#czbhqio7-9)5YmS=6T6Q7j zFtOIg+A2ULJ^cMgWP862QK#7v>X~-K^yOxI6mLU3Tq_t^xPcBoe(pvKP~l%%AdTTw zl{1v6frH%OUH86cs9<$7S77C8vd(6>o zhO>+CS*hI83Bl$&`aUId0L+nLgyckAmT48sgY%D9X82cGd+oI8c_O&<pt6bL)vg?=KE z2T;YPWQa&@;id6r2oRRBZf$T$(oc|dxkEyuS2T;R&xL;XQ2+-(_`j%7qial}jurZ8 zA=#u9srGSr7i!&>GVV|Be^yg{#&^8sNs4t63?9t*+|~23^>*R>u}^dTWhI!OYQ%7* zOdQnxp%W`Ao4d7qeSVCjugi)XBW6Y05L(S`l+n##@bKzY^=;RH6Z?Qjzrysh1`8K} z)sD_m5MSpG>x5;+EO4%vSV}Tlh!pO~vS(d>+GJExGJIALpJpb~IvS_GJ+rbkGvZ)x zfSVy(bIRR9yG^f*gL}}2C+za;*!QxtCZccN@Iky$W8)yolR{E2`}dneErTFdtSH^& zgX53t?^Y$~2zPw?4L!0t3Gcp=c+fRg%m#vXrzK33wrdyi{VEVoR&Q+j5|IyY+=XHe zU`G#})mCs=c9z!S^0M06z5416pzXCe<>j@l8DYH>$E?1XEh1|-K!|rCsa7QV5jaQ| zf3}VFcA+w3;A}z2kq?593a<2I62SU{udFbOD4c~a=?`^;nFq+=gJ8f=!%ic8>xD#Y zVn%3)2;anDGimj}96y}NW`gwSg?skEU!p;2w6}Jkc8yd3yH zUC)*cXmbVM@AIKmsr{L6N1ak!H)~0HY1d0q*L2PQU?qI8o-K# zq%F=nJ(I8$x?i*&--VX zyMTo`rKMixA1*6l!HcrhgOtRdo*a;Sws(qO+4uM$GBHb3&C#BXSwI(l_}0fn^;We+ z1E6{UA75Yl>UxkBNpZ+8456ne_H+$}VvVXU@6(QQpNK!xVK($g5$a{XhRh{ptP9dY z8(;(LPUcH6(e45r#xejbPm$f@wT5>>iW!kQhLlN2bCvL8{S|pR=$VP4#v>R)Yj~2F z4U&VxY2yk7-yMAQv&Bj?pxG!BmZ1{_KYZzQe&wYL@7>!{H%Ct2SA7$cAvj@u`Fh)` zDGH~Bg|67Cz*!8TRKD1hYa}E@uigbD9sfZC{C{S^P+B~@)i+e|K}_LhpFl4F#ZFjM^e5Qb+Yte z*9$L5|2iWfOK_12-JIEv0rV=#fFMfoy*w?%TZHtv>;xlS)xar|u~mW&0ur>bz}sZp z8--u1t}7jV;KV#nt)?;@7r{vEhE%#?Ay*@g#u345e!C~n(F_%&QLw`V9KL!H>iUAd z2TQ3rR-dds=!a{dVL_4c<7ok*c#H+~o2s$4QII2YaU1o{dt;=;Aguh6RW{-G!7M}A zf=^c6SqC{Azv0?smST%(HGd=pOBNAA%)aAefNOO z`fpa)%8jUfg1s;-`BTLW|!S{ojXDi##skk-OS=VVqiI!So!h=1xS-_qeKJ1}?H zU^Yx=$LaOq06Od3_EAmnn#7MmX)=av-y{Dw~o`Q13(huUvk zaW9TPLWfE%zU3VkT^(Q?vh4b`cuyfkC|y|pt1zhrMz{guy)d$Ex-1;SSTUmLuU;)G z1*D}u@dbRX-70sFE(uC7^W>IyX7+=;wms|(v_b=OvEKI1L(soskdBls)%MyafbU7d z1V-XbZ$r_evq@^9NeD)5aIaciMF^rE4ytw-+d;B{?354_Rd;f*hLG7WA|%~k#m{!N zv5eY+cwLqfYq$0;6iKHKdLo6-wn=#6EV{3!7rhC8Ar9q4GDu4*Y_p=B|3cM^U|`LIZd);xA;W z-*|>m*6~cGV++~yZGPg`#tKrpBg~F7>Y6~`2J*Vjc*BI!@6^uJCb8NewO7f`-w6Ke zA6f;)ZqbZbh3u;nIIofK^^MuKKxR6^Y<|*8{y)8R#7VMSc0rAKYgZQP!OW+cVlMYL z;N2n-D|#+J3~5qmmhxka;2+e2w`s2#yNQD|fcGyFe^~H7h3bC0M;!S}l$6UJF`9b7 z%JamX2g96ZN&j{v4^O1X{h*0v=a7_E1?5+{Sg0Z&SD2XlqIxS~y4n57r2I?-7Lq&u z^5f#f!Nuj+<>iRL7#hEI#O~se{8Unkae1wYjTfA2=!|+;XvFi%p5ltp?2+}t?GC%n zL1>ke22-rkbMv8}99JVsO`hYe#}28ar87b~qATi9zxhUCBpLiu2s(;+M;rk(8Pl5s z4suj8P97+rmbH>sI#Z_#aLO`zMJc_aoI5|13;S&J0;gzCfnGuC+!CdggWsp)Ntx!9 zq!COtGG)$?9$_@-2)E_ny+EQhg_Jt!On^5))2%V|o@b?VAGlSxkIua@HnZFRzUnBSbQPR^Hu#oaz@0IVL%;~3nVnwefv9yWAYqpb0 z)>kaA^R^nu+Nsq##B_xe?BU=G)+qRa2oueVB~iT@Wx_#rFOu-xPG+x!*oFHW48J!@ z!nQf-?RH$SAHmo@!HqZ;ca)mf-S&U03Py)39Q`Z2S||D^chmhp(GE{}*+rYF=Hh&hFw?E^-qwI0w+w66d-D2Rl`FNy-r&G{TUDKM z6cuF^wjV+?ZAEda6ny*SEe7e@osKWkRb0izAh(d}wDz-ugJz8U$`bUAS~V}`7loZc zh&iSHS9fyatV_)&^^_S!gp-U)Y})M49n}UGp(On*yLW1ZZJ`&hF~hpLn7YF0Glb%m zs6vw($!|p*zNp3UyI9q$ihBA~?^V{>EggH95vUlua2z_brxapd0YWTUOlu{!uW*3) zvQt-}MGR}~4lezGLk^KUu2vVc7dE|7m|=lVm8rUVWQdMil>+^u)1g$i7?tX|=@K+1 zy(MN+0Y*d#os@0`{RW$!z4EIrH8-Svjq`HS`Oc97dEOrn>IvTunCj{hS^AboA;IX* zE?S#ir@*R_%}OcIymTz1)_6#k@mm(H+x+}_Vc1RtFqLuY=GfmzO~FgBDJT6@zx?99 zhxrHOHK07eaANHlP59KrS6;WaLH!mGg5u1g`t=m8nP4vcbMi2lO{dS-YCQc@79v~l zEXojh+1Mj=S0wwFA?!ThHsyw^E5h}Tw+_46DwieRRZS3rTI1Lw ze1deWQmNb+x~nF3&YZ(H?%4-~x%Vpt&Bw|o6qcy9(VdbBBH(J_e4cpWTHy zHXZg^6s(tb9=E2^8+jJ3$6&!BRhS~dC*nhnw%IrSHlj$TPc+IFBKKf&3#+Fp zZs`H9p6mvX;-M>P?GZ#N9=4L{LBn|{PRu7^OdbD@X8%1e$t!qwfqv!b+Ta;wG#!uh zsBlzV#F$r#m<1_HyafhPk(E4YFtE}#;T3(4@pJ{A`{=7;J!(_i*4GHc1sP-`D{>e~ zf7w0qEwXI&(s^+aHtaHNUi4v&S8V!`t@1tz8Bmx!s^zqrWx-(+O#jG~I_X9u^*3jQmSP*p^P(l*)7 zQ&p0VUQ$bVo|N3ugTv0vey%ukv$lf@#Xqos<#jYS-&9P&{QYYT|EMFc`+Sis44xG% z!31gB^|WW#an@h=0YAR(5UY^^7zbQRODdf<-E~B3RFbJ%lGBtcxSG$}$j%OZW%VV~ zO^YvnRAR9W@1!K$YHf4Y9C!>S)`l7$bT^k%rI@KF%lzj1$_y~SEA}v=PfasUld~mS z5Snwz_RetvEuOjBp=LZRgGJBXc4{`U_3SzgAza#cq z1*s<=c@#X#TCKAI@z~W4XJaW- z-fSqIG0#3YrO4( z0S)q0%6M#^HJ^uw#&r9oF@(C5C95ohR%x}PfQYwwE2xTJn($jt3cYa8ZRW^Mjt<2&Be$_uo>HQ< zA2W{XGMQR-3d=%OtR(im(|QXf1?;aX9`%?yul6z&Lb ziMZ$;=L5{ACfM2DNvxsf*omrfLZ!Pt)Q~urLbW41!9wITK{>8=Gc>kk)cwcN57n!R zlqR{k^si@B8FeA`TcN zNdabo?M4LMy{X7jm!x>Oh~6YK3MJ*jEP%0;OxIa2HBkyXWi}zJ5~wAK@;BOWhaznV zm$v0a2hZ^>j3lZk!40CoKlPIB(hsUJRhd6q0ms?EihC|)2e-TiW-<*@7Mqd+TV9(a zul1hB_Ob_u<`w2;b!a^;+i0vOy^M^U4Dvvra$yw7L){_WtIoT}aj=00U%cGGf)IJC zc^Ikfm~H@xQ~BozqPZR;yRzYG%oL}1i)WnPUJxc)I?lH^3)Y{Az%smoMaHH=Vr=&% zV(q0Tdo7-sCUyxfs0YG5K^PO62tHW24)3*RGV(|*tXQ58jN7a`|6 z+OtKrmpXS>+vApeKxbeiNs;7^b;1+Qh=&NSPb8BMhC(Ew88k&6C=cm6qYQlE+U>zL zK&!8BYn0-b9W)k##-E(v_xx{?nY92GgI&K`XEMfM8Ef=tD|{PHTvy(oI0lU6GQ6ye zuYYS9q14bi>p*<@68Vp9PM3&_pUJ!QgfJkx*J99eWfsQaxj z$~}d=Y6!~5GV`>{na6x8oyGn6xW<0_Yvq1;021V`SpFuO9WvGWk2@QAi4N=#LsAao z$C&z$;Erp&9!rk>`C2qFI;53oudWV;1izwO>hJF*d*K9<9dE~-3QTc^BY5}pE#K&W zc$a$0BtZ^g-hG_uiA!w(z(E>wPy7AG3C94zZAhfiQ~F1pD*;Pd9$)mbUQs=|BVMyBZ${mFNPpiP~(mA@`P z!q!Yv>5^J?&Nz?I)cXync!yY?nqymbrTYk-nGnojj&#z^?sw736|8OlYhJh{jD3;3MzXecetmRKz0Ts%^ytY_PBd* zJ$79GIqoO>l6m9JPy!PS3QzMNfG$N&;osojAzw!9bU}8W41>% zuMvbBc3x&Uj%ajGI@*G!M-cf?N)@UcUS#(>`o_USqUAwj;N-aleEopz@p^hiz)zb3 zL~BF}O5rL}u!S*Ov4Ou_7I*PiiT(c4fow(^dmOquRJ9I6g2CqY)V#O|CDhmcBw+5K zZf&n#+vV&|xUfEpWpRB0&&t}!;pXzd-Hm+60ewNZZ`NCjdbAAXeC{w&J5h^&Iade* z2D!?}!@r(Sd=-}w9H1C#n48+pB9DKmipxXprmfU1Nyc6(bcsub6(L4fL|XBHzkpcE z9Hqy&2y$dGbsF>)6A^e|tQi>%E7ggxMc68%Xvn9mU6E;~g5-({qKT=nDCnyOIr%0<%X2iy!beTpA;kv|#H>eazhAnlN z+>0ELPP8WS`HZDjx`n|8ZWfA6jZCY&#q&L~g$w1|_`)U9;p!_BeiBF;C9yP2XQ&FEqNFeB=3dkzhf-rvQZn;90no9OPqwK~Y)e<); zR-3iaD79B;2o6L=5m)b9SGAVhvq@2g>eB*rbAh%%-9SE-$5~BcIM-5Y#qFpYhVyE; zdTp~@iL^@*v|2lgA^-j1|`ce5NT(?xIaTSe9GO=kJQQ7QW&i^}|G7%;t6a>%m>_%+@AFw1-t6c>IR zLd8hY!E}b(hzxb9d<#;>m{Kp`Dx~cbu#CU-yl8 zLCun>xCqvqQEw{<7rVo&@Gy1nu!ypYzqtF_zjFk@9g8m|{;2jE4Tdk2DT8875;n%d zm&yb&^P1*42%DN|m0FcJS>JiWe;++aF5Y$v>Mj3FR7$_*?0{{Vw5AuY&)_Z3SEN?4 zY&qw3hqiHEt_)JQn84?)-i`DSGDzeRo7|TQ!;puy=~nvDz_V8&%|-b!8d~!7_a2Y?xv4F6)%k<5AL1XYZJe8SOZ0l_^T)8gV$iMQd2@_%;2% zxRJO2qHGEyyC#}MEo7PuzGfd43hXGz)@CG%Aa26HY`4f~|FR*~Imk^_&VFpqLqtzE zNL=ixgz## zv?zYS>+azT<&e;CvP5^iEm>ihYiZ}J@fYJz^<}iQ{3+amMbDJ>T;YsWUM0qBQvKiR zj+Qug!f)Ve+abfB00BoiuX}_wGyi{ z#MZLf7LvTg90-p@-0aS9UfDR)9(UK~)$k64`yus0O#Pi#tb%}oULG-oqAo3_I~`Dr z%$G?Oty7VtQ6@64s}U$~1eL5Ig9)ZG8^qns5b*M)q4U>q<`5vpe=nQ0WZWHHwtHE@ z7nQCPaEGy1V~d&%CUvPWX{r+A%?r%Ae^D7xXMy|x^mh{nJ|mBjb}7EK^X3#KIc*Gn zHmbJFcJw+gd{A!l$`kmf%Khe3+l8>{i(GiX%+M@z+e5qPuV~FY-sG&N&8gW~IqcOd zrri>RnQNCq_5DfLc-3P<)#)<^GN=nBePbEwmX{#2AR1m#6<5qNRaYwB_E#%Xnp%^<|(a7mD$8t`loZflmbThfU8VaHFl}_#1`VYRBU$;H_i-))U*2 z+2-<*8?1{s3GaJ{!v7q(d1v|d${JJO#pl- zWBqVC&BZSbD!`bBn`@}yc`(c=<*N0|cH8hr-{!=>!&L{bH}GA*Z4XqR5ROlqj+P>$ z9th0JlLcw_bzCzZT;>(S5;1T=`@~Wiz;$jawzASWfLRp)iLIO)=_f5d!2EjA+a0owLa$^|W3R$G9@2*f8uJ+C_Lg;`$kh-@{PYqsX zggbPC!@cs)gQ|-73sczR#7<|^1mt(fVYoOG|88@D(>#s?Xnpp+VZpO zzoqoV_p9lNVZVIQ`p5b~@c)mF>%WC4{#uK;+S+>l>q8gQztkqAE$vJgMBV<6`~U6J zs%tBwilhEngMdsy8ZAeR%Oe)kpf41g6eT6*P(+tNUm_G^nP4B^xdKc~5FZ$^TG^4S zdX5Ool;6SmFs4yTQm5368vBX+2~j7{ckS2rDh*ImOQ6mBdQE-!IKN&He7@g7_aga} z8Nh*5L2{N28#gxMEab>qf!bQ7*;1=&q31dUx(oBs;~z(@>{oh{gUW7M6iq8PH#SM$ z(lkH3+6M7{P(ACOs#xWK|H#=(abIfO(|Weqa)y8am@25K#T+jXi09}>Br`skr(r1 zM{*gl}b`e-Y1^gYN~_h-79wE8V=cIW#Nl&@Y{AlOjwhM1U%Fd0k}w zuSs)D3ytjP?nUwFI^+aD!H~c`qaEZ=-=fuX|D}m6wE{op(rr@>@_rNWCWFNVf;%=f2=R!MdMhKOzDD{N`K5ZH%e?X z=HAZ{gU`8kIyRi+4~%=L_R#=zJxMYooz3|gILO-^(}!I_JJl7U1B&KHzl8ClJQ(uE4zS zVST63QPe@&pkhwwG*b`>UC>4%gB4er02gUf4V(aHhJ>Sg|P7xR6<-yM`BfPFAYx7@otU*#};Q5c_TKm&jDmZs>KBlF*X$?AN^rdA@TYAsiKip~xCjoew~i=C>x$->zdFZW(&DgV z4zXWJYq(-TGjAlWdR31I+L#n;`S?_ii0Z` zkMUnd)bq`%-lc=W~bz2q(#kTdEzm5dSCUM zAfr_&UeI$I7%H2!h83C-z`q*NACkWJ6S&9bAEF4hz!zyF9nk@6$AatUmHl9QZ1KZ0 ztljwMAGrLiN@Nh9fOU8eb=Yf! zOGFP`Phd2V`dj{3sK*~ZD^g8u#PZ|=JIO0Lz-6*YHtBh!&||_z&AXV3!B@7~*+7Vk zm>6{WJbG@e#-AUvZ=5$l4|(x9iG<K^P!Jvit2dRoC#M>zt&UY7?Y5S#LJWRV24k&DcG>jiqwcx-c zE*wY9L&Vm&@4ClL<;hc20<(wc2<(sKbdA9;#c({*`y>WlNhXD*g;M<#3x|pq%#<@f zS;((!<4TA9tu_`$19T?+P#eO@7zT!84|;CDvED}dsI$RjK43-$6YMD6e~a1{H0;~# z)lF{@E7SUU2KmEY39|*-hM*8RSF*vIS*jkQJOM#rn@~U|AxOLE+n|Aep;A7UK&ycn zC^w;c<4L#7`V}h`>nbmUodpnUcyL=rI9zH^neBeU@{*GGjQ9J_H%8u7Gxv;gMYFy$ z`@N0WH)A|Sv@`R0UZi$S7zo#P8BosH;arRMEx%)e>*@czb>jL@Z%lkie z1qc1#J0<_=kla+iR>l#<{9CT6xR{!5N$p(_4(5USFA-W|@CZZ!WTkwoqgIudUn zLxjsH)#2}c=lXjXl`N*^EC{*WG5*S>`yJk)f=)puP^;$>G+?sWj5kC}NVHd{RGyLqgG}MQYqzwCf~F~t22Y{7wgjxTz#I2nbSXEJL~ zw0C>hXqoxG)IYkia?Dzpd!_?pXI-+@E6(V|*H?B1H+PeZC5%?0*SCf1a3|`GpdFcEl)(B;4D>o^31(vYIBnJb4m7WFrYNn- z%-Whzcge3b4tv`%^rlW5CkQfJyZWx-$!3$v)6C67qdoc1M5-aynH~3asS%MAyexfn zG~&{VRiA<@DRz$*)FO^bae5I$?tt=Znztz{x6DL*g!Xw$*}a+d-0GLnWUSqrMYF z3n9{&5k_(OWlq##Bz-f=M_0@oqlQejQl)_H1-gyh;_folGTg8`x#!)r#Yj3!y6Wv> z$5FX8IWZBmb2JonG@U*kkp?aK`@a0W^W3FOb|z{j+f3pdOfj5NL7a9Uanr=z;HccF zW+L}t%B|8y>jh#oFs+edLTk97$?t2ETKrUQ8AXBC60;W|U%Vtm#hE4lHwa{t6EZdl z{ON;(W|O3@&F`CoW|I3YN)fSWK4Fr;1;b)!L$QJ)tfLHxXrm~RkvFDS5L{T;P`6x> zQUh$sEsQT3a`sv?9p6!+A60@22HqI!B#Z8lmXPy1rR67ui?#w|s3c} zrV|=W+Rx`;8Vs66uRJl0ao(Ho1OqBN5_NQyr4X5^G5-u7X!HXFH4By`F&Joc^d z7JEwCe6#iEa`A`V1Ii-$syB)~(jn&7kigC{MZuQXr3CLSIEHpD;~gp<36FtxPe9cW z3TPd(8()$)1o=90CT_gyB+>>cPj#-9@VIi`Cz91V20tmh7w@mRMBWK&Y1e-#(>_XH zipV1(N5C7PUMEc6yUgGfT7#>T?WUNYgzt5kbK;PJqwJy~5+pwhi2L9yyE_Od z@)c0RO7Maw{@Qx{-|wy>d;Y!(MdLDV`T+jr%Qw`2B5C9Q07<+3&-&j*r$N>KDmn?% zNH2>n5ff4`#KPJtE>V9c$3#(%M~oDC3kYZ8)CK-kb-J*V_L&j+jG88m7=rSB7RS1# zm0c6@XlVbd?&M}RHJaWwpWD;z3soDujt#`rTkAG=4aWN&V0z73RT8H*`pm1(2OUH= zMvc^>pPCI^gnsU_o!&;TR;^LvK|^{Z{-}hd0=v@6*2|%@l3-5j=mgQFj+Zpeu8>i~ zg8--aua$IU_N{@2oK{?hPw1o6-xZdbkv5%+P&Umyl5r@NyQku4XOmDd#o#S4XXAU* z0#IduB69GUG(1YYmfrA4DzQEislJ&VuK1kg+YpIkxWFnw*eUeUERmTM?h?kTU0zV+ z*Ey`#FWH8{>&?)hiv*)C69dQwKzd2oLSv}yw6`#B{7rBaK95rexp22IuygwGvmIlY zWhmn_IMr2WNEKckbL)>f5o9%yG#~YN>pHnT-#d@JnjEV+tTW`%oBIobs-R5A)bpNk zRemqyRtH>pRqr-G_qErcJyf&D!LOKAcPsQo2kJ~T%MQPjk)!r7ExvSvfa;i2lxcY3 zTMu;`e#8&*%4*vS(HMsPihhm60WBv_%!s(B%(I|1D#m%0LmBr|#3oc1A$euD)K}P9 zIJjIx)b5=LLEfXv{yhfP%qkMubip>EVMqEQ3IjKFPjSWQYzCjeTeL)K+`T;_=1c-6 zEk2a!q8YCsgbT!bz(%6W57aSrf{sx?|smd)-%DwpaOImLsJW z@gW+I@Eb*GMO8W?OiN>Xk`M2Ye}VnArZrp#?8_G^$bSO6;eQtF|I=)Os*d-$X)|&` zjkkk)$8a!$Mo&X4K_2zYBTU^Lj zazupJj2bAejB@tVh%!EI=@{n4?S|}jJ2fHTW>FSGQ-VcRm>}%Dj&fHzzwG{69TH7m zBmBv`-N=g)&YWmcy(M`;eRlB_{)zP(0N(D+9Rx3E-@A@~VR_%g@w_5t$YUR`)-@{< z{IbW51e=p17xb?%R0zhMYBxBgY-y@BU;GWOMx)zKPJ~z(9CMjii*>6+Tv%v(H8$i7 zZW{>@bwfAG^8UVF9TlH9g50wc?pnqbq*DX z3s|8*4na0^SgJ^3e|S-Y6klAU2kwyz?e~MxCe+5|7ZQ5aU!`1UFrya+8|FYqs@Zq6 z6!zJR2f_{1L}5|x;?gGW?$H2E0S)h@^4`RA6aSl=Sh$+W|Jf{5LjdE<-s-<)MsLaRg0+>X2~SutM3@{K7X`*iCE?S5m)6M5=}5Zw4y-xy#EVIya<5j2eT$8r7O6gL5b+F0A2S(X9xO7)!7c@%0g(Qk8g?92S> zxsi;OA<4;#?}6-cc0Kn^&>`)q;>>WimV_$kqx0(nG4irnbZ;G$QfJh zh}}jw*uh37g=utyZn8&9w(gfBeu)y*w85^(<3~P4(`;uZ%-&R%B>se9k|bDS#TeI! zs~QxzntR0gL$yy-_84V0)s%PC8M;OwWt^$@}=79)%J1XoxJgw5>l&8 z&ms`$ipg~};xCOavwDV?DL8GeCP9k6tCo{VCR5vB=GAXh_if}SC!g$|TZ?#*qEekHy~^*-ms!>52EMnx<;6jy&by^~c|@`0fGpPubn_DKy{M7+})b zPh4eEDpS2zvz1}sm@QhzlEy4wD!A|Vasw(YIsUP@dl0o;M^%$iW~s}$;rfzfz{Ia# zoGsEp%xQT&wvsv*i~XgJeptq_R84>5IP8NrFkM=`p5c;H?~giP6wj35DB~4x=%M-G zvHNUt;WvCju#=85S@!lHmukPyg!xec#mU z9(MI5)Fes04w8Qey;CeJM}%fe1V_%0XN&kgyI-!8j#Q6uV#TzgOG)CLP;qCDPULoY zMQH9LRe?D?XUMcIpTz!82O+h#0lOlw^rkV|2~VA9Gm?sLs^}&u%=~lWC!JiM(p0Ts%StVC-96w` z6A!e-ia^8uDI51W+DlS;qwrLJYg2p62{Y|%>|sbukZaP*qkO|q{4x^!`O1k8&Py{2 zBR{wfR6o@-sd!u`9gc^4xw7opZ~U^edS<$QB-CZ|HDXl=+Xy{Bi*D*>rO0dC@)_38 zz?-&iCl&fzA@obUtV6?OEsdl@;F1P>{IAKKwdB25RoFaYp7cKhQ#=W^UQL&K{8a>l z=bO@8Yl@w-vZQj+JGSGg(<_2BarDFGNgV14M!n5Qn*2JnKM!rbQ=fK6Tn<@j)tJVb zNod(N>=$e}1G8w!EW>(kNE0j2!VqZsU_Np8i;&t z8&aS{TmUlzX{1P_%N|-AcQLdn8@yH3+&q76n|&&O6SSyi$|>hhY?APtQe z$_)y}deYfG?)q{3gTnvgZJp&y=}j~N8{j@8Jrcd`C{0Zzb5w+7BMc#}Ez9y@bqVz` zA*OtC`0@0l(U&H5D%~)C#H!y7C~bSYsEa%(=*QnkW;g&n3dB zDUjbR;@zc=g*yzWv@{VL5d%8-3@#QKpNaw5p@t}ijYxdMF+nL`=WFp69h9t^d%sx} zl&P)&;OpYU2l`a>eTY*`7^_uR8w6rg7U4HfO>dgqi!iOApqak-f8p88YvDGdX(Ip= zjttaYnN--`4{vO#`QCf;S{9=cSER4JBTo3!;7gUA1O%%kVx%o>AavN4AcXcUtgx~U z$BP6J$7GeGD>qG{t(6sfu~s|g_$Z=}1%{d{Bda>|km_a`VKAiARQh7LG(6T-6vI&) zQDSRXSD_O2V2KCS{GWo6of7~k@u`W*$vIAX+T%ylPFk~-Xq(#1+{O~^kL!~XBw0Z0 zJwz#?4q@e0OnC`+a3bgBFcq*b;%J-J!Fu-6xr7v!$Xu-S7&^z$u0cpOg+LRbeVm2dMY%fzx=AO@&?2!BMYHQ7 z_K0JiCiM%}{DcV?nsEHfNu$;M$*+xSGf8L0GIPKpmBzvJwyN@mvZ~b+GS_tebnLy$ ztG>Z%+92D!#CboTwje(wCaUBD(mWQGNdq8se7Z-vPnGw!M1&}kiW9g`1Tb8QjRd^0 zhlK`8w@xS+&;91tRh$${M{P%j6=Re-RL*X06O`ee>8{HoxMp-wo#4@*Y27%&n_Ia{ zqdkNJ3{%e^h8T&o&@tD*uw5r_g z0If5{-&{@g;&$5upJzo=gIW=U(gM$hp#a*;c5009(e=aj$i$n(Jk&@5xaBnMhsOup z9W?x2Qq@wY`Kifgn%AlfL~I7=&VDE7e`!htdd^tFPLwyRi=P@2?gAjl@2(~(Q-3Yg zbn$g@A|}3^(N>e}i}ewrM39k9R@C^lcl-!MuoG*fEK@=wW82nj#`*sc_m)9%E!w(vLLgY<(m280-5r9vyF0-h60C8z z;Ly0cLkKh)+@0XA0fNI#vi3gb9$Qu4SGDi?Is5Od8e={^o_7o`J!2a!{v8KRPgM1X z$qmRJcy7%=m1|YEBf;zF^jc|(UJI`)cbICO_K~qRZDX86boNW)dNEbjp(H=_SYe*}P;gR@M4)@+0BlSaVn^m$1E316<@Db0dRNNg+h$36I@jl_Gm> z24%8}xoPs7JKpL$z=g-AN6pYVvSG^|je%d3fOAVTXNMy4&HR&y>36bYX@xn#p66{- zf?MfLq69qK1E1jIFtD`V7uPogDdn3v{_37>j0vMA#pnksmzdR3G0%a&K7q+9p)8eS z9qQVpNZDlpAvJHNWbS5Cvxy~AL%ox9BrBO#Zfl@5n2N`wQTz0N3gh6m(&Jr=ACU@? z)oFOv$hC}NAj_QTZKyWrR)mlmHw9yich8aPF^R!#$ahenjU{~K*v?saXcAA)BkUP> zG=uNd+-GYEMnu_?4HHV@(Vz}B-To?5;lge^WtR@dipK5P4Ke-@*qN zL(z=iL!AIG91bvf4_qkFyaH{dve*0lW@ZJ?1>#uv$n#(%9Hws&owtzP*BRY6v(=Ul z1C!8aNRe`b@?v9QXa8nz}%LCf`TxO(d zpCLv;*2Co-TO;UgwG82&N9|$wlGX`;^i7p^qVQbe6|8{ zVGg05fT7_pgY`p1P5|^TtFl_$b)3r;yrwx)!`Ige`FhYY~iOP|CIy|zA__sHrNNPY_bp+@5W zMyRmt)}n)?-yo1|QKToq!`*$)*Jal?b@A@0Z@dfYb3f47mBsELrck5xl&7i;C~FhG zeAr>C9V4LY&b7~YWPR_xw4lZ{Y^Vb>Oyj6Jy5~Gge}k;kR*{yj>8dB|z65x~lx- z_+0eVwvGPW1O(gy#8)WSaa3h%IhzC@V@&*H@{}wp}Qsgb=!#_=2EM zWcQ1V@z(%iH~U)IB^z;)d~FkB9OB zJ?*{rA=S^11+Mz{qZxQk`l-0<0?gk4yG})`UsJr@nh zRvvll(y4+YY2}}c^3s!&8#K6@t@Ju_+(V?5b3niMylP$`PttQu`!1+3KdpK%V@vks z7t;oY8XxYnTd}2_mAqrkjO(teI2n{@jJly7h_Q*U%O+^uEiU0)3V{3d?l(<<;dCtl z(3L`-O%QZyz!K!lBZ(A(N+XJ{E~kJ2j8-v!DR*tu|1qOO)1MiL!aN>lr5^Rlf?PIX zLjk{3IWr#aPA8K$D=gyU^F&--0Ve$>*?oF`D~h|(MH*rCEYXntY~jolE#<`%8FMLL z|HUnqwz4B^IUrT?2>N2UN9&U8ZK2Y1{|(q}Bnr2#CscOx6a#IWIHJAX1k0KirwQ*= zO%P?uP)iFqyX6OZu26My`(hP#_F(n2tr?61_}twtV$@>UxGWq6eo3(Kh=nu6cB~Cmn!Zg{a`Q>x>@Q?7@Y0CYexgo8vrS64W z3~?$-#T=v)liOFzOlY>QDZ}sooR!$<$h1QRp0_m!g++=t%C2>WH-|Yxe=zOM*@FeI ziJh3)JyPi%_I%rByOKW*5V(gqHn8(G0b+28ZH?#lg2dRjWw=0Mv2YU%)_QTabJm?O zIvi4%6r|^$DA~iNnhH4eGlbCtJKCumF+2j}lKhr|+E7t4Q=xgWI#o@cP@w zofzfdC`kvY1SuYb4efwjH;zZjK^0g$%_{g?!#(2cukIuTKnRdr=_lmuBn470V-KI5@a_}z<=Zk)mKy((Lf{s&*(@< zq@If$UB#$*53WP7)QH{~JIKx!(G0(cwX@&!kEQ2&5xfgQyB4wC(;JX#xj5L zgi*`(xf9)JrDK7Xz!f+?&rO7(Y@@=)tOqSW?h>44ToZ$vZhc`>X{uc7C)zke;L+li z%TF{^)-;NW6B9Ekj-Ef62OWgFtX6%GYY-u!TB=oG62N4Omj;dd4K=FrHp7*Eb#TJp z(8ilI0VhK0y=yPKofJnV4TtW!V1sh7#ui(HIC|p68&$E|q4xR1j$q)_M}i$UJ+cu$}~@!j(MYb*%qd zsnS|K>T>c{u{^!so{s>iO14u#}_yt+WK^ZR>kCNW%MZ*2;Y}yLR$_0Y_B~&CJR8Koc*NgHd~P@n@3mmF2Jb_ zd{{Axv^n*BdJWU*nUPoRuzLsY-{HLZESWN3Mq_Bkt&_t%j)l>jJz}Rf+HO8yy{tOi zceV*aJCC52I-~vEj|CD?6W{i2z0c;VRF8!MmE%i2auoi;iuAyn2`ON33p&*2fWy8A zfUXS}-RBU=#Vs!Qc!z|O>o8$t4y<9A{a(EGqpkqjUszEKOvckXnteyoXhei)ux~q5 zkDMKdpF6#sp=sZoF!dnZgNq=yJ=~nH2R1SE32AeBM|m-;ttZxh9VkMHNhhm<#)7mvbg>fTBd}W$ zcvIe^eXQQ2z74VKSN8@Z~DW zTBh71S*_NocJ!1I=jw~t6(-xWw<+Lkp52}qO?RJU8$Doj{D5oUaa1&QtR^_My$|Zo z4qeE~bnp%H8=SzGcXZQ#m(iy{G1LA4Z-7X6 z2a|`Dq@e>dmW%sjcJoQxDisI8_@N;A$1Ib8P@o|28m=))N3rHw1g1h;AuIWvjMpNJ zvDtQ=)dH41!c&w|<+)X|VRNJ$;*>)zHXO_%dW_JUa)}m=5Y(^uo~opoBrkY_ zLbW#x;p|d;!8zR%=x>>(EnVUFh0HG)y_ImRXS3OuEm&C z#|_;Gjktw{S6&8M?Lq7~=gT&{Ko$||z`N7M#^63kN8 zo!f5GSj!Sfsb{CU&M#p9C}0@wy8f1)Ha)_sSa52KCC|apUSh#NUlZvTp?lch%dWh{ zQJ4X;_nZcth(UNjg9J3u8<+}Glf!Wi2&7#%gvu(8Z?gbTt#YjGJnh-?4pl{ai3jpR z%qB+M<+)!_I`#Zdv*__HW^}#!tmj~>DxyOwfxp5L;!Fl*6zinvG=#9JZ zbDRR3xK*aGqjZ8yHjbV)lEkm=mPt6riK9{=qVjKe5E++F;cL}74h35r>Tt6$}%Hb(VARq9iRHXTHV6JrvVS9(knW*VGVJ=n=kMZllK-b&&3sGpUC zXZbTl18fFtOyAv5n{}Zxu5?%}b_;jl#qSr7J_O=xV(CHJq3hL9E|tYLT$OyLIVE8V z@=1F_jUR8B_vL<(1vP7C!bV+%{ct{G1Pb+VOnLl|Uu1zzUdlNWh*LQuhrUVv`&b># z(#Mv@d=+X0-l4N5Oj18zR5Eep#ci_|Bh2B4oZ|9P@W2@bZasov4*^6i-z@kYnN9+r zIRh?wGwS`|ozuM=9eA^397%d4ArQt_)X>eW(;GRG=``5TkGxGiH9?jxBlz}gqQQaW z8?gIZMBuWPc?-Xqn2Ztu=!lqw+AAmLYwB3Isl_0iB4fm)CFz0?c0Qj8F-;o{C*Dsr z$#QdHs|8f`Z86Ykl&ZVi7o$PCudk0ZVTb`joF;kCygD8&}b#fqi^J zJ|D)q$bd4t<|M8BWqqA*15dM_gusGY1HE2+m5)q}XfvEV-iRMCwsF?Fjg0oF0@p;I zw0yTU^&BAI7F1oMPXbOJk(-E!aaa5HqX!37sV@TH7+RNN0tS)c8)R{SJK1haAF|y? zCqqeJw@AH33cL~)%{WJTFC3RIo506{{t4PN2xq{j;1X(;nyMt)NCnEl2lRz{?IY+? zIl+iD3~GJL8QHbZ!^sqd%L92*C#4DNqr5O8#%n@Sq59A}$d6dj9U2bN?GGm#E5>(c zVmma^PTZ)&&*6L2D%X0NtA3TeWqGDtjaqDMu(9{A@V*bNJoa>GPXEn`Y2fZuWkW zh0NcQ#fN`Y85UDg|9!#dFRu8DuPE4+Q|_*hD?$@O(|>UV`CnYIvUb_gyw|a}UH$RJ z6FL`0h??4%8HulQ)DcooIEtfaBkf?V@6Kzln^ol!;O(TyMforioZ`q-I571SN70&0 zOpMLxl%eSgSMFe~<)mOI*VfU~%00q%l`ZlOOd;Ti>Izq1_CQ1BsEO4YW(PnhA;)YN zx@UWQfVCOamS5aDkhQw#q$%T}|2Bl3fY-(wkmzT-tAH;S*Ct=7QoGMdJm{vYTeq5I zPw_Bh26Frk-g6pfsVsPfgGYFLdKTrzR&i9vFh9-kL0r+?6Ey>8#@7vyy!r>_wx% zgRDA%W)>UW8du+^r5w01Lz7;U0Sfhlfx+nF9Ab-kIzPCeK_|5C>)N0n?uNYRG_D=Z zj%EG@f$l=Zq9V*;5$_J+@=MjfMue==()Nl{hXJkg?!NYjc1FZ$l>khb7#f=B>5o;F z!*lmfG|~DkKuCT?eGhC0&>o;Gahcs-&a0WQ)6XXKRAO+s61R?Vd1apuw8acn@=ORN zy4$VLU(+S7UQsvp!kbroCk|B1BVnntyQ zOclI}?5%6pNcumg1Tevgm^@BRg^E&^rlwnO!r=ogKWkMA@0d$z#5Fzo!mlP(A_b>+ zh38o&H?RdiuAsZXqoSGB-*gNA;UHJm) zJ$`4CEh;BMtR79Zz_ITLY3i3V&MF5JzfrTJkbkhR7D|+1IUW*v(1v0(4i}=3S+k{G zx{!f$0?^@rNt;C3)uPtf#lqz+UyPJF=ysI%@zkB(T9$4fz^Cf==Ih5NbJ2Px(wa_I zTn@iYHF-umF~CVId}LLh+%)srHQ%fe8x_F;{k1?j`vE!TyjpE?hcqr6mtNqIG1Vv&i|1rjxjhLz4p<@VE zJTDEjl|A4*^5(DHWYa6gDB+6{v|UiG2TYPi9Wk)Z(is3tK(xR3Xh!gd%>8Ud`w9e) z`L|YBSe%`i^kc2;=e1-x0sL1mOV^T6x)cXl`SqGC?W-$a20E#p5lCTY4Td*k2%I## zJpi!TM2QM!M2GQ|W!A6nnSz`Pboj?!+t597ZZ{``3pF`A!%Hjsy=@NQC7#gjRTWloevu;9zb;O1} zpeyJVdUCy}YE=NNUUqI zBS4G%yhK3^QrtPAs68yMvcX&XB&8TCO`4?9iNWV=1X%+^(^t5e14kbByBGb0L+Bfq zJkGh&KSabQiWaTY-KcFG3<`R_q+FA`5dp1kbhT~wPuyc9dC|XI<0b$vsvJ;x4@`T( zH}NYz#2C#=8s2=4y8RW>qKGPfa^K5QcO2=ejPa{v8ymIb^a9HYU#kJbP*u&0!r9-! z{X}V^adkn&C~`UFn@Ym}LgR+i6@>7}FryS2abPNkU0cdNUPMfj*}RYQC_eL$W_L$1 zUeuN;@8*eembg1=HjZUI4cpof)`;@Nj8YNFrzgrmyW2_+`p|0hMs4;Ugd}TPaHt+B0u!;X0O+H-sdG-AXe&P#R zTzdRM6U)Cv6Ni6wPy8<}aaHq!D!v54U+I+zS_T{2Cox3$E1d$J49rLpCA&}Wr_?6C z5v0m<53aJLA|6Kh9r1OAocXH$#U<(k7Z|t3yo4XyJwAWVgkysr`<%9Nx_WZCY?<>t zr}OErc}LHlu`9FPVN>a;^J*iZI#bFFdh<+yeR>mzs?%I)svCzNpS@iPelpWYpf%7_ zdvwpaUHf!Sr_JnJx^4rZ>KZxQjf>%lqg(SF3R$lsnGxrzyJzPG;pn8Co1nS6{Haxy zu`Xb>zO*%Yh5*v&8U%y#`?j6h3~WqOJp|FDt%she>f9ugB!NRFWmki6Y$40^_iejT z(Ti8wZYL4DC3@9|37!GK*}f3oAGjAu6@9U$WnbyqOppKMR+v`HG{$UqXn)T;^yL|B zHKa$|VvLj10nMW!7uE^&RC%dL!;Zzcyix-{0D0uNQR|orp_Ah^Q|O!qM?868qgSf{ z%gaSI2YpBF(So_ou&_@XQGtvX&#p@~w<@zM>k10X)GpqMO>TJ^reQuW#vVPzFUwYO z&e0px)u0{c0Tm#&S$XnaE5(W}U*zUV6d)&s=N7JD7nsnrW7A+jC76P;#UC^|NBw>_ zM1+a=A|f#Lf))~qF*z}=C{*}DmUV>Aq&@cwOrrcfrc0RZvh>hduhKaBa8h)RUekWA zi*v$*Fn=elr8yb=bJXtnLl1_AN6W6t)0bx<>BYpz6hXaiEu4G+gSvtUCJU$=-9wYx zX+1H`*qnGmNjx&bTJ~&>dVNFJ`h)7HHd|z)m;H zPE1IX^z6`Sj+oyw*+?fEYW(At-3sFulHmM8lDxW-lfe^)s2gfXjBUJgHbL42h8n)T znD6P_YHuGhx~3xryw1mSyU;>KoCY5uJ30vviApeeSqhK59=ptJ(1*z#jiIeZl_(S} z-%sRXnuCn>Nv@~rCwV`n%HYb^uV`9Ruo z7Pj`L7Q{~YCKhj3jnmeeiM}Gd>_SlN!(0_FZw^~8@JV=eMKc5)@SU*F|5CdCpkrP# zzG%xcNMlAi)Cpwl6r9H?=Rvq1Ao>E=8}YC|gk{sm^a%Ye7Uxj}nOAn+;m!n)X^3i5 zkuL{Dhs>13<{`h93Wp$v+l8?qbOY~K)n#>c)Q!I_;liul2+XV?241u^e2|_7{z{ktsC9nf5Yrghw1Z{f|meHqRGcX z;4Sw_L3#_USFdoyFj2mXmE7pf7CPa)pf=@Y% z19oK3%I~rhNMC*QAl}2f_zt~E6X5%3kH?US9^U`62FGY!*V<_C-)0?eEyUff<)d%a z+Q5pnQ&u3tV4#Rq>R+>t*&igPzq2YdKSH}5HWNRkX`qCX$H3&h6#uwS%ke;Yf&N{6 zi*~mpH-8Zc;olO8+rO&%s#<%SD_Z<@LEHU5JpZTj*{{)mpU=i-N+z8}o!BucWq2$o2&5U$a2ls5+45fAn!*=pXvj?{P=>h}rn{ zKdxubccBo!=8ie*pf+W8W6K|NS>`LoHfbs{3@_NU;rHQ4 z9Q+KQtwGh_ziYZ;V1K}pK6gwr{cTW$-Yq&-E+kq{5^1~|*GGA*#!oV1ex|{KT-~xN zA+I=?q|N$5v@=M|{XDbtHpK;aPGKPiFb_33d3DRH zgn+8puM_vBMd7pw{vrWDLE z*g2)(vo^K|$`>ZkaZ3ESyBUk@h>>IA2VfVE4#`ro?EGxVw71}p-SJjXJg;ylv^Yt! zE}6_@`C_yej2JvS+pu$Rv!(9pb%6&tNMIb{IJvo24r5 zKT*>W;Zk5d&KJ%qyoJY_s#lGi?45b<3tGpu;H1-o;Ym=>FK4!8Y`2ALR0=b8Ol)Ag z)qfi`;!vcC44+VxCg)O?MtWzXH|*>t?l3>4;3b2Xo>f1X)732Jbdxe&9}0)pp9_2g zh*qp|nAvQzCRgd{uLxwrF;ODd4wd)ePE}wdV61q9j5P1qmxZo=ni;6ju_=W~W&mI# zSb0Z@AbIgtEKS;NeJ8<&^IOpbmMSyIiT0xo|1grtbl!S@ph2c3w+8EtugIQr#se6n z*>6T;Xk^78pGFmdw$n7UBH5_je5FxXhd~E(eq5w{9!UNEjJhSt<6tD0m2@u)f!|2S zmJt8|a>d>sed~NDrWX*i<@!F%v>PR+0Jwb`vpI@T6c0YW;1MmDHuIn%)ysvruF;4P z9vw6K34Lp)EriX{DD&ym6bM#BdQ)%k`7f1cSRYke`uheecHDY09AMXTj#Ib9 z;9n8hq!cn7?jDosC&`>Ul=RNTwd}6aI`Md815r@~u{dt(!S@H5`-O6P9{mrd7GqO) z!ZHPZn(-i06Fx|egvt0O{lmv#-%TkruQCAc@2Q7n=PfAj>44>cgF*PjK3{Y%?;{MY z&rvT0VQ$km`zNr3uwF`OC4|%FATjpdykxOfQ*We{$^E34QD;#;zdV@2Kd386{;iEb zfB=e;2MX-=xsg|{0W$t}O)cqp0s&F!V^DuK1woj63R4~lr*>^HS*?%Ny*90Fk!2;c z0|}Y>OfD8vF4CK;i)B)eFd@IZ7RgMK;%}wuqN5MQ>sI^w)mHivOA6(}K-z;Io#;gL zJPi|St5n9wY)75oq99l95~))28E+^Kk4vLu=Q7Pe>ajXR(af>PvMMWyeP9DNVklxT zo!$nm6NXbr?6gDeE(**7s{;R9I>{EbPwP@B2B~nJ`}z9C+iU*e>=JyzIRO)_3OU6C zi{|2|k|`Iv`qEG#D*PhI?86O_aCq!|vh^;Q9Ods+UTY4!FI{6(O5X>X%FoEcx$WTY3yHNf1>>KJZQkC)EjEgNh$K(NuQc{#NU5-;QXl)TJ~Uij?S43T(}Yl zxr8;jvj?xnnhh($aB^(h+r0b96t|m&StDUR-RP^+yX52WIZWdk`c_cT(R4;y23qX| zJ)LsgOEi|Uy$=!X`dGI=l%a3Y!fOmMWyO_6l#U*rS?0JBonAZnQb|eT43Uf9P{j(` z1se8Ce{-_>Ux&av&nC>2egTK>-vWp0|AUtI-*voI&69t}4*7D-nYnw>KcRWu3`~jl zR(9_`7nDlSx#)2oG!E%^=$)G%Yj)km?*Gor&)|kC5)O1hgz~2^nlm86&OyeM0k~|5 z%ggP4{tw5OK8wp;29G~sKWY1JNTCFk>YBSH9>tiKd*_v4x0W($?bMl%X`Z;X4RfbI zQ(OPSj@jyOcXi2o6db9e4i+ubRtI%DQ<;J0speFszQd{^pS8)BAKLtHajLvWN_9EE z^GQh5H`cY0Gq21MKv;3_fuhpoNZx=n=|TKcYL(-WXM@7T#q3+TG4BfJthi{Cj&*oO&vZ&B{o2^@`@_%G z%kLVKv})v}@~@ZThcb!t0UFJ3NSlO6-%dtqVs=Dn;u;WyCph%9@%YQxoDKDcBuMJb zn~`#(MA3@vl+-5}m#j=g8yD95=kn4X;TN+2WC;^8RpKg~r!Pv5Unqo(-7;*Eldo-G z60ZafKjZdL$lbGaPbfcO2BTWQVYepk_6F~nQW&HdJXiIpp4j@xmaFtcM#%epsMVQG zZcxETvDPz-a}TptE|&bGTAd?LRy0ldu4o9KG_Tc$D5D)LW4`WXcJah(;2QQ&!@*S; z{G>fc>kPTv!rNIiW>DEpB-31FpQUU=EzI!YMXSva$JCQbnmZF%7LneDJ=wcymx(tH z#v}>1p-{j8Mw!^(h;hu)cpX+^Zjr$d8wHRoRpAhgyidV_oFJ>@bCaPtUvpQwlhGnS z@5fD%WAenWaXAv$VeWWdpc7FGZJ#2mmLX7&$7I|aw zHVo)4H1rE&c2EFB9NOb?rtXWQk=5}LY=aZy}32~!!*Lfi<+JI8=7E>g_7wl}Q^AWRBV=RGf^ z5L6?Mo_ADG;EcNT)L$a*hXF51pBmODz?jc|1AakZazt>56kW{sc?0HlR=es@%66tEP)7S_}4e-6YpeV$r~5%p%YNI zS7A!CS}=lxO}0LFx0_uO5VBex975EkTlRPY{X1?5^8H1b(WDqJa2H|UiY~X*24(2V z*UfFO$oNIkA!4wc1mt}0Heq|NrOK{@y!mJgYngHJ-Di^~QSVXyH+#T^G}j&*uftj! z6$tJdcD)_k%lVX*4h)&+;5bz|KopQ@TLdg4F$GR=?!F!(g3cq|6{W=g<5?jG>JJnX zv90pqpbKFBjiFj>M(Ng{bJEMB^@2m89J89QlA5uC=I zRlu{*K;Aq+xl>~WFXuVt`R+@Si5(^AD2d^!D~9xV3m!?bLEa;=u|u|Zbf`#89vW=Q zv>jY7jhy&Xlo=ws>0GanvZa>+k_}Y~NIXlh_l53?{S&H*W@JG^ZM!xroYUSBKfNt> ziy(>lwakzd7O`eK^=1qk%5ed!{Pl_f3oCfVv3_Jq$^7~aZn0D6RliGsZCXQilN63# zz$vuY7LKv^`cES&F_-T~RIMj(#6ko07vxnTV?Tv+mtNjqt9kUuPF2%5Lbd|tgA{sj z_JK7fd9ndOqDj6IBRT_PtH>fZ!L;!)7Z=H_@j+qy^mOSG3!SK)0u)B*V2M@0Nh5%! z>_mB843Wp2sVH2MfyQB+ey@e`vRPn4pDxHmwIRvOLxlVT?NAMRiJSt<{bESLwCZJ( zaj8X^t(Sd(ZhG3-qO}-GA1T{oN*0h2bxz46EAbfeN}@(p zh-F1i!w7x7Gg?kIY6_!E2T_3{9o;nY2ne(1!eNXt#7&1O&j$KF{R z4N(;vk5pK8G4o-+b=fPX8vCW~^gO15kdTyLpkb;+u1S~Fcsx8?0@Gzw0WhJyw(%J0kuD(NaY zpAA|7fekGt;)HPWYU6i)3eCc+-eDOeO&<=?_Y7LS3HS##KkPmguk-G+dts{&mlj-6 z$2qn^y=mP%p-wGX&@{+XAPAH8^}{Y7Y*A(&3>KA^ez-r%IsFityOn{)AXBC$A`oKba?A$J_sMp>2G2w_z|D{ zFvYL5E1p#ELH+pD6*PM1(eikrcyVZY91rP?e)e;2={i8cYbP>R^sTx;`#C_o^;Hr5 zCT?co{dY1mDLDI0|##=&nqDGypoPJ7I(M>Abu5s zo~Lg@9efh6@lCVq>XF);a3+6-)kgn$E|j9ig2zoJkh;$tHaI@M984nBKy%9$nB22v z-XkAVqv@@QDX7rim(H|rNw@zIStH!B5YQdUb&(>@E&a?9_tE5R8J$M@7gId1BSDjqsu>T zmDGO0c%RleJR`AJVEN7D%e-)@!sZ@22VShW!DqhfD~R*>`$x2gxKuuKGR z{q+MZ->NGjB8KPCQvv&q?m$viw&AZYfmr>SAy)o@Mm$cAl*KE;kV_x%50nL2ldRj? zk)o;ud3{XMMD`E)pR}ha+mok!2)S$j$hMyQ_`{cRueIUD%lZ26&##!Hnez9InB4|cn*U@r zQoq@xEguH{cB>4XxU7;c*`Ex4XEx{zbtQ&roK+dNFPC{vXT5Fa2|AOe3W*bC3)_V9ELf5XrKwJY8JiHo4Vf1lRI11}#m`{Mkly^UTzN2Bm6iS{CkjKc|RWH*E<)6QN!j`u*FHy{WrO4>fhw5 zam#0_QlAdA>Ci}=NRyDXz zW5f;ha7@|1$yG}roYkrf@?Pl#B}bV0h8IWM&_X3l*M#p5bmAZplVIwy^h`i%l(XB} z1N$_s_oG3=MSLJi%~$4SdR&shuoQAgG`8q3mOw}F&-9;-Dd9eL5kpT@sR@ofD37U_ zA2Yrf$~rHP6;E}dX>BNz4tqhCKjH-Y5>-^twgdnmA(Ol+ft$>8w_zeQ_m9wDTw@5? z#1uT8wW9>Fx}WoKRxuymPpj81))ceq(7h3bw3U#av0d$EmX%*ph#9>8soh0>Yjj(R zix_<~3DPyrC{34LcU#h=(qF{|^-+Z0Q;+gaya{<`3G=&|OpKg~G`vDfGGsol*Smsh zT>a5UV34HPn==Lxw#rJ9C^?Ib73%rgyM2&1hzzo=>r^p`uJX{PA->VvQqN58zjs2e zmVSETR#f8K-bdSp07wxf2p0!CDV%B-KVe(X6TG3u_{3*6@$UT%d4u)$PtedjyiBbaWUt>d za|Y6Mi1Ch3B|E1t!C8>6#}wm)ZLSt`V^F|T22#Hgq}UTy^o7;*a5~v|ty4bLv{?;r zWlWkYw!P<3>#6kYU&3D~8TNRs4AyLboqK@m5EDupNxws&TSOrp37eJ{`^D z+&yB{s9u8C-j+#1QR`m}3=*k9e)dF)?;j(e4G~j{UelrCmcOQKh*jp6J4O&htaUwd zj9(-RpLlUu^heuXJ^A=&?G|>aZ`S@VoRIxnoCx^W)?pP9d8H554zB-9Z~W(9|2ft; zQB_mNc_9QYn74jupnZ#no6bPzxg$XfA|TNHY}+adWx=}Xv; z0E%o&R;Ow`)oCh=Eu3ZNnnk9|XdH1L5R@oSDnGFFjzV+m8|ir2|{h6#Ze`1VZ2H&ZkyQIrFFO4YK`4jk0;4+ zhvjY(r~tLui=PVgmYJu?$yk|JzAr9kADd|{8mGmSr=7;73|+uw8*34lq~}%CdoZ`U zm2_Ixu=P3K-Lk@xPL){#rX81YL@&}wKw#u4R1xk#1W>~L?kHv?H4Z23LhxSL%%NfI z0Pt<04@s#-Nm5IWCaNTP;1pb$w4_)fDjjkYEj1SGB%A>_s2?-{%Ygvi%%u<1;k6ob zIaX2vg=w9rp+a;(vjU(YAD2Zm2NWwZ+%zWHc~-G>`>;-ONi@;Kb7P>GSKL8%9uu8X zO+wFlHYZ%Yx%DZsoV=rIkCA={B^=zQiXsu+hIBx{7Z%X>t;@tCb0$9C-Rg!+Tb}ev zXMy5aXQ}3B`1u++jzxj5 z0!<4)RMZ$2OhxaV5~qOG?orJ(^&!7?>sB40_pD^Xw{;WNs1?z3dQ!!19#l`#Vvd38 z@)?u&PC!h(-sQDnn%I)7@s9>i+^7k+EA))7woJO;VNhPmeA{b!d)4&tYPAb<5?mmo zo-{*uk-lSp3ch_s405t(d{s=4`U^;ckFMlxnkwZF=6W&3NM8l5zAkW>Bws_Y%1vpP zhTp(Yjugt$)a=w08eD<#6J|HxvCHzng+fja@OFoz1PSf2Fx`~je9wL8{cf?{K4qW2 zlEQZyd_f@wnI0}cX%jwN^QH|axo48}{1CGL@;Y7iiRWSy-WonF};w0$Cxe2&!NW}-8LgoBJ>{d(7Hk#KDu!`K*s$<9839V z;?vfGM1Bj!^TB-lhgFduZDAG^wSLoY*eMVFMK3EF)LjvvY~X*!o!P61wkGARW8os! zqEDjM`e3#DmAbLBrHj>acwF|#keBKsD0i3|!imXdt6ytJVhDk~1YI;=yVQ>B(Wc|& zw1zuG)?1PGTTJ|fv-=X92!jq@h*hA;LxkO*6Y*-+mBGu$?-|!Jc^eutH6av4=HX*; z-mf2yzHtffoNKTtB0fQSs107iI#M~YP<$^af;IJu78g1U zp4Bmg{TXZQ|WP|IpA#Y=TeW3Q(0S&Qe?A1ao}>^uq$H)>3S{vuW7&0<4IA*y!AKC=PI z>xFD+Tv(Hf;afU3y8Ab26J0`45I?Y@$10I++b_HUqKm{Ur885!?}er zOip@6{M|GsKCD55e!&aM-!{!p|IeD{|J*bG!(gQFw~ytQ7Xs~#RXRs0!2*qk4@b$; zXk{KVOxgLR9ldMAAv$u`u5|i$8LLH~ae2`t#LWyc}E z*kW;J1$>gUBR}UkGTk?Fyjf?j#pp4UJ`Q;Y1(^5SowpA?%W=?mX{c+9t0^=8OUmkW z3BQvw$==W@8xke_OUi1GY5FpT*m_oyw$%qb++E^H{mGh^2m&~%y&Qv6% zyAeWY8*v0BizO}JuYdXMfS0l{#_Sp!y@w0slujC~%1zk&POOOR@z8IT0Sm@*V%U)- zM}AwQeki%u#@kMUA1_iK@6VEpx5FPCx7rXLHSG z0sm6t$KL0hiqTqH-O}Jf%EY?)5f}&f@5^IgPd+-+a?`aBK{KMP4!Tv6M{eM)yLV%3 zz90EX63!#z{av@zVXD_TK)?ZTS?ZVp3^&Qn&5rfTOxRI`9MVmIvazRg0?#nBl7rP? z&5U-AQeSd%+%yg-1bIlYR9d5T=l=Nh%ML=%A@aQ5(yPsv#0J5kTimZ$QLrri6Uq!& z!Dz-fv`$=*a4aTrIfE3Uk5ikCKi$4ms+XXKl_}gj_cYQnSQpL{O|@7FoscGi{gEO= z$`PtI^ugNJg{_ksj!({h_kvl1iL%!KaxlFDIumM|3RJ!ISX zvR6FLi?Z7G$8e-gO=py}?r9}~_+gXxPnLYtd4ahCFVFERW;m1*@4;n5)|+7EvQxjc zB0dVm&Qud$@H$y9uE|Nn1|-T%ntA2m9Y+KkI*DQIG;s_m?a~W#JSzp($d>9o9ywz) zp{{S2)KTMmXL-IP8=YD5=k_ns{&ty)2DKD09&r{e{7s6?)lpH+f+k7`ZYTWJA2QDo zaO!&Y5H}B9;>n34%iB%VX?XLRG8onT@pr_uw9sbv#6Zs#`fjd*AHpts!-&JnMae;x z?vyqHNX?njvFcrE)N2KO?r&yd!s@ZEMcR%;i81d(-}U0;QfZa|yVlvLyNvdKFA}!# z*@?vMpw9^tvacet3WAFfpdF_+wgTu*uu0=LbATEe&r zo<#IW%k+O7GIYo%iFv~2ukkB}d!t+@ZVXnptb`N}?d@l*yk34JJT~BFt&I-P2pDvs z-iUvN)VdTM|CRD}8%1=a^C)j+vvBz?j%YX>e=a-{`0Bk%MwQ|_co75rgr#sgk@wV` z5i}iAoJUK1^C|Bq?#%MN1IB5t4obxfXf3o~&)bv@|R?C-*Uc7$93pIiTpbFZ)sIMQr*i)1`VC zYM#XMvk~a>N9JY6%c)ED(^ifl5tLQ`yfG$=-b`f$?~vPkow^@;Wl?LXyUt>TxjXky zYn?(pdEz4$(5&&Eo;$g1^m!C7H#2kE=IODV*hfhhDF!||E}AWNg6SqPs(lPm!kN{u8~Ji>6PX@Lrcded~E4k%t`R- z(F{IFsT(TetZfU2%TqJ-_VGuA^7Tj9u|z{!7Hz5g#$neZZ^?I-Kxve?@d0_yRckS3 zKuCnbu&dsvD{P}&jMO;*vLrkU*wOElO3Z-e^Nw*Z#9_?Q+7%XGx{5N!bKn!BHsBgm zT9L*hg_Bb1Q(9V3k*y62H0}&U@{DyBrj<8{yr-_DIO1z?pF3gw%@{I_x-PwA~+zi{W z5jB!pXqzT7%Gqmxo)4F&eOr^5$2#abK9Pz=ttDdYIF1v%_=DX8wy3|A#<+&k00<53 zR7w?_d|vQX_&YV^?BZ_dx-OLv_gYhDtdU?;qcwY4swIE9zr|Lo=>IVH4nUH8Z60n< z_p~)_cTd~4ZQHhOO{?0rZQJIwZQC}c@67-EzIE*Gy|Ej6BPt>zt12rhDxP}t_nbU= z-n4Vv?W2thJ3phwMQTd1JU3Vz{d4_gwBt#ks5Qk+4c`6-dY-%!4p(euaW zHW86t9Vf&rGP7W^q&z+`+9w%eQIR*mRGb^2{vSr8@i(K1`&UM@_iv1*;y*H)wckdQ z`EQNJ;NKe!`M)w6mh&irpnQE8xm-;m9w;#Th}@CiM#K1bqd~?VhWu?bHGhnz=-(TS z$GpJ9~B%r7` zSsc&FZ=O3+2~qG~*Z(?;V&)TsDfz{5K6`9XDw3;lgGn{l|BumV2P&7B35UyC+Izw- z&WaOX*u+WQxZbMP2lU*)qdR z6Opzkal=ek5G0-pDF#Rs&&0HWKY*L_6GkqO71~p}=fr6M3qbV0ugMF}gE8%Vb(tlz z3H5z--q&=E>7Xf67oWFv`+*Y*$ew1Ptn`=R=c699x$V@JC`n*I?jSJ4S0TV8aH%#( zrfu{y5pg7II%zl_NDB}yaP&}b7>cIai>j5^9=GQX^8|TA8`N>y$l$tI0%8B zuc3Adu8)47(5AO$nnORUvEj#5&eIM{nK^&r6T%R%6$MSr2^Q3m^(#yl@v*mPlb5dE z+)#%!mOW&$_?<=F5svv>qL;?NO1n=Agi0gPHMhe;xI8pDLLNnNE*uUVF)mzVs4O9d z25&&Q=8%}|97GJC{id<1JzNvYt`Z&%M_8Fa8P#)OVW;IRo|nRMPob} zG#;bFu_<@X4(9)gUiCI!t;w>*yU}K1iQ0Ta3hXto@t|mbghpkd zz3JZzjfKp_;opU(8u_=-q!}tRYaVz={|7=-w)PL9DK$UnP^r2xJIz&Dny)iSny)a# zGASLrrsrVh5Cnc2ysy*8oP-g4T6W9A|5i*cz!o&e55r)@(KmIW-K>O?!B5*i=*1GN zIYFX|Sbp-N%ukuAHA>7-ZqpLjW2eF&jqbr=oZ?lgqQ2)MqeC4TH{w1YtD3?Mw3@zy4OO|*>5-xblDwN%cF#DnrD|l}4i{Y+KuVfg4+D}20KiCQ zK0qpKsY9|y>Z={cyeFg?C8kGB;a=-jeXp=_oXCa!{)<=qEIuOpi&n4OH$xbl1qFU| z1VApLD?^6bjX>Twnc>0ujbWqUrEdTyf7WT6iyb{#qKQ*iWESR!40+1xs@F3=F7plKD7eM zcTpNo^72R={(;4(4WU6ABxO4gdX4T+D{x|^Zw*IVyb573{RI%>N|cUiEoKQ8p4rVO zGC%ho6(VGjy#m<;E41moQevqf0h~AmBK9H#`x|T@J7jrzAMi-ziVD44JcZT#yR*x+ zgHN9GmBMkBt3^t47RI~XXX*RHLofR%nhJK{=72H7x371jBW`DeV1?TjNABKxfvP<* zC_K8~RI|g0UevTUP|77{AR9NFa&Onj@cR0~N_g-X?oBJxD(~C{Ge||=#k5ce=&c$V z<W*(4zX-jXJ3jDH8d33m=&{|x2qMLsPJuSj&-Oe@4lv-*Fe2i)i0(OS#l*wz5^Tmi zg4>6dxcn?{zGjh!+rf$OxZ@%|<(`)X5O(i6pe2!H=i54fTivkqmpQ)gm;~9r zU@j&q36@jyC8C9-9YIp{7)@w8Uvnd;!Q(g~1c)aCB3L1i)~NU4{Wp5hc>bF4#fcpF zOLz2P(ad4PSU@E(BdE zQ6}csg}f&4(0b!CEAgenLbT?Eeib~8!LuJesyjJffP)+#AQNn>_FhPgTk`6q!))xJ zbBzY3gk`Ri_V?Hqr}Y?@8-vHNY#fbQCMYICAF@tCuh-M-6G0>gBdmrck;p=(ZM#T= zpfGI|OHLU3pn&J1eoBDU{tm{o9^)uX5rg1V7=)q4Y9F~XA@{|4{l_5PkhW@|zK!7C zW&?e&J3vZNX!YjgP3#=h8R2{^hP4DW^ZoRbwqIAwKEk&^8oJqTZ2&mHH@1ZZH8y|u zn8U7HGPN7a=Wy*vF}t@eGO?G2JI6dq-o>31R~88rQ2ML2ssY&9i=|mb-5Erc>#l*0 zefibdTK2A+T3a_L%jz<$r0|pldzw3jW6KM$+a2$!{2k2EyQ_XFl#94kw%+PWjNG3( zJ2)4jG@NOpfyS>;;gxMRl1+dTGQ1%<)Kjc(Q7x!(ss>uu?trK%b-wKx-W{u649OI! zx>2zO^Q<`b^y1d9q)D6H%l`ufLt2L3Gwl2<8l5)NJbBUQJ|*5Q-`sswdo0+Dqcs;D=(YbZ%c&>7iKZQXKc*47`! zU7qK8<$-~KzWt{SQU3QCXZQ!>ntvGo1*oLbM$-)Y!P+Akq>zBJ-}}`t4+UXP!BEnh z!N`TPA$$#^u04qLGwPq3|4dm~nuSC!Zj5J*Wif8GPQ1TATyXwyu1H1KU%pcsW=GVi z5Ex#wWv9l^j5~Eo@WKr899S^8?4*6G+7lVhG!bPM-ex*|$WIHIBJ4=yE9o*R?Vtuk}qK!`WU$~PHasPV$!2I;&y zWpN*QNtXWek#J~?`(on&&-;*Q#Vkxm&JEKd%0J)+vFHYhJwL)c-(TGj{7wih;uPrJ z0I!QL+~!^zNz#1Ph&}Wb_Yz539$d91ZD16U)WhemRZKQpluu-T6AtlzOgQ5|2v@hA zAmAgk@#Py_&oDyWQXODz=6Q_V#~kkcpyM1mJ? z5cq(y;bm8)n{+Wo=GRKT#=t8ki$)#g0kj03H=byCWwA*xmR4sZa=oZ-t$zLLXs$f_crGI^xkJovR$W6s#P|59$p@^5qgxO<}icqJc zGbfCM35Z>Sibs(R+pw8N*1zaLT?un&-P+DAe)86rKnwAMXWd`tKpBB(pY7wSN^cpu zHYxeRV$)-QzE?$=N7kHcZ@Z$_L(ng!Ij~yOpAsgjW!Wj9%5CRlVqULawUI~qJ;})%#l5bRa5u_g#g32Ech{jEWARs3Q@H?r%E8!0 z=iahn+#6H-V^abF)f-oskWgp7d66?HRs76wv`r6!hPfJ1r^Gtas%5A$mA9Yvdsyh4 zkg3F29Iuh}*Ac|uHN0>xMSQ=0an4vA zny>y>4Ht%j8{$k639OhI%$Vu-xA!N`8ykB2@|?)ym4&*o?~D}0#7<5u&)XxIM{coA zu^6YOZXh&;_lNM*19aOzgaiE_6VCJ>=9C}0Kk!f_@r&Ctb?GZlwO5^6p0=Cg)mvM>KxDg3q4)r5 zRnW;UJ3|x>oBD%>KqrYmoPP__{EKrkPuOAvoUdzstEgRy)eDd11efx!TsQ9PO8B5> zNDjh(IH%brOy+sjj z@o5N$XrI1#zW@?-=b`1OG<#*ClrXnOvDR9GQ5*&7y&o*fc$s_;mcygjLmiPpzb4uQ z1v9s;t~-q+q><4{JciqwkjerkpEZ;h;Iwb1=la|}zfxIxa)4RRJ}B@1Tm*!;&Nsn= zJK;p&rGEh=`Yv6S$=xTvnRV8oc}h5Bo2=?2D+Cf}i^hhSQJRmMX9ABI-PabR+lQ!N zqMFMhxh5M`)Y;V*j_VsRRyqH~yJgWKl+2LsSd`he%F7li!a6{aw{DkvhIzv( zVq)(bBpl~{3!HHf_4Gb5O=gz@mY#){kQJOzaG=}lVcI0H?C4Lp!DSo*A4kY!<$3I- zb=tXWI0kGn)ut4EmlR)QwTm|kd$hx#6tAMP&pU$uE3nw`Mrizo9sU0pcIN*eu#gLf z{Ru3y6qHb*kV6CCn54tdHBaO5=ZrN_|AcZ)M7(!So_I1$y!~GEL_A}zdM1T`nOU%Z zy}pC?5L~9A>n%Ge&z(T9D){X!V#x@KnF=$fOYlGiNbim!xauZ$q$xtXrfW(!5_=VE zlsb(Pa1`CUAKsNz0k2kwj?kov(G|G31#|Kw!Jbc8N4e$-#4-2*YDowDK5EC}SW}?k9ZhuYpApM1_f179$wc+i&O<`x(D$-mZ?s ze^7#Y66esWd*D}mP{ok@JGH!FIk<#E8GZdtIxw2FmY&;+Dj!y|9zBfx5{iC`_I!(~ zm6Smk{@k}%7b;KN0gq0yd{~TIj)lC$^tUHtHb3OyXHktNJCr49EyL?i(yBjf3-Btpb94QM z=7+o0tV3Vrwk{~{6*Z)prq#NgAD4dfCx?tw@7(UHpn0rIq=OGC`{X~p(~R563L#Xy zZ~+7bG_y`~93V*&CwpS7yFishRI^#cmps37%K+PnEA9o{%PC$c-bBoB>&~^1O zw_;ej2o2wR3T}{opCTgqai3RcyrNJy&ap@i;~K>Aqh3*Mkfi0Hk7~aSj~e_Vw+xYp zQK|g@AepoL>&~40DoIu02?X0{+oFYqWRwyie}PUkh^X-g^os^68`F_XR7BkCqi3l+ zGp}h^-%$9W=Np@jdZt|ZYZGVIInSf>@r-yz*P?8n&QBmcI9KU=I;)nllkOZlBsPI zHX`x(jr*~Nq=e1`sGx1bNl+>$QN^^fF|^P_PrS~3Om5m4!;(@Eeyv!1oZfM>e%_S7 z-xnES;XY9e!|Q%eu92h;*W?g!$UNy8o*cSp-^jfni6e>1OMm!1ClW|JX= zPWcN-tLAUaFTeRxSgrE`-se>8yM?Pd-c75hG7ZMaNUV)Gn;&o!eaBn-n)f_dVolLG zx*$f={Z_dtoXQI{{3rlTK(fDaJ=++U)hQW0xNuU4PhKhRjSPi_(#uTxzi4CU7b`*c zpZ|<%q4<^w#-&bUBbpVrUd*URD@pDz{KrPk^G}rIIR8*@D8*_H-$+CyFs0y<{fb$8 zJ7=qRw6(j=&t)QKc!QQ^?In`NknRu(x8oH7Pq?6CoSlc8KG6;MfFtC<-o3>q$?6pF z-GS(2|ESHx9)O0OgN`dM9TLZmprwnf7Q@=2Gw>QtxdA~!CXLL-xnE)Nj>7yPtVmCh zm?fC2J=JWHrswBm4_Hy73@4qr``bliR;D<^-_(o!A5+izZ~D=y{zbh~*GGw5SX~}b zik_5M0H6Rx0GbDbVMAtY*9CBHgTM2|_n(FI$|`*t{a<#Y<@|d$TK{5_SM*2i1*fQ> zKf^9(u*LWVigFW0acBB9vg+)+mv4Eh&Sg8|^@~c(JDi@0qxR}T$+137-na|OeBsW{ zb>$>5fO&l0!{0%sf29l;F*Vc&a8KMe7Z<1M-8+qk(uUuH%e6Hxg0}24vk?7~Mpb=_(=8e4I{-Rj7b8sZ+65c}tzv zno?GTU^x-LI-c0HHK_Y)NI9@}m$#Q0+SPt*fEzIPS==`SV)T>O8s$lIe>B+laCC^d z$%xL>u**|3TmEG@gV+aoss4A7A2|?~V~3a*Z=e2M z<0Ioj;FKl+AZ={F|I5(*w+nxG-vH~_T;~Y;Gx}oMvzegq74)BYZ~yXl-tqqMZmaN^ z@rU>DZ2hC|?L~Jk6Scp1har?sm2MRgwc{KTjXkY!5Rs40obvVmKr!Ud(z^w&x8*gc zSr);g`E^WmbR&>|@4s(ehJgrfh+GuQzluJbLhom8h**z&6j4g^`U3YC?&oQ0VzUI{ zwWp$PQZqT3T73=`iG%USFMka&=DwetX#JPC|4%kw{tt2g8|)XF?p~S;iNB(V2{e7w zGY8Z|>N&zQ2iTzfh+s!7Gu*;2(6PUVQt@(17_EpoxHL5-2&|Z>aTNA{9i2Ua$@JIe z{Hhp7j=Wme;G}U(H#aL&JeN>NeUab-Rp>bBIW-%9zb_VbaR^V!+x=GMbj7~)l-b^0 zZ0mbJ&j_?Qoe5WfP<89nfOf9Rog2mHSKL^cBmIDe?Ap-m`mEjCL(^3b-^%?)(K!J+ z(F<}xeSt$=R-IFutMA*18CKv``p_y^iSvcUWRy*hw1rB`jRUxBCC}yIRnVeGSMJgR z4ghQ;Thh{x=ivEa@q@0aprN9wA;ON|ID)yeYi&`uEhKzN24`Ed!Hy|$$?y}V-`TF>6`WxXa8G-FduceSRxq%_w_ zRa#rze1nD%U5P=$BI&h#b>W9*!*n1wCpFf5KrT&l^~}YY!i2+OFtCpA8UzGIYMvl| zBgu3g7?XQHyY!ZMTNer}{Vi(b&-8|l%@}cQ!u-(m!ca}E_RieWCMK$jLc>`S%1W_e z0kcuer?eVICjB!?m+KO_rt$_4Pi3`@I(p}L<>pOKwMugog0!C4iXwZLgdvm#SVO@p zIpV78U@0g^86-ARiS4$uvQ1D63(g# zr+fJ-xL-eytDGR}J93M=pb$Q3T6%Y#=4?v%=BYuO|!K%Ll9@SUQFRp6$}1eUXD~$`&Am*eQQJYG}|g-^=M5PG1LN}anvMBuu$Fam9pLap%(SA!G+RiEhx2NjhUT6 zD0g7K(Wuzr4nYROLNV+|)$rG)BO9HrNXI#oqgR`1$5G4E$xkJTHEH!4ack17P(#(- zpQHX%Ax|kXEr&p&R4+TNdNg64-T)0i^1rruys=|0tm`M7Q|O^|-|M%>g3Y~DPm}sS z4$g!E;-6gZlgiBrtbAK3nVuPZ5M!vGkHo@6whXukM9TM{R?|Ws7U}O75O7HKPfa0q zm4-Szc2y-yDc;g9)XVj0mh3h7n5@)G^*NHS(dt%2LDoZMJ)Xw3je(B7u7z)g*M=8( zxDJyYxfYsyK(sPcm`m;T050PksC;!jGBCv5Q8Ug1QRSQ#M_0Lo0^YuswNVswrg&4( zl<>A_XK})dRAhJ8cH=stAu)tMs%#9+{>r4rJmJ~84o3O}puxa64SfCr3T_{w54NYT z6R%_#(!^sm;CB1dD!N3R&9?g-8p2+5+7xVXL+2HSwzwfl;ox!}%pSaoR4b;8*d}|7eIApU8jXT6;r{;qe?qXsU!X>YxkK2w0RG1ldER0ENSseobgQ;VAh@S zhP7qPubUV-vy&Orbq^O82*doh*p{(jrN~_WU7pk~8s(CrmYx3|`5+&p zeheQUcvL-kE6Fd|1DrU@goOjQx^6?T8wmc5jy@px zdD4&X<{Pio4vAFs$-k@Af65Gpjbr5?9C1E51ZvnnZP&aq@E!$}J%#e9Ngh8EJH}*NIrQ`i z;@1p!rE}fhm86v~UxN)*lOV@+5=3{E9uMjOb#0&NIEI@b@H-x1BZY+B>V;7=Z`}1S zH!Co_)jeRyOIc(p0UG>aik8^9XP9>>gZHh#e&5buP#LfrUc?*SZz$2i?-kjdV(-4C zdXPyZVcnF7pRPo|uA=PT!F~64jlOj!J%5@|{p!E@D!Kcq3FNl?`a^UcmICl z3ECY`-GaS+?8)A@%XpsLU!A+ChUWwOBF8`Z^;f|**q4M#ytYB%*c$p)!sf8A!C2T8+Rfm9DUtmt7rwEUiK zEddXOFrd+SG0j5>r7;3NO7Lc>fFcjja>*-WO1_0fI<*F#M$|Pz+EFT z7@N=)Df(K-tJ#n`WG`v6i~^~?eX-Q*v}`iX-aCc;bOj@ef)MuyF(%Dk*Mj+S1q#Zh zgeEZjwDRp>g=1K9Cd#H5_eTPalI>!JN7F@P?ZY}r=O`)}$2z zm(A+V9>}5)+CoWerQT);A?r>UEp^)V?&EHd$6bq4JjK`X8jdjwIXsz&8o!+kH>=Y` z#-zR~c@QG%l^EX?7fy%oF@(SF8#Q9|Q4We=o-QyaRPc&`X5JWoDpc^(9*JNl*HNgr z*T?s}g?81nl)U9|NO|LsxOCoP!Sc)NIz}bZXB=O_YT-0?>?rrHLZ$PpO)LdxuY><} zqN7AD<0lE!kX}!sVH0o10IJo`MMAS!1$=F$ZBsr*gcgL`DicH5Boo_2MlhAnJ6O8TJw9IgnPJvOQ zXQ7#yW!*tF2Id`GZe##i>0(QiwkWotJ@(gEkDS@FEz%)dxnql$p_vLa(sAth*+{6u zooENw_>4F&F|~B7_D~OJQL1$UTJVop=7p(9)XJ#!Dtxvx&Ng7&#&ODO7b%wVIt3ua z1SnojipSOfe&!H?Z&pAidPN=H-%bJh&haYiUf0{K5tQY zV2gDMv*g-e6=bBW!L zz**et{zAGfE4Xlb6x;QVe0<|0r>OJGKCtXg<=XYlTJ44nt-(CUq!u{`Qmi;s&J2-c z4tczYimIR#GlXk{46feN%ylkweKzqy|g zV?KV?KYZ5}mh>h!*vxvnRs3?bh}06F(_1y}`(;HQFT1Z(cK3?n?pAi^mk#z=eSL{; zpyDZS%X@)VwjOQja^EMon)b*CPyz_&gfPj(u#iRwXhQg41NxacMi?31K?AU+Ik82_ zk0%1k+Ds_sp}EFwR?IruX>>ee_&yq}NBG*Tm5(4!RQ6}ZE-tRgA!S_Hc<-5z0hIu& zJ#RA1@0vfqJQMJbIPYc4ZtGf61$yMxJLln1RrA@xf>e**O@uY2*Q zr|b}q*Q8)18Bin|LRt@TtolbPg-Vt}5i3P9$TUy0DCVzP)TEDg-qb9XB-u?}4bMpl zMdw|#eKF9L6g$5a8psMIeXQ14n943k6M83kkh2H2_at#wT$} z3B@rmSb~XNc11*NXF#aE8bW$&*6AP_sFI3Wevmo`BXJ=_Y7Y(F7$30FH)v+4T}xfY zkvf+larymWmLUT^DKX2FLIc0JvzC1ycct;07}*V;7;2|}KNxG@QkUsT9)XbFfRQ{? zLb>|}aE%S3>1t_VW0z%rf5*&_W#2)hH+NbY=-Q2+2%Zt4-l?J7y#pR8YP3jah6b_> zwZ$oFyhxsDp%09;@q$E;Dgp)*p&^|(vgfLuZn7cFq@w3%Qs?Ri#U^&ZSI8UsOrivlx*=CUy zKkofr>tLd*Wt+%gJU&X39)`^oYv-TrDCVAos?EFFQ@FIm<6KJg?s!QCLoe@~@MtiF2xj%oJ=O~1aazgt>Q@!^ z51wCl@@Q~`^aq?@f8*pDhl?)Qw!=8UfLp@YpfJqQ9C*A~TN%VD>Pkeo)O=}J?+aO+ zH;m-!5y5R>s`FRTK%Ysot%$W@nKd*o_(4-cm&g25jc}?q)>aLZyg(UMq`?H$a-W&y zwyiLBp<(Fv(M|@D8773?zmHC$Y54v2U^PNt142ACOm$H-dr0ec88oanzF?NA!?SqG z%B^KttaKB}={Ivlr1qA3Hk7maKesatF|Nq^FKU8JCBf8ffLm7(jfBzn9X}eB`BaFZX9vHBV;DgO zR2aq(!#H65**=i}s9^D{sQs#r1@_{=y8t-?Fyg4&+62;fQs z9=RZiiA?%V3mxE9nVt4^ALXZiM>zjx|Mx577s)l7aJqlo*H zbR(>9=FLB>WKj3#U~VzM+~fGW#=pxlj3lG)kHOp~BJ+7jeb=PoFVl}Hek+yc^N0t1 zaRhsT26Ip2@0$89%Q&*dIP!$CkEa0Cy7bi{n^;U2ec$tAA1x+R+`mEg#|951#^cYC z+NnWc8MGD0nBPCe`JDogJ2Pm6y%lM4GA8>6vK5DncH)b=Q%*FT_K?{L=0#C-RWyvv z>bc2Qgp(&I$x5?ck$3q|+o&B@oVk;|d&p^`h z&?|tF2uH23w!ScYcqlG!Th-P6(q`89Zp$f+}es+RM}cIVCK*~{2az3 zK))LIx}mATiTP}%OBU^RmU6zYD2vMW12eb82EgT?!y z4g{=BC-I2JijLn|%D7yVPHmydhel=&VQG=0%nbW->4b`vOA~ipCf}*Cu=*gdzdHxT z6QodjE&?hnXJlFAZ_v)H$q$Ll5YdE%;5SqO;H@8r8jg;h6fbtKxmVV;`(#B(JZ7F<7R$+S4M~eGYCI)cM)b#`s6ANF<%Z z!6EK6k~jX+f@aNPqxDh8L68&=%YB+Jc2%^d=NG1!HLOIYGnCc86mJ`PfSbl3r z0Hc>YN-{ou{EbUhIX@S_PcN&eh_AC$ILIK#9}GRsl*{<8wy~w6WD6hBpEm(iI95!gNyhvG*dh&dvN>cg)cJun9^>C$1k0?!uv4KNaw6os4TnnIEg=JIWYr8okw{t9+`7jMW;(Q?$reWZkrPd zZui?=Iu-w{cZ_E8=5lbCtXQ^>YA?vM&QQ1_Ymc{8N7q=0P&_Y{I-UrNBp{khEkFSc z7o}vpC$LL$uF@OnM(L-HC5nY%CNTRejo+zM4_sAfi6ml)p|~`#kCq>K^eANLPQe7R zX@*>l>LmJDp~OxHwWcJ~i1;rYOo$bU*;tWnbsi(9{BrVomc{HOMaL+m(4@QqZfXRYFS_S6R_PtG ze>Req?07I7SkW4dZE4|EOtQU;26-8$yURtFTUM(Q%eEHjITU`-0+o>0yA^+|l5xEu z>Lg*R?-!K@-nm}l0Vw^xX#a%#9K=nWj>K3f!@}i({vBghpm%#YN8}GxR%m;KOlWBIcoA(ET?LOyEll{8`YtBx`_|-if>>t!m;CpI~3d8A8K0&IW zL({=7N=)dvI0`Se$Q=ZtTGo$Fi!K2c9-3KLqM%Ue{h38Y)htHFRcv-glHy)~IfpMT zbm~5Nhw0(A>?22b)kZ4q5Md8S%+}oDnXW1hi}eE@*?g&%auTpe&n)S(FH_E#NZI`f zii-oK?>N@5O1og?;3M(bjX1d^k0Ub*PwG;RM_Ij2FN}h}#wE;B#BzF2CCUPqMdUDH zv64gvlZLU!8xPy%504)myNEbev|TV2N2l_LNM zK$B*E-X92zS)!=zqjQVpyL(MKB|jM0!(oom;&;CT3q7%iNMF{~t8MOQ4cBTq&{wA; zIZ^{H%}DleI~{i#IsLHV2_a_-#Ij!o-f2pl4Tq-s#z;LE;U=M)oA$lP?!*Fu9<333 zD)<>_Pg`vwmf7C6drZF6w6h)j;qr+71Ao4DrKj5&c3_^W=Wu9lc{ZGOAMwqS%psid zI_t+S4W;iFo~8|Vr(H;77W*>#tB!YW;Sb>k9i*fBID8N;Axn72eT1%$5V9zGG2Ek9 zE`HSElLjQUUdDRFsc(1nPTs7Gx2;j6N_{tHIKyKoRSnp@=~}=Laq5)|yrZ5s`!++_a!{*j(^}CImjOPgj4U9T)c{T=oT5**gks(^n37RJ6Imt54%47tVg27HwLOoj~v=<`s(@50$+2*%qU5BDzZ*yzKe`;=MmuLiF}em^D2fLQDvk-Y2a$3*_uWm-B%SA$*!&yB+KNO+d{e2yaEhtFvIWc@86r>c<_%#Y<>n0l5zAo1dvUGUNk6cH4zty0@6@^%5e7@oO~{hgted8J{&-shV*XQDoIj(Ys8-( z*9tJUsv>TL18d?P+5_$JZmtMdI=dUf9iAbsv^SSnh*x85yg-|K^lopJ?@58K-S20; zLFk(w7(1QOZtw_K`n#RkZqeVarg{evvz^k{`w(awT z*jqh#*vyL!isFjzxE7wi z`MNK*WxyFQ5AZ}Gb+%|SG!9ufroA;K@=W@#cCwIX^0HJ4*^CcD+^3-wr_!DbZ6o|n z^igjt(-K}-u%HA1JJ&2Px?&zkt(mM6 zhDi#~w^CLEQ$`+t8OUb(b-InlNn?h`Z5IFvM!cfgz_o}bPH=|IY<_v+Y&+uk>(Huc z`h*swgE+=mZ5|~4O;QDwrZj_?z*ONcx?~_3fxukPOa6?&513R?v0%vLP$<=wfSoPt z`oVYJLwb6Q^1$H%j7O$xbkfI*M{xj?;`vDfY7xq)i8Q8eACRDt4&o2QIGDF1a!4|M zeKk#51TsIDx6FDOu&|3O8H|1dLd|6KZ|?JQ6&83%YP>XtjXfS>0~$OPiR+Pp2&ax1 zjMjZ%%0rm?f&hI_94t(tFrw)p^vve?fWY_j_q>}Eet(q*>X^G4akf#rE6+4dq#9_3 zD#V&_g0aJZ3tUMeY(q9D^*M#Uh`0z;eUVgsM{dS41!}}7Mr`$#`6xO&fguk4ZPMeQ zjb%Pob^IM2FmL=h!oHz5;|equp6_uBkyaH#ABa4IbZv6%VEP-y#tl$sxJE6txz39C z^?|_{5katXL8;k^_K|dVGbgC4;he-?zs=q$KumS{859F6C{owJ?30#72GkNUOONek z6EwWA)n{QI{sgD1TNEXppO$PBV}!f3-P!Pb3IzCjQkK=ct2O)C8&P*f^2&=9u} zVQMckMARe))Hn>6s=9OJrqf5eo-)_Pcb{ng1&usMrCyzb=tZ5ad;QpoSIm#4w&^$s zx4cWm=(8MQx=Xd!PEvXcV^fhaX%}1CEYe~?CUpu=L`fwu!bS#V%mnac(KnrB@c^gK zLLKRA;(U69)Jwl~Gfz*gHVo}4;(karfgj0f4LE3bbvi%JQLi5a7MAswpMclHjKX`Y z`liCEYo{eY6;Q{#e7St&zFSnP+2xx$S{x1AwVrF8kDl zxxvh{@%#Bmo{b{Rjo+_6Ft<(cY``kF6%IU!SmiFh1;uIH4?lu7fvp0sf#AWMLpVw8 z9)`C(aJ7-l2;X}9UGk;ucQ(D}AI-3a^29xXBl<;yD){w^W7iyjXZ~_ke%-ow$MJI&IC{*qNv{upqDOwB7@u+~&OFnQ7WG=JwEsGD;RKB1t0&fqOD*(LI3%PpN zzC*+|TJ;8bb3pbQ)jGv?*Z3W$dyw}Ujbf{B?U{13cdO)`)UvmGS)-$0W7%PG$Y^nL zQL#04W3s7+2DQL}^~}&yJwl{8IooRw19RyiF&nB{FHZ!|ZJ(Hn)9cIBgLQGD$Csnz zZJ>qMj#d6@m*w&kor!x3(vDScor?xl&b7_lXWfe_66#29AkzVk-Nxqb^x5(E3Kk8%RcjtA84fy3W@v4 zETQ607`b#=D@;kY-9M6xQQOqF4MC|40jxyMeUuGqee+A_S>1JbT|g&3(v@2YW*a`k zH=gfbd>e-KnBKFmO&fmw)mkC<-k6dO5(o%~{C{K8=RZw-`&$Q1eJgVV2Yn}VTbsXi z(fsHAf81!>sH7=7&xg(pLTPLn>)h&gkXLnHM>(%7B}GTlA}^p2Xs4b9lj;&|Q=1uQ zj<)&tDgE~wc*gHV75au=J;BzDnYLY%sg8%^OTYfQ50RLQp020nYB1KDs)I?T$#r|J zE5?N|Do?G7$Ra!MBEj=2v!`)mpU6VkUNZ3Urb+DLFk3Vr*st6TbAZ8fj*(^ob{`!o z_&sF}Ke?-O2NyBb4{3oh>?+txm(UbYaGw&$?ycM;r9=yiQ9z5aE|J}Om=4nl z=69?2=f;)gf$t*J`|^6|6~~bIGT#T+WcHyN9WRAvLb-8STA}V+(#OpM(A|8AlTVGN zb56yOSnbAoqyetp#0_>>B>i+xT(Lxj#1o!NeaJ-^s9v!a&xhr>e2jAD!NEdhvxzE_ z2o|a&??0$KR8l{aIdv+8s+$O_+>ENLekwf+P^YI1dV@TnpMJtNT>}v-R0rMG#k&#)K=e&sY6G zfohvSv1R0=hL5jPCHIgq%%m@GoT@3)wYy+Scho+rV+}Nc3qw{%K08Mrs(=3qwV})- zSACRJo~`FSSa3OMcLc-eiATSiVT!lt;}kGwl?&O%f6KJM6biBy*xMv$#F=8$o?;+9 zF2_6k=y5!z{R+kWYI%v7GBrogDD^-{C6}GwuPwwqH_Gr$yZf)UPMG;SzIwnwKvtmt z8xueO+sOY7_z5+0HzidJA9y4NbsD+F8VF$6ZzO)?lA1)wsTG+FkmiWMxwCGJj`3P4 z#G9!=C%Y;d)|Q%$D%6XG8Ycu4lK4~-`Hh8@jjzMQ**vGZpQX{hr?**-S5!Y??&AV^ zq_bL|GCZf6JGWdWy^p%lXhD`Ec-`ow^?cb7?(i7;N&^qzpB~=cB3rt75W5;wntH??)uFF|)F;wL)wmW{OIet`6=OVK~_`JP8O8DR4|l z2FtJBI4(yayP$j9^RO6U2wZl{++TyLjuw8MO%N;<`hR$Przp+3Zd)^$p*L*Xwj(lZ zn;Etv!`2(NZQHhO+cqN~LoKv-{{;R#~Zq3!&x|?nE@vJdt@5-&8;_g&@Wjda8 zMo+(V0&Sfn01ZI$zrQ|MIO2X>KQl#Qjn|nX(5UJJVskX-gTE7R6D}Wq{jLed9zW!6 zMyT4B2Wc;>Z!E2@5kP`nX@=qn>eTk?2)xej1kcZjnfdNzu8^0X-(6o=IC`Hz^(W2% zfyL+@UM8QP+g~Tt2xtm?wn!zwXTeJ{_O$BzVgABv1Z%`EkdW;9`-Clgs8%^p`mLeP zHC^3GGIoJoodzjfQ&h}g5n>I_hAB~xVGZigY~m>5BPz^)Z8VC6k~GJOx`o@lG-v8t zejf_!dI{DM6GFx3av>P`=D?I0YqMUTN^^@$URjQfbUg@McNr42JcGsY7(!MNP>c$r zOp!PPH_w$SC9uLOEyjr2yBw&@jiO1zL@TOt_M$&{vE)?m7e|YS3RDzkvzOHtn z9;Vf^Uduq*cGUsb4l`}rzGx$wYCf7xJUWdg7V#+miU4y(wj{iYQ28}*?Fdu5c%^0s zTvtP9#O5t{>Lz*NP8)vH0cu(Hr1Do@r2*EY&ji3YfHBr|9xcsR(p4#->v{!>cDN~( zo0LgJOgd7a47MHlxCZ*V>WSpu?b1>-?^dAe zPiPCYEtGQ^-1Q_zYm#xDnC-Pg$Zjo84?CQff=tM`j23R*=slAqyv9Fw2RWaxdpVef z_z^fxUUn~t>&eA{kNLyl?q4km2KEK}7~a}@wS?(ldVPCRsaD(tq@L}N-8b+>R}aYW zjSh)X7Xt8KERz%MO5}(lCFz(YeOp&rrOtiQcr9)wm(x=zi_N90PtOM5o^PQ%n zm5Pi?vEs&gn3Ik?yr8QS3Prph z_VzWnGB(0~7-pyzp!U^WkfMpzCiCaGq2?gdjq!aeC-)4qL>Rh8fJFsI;bB#0y@w8$ zU_;KyLFP1Emv13aGGT-(2rLeA9G$M0h=fm0SkbrTNXPK!L9WgPSk)HrZc z%-xP#O+zz1n64xNT84$= zNw|w1hyGfOE=Pv+Sd@+LWjV4qQZ_^ii2g=&3AyClk4_x$dY2`Ot zjFlfY?71=-++E5{<_Wc*nT|M*vj+E;-dBK>Y~@M8nMxBVn^J!cIt_(mdq{Pjqt^n- za`ssbADl>QafilPXN=0@Vwy=)1PxG$vNQb(rtkZM5t~k#7y_!aj-?6 zQy(Oo`s1I`+9d@ly_YfT9C5U*c0{G7sfNa7khXg+kZmlVs}DP?395Lxl)bCxf>-tNN za>n0A1)V9P&mXcy5^vR1@kQW5g?U#W4JV z-0y{Kny^#mA*ZjPB+Y$u;I~n+d8W6gb>SOjpHmpyD^dChQhCqUasX-Ni8o!P#Cy-; zx{tm!{b84-h{336cjaX8qnvI>2xg%J7OgwBy6MKxgu2UnV)A=^C>a#XNRNahxdrj) z+VZGkE(eDw6y8yd|48;o1DvEgG=v2E#8JT`7Ek0yad@SrQ6-z5UQ9UeTP}xVA?zVs z($9E%29;bT=|Ai%doDKpxNYDXXDO{`!L61TI&9C|S!J-?C)0!4$J!iHIKPPmWMnQ> zO}u_bD<~?9bV`Sg=<-GUX%08u_J!X6O7NJMMLQv%nUhGeXFX zM#x2Z@c4=L1G{$A&*@Bt$GFhmhb*Yh-gV4Cv1P!a zBI+`lQevTtrTFFPy+}>n<#}w@!l9aet!u$&h;6Dvmshxn7Yw6|$`CE-TRHwTWpMSh`Ks3(Ctw1%nPWEb0dWTkwQ{AykeJjz}vbj*6dU96ko7Ttzv~dcnE63=< zmo6i9ivB?Q4RRK|+AKDAD4bVOL$7L(GuE`WJ@_Y*^pMgN3ZikoJDJ3lvV;xH3G1?c zXd5+=0!&Pq8baCP_&evJh-48jgp~Up_4kL9X2}FoMn-~Zd&^-={@1MQC<7+o;Br7D%A5;AS@XocDbQu&xn z5{NAkM*W7VGfd<-!<8LU(@XJ->E`+9#>^ArUC^+)C9g}?d8_=NnBVBx^0VDqM*d7o z*d)#+Ns&n>*}SKx+Qu` zi_x^;C&3*1`f|f6u341L?NqN#YY&C7I$QIJPP^Ii#Tb%9htzf+r?Rv)&r`?z8j53z z0@btU+RCjc+Of&<)Kq3?V~6pEynL$xJ-+<{RlJ@NUR#!9b9z$SF4(Y8wvnv5xN8-2 z@=QrXHmp0vodm;J$K&JjtL&&L1_o5PF71oclyZ@y;jETA;X)BX#B6tL_)4?P)xmRY zEF4>`YuM+8Yb&NYHKjWGvI-?0FgeC$+M|#S3#?o?mSHXkQ7@v{HL>=V92?O^mg)LX zB6;=H;^Y@3&*X}M24(6>LEC`gYXKSK!wtTtT7IjDN~iLPMjUEsnmMg;JV_ZT!yb@Iu;DIzB?-otOW5 zz2?SZOA^=d1}BF5FukQ%>|NrmD;0w{t_D?3N8_GIf20yt-|%b(chV+<7cRY~#?+tJ(*Te*4KPF2@2nhZx0 zYWp#2%Xsp25xYiMzI|d9D})afVA{q^6`PIBhBy9bNgfim31<6vBhF+s(WISCnqT^L z0b%%Y^^aMb&!xkLkmR*+Y@i(w=(2_9+GeQZsKRwwaVAC>M5DxO;T3dll8_-|XFj&) z2x;+2I)C-9*5MHg>4<;~2@de$kc^2C0x+YkEn&wTvo|Vfg;aB@cENN&Mm)o4=nH+| za$=}5P0XcWLU`}&B~1S@@=CFMNSbBEn~2SJ8HV=SG>IpDkJ^ork>hOHLYcM0!C(xV z`KdI#**2so@gY-{#%5}+ zj;XlQSEblcsG?AVp=&Ce`iIi)51;yX4~^=hAGo%)fzn5Gxb-{jc)Aq zf&yt3)g|0$IUTM-NJsEnT6cT$cMM%4rF&3;B1C03JfHqLa}2Bj50JIo)3P5^owEKQl_&aSer`Y~CR;s?EEfI&B3YFeQh0sLxEb{8&hdJSE-ch%84 zHtgeVr5rW-@qwhXHHke(c-5r{DvW?RKjb8pWuq)83;O5Pyxx@XWHYynCd+DZ?rOI1 z`5q8-batbP((b*TaJ{FJgtA(x(znhx+BMBG8l(!(;8Vgp^#qrYd>*Nr_@kbJIRU8^ znTC9>C8BZg342i}3?*EATHT?XGtGIDi$de!NG>EF{~$q0#EdhoAS2HfMF^ZJq zQR;a8TrtFS?L&fJYxmu}B1)JG6~Ihu!hG(nchrp>E85c5@4V-HQuS_<@X5-d(j77; zx({xlQ`?3OiSrxMw1wYg{>U6O@#VG8L8ydo^V(O}oVvz%a1-8u&_Aw6ejJh-> z*gxK=93$QO9m44M-%#t8aTty*pp{K1i-8DT^17vD_N7Z~Qg|dYitaF_vx|pQC^I{R znge$};V8(D(2#Rv_e3lfi|2INJW1@Flq$r#(%g>24mm};6Ye65tI$fuZF^q16u$Ad z7iNZu1c&i=BD!`SVd0%rG+mf&l+G(;YH*6%MW^(zha3Ud#;W_Qmag{VQZ3(?7eFtt zAi}7f>b~dUvcrKh1P0J_na`8%jnq( zds4D+9=4PLSy50o(V?z#YfBJbW=i>2hy4fn$3nC6Jcs3h3i~zGwTjyH7A~u%QN3sp z5xsIv?X}m8$BeUn&24V2?-za_Ru5cZ$bNu+!;)N0C%MG(YNS>C=7s8bgY=8Zx>m8) z%JS0(wXvKYtzaFjdU>Cm3+tpFdoS;lQzmZ)_32`cscn4NB)wgyGf*!s(wZ<7*{BW2 zK$nr*ySEyCdY;aO!_W&u%P~4(dQKoaO-pu)NmokEvTV$vV`kFyIi}Fo=1$ly5@^}e zGq!pNh_6y=VqbOUGJb@Qh=r-KuBtBH6 zqr*zk(eKDlL|JK1U4pP@X3?zIi2vrf&-cbM$0q1`8IpuB7pK&|ZwYL5h}mC`SG>@u z`|&g?`q8tH#lk+&K>|0>ZJmVO5>qXU-BHC4hRre!5ACA4{)?;HFwGX_RW+$7Sr_{3 z*B^AKgk^krG$z+aKjpd66h6JS;C!ZU*csAAfmB8Sez6+{r$hh-N(tMCKWc zGT{7(;am;$ zzanz>;}^|^H_tW`uai*Ve)8xhJ_>6Q25enB*g&FqXqL2w5mGVg8v z3eRhucOk?1fW*{^!}bV>iN~*_>LG~e_D8vfn@^amK7->Y4p4_V41Cg} z^n*KMmq3hw*kizEgI@4~v8^)t4i=d8EORp?3xW~_Z-7RaIP>_E4Zn~%xDv%-Qsyc6 zeq1ICJ`n;n{1}`t`SrWRPux{EheIj!>YS!()s?p^$S4Z9PCq+Ji*Px_^;~c=^LzJ0BsUbOLL^=;#UQSa#x|zj{*+IeoW%J~;ob%n3CT z>VG@9=KV(pSH1t%%Ix~TpZ`5j8dm+6iwLdEs+bir68c@?f^t&xL=eo#kSf`bdO@+6 z5A&iaRb(ftiQDFg#s4u;>T0ac5C7XXr_uTJDx2GFW{X$Q*Z1q20d^}qfZ2w7qIGj1 zT-AV=SFV$~NKd(^_9%$ST}++*VCJ%6vkupAboXVscimz5f&r;YASp^K>NuNh_cM3j)b~3c zoD0w-JWIs@tJ%O{NEFN%Ls^oQ>|w*O>Pq^)=$KQqZhhOUqzdn5*<o=}8KT1#B zys?Jes>zs}WN_=RklwaGhwVnEg8S&GsgBEi=)f62*!}@_6DeML)K~4I(N4eo(Tngv zS;HOSnm>HEiaDdf=skp#H349QZ%QHdH{U82r!5*Qv;#;9+CAfLCgaJkj@IweQdf?DgLSdSkXQVH`ISAbiU_AOZI z)&1l|P?G54(gM^95-1-b!c+BAGbMH0F6^5CShl!R`l2N?Zmos3XW}*q7SQUfa62g6P zy8bBet{W?$5PkEO5fFk#-+(3I1I}5lu%N_{k2N}RAocVK_V*6|Ug58(0R{qs^B)aF zbpEGy_`l~z)<4mf@&9bwjF}|D*n7YN@0e^*)CnTUsS`#i7}nv_f(;7ND z$;{1fveW+@zWVKW)%v=g^MhpGVM0OzI-exReEcu#C6}sS5!;~L*S4`>LP+*KSvO<~ zW70})U$K2|1e~eRpvA!W&IIQAjc;m(ibFy@R2y?Pj3Gk+&sv(7@l*<@WVPa4BZY=; zGCsN3kyf5n%qTII-s##Y*`7B?TC&b)}gC z+gd6dF_;Pq4*!uLS8bo``rR3-`Od$S)(C>d{bba!S!dkgSPwsEW~W5Y*U!yf!rZ5H z^w#q7%J#X1{dwcYfY&a8pMT#y>{13OC86|6~%rn3|o7SYe-6DMI>BWzR(ST z+gQ%ae67>Nk68jTdESzWTbC83jTC4KX!M3Cq$jvIoR_a= z9K$|&C+UE0DkDC587$zz9h#rejY`tT?S?Vd%pqgxb=P5hq-T6Kwbg*Z(=0ZERA<%g zqQ==c9;jLSB}A<2R2soDg;v;1b7DXNDQi<}$a2*qq?YJyZD?pQS-W2reO~UmmV}5K z-vARp?7!fdq{71b`KS&U!aXWfwi()nHTI6g~q>HIlG#AR=rNmeYz^GB}0g%Zi8nz)cF#5JIgcES-qX7p1avAvc`DKz}tR5DDo? zz5Kvs?^uo$mwd+oWhrazjfR8P{;BERqbFAR)-{C3V)VYl5QG>$>Wgl>)?erTUEEBY zsCZ+0W+Lk|+e;g^AF<3r0xC#4@GIaq#Mp_f)@ou?@mk0>>{urJ;%Ui&&`*_pQaQJc zO4!?FfkYMj`fqq3RGzn3p__e$w={T4Vfz0|xK#{Y0G-CUa1} zYZQ9%qc8#Bvx+`lL=Ax=GhCyX>T4wyl9oEoF~$8J$ut^PQ=m-s4ezTssmKa!)s`d! zV`HtgST&#mn%E}!=LDLcr%Oc+9l~{S6zBGtJiw?tkdYPOBQNu&oEAo#2T?JlW{nQT zG*mYxEkHj+U4a8sAP zI)AISmDh4HPSI7_G>WkK9TA~irg{s7Dp2T|%Q?GvGbQW#WU;!Yv?2j+HF>JcABZ+?Ft zX2v65)d~JxVg@NVb={OexYQ0{UEC(hkuJ*_5&?qw#^p0(vaOzo*4+>dnvOQn+E{%p zO%i0gqRF3{Slk!AE2+#b7xI#6xBCfjt7Sx?4rjV+Q-WQ%pzro8L5@04#yUc6!vJ7+ zjMjWaS~@FNQupM#=sEl;u{|4J%K2<6hRf%1-$IZcWi}pFUvx*+S(=rtV?zgx@+n$F z#MFIR&_+pCK zfig7W_q2{>tXyMaqN}QA5z|XU7}SG@{OGBUz?Om}N({wZMe-r9pE_rfQwToner z#Kl|DY(5fk!U*Z#fWhtdlZm$I*gXd|o9dW2sp^y#D`Ts+@Rkbvcz4y)X`m*}tUT)k zPd=e7ez#!;$2a!HBZ?JNK`4I`I*iZ)HWdqXf1?cE#S`+U!ru&|rfJl-O`fT*+)e_q z7AFhIpE9id8lTD8{kG=yM*us)$m7!EQ@1&_I`A7(P{cf40rXzAp2`bA zifXJu@uVYy^-wX(uqlHNBp|V1yC_g-08z^B7=vE7EJ1oog59b}_^}?ruE2F+!oHjS z67qoLt;$tRZwLtXR#}_Z<_Wl3qS9=ww1RkTX}3Dt#(=VtpASW#_J*NGXf#*gk7+2F2?`w@mkr@X(7ZrfRKlNZ;sZ1%&N!s&C@&3*> z1Cvd?iOmk7^0 zT}~Z-W|N{Gc70dK>j>?Fv#Jhp583IG7WmD~eav3fuTT$Jn^-bBAJ{q}TsHM=dRbghV^tqP!&(?iMKB4b)j64Lb{^$|S z!3FaKwO3!jXic0yVKezRotT;Cw`xik3i&cpjp(X68~N|@Di#I>`f zehWy54e_-SMt&5%eB@fN$E3vzjjxFWUHP6$7789V53Doo_f!pU#FJ+-{()dE?lA7Q4CJO#*SZ{ueAFI3ZHmIW6m2@gXoU%zMx0?^ zOQI%W)>Q2A6|w4^5Bg=l6;7=wVkvQT!?L6DHMf{hiYQKAS}}Gr8}2#5yS^eF?(q5z za@M2TG(LB1WM@c2Z%WW3mP~#t;FBz3T_tTe#sJxiNA8M6$A-Ch!k%h*?aH&>x=yUR zC7LHl(~pTcShIj13C7mHAx^g)V>~EnDxHi_PF`77?92oM#rGYD%x_BiAUi48mvHhj z_s$%fCraJp;r1UBA)gT8l1CU2khT9f5wiYo={^5%u|>j`KNXxz{vGl6@72Eyc{Qw6 zP&Kf85kQ>`A#u?owZ*#70vmQVVa3`-MN#wM4U}lNZ4ijlt`2S}gm2Y#HqT#MW}YbD z0<0?6R*nq#FI&OZC>Y&!2aKdkol3PL%+?*395>~mo)#b~=p zOR1PGT4v*10%c8QjTYF;Uk)` zZ<;|5qkJvKaN{dHu@)I;9>{T)M|WBo3)>P|AeFhj*_VRGrIy+Tn)mND0EveR` zS$*`3*z8D7cVj8Z9|;}(6_|+0fTZp=Nk>}S@mUKB&wjwQ&jE&{t`~P{dQ3$)KTU4#a=9h=_ra*=o~}4!a&soY>&528E5jJ zDkT}v&8lIB7C}v@a@}3AGxkLqb{C5!=`&6=J|xFh%8l(jG_BTJ3wW|73&4{j`iIk7 zIhCzOsiG@#?HrL@!qfAi-k}oaNCq0xWaN}}*mvf>JjsZdv>8c(Oj9mh&lA0eYQr#2 z@(2yper7yGL+C+YU6Zv|c``KJ0aGAO;>_oHh1JSr{v5gnQ=k$}y7t1!H^;N@AMb&_ zU88eq?1$b$r%st}e1){e4M~hlc$M-=sS(KYEn`t5%^tN=-&kLcr0YAI42L>tCgz}E zOB|978PO5BZ`C*9N}5kv%-dQVgKMd-0|Be(-eC+KNJHpI18i)90!C}vJz7F2Jf^X` zB%&SMuBxP9+^QN5aI@pEot1)i5jE21`5MU=}buv1no z8basHMEd|pij(b4MFypK#$J|gE~Lb_4LbEW$8Li-n2>^mljc?a?NtIHC{7aXB-Qc> z4AXAoMgm=8x&u@}0ezWfvCVyM$lL=~9-jFV8RbJEPh3>{mY<0)TP!zMBgdy7*kElX zklKAX=I#$w8ZR)@3Gw@7!KTOlzEpJU5$mc3wF)W_)8un6w+#@c$CtZU&2zkDxNj@* z4RZ~tk5+G4Jo{!C){E-rFBjtWHZZMl|89I0KiJ*8@8i_gd!vB!L13t0RPloRLP>Dg z$B6P8x1=evOKK7tLE*Tp+$~6_F)a9HclT3|EOS_%e4+i6dM66+3qD>gNn9Iprhs7E z#4T3TA_WW95UMEoftitCFoFT`nW{NT`$wB&IkY-s>5LT8u-?meEbMlY3eN(U_#epB zm;`jlHIKnT3%nX{XxA9l`I2e$heL36PQjPt(8OKQZe#;m54FHgRIlA+N!BKjH|!X? z!dFf%k)GbkK2~+jL+<2r=>c-iHT8U<-)K;z1BkwXLCJk1K}7pUCByWwY2Z*959P zL2hd_x{abt)r>nfECoLUxyi)_SupK+W!JeAz0wIv_CA68C%{c#IvxiUWkMyy{Qyc0 zeK(48Xl-+kNG?0^BqOtQP-%!?STh!HC{d zGKt4{>drlmG>(fd{?A z?SOronFBJX3jIx^rZin_`pKQeOJQ?CRi%-}YR3goxnT4rxs{qlLj9rKVW|n^9iHRo zQ8$5}PN;{L-!s7q0;CTzBUg9autS#4O*)jMDPXRcvxGb!Z|U;1>LUh0W69H=A(P6R z!ACNBEW_WRHNht?W>!_h)#HggeT8;Y=f2(+3OTWl=5^tuOybK-n;hw}Vz!ZcTk%F7 zTsK9f$9OcuE5oI0Z91`Q*Cyi80v%%l2$L@tqkC>8IQ5kszA>`$@nU>^20uB!2`;n| zFPh0kx7Cctx!vNh10U{9@CU!UD9{6oXDSqymDK6wjj=Fz$k>W;wT@G86>I;<{rpEx zIL%7qL10fma7 zW`VjKdG&F$7aPO6g4cK9r6S_LQ}xuk#MrE>*$A7^#s4(z)Q2ebpRJ=94l+49;4~dh zxT!*5%a1W>EpZ&DV2pGo=|MG1{*sT;y-$3cv5+u!uFOwF^AcC?cPX+s?ti>WWiy=9 z@Aecu!U9S{CJeK3%V}}Y?A(N&eCCrQ)3?84L*5#v5HH_cfJ4V4SOU`rSqmf!$T2VD zEq<=t&i-+T<1s;-Iuvi$l8QX^tE5}6S?3pe9>HF6KiMi zMP>*VzrzWIurhXpmWz=RcL=hJ<{I&UMCm%AdiDOBQp}!Q)Z63d_a(2hoUmcPkzxiq z@|--zdhnM!jk?YHw>ORv```nGydj_n+mSRUPy`WXj^0u?&U(eNn_Qb+0u7zSA@%QA zJs&CC27v%Fi1iMtW>osWbHW2*y5u-!7sKrnYKV0cgFACba7K6)92sPxDU3!b1&BYs z|FFU3bai+%OsvYu(kYLmgdS26huE{f-m_u-z4@KbG&Z(ZsxU-_ zr2dTq103K@2@hC?`nq0){`F~Gr?Oa(^w%9*tsu;v=I(Q6!Jx+TH`&o zMqp_4fi?VPuzGLVC)@fOT7&?R{|DdWYihQ0_Rl~5Sx@%e&>TR3fXx5LdAaTXK;`xL zY5ISH!@rmRl^ozWXfT>1+^Hcz-);yniou+p(Do`ZtO^!nyZ&rT;IE^ zS-)U>>(*$hRYqsOcKjC4pZFx&0I0W@2%GRd&bA zB&&Lp>d)m>8OJ3&2FH&n>!)j|OET>lzNB`t6^S#|-W2wx?(*~{ZIvad0;Js2*$r1+ zcu%vP-fJ@sI?))kp}tEjY%>;Oa?_S(>d_e?U4+koZZ*IheWu0*ZbbMsX-4&N`{Xrv z@%?vsXFQ;ypN$1c242)NId;?=#jnNbJ8eD=9-P<|7bvHcbh(6Z!2Vl9DfKGH6x}sq zR7|XBqE9$gID%%$p;bxdiW4Nkchq4sasd$$HtrOzxSPmWF%;}$v{DKgeA#Q!1)!@mjQ zirVs46-gNU*Qq?NXfcq^P2$wNojS3t`Y(dO87^_>Ui@7!ws(g%DEx5&NLG%UmG$7S z-qVgTtJGyY!@fCdVZOvkDW@GBEmM|`=#rN1vF(_xiGg-VI-;7ZdM*j(j>*C+%pmb0dlU|+#^Y+i zbkH{bMG!TA5rpzT2x5`>jzy5KGhRPAA-B28CPoDxO-h53J+yMrsWXLix<4tNoxRl{ zQP9sm;~+<_(3BDRk?#GIOQQ5Qxq9@PZflt|^d=tU7nXq{nN(s*Cf$(}Ae3g-C)}5o z>p(6X2Sd#PZB!Ubcq$eS;I$ea5*XPwq-Z?fE~ut9?Wu*97WA&c|G2D=FlB^-Hz5c%lA|fHf`gW}= zRRj9*Z7EhkJ;8Rz(L=xAyiM*@q0!b>zt!v%n?&smqml(3m9cG8jX)^#*WBH{jFRzf zRYhuXW@m<__05Cg1kDi zz{A=YsnU9|=Pl+6bAk6-k?nSj`-N|1@DUh>_b^79$ljk^|BiDI(GQ6oy+z@Z{TLtjN|3P0 z07B}(7o>mHq~;I`rG|P2Yl~MiZoQQO{zeFCq~fNl045eEDb;7uOOjra25t8`;kFr6 z1nFDp0ZPkOO*pXu8|2X+{?+1b>H$atyzUw#S;T*=#suqM`NP@7c!P8I$4ERG7tI}z zPYH)Hk^RV=s}vC=#sZEtPc2sp*0mxwrXwUn`01mYF2Rc=J)2DA1{9zH#*$tum=?WZ zZZf5FQn{1iW2n0PpAf5rc{MNjxA{@)LNN4HPN6+N;&I*T@n7q}UyCNFX0jyq`Z$VNu=Jzo;!IUUR5zvwKM=??8CV6V2TN!vA6j_5aNfB7ZZ) zKuJr(-wct-W?$^jy+F~Lg;B45_fLi(vGZW&k^7q=z+Pg1Jc#AQzJ?jc-Cb)BZS60w zo0r!l?E%Avqc3ZORKYT8idwS;=iDyBYux)j?Ke>CTkcX4#dCO9e)zU7Sh{$>KCML5 z-p>S)#mu_C*}ZwXzWeB<@A_JM+WQ4+0Qey>KcKjPFSC8naoSd)Pg7}XSE&+X%Kaib ztXHf*v-lJpRbNu0)>9vmqHoud^ul|Mr};ahTXl(CV{_|h_!Hc!#DjWL z1_r1(L$#T4+L={c0c|dO|gD0jIukmwr z4egyj4+S;0;lo4A3)4Lsr1;x0T2zn<7HGowKFS3r)GODK|S9+|%YTi!2b)-Z^OiiZl)D3XXmx|fzbmpikmlZ@wUCl4a~%(-5*Fbo3?YxJO0 zg}K^*wq~coBT9A?YE)Rq5-mUjeXFk%qEQ*~(NHAdr=r&)ps--Rg&Zu@@ac@n;xKu) z42dNxK7ggvb|RWS0+FgWrXrpt2d^Eg=(IbaMErE6M@aYz7Y4F5j%;#pm7C7CAP?W` zJh*TEK2VcL+dFYFfxPhQHiyeRMlSqJ>XH)OJD3`1Qn(TdLPDSnNF0?AjTfcBtcY)$ z*X<>A^^TJ*LZ8}0<;k7z@cO9WqNA)x7CX>(pmt>2C9CoaEx8KcBVn_=YWu5U5--ikY=ZzA#jP?LU5ArrI??EAAFg&VUfd73{Zjy(2RbU z@WyR*b2wFkukO*+DW8F{FeFJ5IihrB(xd&uq?(gJBKrFVfnjOFkB~+I25oFNe|>TRp2>nT&vir_D%KJC=T04xA2DsW6Xj01?s)_Y--S!;`@pS|3BToM#M_B&%S6>lD zHB}D>(|=OLzZU-wh6u2Mt~64mv!E8U76H*(&n^2e!EE_m=Z0Vq$1+yHRNd)I&S^LQDL32bv&vEB zIa7IOVoG*G&`ke+eu!3$%XBRO4UNSncjeTDzC6>hdQ!F&?G1b5k&2Tp^Yr549Q`1u zqq?+h@;WHp(OlUL?^_5P9&fq>w)-vy*TMu+o}EafDs_ik^tzplb4g~?l)E7IB+`Y> zJ@?553@ZZ&P#miBowq;_u*pNe=;*SDKc8qx&?o)QZ3DIg>}7|kE$JGaPuJe1g#goEva?w4S+MAvRIoRyfsz_1 zr!~+?)QMfZx`~X_!exw;5T^Pj?gk0_rFR>6W(i3dX-}S>8_jszD{b){6m7<9;aZ%A z>DoAY$V7rM$1mWrJp}9t> z4eUVu6(}>##Y)+O!xVG{r-~Gk{f)L82ixxvmr@J5crrtB+j5&nv%5MaZMHI0>+(f> zk!67b6=<<_7IP;+Q+cvry_g7JfTCqG#C7Y|@1HE=4pgsQ=4GuBggZ%8&Wz<2gK$Da zOjQP9u&du36`2E_0gxEkuZ14VHc3MH)~drEQA+8Hqxg0xK?uQ|J7s%n6+n;2=~^t^ z2#?T4YmdM1f>xFLaq%dAGt6w$M4<4!O2a4;b!N;dpSRJniI*{AE*KUeu)1i0_>?ud zWwSwp9}#PWBlhNUqJwBKDFPy9(UfSy4~aFe6fj@@v$_rz6~i=k7MWxl$Lj%kpKrV5 zF}-22Y3Am$HovOU$!+%V#!BZ_jh8sNZ@4S)$@9U+zx045j4yzC`~KpuW`k_&l4hqb zGd)w0K`H!)m!7915ykzomafD|bf6H$lzDPeb)mj zZpMh!N%LnEh7rARe*V$Gmv>=>Es0@0)d@p2!!t{6KBCZBv=D@GLrnzI--^|EE3|$K zYpr1uYZm(?2t(qL7|1cv@0d!2op9IYmO|h@w0ouY_#S!jdJ>9Kjn5WCSTPG4lHq>u zjt5$98C?uT>d{L#y|E>dU$qumLYwlHLH2ykbHq8GF;9v0zoqFzvOpO^xH|bNW6Q#Bd|#d zgh6Yw@k%suh)s`&tBx%;WEU|Upj`XX8^d=mG0aJhwwe269Eo*JT8GHLW6h884_)3E zzGFnd+JD$hrm;&}2vs1Sd7&3T-1M_w4ZD=L(10h%DYmou(|{oxr2y#SzCrZ;?$-~w zu{0deUGdS$a2jMS?s(x; z1bXL~oD1!!9(%9Xct(a!Lw3X!S)-eJZ-o>0kp18HObD1_?RdN9ZPc8bB0Az4x?tVd zR_o}2H|SJmQNk`jzF@G3wP11!*;0qcXHzXy#!@Q4PiIIfK}l0%Uy1 zd_Br^*ChO_HJ1OlW-=7nRm4z&J7zwt(tsftRZdcS9;1Zr-q149`;&iq%DQCq@Lvd` zrtVy0ta(f^IJ(#M27p;loRb@5*}?|S%-8dYP)U`LaD^-yKCu?Xj)*i}RIH)_@-p{r z1X8uP(a=^J%cnh|Mf)7Yg;L%9c#Ji@$1Bm=8Y|Fc2kC_>Z#6F}_0V8R%o647B-K@y8H ztee_Km&f~yJ{}^Tu2$uCEcIqLwWCpVRE;m7;FhY&ikfxX6b=u%Rlg`j`EgL-G|+Vi zbwnFiWFHM>gr3|kZFR8FBWvi9*#L>5r9!;b-V%^;`$>QVv1%I5My8$OEuJc|30EhR z6@}@}Lfh!6YM{LC6{aI3XIx$~)U31OM6gij(*|?AF%}8BB*yF!o9Q@}S7&bOqeO~m z)6s=JwL75{P_(iVkw}!M2+IyX8(9p6p8H4akdxQf@BfRqw~VT@TeGy25D2ny_uvj2 zcL=g^cX!v|PJ+9;ySqEV-Q5Z97Mvg-U!7vORd~x|ooihBKBa*%)b@_rrAE$%>Se7YR7NZqmjt6Q6gU-Vw~a zdNRQdH15_H$a+JO$n9zfWt@bLya;8?ojd}2bxJvj&_A`XU|_Jbp?(DtLXUQfoJTlO00Hpt|dOyjg;sz?4x;`lrF z1Goh@7WR7Iojv&tikLl{pg_5!9@|ymyR_&&P?J&GoO-UJ9UxocJkH(U4+n-sVo&R^-oiuXC?3s+wFKW;H57yjI0Q2n{Z z*!k-g!%I~b>F`fk2KC&=6I-m4vC?-|SR z0irn2{4XuP9*Q!YGM=E`EZ58>#5&6`sT(D@Q*r^ zl$OH%<4<5ujBfRuLzrY9zhXF4mTqb5P^c=gSe*9-l0s8pBmY+tZlSr;JY|I+|2{9E;NvdgSg* zsb?f-W}v&e5P{^6%eds7Ps+@g)of=7&;*y5ph?*?JH|&?7G_cxw+UEwIBjGt%9{qf z&)S~B?AA@hrB3F>1?=d}OwlqAd#aZle~OMz!XT8#&ICJA`_!y;Nk}Xt_6tz z%WgD`CnovG^U;{E{NX>u1p=T(WmTDIwiM$#A2qAiZ`lHxW^^q=niSz;Z?7<+}J z_3rtdmJvC(q5$ou&PwS{PaGZcqbtYxdFv|=oh=1{*3?{higO}_FD~yY5QM~AUI9cH zCH4(KgiW)`92~N=-YQWrRL)QY&?}j`zp^CEyq9y91m%R*r|JweYGCQ(WBBgA@+THE zD4|`T+y=q z{lGMDe4m?t#FeI$qgOnib{HkEA0DMJ5i||>O(D2PVaxA#buc1lZ)@hP=l>JasGd@W zeKCqTn}}5#uYwBdZRGu1NG;>XwiWns%RFVP2juuT5!>QO!jnVa_}#XINFJRp5YHGZN{Si2+y0yO z{d`qV3R2vOx3^;}o*+uMCx9MjjTj4B=$xgSC1mYs9=dpuI)YzWqLaL@aN88w)Cwsg ze8!q~zaQj}3|=#a?m*k%Qek4?@QNEC|J^PFmvW3K%a#!{g_O%7%ciLC3beLMb)k0g zY?QW&pOieAcHYo|sZJ$U8HN=t7(k6Rjwx&M3vU22w0&x>4<8OV-&f+t&rVLe)=EHF zpX&ZSs3@sOZoj~`@7O8zZo^CopygF7A z42h;xl$9HO@YmDo^KSGSf4sBjUX7oElcs14Qon*Qt1qKDm|H>841oq(Wp>PbZ=6{r z|B6a^>d+l94oZ6>tT1Zcb0XMcN!{;EjH_~3GY(WZ8=L;hZ(-~lO{TOGbM!KK)|A1q zox`A$yb@28ezV2tKZo9*o51j?uElRCIpR5w{HPpl{_FQ8+X~oVGy)sk{CceAqC9x^ zLu-MZF^|ndNslUXbjRr-JSWiZnWD72Z9hei3(8Et`>nqN^VQX`C?khcIRfPr!Sb&z|1{)S` zjP^kgL|==BT;0#oG~Qm*`s;op>l}JaE4Tk16|jb{(aCvB0)--GlZs;!Yl@D@Wa=3H zR+Dm+%H>aw$E`im42`)WnNKdvK-j15b4$O*T%z05TqU=k+7e@WgjAa*l2`+o4sx$^ zW7gE6tmp30*lw`|t#@j!X$hVcg=K@eY^;g=qch2$Zpmz#XR`N8T8kAKMEGDRo8h3qM4Xon$-W zb0z0%OcBlTU3Cf7W)Xf0-z|j5a#A45C=Q!o{P+pOi+hGbCpgpa4LpNs$2i51oleDe zxf`;gnz)C&$_cvCKypl&54EkL_1s-D3vmPy=MHT>A?`1<_*B9pDE^8TRR8jvv-&SR z=lFqc3a=e;C`DlI#!J%Nu5;%3w`t5lwW6v$KibvknDZrpyEW@qI1?0$cA z_D<-+5Q7F_-mG7wu5pW_JPQM=8?bcfs-o`4qidp?8FEc-kD^zaot;uvTC@GNqR>#i zB5&7{;39ts9d14-HFp<3jwQYX^!xUGmG>5lYCEUd^=7uNF*f#DN#=p=FO}Q}@-O%60K;LBJ$GHiwDQV z%+u=RfVgKZO6DuF=r1nkbRTFkz*0j(co2>Ne9@QcSV<{)v`{^l+hx1Mf#|^atLJj> z2w-QV#mw(_{J8?b8>f?)vZPVNO=6^KqhY^0@e$=hYP~7kCDu)u>>Qk~otpM(YuFRS zgsD<`ZYnymxk>%W%KA#ZrGfolU34NaJO|NPY&NkM4-Yw0 zajKErV{UMr%ViW16a`uOh8jzeGeT6zBK(nM;&PmmNWQ*$PZ*tU2A3ajVT2E`x?n{c zcfhlCTVFo3>GA`k_;@Z57e8_6EjQNrEJv6d&&-iyx8z29ST0Bl7#3IWqL4yzp zg`g%N^khr8!%1*Rot&Ncs{XAoh5V>frKnaAp7FcwMY3SpiB%X<6z33tY}DAY>ao7} zbbZ{C@>ZDw|GsrM7D4GBYh^eCDsPD|JFKB#?v-?y7&4%?>!_-jRPLI+IwI<;P)MRc}VY|vn&eGLVpP8vO%AYAr8oiSp zp3v@lzgq2*)wYp{fIn|R)2(TRKN9w7I(Z8?1BIQ&Z45~0#3+(sYfE1}r8Q-ZtRI;n zcj-sKQiWmISn^LIT51no*zFH!esgZn_E7Xs+cIs1bn~aDAb`^(=oxJm*7brm9TT;Pmvl%QE!fy zGW%1Mg2eCY%3<-(w+-JOsi%U>PWQIm17u5i1h*iI!>q){E#p~HDRUAqMblM$lZ~~s zh}UJ;(1_PqV`QvZONe)%5w1}zH@%;DiZANZM}CY?K_x&?vR3aM!WLwey0b~u zEi64^tzOX@@;I{7_%UY8q`4QK)7LwrV`cV5O0ro=0L)rz|O-{((h=PZa zlZ9LQyk~7xOrFnjd+dy+G`>=@&Ww15pTvJdvU&{Rijud!GD&tPIHS5$Az6MM8Khjm z98jV!ry;(_AvrX&QYv}zs7c@Lftq8;i+G6w@yI6G@{Fn#wye=Gf+=vfOU~xQ2LXz< zpRpCLIbiDE=<>+OS?36Mmd|zpq2dS_BXkGe+l1?`Lo~^J#Y4v^re3-w8%ka*4DM3W zcq5Bd(`h(#kLNGW`XF8&oqck3J5TXFxsm0}$ys`rA!~XZD(N`oV#L|{f#kkA@QT?v zOex#CjkI;9LrtWxeIjuA#-7TArGV6Nhn1T6w$n=E##WbDI@2?6fHI1EC>#e$4?RK; zvx%pBS7n`wN+*+jG2RcpKzr9?a^a8Ag+}!AuFc|)wBH&A11RePw3SOLn2J65i~DhQ zpMYY6HSg2Ck1|(L5~p!00;WJ;x{{!&skfyBn*=S}?-s6py^%$U3jd$Cw5WH(n96v6 z9gN&Sa@79)mX>{EneBYp=lJs?{D%1$%Rw6#p-$sQf!}X6DbWVBcnm_rJ2WarROI=3 zPD5J0xK@+9^Su2kr;rE3({0*4wLw)p2^CfKJ!4qeUCSd_dq`9NJ&;-)SM@Xgnbv)a z-vBwi{w#!U2w%&hq+x}|pV3L7zT5%uK*KT+$DxpZH z|7{Zr?vc<2UNmI(ii_W~&;*5yw(hChR`GFq{L}ax`!7`y%BUOe@pH%Ree1x|ET##{ zuSj+KBtL!=^T+haKyrR=i@kNlyqC3iE)+f(-9Le0<{I;v9V(JX5*(y)`y868p{U3` zn>h|oupt1 z+6RpuNjhO}1HmuMG+P}r;M&{03KP;JNEpjpJuiGZJb|2mw zQeBP-NgvM+1g=0<<#E!km$+)$F^i{3Ew}e-jxyq;WO-1gsfrk5lt$b^1$FQis%39&V-!-X%u6gymU*WlD?27-WNd+a$CLQCQUv5&EisOM4 zgOnZSRnULsmUaBNaUZ2N%O8(v`n2T#R+EywOgCSMgXkqg>DYd&NlpEuCe@imC}0r% zcTH*l4?YBAHnD>8ttQp3$D^q-W}GlJY?riiY@yo}4^0nDRh}T7OC7~z$+#{ZU zjhRkK&4KCC5E$_ZI4OE}pW&k$JG+x>+lh zHB{j)ThiaJcD&b1w4{BRAu+t&to7Gz7FCcRj8d|4Bk=gWZbGKIx|1v{ss5A^dt|yJ zhF-2m9?a*T|11A<_(uV0KR1}vujg`0+wq~NPOyj^Tm?>bl&FpSBTVpQMNx`S=2koJ z%fub0q=1AEaur`S6u;tHBafI7jRXXU|!v7)x$=y0dj-`_&6)vg~K8@LM37` zEj6tyWLt%=9TdV8E>H&UGr7*-S(rIlZzQ7i)B|!eP5tJC=IJ07IILWI>q$)koWdgl8GQYM`(1Ogz^13G7V=A9<)vC$7&+L;D70>B+G0Fj_1cc-_S$)C) zv7$av1okbINrr9EN`CLYeAF<0@MQM+XJO;!ZX;&qp4DnJtaw3X=Zq}Iv%B&!M*m0q zb>pXG9q*0)ZWR+QHWr+9snFaDVlA==wF8aO3A%6+`-rJha9o*ve4q2ikaUf_mOBtW z-#s`t?=XmNqE53Nqd(;Bq9Pp)k|wGeazFNu!+c^!kyD0;71|pUbj;;@DJgtP5LCaj1Qm zs+Utop6C*!3>c8M&@a|{)-B{h1qD8?T3*c#ztyC`Q3lrYX9>xxob_NB37|bApDn^TTP0tBIA?8ZSS9wss&pO&s$Au|6kIB+kch&%JE6cSeshe|2=i_AAkDytG!S1 z3W^w>;V{Ralyen<6C)EAs=ZYBaum^lf#fjTAN-RYn{ehrT5dPnoMew%Mi_oqRwR`s zJ%9KHq|Qsm`BwHV=Ua}c>v&Uwq1RC)qXe+~-ZSIUlk1lI?D>8G4M6h0yaN7R?avh8 z9B|u#szAzSwa!8jf4mUWsyI!F);I|_+#_7bRC${23M=QZ(2jyNzNXJvDNW2y88_V= zqB@z=YLT5?6kFN(-9TK7Px$ZZ*Zph`C=kFt`Lu9UhamJ8w;q-s(pMNIqnSKRhL6x4&%7mDoHf ziKp6&V2$%ExYiuo$R9}PLj8AU=ldLYx7{GS^#?(Digwigp@tfy6DJF9h|9 zI9=muXW@lKA56h@1qlO%WP~v!X+9`fSSTZ)Vpl z$%F@DoX8^dyZSq{`49g7)g)^LZu6Cd6pZLp`58h z)6~grjUYYDxPqISzMW6p;VG@>~SiatdjKoCuU?P0z4r=a`of3zke-KcZYAL{*1DDum4CA z1+A?#;SWZiOOMj`nWVvxD@O-|40BE;7WoE3t42ejSCa@@YJ(|{-*RSy)W%F*&!rQn zl^2RR@Xk|p?^ohWljG>9sJv%VwK>oRk3y(Nor)-Riu8#IhdFhl$-vp7H_%xuH;*11 z=VOasbdbhv^#$UvmW%^1RjUbJNAwWgfUTmVgU1!vgN)b>F5@R?U##J-;sq6w-A{)^ z*ha0$C&<<-!?8n>y-VWy30)OjKF|JkORSEjt~f1nXhV-O^il2?wNJrMq(H8y%j7L% z1xhO76;$wwE!eZVSoPQ|bl#$N{6JB6U6h1K8+PMJXn8;JV)S^htMuO=xm%IevNMND z$P1N`u1ge$de7hU0JfI+4<$Ki$0_b0=MT(hEYwrx$_7pS4c`5B{SfaeDC$gu zP3$Wz`21uqOMAU`_ZgJX`cPFH*WlpUgMd;9+iKi^pm(Pqb$-}p^Ac7V@z@JeqT+r- zk1Z(-ZF(kd9#W5XP~j(RiueBeKTtM&n6tY+6-GRGjGPUFr1LmX=VsqcJ`LPB2FcLSqqKhZAQ0-p z?sB5j%ZOO|!kxo|Qqd~^jw(hR7fJA<-UGq^30!s-oksH6cdoZfIM`R*W22B<*L?$x zgXTtWkSzuDTcENR(l`V`k1doo=IyxW>4ChYOAeq zwcvugKfol`9RaV_Asq6p4!8WINsj4+}u8h(~WjB#5)9-vXb{|d&_4-nU7I!gvB&t_!qbwnxv$(CVmqc<)Slmp%_CL#5DYCNSr;_nb5gS zmHI@?wOn%+C+;Yn)(hQ5R8!&%><6KdsQM$YIJmW#voAlA%+lpK?8r3ETj|1?%TBt) z)C^QJWH#miC|Sw9Q(3{xATV=7a_y}IIQeJU*_U=8Bopl*rgj|wA26qc1xQ^Tcok4n z`B=NZ5+saN>`j>uUhm8_f2m2;8X~JXy1x5!^+8*8W#3nM7j10ym8`;2fvs(Dp;>2= zzGorhSn3Yqkshl@U;pcn5|U2QL9M%49Jm#f@$y)#n?`x$=Mv3iZLV~0(B zKj0XnGaUzMG#}q&h*WFwPt?}F^GB7tE5>>08{|!QZLu*$rmkjEyUsRq1xz!tm~?>0 zE}k1e{Nx%UPEqxgtxQ+N1oPyxO9a&`Q>DSRbO5P`4(Vdu}R342!6^tB! zrJ*bz3cbGdXJ*XPO-qi4Gdzr-0K4Ukt=pVy%BUL`DwL%xrhzl() zKj}&0CLvA6%&jY&Bkp1#m8s#s3v?D?SmELz3?^o1l8NXEIJtH^!pDkEsP#tS$vWfU zuX6ejB7NrEHYO4~43`(Rs|b0o?FHoyFp-YVBLUCQOWK&)=ZSu-2F`KyW}+Oq-}88W z)my-{?dpcfzHJ)tiU3(FF2rP&7?do2@w2bMfrK^BPIe#ot7b(Zuma}q{Y3-u3TRPR zEqhs4cks(uVq~=Ef;4GSl-09Ze8qnsGhgi*7L1$lH)>oq<2bBR;l;q$5u*&^69@xsz*7k`1sFzs-sh+IN8mZo?yGRquv`p1dcmm6l->Ip%1GTsXMtBn%P=ns^Df z_;Gc4TJqPTJbVal(YGgjz5nGCzW;UfBK=S4MfzXROYJ}CrQ97wWES3yfU3+~hs&hlFWy$7 zx5A?xva3|&htt3`9}%^|-EFmIurwqc&e zovU`i>qG{`c_}l-I^DwNIRcz+;2a7tX*0B#(FK>TOLeiVJ_(S^vX011fff*bi3*L# z&CQmDv;w_!YrJWkgX5Q;wt{-(oUW)fi?PF_uco290tFGmGUI{C>fogd3t68jS@aOO zgt2Kx?XVr7_4IPMydjoMs6>wC{?LmOLO;a6q8BCIZan|u|1G`r32OfTqn8r(zv!i# zt>Y{CKc|-+8i%33=p~T$-_c9w|4J|I|BhZZ2B25R5H4LNc$=b?ToeXWlt_mucA%jP zbCSDfJzX@0T}^59&8*f)-JT!TX|1$Lq8$+=BZyFi=nP|o_t|vpRvG#MSw%US@K1o? zT#JmIo1Gd}|FmBAPNJ<3eRtx7sO_bhxWDy9^vOf{#H@y$g*t&!45d}%WXDjgMoo#q zEkY=%U8Z7wONHH%n=>~(zr1x@#V{Eo-#=E5?a;s2ousG4cvYR{j9iiG;l>N5MNt#p?aAdtv~#^F2+2Xob{58i&Up@qm*`z(ehHQ zm829SG1$U9a^(z>SQqyDovFh(Vgh%yBa7n|@Js}7M6nx2p#4kic<@w?< zbEfa9P3uZITU43fj)giSe*)TKR{7B`gmS@zR=}Da?O1H$7z6BGPg?H~+DzfUAUn(1 zrL7-2sE@v5v~AXu%Ag55i=FmOB^}b&z&0ljR>ZP; z#Gh^k#d|p{&4OPPN59~*dy|H^+Sy-5EvdXfH*^m6t_ zFMo}MV{+~2d-&m^9me+EMCW^5kK zAHg_q*H>}82VwmQ{4g0~+E&{<);-qto~jzY@w{9+y_3J=2!(@CZlE#?J1RdZbS)~4 zZ^|26jtjONRs5S?Sl;NxN32Q@y{Txn8GVlOc(f|6?-5Pmm!+gh4}+)ueFPq0W>o`4ATS=xkHFp{db^Ea*OJmGDi-eT*R6VVVJ%Ij(tfjyM>=^@g zvx=V0kP51DMnQ~+*)B@GYq7qDcx`M@$1J5q{asyRas!Prkz3lG3PI>4U@as(NKi)R zDjT_i(iyyho{JZa=V|0R=E;|BJt6usUr1%%fVR;oj8fplU@9i7qPici+t#g(&rmU* zQ_36zZCQ{jkI3}xp{xCuVJPAfP7S-Fq47s)xqAb`0{8^_KQkh#3U4zanIo&zWD2c` zKo`)%LksD*y0LSbGOb38|NFwc z%7=!VdQ2hkyb{u`K;2*G!2QDbvqBMu)M(wBT+1OMU?@EKGF(a2uMC`~O|ql3$@)Gs z%k|H+W3i3iM~S4vKDX@TL0y?O9@pSr`WVD$foS8~wSQ(rv`Ytx(P%VL`1 ziivzdP3-9ZenYIPrgToh07wwJjoMD|tJ!HyNV_p=1O`)q1 z84|eO2P0f; zyD;Kejts1$N_R27B)wb7gN60B*XBs%vH*8i^jK?~f~RXjnV=;6w8H z9|zW#I-7*<&%kylO5E=;)o4$sUV}W!tX};-}>Z+W&3?NopHfQIGJUW?NJ%J}4MWP}2|Jv}Lzw&tmQ-sGprd;O5_MCOT-|uCpKE)JFa-LXPs5ya1KZWm}Za zbL6~!f-&BYQot;(Ygz}RR#&gX+lv6()Bq#Y8xDigO|I1hoEg!o?%H^GXvZ@yApM3@ zM+_gjJ4K5mg>EtnLswi4quT*_9>dX9&~OWa+W-A&Ghy(r;pB__FenLz?PS6^n2h#_ zULzIsjrve$pQ|%eG+Ma_Z5+`FeCysWniUrM(TO|WP!^-e0B8^z-}B7zF+hk95E9SoQr z8~ZTx!bGqk6T=4F#M(qkHW!S?o9G(sQhNT(@s9!}VKxSX)q`{UkmaOz z0W?79!T@2vPHb&w;E{OMBHR(-(&2W7Q(V6fR)l+*Q)lQJihsisbbX~@ik_gQsV-82 zq=w$Y0diazRV9Xh<6aOOEwy={IZHlp6u5>Gq;=OLO(`oNxXiHI66;yQbW6v0mM3B< z6^jZpZ!_Hk>)-eCv&IGndd<@NV3iP{HgX*A{Mhx zD&jziN-iKRzP7j+*JU%QB5raGn$E<{?1cFMobtxdPJozZwsPZp`1L>%79;gDx3M%R zo3(fEDDJ68Ir`H~$xU-Cp&G0+PDo;~(5meS!-pJ0()Ir?VxM~>aQDwp}J z$6t=2g^O}*T=_Oki%p^7`d||K#J6G5k^3O>LnTKhxXcw?_d_%vkYJm$8YD*y2M67; zu5nlL*ac8EI`pup#L*`&|I9t4Wr%&3c@_7Nxn2{|;#bRrUkfL}b6)TlWvzIPRKWfjfi;_OZ$+r)js>09i@SiNuborx18r_Ul0=My~$-BilpQo@Z@(6|kYwrczwhNvIKc*43G3{Lu1Jd`gErMNlZ zu)NG5*AI?^7mCt69NqC)6)}j<7e64U76BDP!EQ068oYp(;S26;T+#M|J{k3spK8 z{UnpNtF8Rm0@SopaWOHyg_k&$(sk}C)48i;Dj!-&Lo>2j97F~94VGPP1B=!T>7yK=_I(C3zwOQ_=@qhTaXtBZ< zUe8Ch>zSfZ4^d#dl|7#d%&%w3~RKr5cN*Ht%)DKhXol;)twZ`BSbth$tf6Q7G`cAFN zvWS(|qu?z~G_Agae7(e~{rKTGr;)u=@KJ%v!b|9+7EtE) zo46qicst(2J@MZrZl=GTTm4Pk&;Di9n&_q>-&s4v^YX~4mfploU?LKXG5qS>jGFl; zo2P)qRsKyM-tJHOtz7s2L*XNGQ%LT$r$&xr_ctT%dn}hnx3~E3h8j(?BQ}CcJ{bQc z@U^d4{2VZpkg=`ke&eFWuL767Fq5KLf@J}#qi{Dapwu&dI=>v)v(fb9`+!e*Umb)Z zU=(upwSTXAqjaV|uuqUzpxlSY>L2MOMJx6PAFZP6_B2=2%0({vx}meuG3M|Uhk%*a z$bU#D*(?~v&T?E9uj!;5uP38~JmL2d*H!HrgggfYK-z7`qFq9izAL^K=wCxR2DG>e z9O`3N0f4PIfKYZ`(}{POjRY{1S+EpcsVzY-ubo`IGda{b4e2L(!HeOsuqaYVIEVEH zA#F-y&%~p4DogoiY1K)npPnIvaIRPvn^lqhK*O8~&1ChNdZ=!Ob*YC5!64m6I}_!U ztR-#}nUZ3)EUHsCwL!;uH>G9y96GUie0EB6lKQTe`p+6VrWb`c+|V`k*(*L*^H@qkr6otlj` zrbl}bM-sAs|7UIj0&22Q^;PBj|7|K~{#)h$X5k^Rgg;*`+;57K3OWd?uLpsN7!>M< zloOOhJ6&DLDd5;Za?$x?i!mtsf)6iL_FlG+Q`}4JP2wE4>3^BH+xgKY`a8x(^X!lf zzmg9H6e}uz;p!!v4g_f~ZzdkxHE$57e`*!iS}Y&t=zaaA3})Rl9(1e_?wNkiRbB)X z`AI~^YW`~Ci`$Z~CO((8b4WUwxc_S6nd8`Uzl!NFnzvx-hE}s;#c+pA!$t6%r$X=< zT8ErM4Xe8%lMBw7FkCGY_p5X=$Az#kA&4r#9>mg7q_O!FeW?N-YDji$e{=~*|E2-v z!TW6(7DSJZPQ4~@0X2+15HdQ(9LH+{N22z}drRQ9jL8?lVThp&fLTx}dVCwJUQ<2! zmLlc_*1`IS^t1TEx39!}{cEXyC5={_SOO<6z@ziwDP+2L4lgZo$- zV`>_Y_Dt8}1lLtOV1IPeb9h0L1uGXlHa#CJZ(GOR&(vLD?k=2Q>yuDu21bs{3Y$qz zhRNif=|qC-Y>z=Q3k9j_dY5Igyh0a+1X)wH0V4Nb_hXPxR@=(|tr?u5~%|8Cp=5F{d2)JkI||ObLSTb9P}(rx0I2 zaJH)(y-K}zHEL&EPfZ&C!R!7J7?eV~gn`#Y`L*5`yJW(qgt>q;modlt%b=U=U2LoE z$f_}@VpAdeM2AMkyvwP6h|p2#h8Kn>qJ$EF0dPZn3}pGqcYA|fHW2fdlle>;agaV znt!hek`4~I&Lr&0Yr8fM8QOVv1Iy)w8MeQqW*jLlRt_&WEDh@b-ylk zfizfbf(V}RA72e!IN8*tQJaiJ>k*8^C?YBwzneuUne_q<)wzphoHZtxSypGCoo!A0 zC~Ikr%CMyL@XgVir&l#Fw>Z+ndrIv+P+h87=r$edjJn@zetPPkf#~j;RBNO}85REq zR9*^wv-CQv@mEX7e6w^DyP}7pw0Ezug)c9qD(o$`kPWs-dW5O?RW($?oP9MT3p$un z`4u39tsO}+PO6>5&6f7FZGg$h1*Fs;j7|kG=A*(et|4t5D=yKz{T9WksukGZyH@id}Q7z#RB4F z4-X<%jt6A#{TU^&Kh0OtdzCxJzub5EUnzIi|9Ph?*xOE5F+|FBPX)E$>TKdf9SKN2 z0Xbh89z7=d>62RO)3L}^nnL(z+ze5aF!+bl2!=IPF%v+m?CR)oo88S=DyQ-3$RFlR z>=r=A1<+}tvVH0bQ`~Q?YnDf!QkCP&+}1;BC#b-&yR{rFVT;=b7D5zLy6ly#P zsyV%E%zyir3TKlGGK7F@1pZrSIW1MZc?~V-0=s}!6Olox*U%E|)JA^$U5>Jjq5z!G zWmA;SbLhNzf+fDl5<)+yOI~NcN;i9%pUl-VH_~XIdjI=cG+A$mkPPC+?%)ICtD}EQ z2}nO>+SEBQ)QF07GMfnhU%v3meT5R zR~~yHnAe5%&N}Q2s`#oiY%)i0XzCs^pt40!20dYGRDMNnkX+FVeEIYvjB_B$NDc3l zRV3*4)(s^o-0^T zFhzV;`UF~qqYR#MH57M7t`f3MY)${ryoXZio0sNeu(`0PL`GjUFVoV#fInA?d)UpE zt2g}T)zlp#RooOh&sX~NS;EoZ#z5xGn2_h-JCk~`;1C`Z1p6cOtyiJHPZUDK)Q9xx z1NMa?N<^kH390X2N)2M4n0X0r8Prqx4*6T56|7G?h5SKj@R1d^BDC|ETl- zoXy4mROf%G{6x*oU12B5b8TdRIHvmvi5BU!;bY(iA#|Vwt?w5rVgd|79R_wNu)&YU zq#AW*>gIKnr>^P_nwBMwt931rOnjlJ^=g(S3saVLM^@%^%QSUMbEk8TC3PO_c4H%{ zN$ki*w(p-IA8p6($K2O{^Ne45-d=hfZS85js|-E0`5ac+J3W`&AbtID`Ozgkf49|W zHbHq|ZfR-P4*Zexu84I1=9uD=Wt;iqO#@4PJ##UQ%Wtz89WBj$x!FxPmb!cOy7??$ zFh}p#9^JI4W6$Qd{+gn6F?f{Jg|o0$r0m0*{oa4JihWgozo4}+Qe3@y>T%kN z)=gJ=V5sfK6IG9d59~7VKVA6Rkbj`R{XG zqEM;`|8aSh#^E&HahBRZa^mco8NM(!nw$+of$Ax&SbG>n%5*4vK8~g=43Wi4MxaXw z>IgR3o*5~*RG(QDri5jFP8l@-q{&Wv*aSkIRQW&?a#1SEAsbVhZ%=jm{>TwU*@71S zsM%3u-tI_ki#u0|1qz%-nYgGZ1vSsg6m%kkp3>Zy*Pbb=E@e7pBrK|~sj8(o_>lat zR88O)qo^`tKD}#9nngrccI60runOO%spQ&{eT9d|T=MytL;DiF%fR|Gr9ja*_Eobw zh9QwxJrc_0fP@JLFXOu|Vz9&uQfTFTQv)KV^oWZXVQJjR3qt7e!2ONymA@ZhxqT@( zDhFD~ExL1>r}+xigE&sVu0sC^?qVJ*z9l$r0k+}k`eRybC-^36`b6C0a0^o#C6Mgu zuA~(s-Q_8f>nop;=@RD+a3L&>-o^q? zaFZ|eXQo}qzVxw<%E(9ySs+x*PLWop!qb5o`1Ezb5z5F^h9h}m32zfB^+X02 zG}@tbu{W2*t}D*U|5w~y07S9vj{{#px=XsGC8WDsx*K8X25Cf48l*wG8w4dql$7oi zB&4K6I;8Z!T;Kg&7x7)+eenLHvNN-?=QH1#IeX4`cIPZ0l@tg~M9(H>&+^XI6V4x>PPJ%+!q7`4m^JMquTvmWTS9r-%}8(*zO#t&Cuvg8iFvqPP#oXw5TgZL^4+h_2|GbBxj%}q5-1s15* z9u0xpoY7-=iqUo*{0V~?vDwH^lipU`N~JP)%KliZzE(w8m0+j&d<0hRMgdCv?ZrII zM|elR38}izP31F^Y#E5d(?UK>w0p<0tL6*8`z$~`CXhA5-m!tWehAH1y;`&C>E==G z&9lXoitgYsyK3}YGBUEt!c%Emt`7Kgt{U@WC|M1(e%nH*ENRr*Cy)J{F_TZWcEym7 zrKy+e*`N+*JvWYV%ww2lX+EQL=bJ}BqO=|YIwlM>C$v?L{Aa9fKB$+=@%l;-xN@et z6X#08Yi%9+rrl@NEr*)*bQ#=f_WA-N?Af`ifjdU5UIH7OqxM+n9d=HP@$oQVLLn!C zYl|FcWh9;M99M5$&+pT<<8NB0NNc=u`gQ?N* zSi;tqn~+@nV$?(td=ykL+f}Tsra?OliLE%bYcVPlxY-4&wmgc1qG`$zenB6DHj(@S zdA4sLumXi;q}eNDneCLur)Y%djz%Z!%c_g-(Yr;O4Jgpx11c-5wtv8qd6(n6Jy6Q( zyuiGL1h>EehvZXFwQOWsEJdP6)=3C&G^kyG-ueN{$S~3Bxws!wSwMmp3wp;Ux^qhL z3l*yB)70kO6VW4)ZJ7teTA9bW-nj9&9LDgr0Mi+IxYftVr*u^BC@Z1~zbXhHXJw#q z4WGHgEr(-uw-N|fstS@N&EtMaXx^`fdxuc!zG-y$jZE6I*Bcte@jN3FY7)agAo_KR@;Ex zP{yiJnl`f(zU~gIoDwC_kzC$&Q0`gIjB&>fQU^0bR0}T_d1B_wMATZyJRW|MbdnCL ztnwCQ$6l;aB0*9IuP9oN(iTR?3CmgygTs^?{8VJkrqulcTt%UYb%d%UmBtOv*Dtd_ zEY*C1&tPmu_8Mh_B|%Sy!!;FTG{6<^XWfD=3V&jR`;`of;%0{N4C$WpyrD2A>dRms z4Knn!&3HV&+e%|1`pAg4;vLc!1HBfxANTjVnHj2BSyIkZO%$tJq@-2*_3%bnBvi4u z`nXWve^{alk3<&W^HR!2fwiw!N;rbhkuAd$0NiAuFj?X;M|y*4l?l2|W<@4o)9DM3FOGOe%!-p6yBz^=pIMd}Juqj3v}KlLT$dX^gx@qh$#J$)FspbU zRwfj(iB4rrjtvyu%NKIp@|HIA5Z3b@%kFnY%QZpu(_GEAKr?atXeaKv=WRJOLF2Bt zjORxgB&-dim|-mU9NSO4C9E7)@n$RZCWAqIASRdnh+=nQU zd_Z+b*o?$Nd*CEg{aWmnA7;9TeLjsqit9EPOIczv(Ug0FjdQh<6oJw*<0MJm-ob{d zN2ssZ?%Y|c2-71Acn{%>q`*1uWU`mxbH?|liI_Ztg+FxN4TI+60V);8+AQn~e5ICu z-GSU9;k(c=5|i&hXE2M*MYAh0qB8wFp_X;0DrBa}-15-?a8oU;M27ioIK9F7gZ5q1 zlq&cyH+^&wI--(4BI}fHaa!10>E=gwvDuH^iLetJRY$)m%vo#l3U4>6({K|%pAl*@&HA^1*#&mDo{aDie&h}`hnGqk`?T*ZWDj7OH zQkfG<7KvzO2;>%pcf?wQKw3lns0Qqj7ukMHvgyF2A4X$I7_J)ZYcWcH_1$l%O%ysF zLYDEf!`&qjxVH=mV)Th#w84)*8CLOsr4n}gc>{NyZMtl()T;q~jxg;x(iciSbFtGt zO9_EQViU5Y270oR>xrVx_XDX8Y;|4l1?ol}h^U`%v0~u*H-D`~u!SwP?m(+f2%2ncwlOw%%~U#(FiI%1E=TFi zfx*+*ya6AV2W&ZLXxceLxKQwL%12gwoF)Xzovf_}ZI^fCk~rrET$}b294) zGV5@Z2jm#;PlNb6no~i|XfN6wt5v2YDm}5gHn#$P@(!IkA+Q zCX71B6a@tF^))|?AMM~rcc&sP^%rgS#FAhCpzEp^$VM))ZYi@aMtJ~_aYBjV9urjC z+I-*CU>ay(8b9iiFp5igaK?{T-qptAGYb5w3cVo4)wcb3JR+_6J&B2$pnyTUfH-um z5857WNRA6rqjwXSCs?$+WKw4lIV?JH z3PQ}w69x&W%^jF{ty9hSh|S}P!dUS-%5Qt@nZg<)R|=MOnatWD@;oX?YTf^22gjq+ zi5yqjv_Qj2V7p=m!NWT#i{bvDDwgo=DDVakoy@yga_NBRv03~{NAtVLw4*=@o+5*Q zBqck};Xxof&!g(3+`~_H_&haXgf^xDJfQVWgR?Tuu9Zn9ho2$>wkr76OZ*5cb7$@HQi(1S$KJ5pEjPRXfS<<*)Ye5Bnk|bEBfjxY70x^r7=Z=m=z5Y{6_h z(D-gcgY8OMCP2|b?o#pIvPeBGJWaVcZP0%gDT)**jYOdjElQ{545-w}qYZUR7r{4m z*nbzJ_HrX*cwd=(nXe)@Rkw&w&hMD|;d>2HbMbPw8w7X~uZ+vAZ?9K&w3o;VRa)OL z+3~2f=3m^}h0qQwAX>z;V|HDr3R8bJ`*5^9i^7MF$xFu;u8b9NCx>X9nxrclYQ-SJ z53wvzNR6faHuRgI^T$L?LA7{6H7)NVcpu(Lkzt53cFl;7#-my|MzlV>-6Yz$^Q6#j z@j_D(5bZsb5l*oruYHB;21NEDcE*i_rn*QrO(Rek+o^EoArW_i5qIFAkBs0+UMC3N zH-)oz$C;ntt56nXCr8+EgFb@r;q4%iXK9Z{++l-uOBAY0g^&z~Gs>cnWJBDsLSaLY zv@Iif+)MKK9Z4T^I||OcCiIaz^wABUQxSL)mn6ZB(wk%G&_|vqM>prE$c4rw8f=LD z5KqjECh~xk)20*UOaW=wqj`CNorgR4XQR%&cPYx;sTCe4k9XO(4Su!ZuJRig3>_EY zm?T*FSTWF3N3?RF6jEl}Kz{3X$FFCngEMZT>Y{ituW z34b9f%k-8Q|B!a%$#VHEF&lXu@)UjvsBJMLzo@GAlvptvSq1SD?t+nG-AMg)TT5HFuPWDdp{lP3_Ls5~XSWjKm5E6~fONg3>dkC} z!dI1<>9H1qaN^I?E6m=FkBoTA)SGaptX2%wpBA!I4o!P(epWBL$4>4@z*4?B>9WbU zblUr7DcOCaC+Az;>76HjUs52sAYP@~^$!=gWdfTPwvTi@>F1v#!1&B6$Tp95s#&V+ zubaJ}(ES{lB4o?BJ`C})SB-wvA{u4Po7Mee`BqJv(L7oqDI3%JlBbN`IO+~(f zW<3W7jd?A8*fsUp;z4$(uJ8DZooT z*cGu>Ycd^?quy2ajx zuzq~*>uV>>h-^m3eKbK{4h>f&?je$eyN8TQduFc$ZH|)Jy=u6hQa3nJJLs1^ai0&< zcY7rIZXZWF+|2TYUi~n9H3Vv!H&a=Cl_H9HPpN*jNs;;lWTN0b!_h40aTSrcX=l?? zqE&L|V!Yv1l|J?tsBfwi-%%;vNtnz|hka_*qoQE-%7m8MOSmO-VlS|vbHL7;GHju8 znCNa_vt3EZymOK*o4y-uN8-F$XacP`*UP1fdyqY@vm&+lk>=Rjbb zYB{E~k{7zIL24-=h(R43uvi?JXuJ?#E@94vVHMPCN3y{f89(@({JJQjz~oIxIedZZ zD{py2D4_UpQw>kyEBPgUi>FMUPrdJ1!iNC4LkGyP5s5LS)6*CD_yv60_JSy1HFdv7 zW-ZCbW03X=dT8JxHP)Z=Kp;yWNeU{LWzF3=zN4OU-ifLb@^!Ih^qm6nxa6tqbWORt zA?xq6Qmw7uRw_HcrmjL-tCBsDU8D)aa^dc!>9aU150_g(Tf_Po#@_WHsirRXJzM_z zT}Jwtx5^3k=r+Js}=m zx-a=$rQ)h;NaEJ&gDp^UVRT63RVJ@$LmOu936;qVU}C11L_i-5M--O*=|TR@vTv+o-rB!uaWSv!7}HBHB3TXfb)U&8+bdk(d{Lh37<0zv z4Fsq{wO8%awI{4g*XO0gRQeP*&;3Yq#wUD*8_^R$zttB01ftx3bUDg}mfS)SsrnzYpcC7g+Qldm2MclJYXueWhv5i|%bGHKp7ddsdIqd9694m;RtgzhMvfL zoIZ2YlbUhL9+AF37x%4voV&y4tzZ)#x=*|slmg+=$c_jq;UUr9%C24;h2pmpBk3@b zng$j%o`}EY=)xFHAJ#XC0;+{um(B3d7apaCC^}Kl=q7GcK-Icx>OVJzI9Xo_E1J%I zfdusy-E?51&@`yf=@EUUF27q!wVTQ#eg`(vwfrGO6>YQeg%{j+>|rMOjQ0gsjt1;3 z-}j5~8pkP_lr2^~e3Nw=KcPFlF&W&E4yoVeOi#aMI6@xkf*D3PuZHHp%vSJw5;v=d%R#Tq6 zaZh8pXyt%X3%DxCr1~5Q)g3iK-L_3e8@NghtieI_f|WY)w(#^>^w{xgg^j}6%QxVA z=G=43GqHp1`&Hb~j$)Qb-}VVxIjSYUD>GTr37bp|elwXIZwXPAss^!2=%mb{e@RcY>$onL89;Mx7T20^1Zv zy974_fAiJH@F;)VQlz`;RjsV2R;%cO5sAY|XNF&W?!esQK|SW!!6#V8N$O%U6ntTd znC(QayVhGZQau{0)z>b!MkK}46nWpXRv2?B@C)xN&(LMPybkoe4aYU-!Tt`<5lqqFo{_gs4PiEoCQKX_&z<1~WsJ zN+?BIiL`2!HtmZ-S<|YtsH9cF+vqxB4<=UtMY=PWGkG3DvVbWiWjUh_)lm_E9_KO@p$ugdPi>EMD`d(Xn=$aDXTxiaQ{l@ws<#iW_CFnJDagCJ zYM-H%+$FB%1!?cb%yQmjv!@L?0dKQY=A4Z7v#L%|6jSb7Qof|i0IRDiXME3;=^tEq zB5Kdf)e!PFt~b*w#=!(^idTwHu*VU+mrqa}ta0llt% z@4lqy>xZ=un@WrvzZ)FgZnR^ycTj>kO-d-d{@) z8z|cp@Mc!%F#pt_!1?i6N2k}W_!P!W?mlnsWJ3AC=rhv>lxuDr^Py>)xr<`-U2E~1 zYOf=L9=rd~kmJow==DczX_e>^YoJ{w&yg@r;DSE%n5B#iqibZ|A-3?s{IY zwyvlyd3Z%(XZrH)!Bf4P$30kc|GEl$<)VRCuJ(P;+E!t^bzz^SgNIih$?hKH7p!-F z`QH9fSA!XxjER{W2Mpe3y{<+{h!r;PvPu|K!_qrJZD=xWDBgI^sO z5L4?jCDEvBytlSSc>K8-w&FftMVF@d__O^U&Rq0%pT^sg%&A<}MEloG2A2z_@=UW5 z7t6QQf73{9`l7Mtx<#3WedhyeVzoVb?r*Z|@o`e!3uf}QD6Z6P>%F;}S6$yNQaqC7 z@G-sKZ)pF|HFlHq!hLcY4w#R5pV}j5*zuy(jzg=%o;U#S^9`1pZ+(Y>7xm)u~a zcl{{Yz+Jv~!iU)h#!d0ql6ke@a`m_Mxs7Y{ze=iqV{SFua?I;gR`M54hL~qoW7Xr& z?yd}#!xzf}e8WtVUp7BY2`-W!EYSHjBTqfpqkL_3bn)X2iPM+%WX!4Lr0mvAI`rLE z+xF%|o1SjRq%!5=@0V#5zFlTAuIm)1jIUkSFKsm#Juoh#;_SKyXU{*lTzvW3olS3? zU%eFn%v_=7WU;m^cw4#F#VcA{#)UIw4IgDWXLSj$(kmL4P8^pTwRea;vR#PfmZ`nR+|NU1>(dfZ0szf{xkh;TRPHb81D22Xr*l|YZ&S!H=f)g%YIJbx!_$IM@|CbFL z8rPpHUFVy*ZeZ`8ijS0CEfwuYpB$dRu5vd|+> zTBb|PF?&>hG4e&K@#7xcRGE^2J>M)2@$|g)WR>#wNMofJ8hzFUjnBOIu}J0d`!jv5 zeXc0o(LCDs_BrQWk>8WT54BWGzbtXPuDG|N@t!$39D8+%yy*ER8n$ZDVK`(8dh$E3)7S$FU*m}X8@ zIo`C3>pF4Zp(BnLt{!#B>oY@j1LM-Y-Y2H^{ouuwNy8pgeNpZ&^U*Fe!DZza zWv#7#ueA0Aq{^i{dKH>hr&v?L(b_$)No6#1R&wvvmVtZbE?D>Y!gJ`p&ukGZ^V-zZRZ6c^C+#rVp2Ql^d9Kl>kcwT$_4QJQU7Ij_>telL8xP4}xhN}> zkg#`TO^?H$_A+0|DZjnd-;Y%u5-h29T(SA}CYO=(YIOo$R6c5mjPO-WO*Y@MMO?H0 z6R!cKeNx}~91~Y(=Wd)|?WXf_S5wHh`peHRY^|Ef&(z&8rl*Vj^>d|;JH98cU$XT| zOpntZcT$!Pf1G4LVywi`fWZU9I;FpQH*|QqhqFdmKT~n!8}rl8T~F4{8x=dPu5M9h!TSj=+s(usWqUkcd2xVj zv9;|sjp*F%B|ZEWt0>4H23W)VkUpC-WdHAn*!Yp)oX^Gnj61p{gWBlp3Qsr zt6kpKa<<+}zE$te!E9d8uCj?)Z)O@t&*~C*esI2DUG26Q^MoDq-mf)JTtoC_s&kj6 zUXEY)Epn-xV%&E{bC&~+mlm(nwL5-%d6IQt%9`D4cif+6`<1s%uI0%#qt;2o`|97G zc_!oB$D|hvu55GaoM{$lV)H2^H^7&*ecXrn$rYXVg-@vUNVd$`DreCnMyVw(Z0)gI z+wu$(wVyYrMUNg*__n&B|L3l9tk&Tg%lf}Inm!`9yRV~|+hJ>WciU+}c^6M;hSd@> zPj9*wZY-Jptn|3bCq>!kn}%pRDXr|}mDtbSE-!z{8|Qv&gM!R7x`ufVSaWEhk;10k zD`tjw`>?w-;lbO&;zpNcbt{|d=gn5gmW=o4GO}JmA?3`*xxGRr1ogP6muj71{O~KI zMfXX{7&(VeNw4qTSm}7_+uoa7Uj|Ld>)X99>2TH|b%#@vdnp$WmfJTZg=c&%yu?2( zVxA_u>+Ha&xnp9KKkbM&Ph5C1MB+qdf+?1(%2y2`R0m6ee!P|52@cCR;i_W zmsr+og;#e&kCUd`2Y)n=IWVbsrpye7POWM^XDl1sdVO%MTAzb+&knu2YR`@xukLJH z_hEA%wH~gxov1VUNElD%=8Jv1BA0SK_N#nYls&fEYTp#)t^GZ0GrpE3 znHA_QvM0r0&NRhZ((_HZg5?to_Y0w&DfB{E-a_JGPH5>(}!}Y5nn2?`vY- z9*NO0E%!g?KX|@3`;l3>Q6EqFaeXe?#T@9h|Ja77hg2^gp5qxltspSBSJPgVSB(j8 z4;p?pX)cmG{Y|my$oq4-_IYf}BY7(|YI$Q6iR0V_PsiHr*gD3tyGo3|dy$5T@~4eX zMj76zLrl4cral>UIQvUQ*WNBq#oU&SyU}&du&U;r{XHe)(&Z*pn2!52EY0mn$fanh zK8@>*j_t2r@j>Zh@`C~}LmN%im>8sK9ds@5LTuMLiJ1XUmS=qB7+n)M%g4M6UorQd z$*jexouFFPd-tY*}Nq> zdRX0qE$mCzYnm@@RepO#=3cgvApiAjzlR$~*W1Qje`RetuVtXYLd!<0fnuX~**@L6 zu2RpQv3Az+Z?D5r){mOeD>Y7avs>Qams?V2B+N=EdAEB=v_`5yaDA$I73-|>rOXp! zx=830iM851P859SIDa<3wN^!5eMQCf0T)uI)t#}Ld;0JsmuFoHOdbtOs#;z>XLUCF zZuQ>#EscYdwUkUWC3+G4Ce5pLKP46?*SP0kqLr_-jglB)c2bU*D8>~(lO20a(8Wlg z+VrY?v-gVTJ5BuC2d)~%#AIn}sg{1xdg1M6S~4ZAIseJh9nvQo_@nw0gxJjc>$77W z>d$$)44&%y$>(8eiO-<-0mPXl1BomNk4D|MQ`Gbr9AA#IWd4HJO{tcNiDgQKD?8l| z(*9^AK}?@YERbKzT>E*jRxD8x_e}p`#L280R-`~fP!gOK+jrXI+@$0>dCA24zKn3s zbG3b*YcpBgK;K}_<48sW?~dgyHKy92QJK&0m(ThdbpF9<+jZ6Ns>eS2lA^bu$aVo} z8*%uP+{_&g)io|PHPz=Qsy&ze?n~TRIz;c;j^VcBrQ$3zWaKxRcXyihdU}*k;j=Mo zTir*=%5RoBCnNd6eDz76&8PEM9c*sBH1o2qAULhR)S?R#?z-Iubb zkG(EhtKZG0Z+yMiviSHXpQ?IJn$+-VNsF{v>J8#qCwZ4fCq=dAo}S8I!#If--i?}f zb#da}mM2{X&2Aib^qp+r{u^In%;s-;o^+u&)VHHw z=ci8izQIIVtw7$n@%5R=z4@N!zilgM-4YbWD6PwTz!6)a>s-(EncLU1Ik!U4Xc}I) z=#|#|(zRmpy^Um_$t8XpG5^zv7?W;e{4;V3YhEf&o_$D3o@sjSrI=s-w->Rqo1Jz! zT)6&l`$S^FQ1bx&1eX~Z`{Q@dexl_Q#FC0ubT)eO%s6A)OOE%-uJNCZC2p3QeBRc) zXF^>1<<@4+ZlM=W%1KyfPB=C7;hK$J3U!;VM!owK(?ycgz`MWvYS{gu&z*f6bBc@- zPlsJ9xc{K(tL62>aYg=1TAH8kigi#paH}ZQ;Fv-92nmJ$jk_;wJhaifOS%Q)qs*eK ziWhG$d0!aXqFr^V+-HiM65(7TLo7VIHhF4mitfAm=67{P&lX>wUef+z<|7`3sUo5GgQ@)g``|?#{M7QBf z%bA9)Eo6>V#arCCX+B)byef9__v3Qh%M*uoombiLUd{c; zz^Mm`<*^=n*Cn6-;*{{cN%m`h@t3zWs$*BA8a2MpUEU|@WJags7UnaDRbKT~dTRRU z>*h0h{x=?#8IOwJUGC=m>A6D7Tg~Y3z2nv^Jo~WK@#al#mbYNU*pMz0*Wc|vukW0P z&pu@=W%oXn@@4#laa!8DHY;fNS<|vPskKXeSlE=6O3zoO#TQgdd~!Y=ec*%lheA`e zip=CWN>_5r?-i_#KjwVWqq1&;M^$3Yn5^mzTV`>_bM6(IDpe1=)Oy}_OzQ!`=y%t} zbiz9eP9OA{`Pv}gpnzL@|5ewc%lE9cI9qI4xOUXz!>9G`d1nSb>)S21!Ee#$hWfe8 z7~Pbmmpt9S1=gIe5MRg}?N=G+*V2bxI zD}A+K(WYA|-)5|TTGW@Osh$e`-gc=^)&3S++B|QcqN z`#a7C4?E%YCS+Mf_^O`6vTI|aLRU;~@vOOj%QQAhKT9^S>sCwe)6rc#qZFqf7*o@{ zl`(3{jyz3e&9g1myjcD{t*004@2w0%5e{}AS($>3Ls$Mr=KmMS#TK#&dgw%l#SJYaM4{2e4-8F0Pluc?!yesYW z`wTi2bIU%j*OQz#4Moxd&G2pBr!~?)ycs;+Gt)3RT6fE_s24X5LR* zwaX!&Q)K2D+~1cJxyIeUuF#=NRHNLpxAB)tuWo*S&uq{w>!wm;VqT!Qyt7$!rQTD4 z_hT=qCw;RM^E6D}ZkTgLX8f}SQr#~mJ^4C2_TAPhXS^QAFY|pilQm=jr&JZaqJxm3=4MZbZpzvo{|;WjkHTUNTGP?Ho>8 z)YQ6X;kWCZvbB>w8sDBj@`i8ew9B#c1NB-3ftLq)4R|w>>CfxRj#ZlXQc3$%?tF(s zvFWui$z9E|ByDfieV?GavF~C}N#$Kj>ONV;-fwz5Dk^&R zWrI^g!sEjS$6gKn7BNkkft8^A8y&(#`!JN)eakucQ{XDmzb> zkW?cGSy^JJ!zb6&;BR(=2!a?0{;3jLgoBN{#V|WZTYWdX362)-Q(SH2iGBq6pBT}d zAf|P{A~FA#82r`E#cx*ntCpP6-z*-eh?EMGwg5BZNPQ~vlx>L2&@^GE)GE|d>w68->x7Wbb&L>u}L zUCM_H7XRaiScL=!hj1>X3m9C11H+dW!pDpiK^x09oa-xKhj1}r&7xr4 z#)ah+Dqsh*qghPMxV98rcS*Xqc3cjd%lZL_&gD(vI)RPrryOwukD~w^OVI^(j|yd3 zv;5G3MpJ-R(*Uw(aQ(v>{^%COn1b?x28y$*iv==QLI_3_gzA4maAk3<9732Z4i!Sby7XV=U_pVya*apV<}W22viYl)*N&ms-?a_lZV9&59P3Z8CVpW zYLW&k&_ZH^;l*R&8SvvNK#S=Ch4NT@7FU2rMAVU1M~{fd;^3h%rO=G)M2iO4XBHzE zGfM_NmIwwX9QFp0C;E3ZS=fBGP`ro+j2;DMqT)ZmOcAjE-6e!0J=D)n`2|;Q78G+|6pV~XI_XPL;!q7`g~pE*6!B=y0;7%4_6AG zj{!bD@(uco@)PCfF~Dl^kUBv)Q5ZiPqcMg=MuFc)?qruLyB(=Oh=q#q04^~{0<`1$ za>AJ`J~Cm=96f(SFi6sX7+olYrItv9zq%L|QLc~Dm4{%a$OD*DD2RTxco3~w0FKu- zpV7xWxyvkp+@GtHfCo(8L_C;wZ6?tdVZgjpP zwFTdv%@@$8?DXhye;> z`j`s&Qxm*_UZzUGHmE2F2^07ac-)*78XFvw!8Bvriy%BHge!tk3GF&oy<}G-gMPZR zZY(LvwGyzgTpo!EO6hd^h!Yi)K9+zPr==6@R?Lh>Ma1DS?p`eJK zn}ryps?s@PaRZQQuqr{!rZ7KC5hXKy;#tol#a@H4qy@Y;Hwv*w8Y(e12hMBzwX|ZO z3Vo&FRnFl|x{w`=7}j82lH)_J1G2qp@KAcNfi9f`E7*Y%YE6cqG01PH^Pqu)fc#cV z!=Ycz?KBA6WY#t<(nq@V`pBk4;QwfjfMfPKJCTrp%;;0CpW8EE9|$S|2+EQ|wdxpM zs`g2bKGO-c*qh061X14?PLAn!5{(H-RK2v;_8@i2R~nApD;Cqm0+TO&Aj`Y8%apbMl+O;*xmQKX>%#6FN;>Fyb!onQZl7-?P(g zbVBsi@9?q{y;Z@m{2~PpOShLa_v#D~j|mA!V{EFN3h1*IDR|e>y_p^k>YOuh46o;SFa|pV7%OV0wW1IqiAk=T zx*q|=^jZq;HD7r#T2M&y&6V(bvYmkEYzyQxgMw4g>EChwm`iIF!14{U118Hkgv}M8 zcz|OMjNfk!4C^j161^y}R-JLd{&c}?!VKFzR|KbLwwK0f(AR}vlnN-k66)A_?fBL| zQyExH%czcD^kt#8!X)r*^JF0PI^e!dr?kSQJI+?vaKnR9S(R>ADtrghc2kF!u4=t- zv)V+m`2s#Fu~Yv@w*+7d4ywYj$>jqu5#tc-S~scrH-Hl8%fpesg}S&fvB*=}Ez@N( zFlY)21i_$yULJ-C)RxU06@*m!$&)c`h zj9s;2z&iuXeiUBSks{%B6EK~)PJVuf+^!jm9rXeCP+*eT6mG$2(Qrov`-E`F#RL-( zy)f$C>1cpn0nh`fIc8%-g6__W6ofOdu-CY6*3lz3EmdLl9%_z>o!mQ!U^4-*a|mD1 zmS0StH@#xl%kx0Bm&w6ua?=_cFS{*2+^Qqj*MSvmMdG4bk|8#d+q8l4E0TkapN<`7 z^ob09fK><+*}I6gkSv)G=0Ca4uy=9M0TZ$VgC7JuBDMgP^;#N>-35qONfGugirlcV zMuJI&JWb(2Ci0;Yn;BkQrTRx=x2d>@*<75&%WtmVv;>Ska+{HQTpud}?r6U-b- zfj1vO!9DAb4VP;TVB3M&VC6(^KYNf#lg;QUVA>{g>i^W7dh0n6_4R^5Q&#~e0LU=Ske zuI>*Eorw(0zAg(hJAgK9mpvx-*}40aPX1BuR@+6u-Y$Dg>{l~i8@B@Xm5Q)`x-bVP zJ099&%Gx0gz!FZEg0rQX_hY2RsvVcUS3ElmBwVHfGoL?*kr}I26pg+eRSlSP6ya&S z`4}c}DvAG0MJml9{`SET`)OY{Kaj!$(;tMKvuaHy@r zLn%LW@^cLd5!i58Xo|wWz1}bq%qLT2V4>&Uz}E;Eo<8p(uTSH$fzUexp$AbbuvLqW z7n87+4|KlL04Bl3hOh~#x`PiMlcd+K$egeZEV}bF;Lwu!YZ1X>67$~li?eqF@>e}! zo%Z{Ti(L3kgxu`y6LZG^eV(Wa>vResE;3#q{I;)c8(8$=U+df|8VaoTEd|&LI!lWV z-jgi|u;co%BUwy4CQuf(9~&hSGWc6{ZeP#?{gerULrrp35Md*DYys=%@|`}tR6eOILCmF~ZtaZ;^*@y|1kT`}e?-4EcNTPBL3&qTz_5&`?&)ibxHUgl zJhee51@0-3UK#$+laV9VB)~tnoW=0%Des1DmYCN zach3gEV$d0Bi{IBDX`nK)ZreIb{27)-0%;e9xL{0{&^M}GF8;A3HQO>n*8zshr5B% zGgJXy2pyh{sWoIy7I0>9Z{@_@ob+NF7%6NeICIvSg^L`6(-N(7tfdUt+pzAi|LPZn z3DXVRvY7v|2Rl@PAQENaP179$e6TpgYLX%-@At<|)1{HPNW*>+DZ%M z-Nev^g=<6u=ZE?heO$xtRsI67iYX!sgi~4M^d?t5>%Y%d_+fneffQfmyx z;)4DacE?4%tGt`XQJ@)I8JIdD5f}9@&lnf=IMqn?ML;<=$-{{@c}WhNh-n#S^3K_68{#@rv4OD@UJ0kp}_|r_;LkU@L8)dHbV%XK5;@|eZeFk_?k{| zzDVZ`Q4(Vkc&f>R=S^U24pN6L_tW(l@o`DpPV8aHK%gJdvT&-x^z9w>Fl9@j7;hOk$Q9z-+!CPDk@tHhP z65|R7Z?d_um@I7ZS{WXYrA4^-!LlBgxIfutKH>k-l`5{lh5K{ejtjbG_t(2~0kpm( z93nb?0T=XtyzAumNGq-eopGD7Jsvd30W@e4r9qXKMBX6bU@NX>wR-Z6f%igag7KV4 zY1XGJB5&3o;;p#aRUG>Ea~x>b8);bow5$FX?ZVz5Tlcv=x`GBBkb;AH);C4pAZpYV zSDPkDu9cMoZHkqGJLzk+$lLUL;1ySc%4XH>Ncf|X$hs@?1_{SraW$(ar}xd6KN|D0 zdm?X^n+OKeOQy??d4FtB?S0WV=(h+gt_GE4+ckuM25pysU7E&+xEkb!Z;i2O>k=Q= zKL)cNJ;sI`?t=?=qR&0ENkFoBV3PEw=72q=i~I8)G%ND5u8R|O6Y&3}mu-mzNic#V;IYtNXlONs>Xa1gvA>ee6{YEX=*V$sE{?GQ?fuZL;r}JOTzUwD{#ugYDTsG#z=&)Ny1XC9_o?95Hipu zou!Oja=*O4bKU82NVt7c(178oIGFJfSrMRh}{6 z%TAb@ss;Rn8XoFkqpkCcn0EbM8WN#Nw-FF_F zZMMbV$l4#Pg!)i!J03U>*0mx_Q(1g#F|_`KMks_(QJkUF{(<+G=a)CBHToYF#)4#0 z6!S22T3Rdv2?BBC+kwn)2=m)s7SYYJpyMQ~+G+e$mNRL#WNzzN5JL`&&wRB%x1ki| z95Ox(_kPhBKs%TcwyL}J&bgP)-KR-{!CR`66~G@v>{25h^o?QZ#Y$)qxxh4XHWGG( zR$1#~V#4gHp>HQZ)^rp8Sj`~zX@yFOwfsw3M9zL?eQi1MacrfK@-BAN$kvAQ264ebt$7nHsqQV)YA(45zDM;2zcS_|ac#5YXsK`+AP_$gEq- zo!K*`?&9LI(Z3PL??<*ta|&NKX#1#%+`=;Kz=W*R=o=$U!|z!>yASXhA9wD)ULu-3 z;;4sl#D9a+&e4Y%F*G2+j;rYzE~Zxy9>p@Ck;T8z=Yy`gu^P2LX-^}r$w8XY*Zy7H zR0O zl8t%beH@-uW$#e;3d5z%&1BxO(=IRYXT(A?b}kBoZdyA98XI(L zuAQFpzd6P8!{VlnoN+Om-_VkJdX%NJ6;-$MMHl)Nh-m$b!c@V`V=Zjirdn9~JWBsA z(b!51v>;eop?2=<$)~ZAr%>BJtui^Gx$Ln+fOY<~Y~mM3YOk)&QwZDz6&%q}XjW0A z>~(Ho@?JRAB|nNGXg`NLhbtY+@{+$mNcOct{RaIG|49e)%MhEI_j#}^(xtzKi#;Ps za6;QbKj59SP)Z5DEJ7u9@!~mz04-X--vF;{}vPEbQLxt2b{uPpd;2QyfWHb`!0Rv_bOE|`g&6T?XjcDdz2{43g<@_0W0{M1N4*jPQVNcs6ZIGib*6V8Y|mNH?a z@!vul8#t*Qk67U7ej%5`oFimQXHDx*w?x& zSh;kSum>z0_=M1~q95E02b01ZI}2&PazTlQ9yA%Mobfexwwo6R!idQ`Mmj1sKq+nFkx7ETA__`GDGmCWm|XwY zhJU}EQg2!J*p|iCZ6DIprU`^%PFUKVj zVicFi#<2*bVvPsM-A(e5ydOm*q!Usw{yelM6|#1u6o!h4qNy&}))_pBzz+RMJv&Jt ze+!ew9AmzT*9f$maGJ;0eOILofU2T3=Nx_qPG~&?R|$h=Q<{ccYE{-H+OZY~DN>lMq@9VE zM!aSbE%pwki4i+6VRU_>1EXyT8&mnkXU$A)J{0H!ie_;BEC$9<#jkDRNE1URAonh@*Nk(zd?tD3|>MY(n7wI;^@Vzar(ARR%#x%1KCyVieGxx zbgaq?ir=wz2H2yWhdUGetu2JvLPAW_Ec=SdCt(+N>Chs0@-T7%vI%^_c^7*GR}oLm zgMKabc4kKms$Y7E9rDTIE)|U*VQQHKd<)xgRUI$t#IrW#hK75aW9K>0)^d>GhYFIv z7OWKZXHTDY)kI~>@Ohsgx=?-^iOC^JRY@|^NFmub+>iO&^$KpL9GyarP3oZFM#leL}i{^vHFI=)bgsKI=v zgY2X9QibDqu2ar&Z)+W81?=~Bo_RN5zFWm%oTdI?Bi^=G zCr#M5_00I?QUpu|bSRg3m)N+R8-fQN$((j8DbLZK0YxpbjTg@sdr3>F#Ce3&CMg7{ zIk?=Dp^(-I`jfVGvO)gEtVgh4U>sJA^wb7IKjySiQherf>(U5B^B{;eVp5PFlU#F~ zZ~1PLZ~sDtta(LX7qt|6u{Y20#gmE8!9@$T+^k0#)^@p2beYT+&^a%e_DnbXRy*FR z($DzTENUMOx755T*8-L73_NK}@cXQ&5$UXAt$X`fh&tpr017)vyea z`KRa4m|@xZ3~;)@#M?Ln|JUD$(f_Ovz!t&IeUWWYj)SVhJq)*R~<$Js?hszr@PKA6KS8&%Xgr! z6`Ig!U&^niWHPEikJ!_g6jAbp(qTKl^=|{oO~+7`EKy{(>$s0N(8?6TvHMp`+Ekg! zH)229Z%-4?hQ*3_-$iAuLFv>yGni2*rM=wBf*_~jIU-R=)hq^|5o2a9=T&y<3zc0- z5TWymIUnnYqX3=(1H`EXSghBI+zUX3CJHyHlkwg?P2H%#jR+waKEdpD-VR0l?X|az87W` z9t2y3$Fxthc5?YRPqV;te8xhBia8D3P4YiWEA}N8UZ;fbQBGm+k(f5k{^3!Qua2%w7BBFqbpWj7H66)|dT%9r|6`kZ2YBnRKiT|W>5rRO_XWAJe7WhxB zLa&~QP^Fv``T(y}^V{5w*f4sa;4MZirBMW?$~>7U2fBNiI!fkWetVga5G=&%|G3IM zu+|ViqJ-VfUN(VhR-9s|z>V|CWy8i*SB4Fh&pS)?{S?9nIx521*^ zOn+g;d|F9YS>rfr_)r&ANvP0ghrulig=7`e=}r4|!373p){znbZ~!xVfuy#L4>0q@MY2JL+>nDZm?#0U&{CPapyw-eH;Mt~=EjUm z!L1c`r&HBbm5rOI?yonkGOcjmo>t3g2U{I~Ua?tRiQLf-RGWTMf7m}9_)*?^!emL^ zr>Tr(8Ix?{1s?veB$c^l-;d9U`cK+2=E&p6sHI+fd#u8yA|@?L4c{oP6Q7T1in=S} zJ@1X2D!k4NqbhW$Ix3afafW8%e9brpRU@%v{8gTbXbJ^CVkS1ZXou4$=X@^-B~?%a zeuRVonKy2@D5^_bq?W1No7t9frsPW9C~rLaWs2$RU;T5(ua87dcWH2LX$e)wkVr)*_pPgFu$V`fDX&wey?AW{{ zB$2CsCiw_mpkczHJJ)nW+ckeQd#C5=yr!4W$-sOecb|U`iX?P3qnx;T{=QyU-&cW` zn)#u%aFWAgZ>b2#dkwv>4R*$x3!?Bsk}7z$N9m*<6B+7b+ie9~sbE&jR9*=?FchH2 z4vD1-5i2D-(XQ6ptitI_C+W5M{S3?57%Ak8uGZ}9V3t&BW~b())I9b6zBhWtZnjT* z{a%Tg>17&b|Ib;2H~OOJy^IFPmOegcQAoKdBlFXgJ-353JMh>zl9c4PbC2Q-q5SFT zCq4D2mty&u9S{Qv#KMgbz zEi+aZe{uNC1eL2vC^W;RxQxqjy0r01#Bf*;ljs<8BM;VT-$xyhf@#Z(?oaqPxwh z&fPm32fJ6(`)yQ4vaAJn9y{Zh6hxszEIOpc8_9<2P877patiu>VGmFBjhzvsH>Rcp zLUat-do9}xPw~m%t23Q>F&UZQrF}9E0xL1>rF)iIW%*2Z&D`h&!RDLyXw(|s7>LP? zZ@7`+P*P_Hk5O^Mp<9N=j|fS5;lnV7Ql=(bKhd7xhV|=hr%!}QvV%4f8>h@`y?lw3 zigz!Ff1+9)(F)TVkDT!OtX-d>Iq7hR*jb}R!C>18v zoyU7palHIS{1J-#d#8Z&(^K0crPqYd%B-?P4Bzp7LeQ}?;#o+LT0)RB!j)AfuRjdL zN&w9Z+Ww$8NFv)}s}_RG=EOqgJ#&+VmVMf?4fORf1dPlg12NJXbDpjyE%v4r;;;rO z5=|MuBgqc7MC* zGh=w<*;|dX9roQxWwEz)(8(uQ#YelH1&R?7u{Q4;{ooP|p68-Z9px*YFNc&rN7`Z| z+^Hsv4eFCx*$KzaV4HpZjPaIsV(CmTA1$bYO#w@qKWsNC5I+ecWQ592OzDSrAy&Fz zK2XXwn_KUKu0MF7W~Jh~zTkxiIKHUA$pQC01GlPfea5`&-tW7{Xjg!>kA>$phuUXR zF9Wx6lQ*gYW9_s;RjP_8pyvNtFA>A2x@DyK{%KwI!`YH^PIk;yC(=Az$xFMRUZ;D;Cppqgv;xpoyGN_Om$kP= zz>HRpS_rX*B1MqEA|?l}EO06HEMJTzKS0G=C0G2aUg;EmsNa2Fxh!x`JY-7)WoQpy zB4oa5v-VZa$w9<&6e$4Ti7pj(LMJo9HGA$7axM2xHoddh4_!VMZRr zwv${EZ5o3>ip@e7yu)7W>a5ZJn_bGxAE!tWhU%&)2nQQf3j9(1=Y+(REl92gnSH&L z;?eAdCe@-Fu*B2?KM`MuM04J1eT4TP^nX7r#E)EKPHioRc_wal%J zvpP8hE^wI!jvkI+BL;bGyO8&Xk33;(p%L6>!`Bz~0VmM8L|Z9bWR|wpqzwEL zwnC^YO_^yxEGZ`c&+B?Vi#6_@z&YF-X?KeoV{JHUm)0}mB6z5%=PAJ>!#p44I!-g-bC2LLu$bB+v7Ww#@EWde&4 z3F<$OMF&R5v)hWZzk@0nep^O=6`hAih_|y7dXxPD(A-EP95Zi2l`k|q_apo&T6W85 z-8j}8sjW{CW%BVaT2>2ZdNSvdwqGN1-=QNcFq)rO!o(+qA|ZS=q4}k;HfD^i!us6q zF&d^QK}5B6qWgEO@$E+>^y=Mk*LI93jYTR_2|q&<3yy{t4^zGgQxI(VG4e}W=EuJw zZT#jUSO4RuPn$3F1N9K{>0gwq?#8F;AffaOq&h3H+p}&Px%rRV{xPec9 zy9>!<^IyHKk&E7_Y|HGS1hG}v6O%_qI_N7_105v>Z^n35+cU>xZO^JJ=#Ruo1Dce{ zKdxxxHQ=W&}9|w z5cIZHhJ2`f*BiG=5?37WPA}sNz+c`idQWN(ScAr2!Cz$;CbHPf&!SQ6Cs3Ht@CUf*!pg+V`I1ETti@ZMOk@kwe)y&3-@8`=jsQrOO zK@RBko<#eWev9Ht64yI0CEK!*?gcc#v3k0nOYni0L#TBcmfq^o6R>~*b;9I7Iufl+&K(piiid1DvPc81wz1f2c%4Swt4l+PbjbOkzoVBK zS3m;kSj(y)HWk)~nYydAO1WSV(Nt`TihA)%e0YJzWUGdh3V5SI6w+#OF2cJU2kPKM z;(XqV&v^2tpX3+qNw7*PNokOyAND-A`#kH@EwN;YABtPpOMR!G+s67|qdU#H&(S}z zyzJ86>Q7SeyppH)GF)!feAU&vrQ&9EnWOgvR-F^|oSYDkuw4jyOHJC|Tcp?niO?_L z>CspX)>Iya4E_g|eXmZL<2E#M*dm@6Eg@L5A?;F$-(uazUu@uU9y~popUy!SqN`Gq z5+-}pO!rY7`+Pu7xKrxNPLUk=L?u4%hqxsvM;QNvk;%4nTDT$UM=k}G6wK`+oml~_ zw@X`&W?Mlf#3u>C0wPOh;CDEN%%ty8xFL0fo>fB$(Rbi7XH4&ZU5d*@VA_6A%A+;9VXU&yir=T9?`HeZlQ9ET%Jol=`)Kjynw7Ff4l+O(w{qV0jw4qu&_#5dR zpKR=&p2K|Xs$NO2H#>4C+4TS3cH<#sWq{9{Xg@MfF7%kR*CT}LS*Jms7~L~#zG%^J zkpu$ddqKLXifum5QYh5S0tKURzNf2gD^n}!5wLr(WfR@7F)knRUaev-ArV$&WSNfm z6rt1UlceO#v~Q#jt)#y&JNo%PsFTBVzWS$iNio{BgJXhcqB3+WCvNwYPa5HES=;UN zX1qP8b(63rJ3|Snr(LVcU#%|Fh)1D+<4q1NJMC_O#MCWMX#QVLQ4dDVkJpjsR zq;%E!MVN2WcT97{v2+{n$;86To+s@G=|iBwgx+kY>33;6*51MLQ=$HdG3j2q&vECZ zv3E1S;b_N%u& z9nRQPF~`>78?dgbODVZ#VZdaZJU*OX*^G-QLy5pF)2AEkGTEcrm{bp4eWV+ zv~>Dfehh13`*90>WKIJ$H-N|4Fq`Y;R<)>nqCo=gs5-ek3=H}5cm8RxtEiD+8 zbIJ#y37nS2@pYnjV)RwI+q*IBub}4>*w7+6dCPO-AGKQ!t$s_IyA*4Z;(Gj2w6K0} z->sS!DfkOg{&2M+w>slO)$(_fvKL6KkCc`^(!aVqF{5VM8j*Gtem8~DGou}xZW=#| zo6-b_Hzg3NJpHx}hG|GCEelB;CrrHDUJh=*4jLO{=O;$VwHatHDFl^+JjpAum>$ZA z9ZKQ6Ir(f5-cl-WiRUj!m*Q#JJ<19eX^d*j8kLs}dbfnrc>XDZ@^8_7i8+3O%ezRF!9A zg(w@)6cr-s(zU9vfuC16YBaMrp}XtSw$;t@RhH=oPHz3%DgZN!{grcDYxYNq4wN<_ z`8F-G$&qM8vef7d(ey2RRBh-^JX6}A`k_#ZoyF$umkSxErV-EMY)hfJTIeulc)Zo( z;Lfea8)U5C!KEssXxI^4l*8vB8Z?$jd?RiXQy^23C-uY<5>q+i2w5FWt%7xFM%YtQ zF6lyvi@2EFSU^AkNPI*2Y=P{wzUdxq@}0k~LWiU>P8n|Y?eURPUqb}JqfeIGgpR_A z@Vy^5R)h6V$jzvo;>RN`tq&Ugo1>NR78ns?0^CS%;8$qG9@+37Qs>l;g=$p%Wamg) zhbq%>05zZpGufG_{bFcS6*YnH78GpcVEVWp7+snYV&z@Jo>uQ-cd>FwP?tU10U8zb}1U{k_>(v09b35dvjd~)NB;`ycOZx*BR*0+`dBfg^*KJ zY~?G(@i>NF9r7Lxl7RZUPC~{)WS~lzRJXLmOV`1gBo5`rgJ9OOv-a$*;+> zA2U(dc;$#r;6gPS)Q!Z?o1Lal3GA{~1$w8@?17TeaiQD{f+-Se#MnuO7|w;bB+Izd zTPfhng$?0Nw;gBfXap3CS($VIt}TpE1NGWEpr!(&q{dD}1a!Vw5t(VVWoo4I=fM%t zDGQv!vk1T*|7r>SK8hUD>n_t{sLMQBr*c@8H-6`O@0A$kG6` zWl7rDQq<*0-hM3dY6C>oHZ#H6{nvBO=^lgfeoxsMo}Kn8W>ch`h2iiMTSiyG z5ei96XT2|g(Y6!_cUF=3Al5>sw0bNvi$;JG|DkC-ib7=v8^bw^l?`EcP_2h0zfoQB19?8!|( zZ4v!oWJY4B9AUf5bh+2BZQGsUvl1{yE5px>U z`u>^7b1dk&l=Se~@L_GU2g3Ua*i51CM`YShT`T9ZKS+{$^c=6$`L7UhbMmJ)e8ea9 zc#4>Db!EsQPn-bya6JF?XwV&6w32rPO0XCvWPoM{TU}STM5S1J+d-)6|Q}n5iXy z)@zL5a(TiK$@X`|<{nmZQN7AG;F_VxEn(9A86S*cO#i&QPyUT_9dlU8iYT%*LR4$7n-Xp`mb!X|CVw^!>4V8eGiI@S!R6akzkh3m|p^VS7@ z9|BUZYhS3qPc9d%;)oODxM-MXj-khW;b}uKSr}-mpB7B2G`*em?364eov3pYr6|M4 zu8F1gF!Q@y75QGf4IlV{0cLx*ufe3J`yGWFw~=S7M7Bn12=gaY*PiwleG4yLROgOK z>st1VoPkZF@6$N3idR^MpIiV0ImF>T$PYQ4#n);&5cc}xlTu~Bp%j)LnwnXB=4-3c zMoo@_X_JvGlAXOF4B|v*)nYIIr~y@(g4$$)f!HMxJGEC#?qA1@+UAIleYj(iS@8qc z%xW`8Y5?&4aqeliL@s|6r)^j1jFuZ26w1~PO8K1ZkqzZ-z&+xh03D2@|ue3#lWptjwf!R*vr_)%8|BBW_)}$upsaGa0z-bPS#nc$P!9 zF|`#5r|oAP^*9jtJxHa3?vGi13=3@vUFh3OrJru&Yx`4E?@QT+txLs9ilur_^_Ig8JoVt=XE7DL zh&(>yVU&mryjhKTsq53xN89sx0Y-ijI7{j&+*P*v3`!_145NO0$*tR(V_2mRd9gqk z4};75#8YlF>YR>(TQ!T+Uk)kqXCTesGfo)#lXC9tox#-2@mDD@Tc4gDQH@Wa&~xjG zGuT5$6sCcM9mO~C#y)eBP}XqJH2@`jkP68vGTGTV zArHq0G_^~E=3^{{&vw8o44Zy*@w%loeKqb=pXb=46?L6}TekE;CM2B$rmd(PDE>3u z((MGh>OitX?1o+&lRCuF%CxQWPT_popq7H(Hg(eP@>m?^HKSH!sLOKQ6e&oCyf3js zvPekzhJ=b!1|yp&P)36EPi$6?;e_$2f3)IBy4zi$UG}yhF<-F&dZ~e?+oBX?EHG&$iOVH7kE_K!d({nb zuyrIzexD(B@za=DEX9E0N8`u|ZJTJ(`D=!9%IrBn4(wPlseFX+`GZ9$8`n1%MJMNrF3TWRf#$dV4aIHJhOvunzY6ysa&t92UBA zRU0o2{q^B<{GqMs)vcK?)^iI-Jj`yg`XzIcBWO&n+%_r5c3HUl z;R*%^3%+c}sDO5&c*12~wfoViEn3Kf4$&9c=#x2v7ilsB)^3Uc`4$5V>11+nwGVH0 zx6F*FN{xL5>TAA2cFQJ&=6wdF5#EL{ub^FS6^+A_L>5FHTKFph#gRNt*#v_=2X_su zEB^ze%J51+d@1gZyu>7nti&(x_e4~0h8FzMKWwzTq-jEL&<&2q$Ur03@QU}xUg<`j zqgZgoefH^{$s0`c1p@Wg`He!bbHUlX3Be9(CUD3`J??gqAnH%FHkoi8LaZPa<#j4H zL3_$!bG6jBuzdmwSzfFaH;MijGz&9G$6gL=BR7xCLujk!WL?+Mn5`vS)(Z5I{*m*j$@Y_FU^VVYXAN2H;Ds*k@ z(piY2uxCg+IixVB!aY)dE+U90e;9+B>5}M2PK1&Xq>^3mo}Z9mS=oi(sCf-bFaffL=8@~|oamiY5!arqOG%&LsRjfPzG9)PS^dw;CbS6+?pjC#qPO7OKY z{p>I0_XAqO26ui~pY&OdUdaJhzEXDC(a2(;43o&>E~m7wR+sj^Z&>eOsN(UFHlS%{ z-6aTHJTi2n^*(*9kKE#7F(yQ^N2-WeQu`P-!0%>g?_G(w2vt}jdUs1t&>`XQDnE*s zZaM}oY)Mj?)k_w?r`Dh4cq|ob+fs(sYOtoa&p}jo}GXWD~W;gs>CQo<7r@ zYyXR?{lJ>X1M%^~E*6$XLRUx(pIvg-zYqxKO5A3vi*wz|FF6CKFyI{|-b;C`@l<2) zNb3N-#3u4km_XLASPAV`g{NWh33!6~WG9hF2&6s~BqLHy5Q-LOOp?AhYhAnzD<$yc z9^^%%rXE~#J`XQO*WTk*{c+KUMr1gn%^lH%>idDk{#!phW!`O@h5JsgDx4|j0tpJN z2+`vOM=@_RaUFPkuZ!Hg{F{%yF@a0RBA?B0y}xQAx3~?-k`r7W(!DMny!=K#xU3=k zgMr)I=Y?yaeh(Cmt&rfOn~{Z}ijBiFKh6QvntaW7r1WyXz=xbUWau42jdhMO!_Av_>Y=5$V!?3l#p98Y zF&cO-iCG{dxV}*P&_ZBey5i6uR6ARa*&DzPd!jf}Cds$tT3J~e^=bnIjei{#gFX+|ApPYa}*1OP4VWq$M(9)Uj$6vmf)?v`&M0_7ZhI= zYdeDT+2!Mwa)0u}HL^iCd zIp5ZAKa&lfD~w>u{JPYH{m97xiKvI%jXx&JQsz~nPwH2g4Y%kcfvww;{lSpef*pVx zir`GwNc9*7Qq58Z4lfSUZ$UJY#FXi<&e7VaeKFEf^2SCykvjXUkD2mW1yi(z1P8sQ ziZz&J7F?pW7u4-Z9f~}{@k>2LY^Rtsc0UR5IEAEKcw8ZLa+)q5`d{rId|D1z{)F(g zH(`;we0J5aI!dH!;E=3Q3wB!86|oFu;%k%y%pnKmR#rukqkbc*Vay8@UUw8Cr=a#S z&h1KG<)0+hLHtSHx5wS3?i8~@rgalueY{+1?e?;L$@R9BSLaB&-zRCkM5gf2ENb*& zdJO#Hbk+`Tzs-8)Bb$EpA&gM`_!E(KxMM zoIzb?$S#V5;9Gsa3Bp1H1yw^K+eTO%DGy=CPqbMS>oZU}FVEbrfb}@rh>|qne7vRH z?N2fn5Z?6Ks%V(Y6xuU>H}ddz-jzz&pCc3=^u6>ZZcUtM zXD->Q{9NlAf;WZ6xvR@PK&eH?%r!m#a~2z27N`IlVBuSmjP6_*#HXDwE$Mr7wN1VZ zKlqE#Z#>KQC91~A@so_|V}*8E9E{);WRFT9`N zrG8_5Bw-t@oK+v8DDM5u^heZ8Bj1k3Ref-8#e~Ku<|h)fm(E`nGC>)H2AjQ{#CizG zo*#xe)A@glc{X!3!6*@t)R=y%VskCDG04DPdi1K172EiV>JYnCE~tI8UeL%~w%`eK zOveog&sFZ3y_*I0yOC7};V-t^Fs=dlOE#Z$T!e|%MFa3#3BnA*)|N{4(9L8;8nP6C zu0U@`>tk!!Ajwk$;oDQKKvK+vBK`9;%xMwC>&5b}6och(uIYxB15QL-m}j-LM;fCB|;Yy+=-E#pDYJt^Vi#U0#Vyj7`T*{!_0WX^gl5* zQlnchNFGHlc$y*FkeZ0);Ls+&;OE+X(^-Bij7m3Gh*hW5xz@+vALjh4KMQlG zST%R2TrJb1C^HSeyh2>b*I0-8IgXDpX^d~y!D*4KA|J)>F-m*@KU&9!{Sb1@FGSMe zv9-za#i|1tYG|-Sjpys#vH)WyE5cO3vzJdEHDOk|S?9OU$KoGO&lxgk54d$XaoLSzJ|r%_LitjB01$qr%)U=p!<}hE&ngOAu4YgDb>Jci|x2Z&uVV zZJE(pbFTIp+I|6k=Q~nIo{H_R1uQL}Emd50=zDFlu#-$i+@W<2;yo53Rny^*?c{Kr zgC0B0INa0i>#J1PAXs45HOI{WiB3?mVi=14D$5zL3$TA=Wo7q-JiNh->t%l}OKdJzR` z7bjs%dew!OnQXxAwG^yo>bs0t*xMwM&}~ihG*Ihq|ThHK8j;MZeDq zbwGp$OA3B~%hjerO}z-W+n6d~lBP3Aa7z(^YIOIe*#G-J02jqa#K^jWH35}|bo*d_ zmG1;Rj^&6mH(QV>{ky_pC72&uv7_&X0AJ{O z%!^YU@}PuYR3DY5l&pyy&=MNwP*s=MvjJ!y7eehivNb~QJ+!so$G zhJwnn@)(VHEAh;}u|gi+ZZ)5yDRSz-e>^fd@YgG)9>Gj)Bj8tC)k~5tL^^0pB04zC z>$Ef@N#8>go+Ja)iXqDrR`kHqVa%H6!#~fSM*%)Q|1No0Gp-aKwJ^dF0=wTzJleAI z3AFUt^CD=(Cl|9F=6NIT&>*KXy24>)DP>rc8yt6j87%kvU`yX;=e!HR?c~i$-cQu5 zq@vX4?bIvnkC=osJ6E2Ex9K#kv=;&^m4d1mtO|;qpM)DF>!fLDmTDkpf7frtKSll3 zs7;C;Et*83n1F_aW;raShQ854j09x=rYyb^FSw>TW zRY66TT|+@mMM6{SsSGlJ0`U6>3P1=5l=W^fEuMqA|636?#uH!H%hIaM#JciZI_cme zH}}#TrOJleWUG@#HRF`1w?6Pb@BlSMC}?B=GB|Yrpc9-r;NO0bz^UK;`IqJ234jH{ z(%(rQ>55J*Rc8I`_wQ5V0{(Gf9pF>rPZcSPKmh=B&;an!e?K+zzn@xJLPbGVMnjWL zS@upUW!uI7f2sWQ0y^$p0PLMqUW3y%cXD8d^sFd%&f4_%Sv`Q}ASYLdPmXctaRNAZ62ON3j|8lMju0opb|(?3|8pWzP7V%EjuLLJ#^Ar?fQ~>{8*}h4B^xt{ z(-*vxe*Ax(KKR|vrmm*oce_Ds;l5+p{;w?-rXbS?&Jcc>KSG$An*-e-&k*4|mV`gE zn7aZW=Jtr*(R}?gjir;TgDD6Ed;pKc9gi&RA9);19c`T5?M*>8PL7b1RPK-pAA)3V zYH$8vKK(mBEVzgExj6&PZA|TLe1H}ZTb1ruqaMNv^a24L-5w+-?^ex|KhwDZT|I2T zEd|6Hfjb&y`2SV|^fCuJKTHw3+kO`O*Ayprkh43;(#HM)vPI^O!$1G7Ndy2;fpbjt4$2z+zebt4fm}_^LH~2~0f5HM_@|5D&)9>%*MQlf!w5#PfjfNNJFo@LKZj`mL7?Bw0*#D}qq~DN(9*^cs9|mmbbufW z8;?;gB*4;gu+-{~)Q9Jxq-v(FAe-Nfh{o@@&(g+R7Ti@r3SYx)H8jvtGydBJ(>}||dz)o#bd-n&yR=43~9fE^GTdeza_e|%HhRG5Z4mOU`;J>s$ zHuit+auc&eN&$z{bL98yuDszNxqg$L0-gU{e1EP3WaxEKfor5J(*1B+&I3XnWVaPFckgvGxSvo* z0RWWmz=nPP2&MsY1$Xe^Eb{=m{+{TAj9097(_;;8a`}nxm%8&nNY(|wJ`m6mBL>@y{HEprwfb5hY)PiNOCL zBEEV^BG;c2E4h-Fet?N)|3L($JS36(&xsu(m-xSP(c(Xd3uzBYr(S>fO7dp6! zX1G6%C71Dl#6Jg43(V36gY)nd=6(Zzc-N{pljx=7+IK1KrGB zZT^}ip!w%9HSk!&0SJPm6b_^^$@_!56H?OqBRHMb2Z#STQ%7%`N)nvEebE0=n+G3; zDd+0s4nf>spyqI)3J%3i!39+QZmcr|84w(kxtoLjT-LiaweWj6LHH2>pmw*~Oh6?2 z*DDf#9e^Odrc1pD2ahbVnD5UDKUsW8q0H~~YYU*opG#f+N{r6I#ZVDE!c(}re_{s` zsRFpshAA)KENs!y1o-xT2ge8+cZ33D5DMMhKu!+7TN;S7@%&@s$$M}%A`;%uMt@4k zkblphLo7_U{GiDR&c=Dz`wh-3Cdh;`6882^od}4UV^#=_ zj_wZsSW$vBAK@cJJFCDg&KT_dQL_ynWJU#uZS{%~1cl(wKttWnzYu|ku|Xd4Qy@rI z1%qn}H}U;uF-;IctQ2HQMW8pty2Dq!LQ>cOKn>sh z_3Qve$aHr%c|Z)UK$%y{0gptHsO}d?UL(k$|C*|S*og7HpRn@x<2tbS7ky-HAT+uH zEr5{jU9f$lN6d=^L2#!3M^LbU?A%Kr1 z*^z!D_%k2De&;*>=b8Tteie6z-yblwf4D0!Nz%A#`TGj)-htk%|Ai~i1bTtoAJYFM z?nej;901^r0RULveU9|aL;LTmA=~qyhWYI(06c7I2KUaMcPGILp#B#h7n8MjG6g+# za(A@Qa(<9oU_&fFwgSEg22}8v@a|(SMgN-@qHJp8_^+iS8xI?chbd8M$YD$`z_nos zd~ZVTK5Fsd|Lx_dT3WgRK@W0KJAvnW+2GG?ga4V_eJZLP>Or6P`+J5H;!gNuJJ0Ix zwE&mj0qh;IZ^eU)?*?Okj>d!c$WH)+{b25IyZKoO1<`|x;9(0ms#S2bbb@40%jI0& zwmR4rj&Of(`dRgZ`DFeYV%b2x@1IVt6%!E$0FdOpKU8h|^iWy|Ha~csDouf#y(+Z( z3(Z^u524fe$A2Lh{;e-`{r+N$D%kr#&?sa;8D)2Skc~5VP+$XsV7X5v=GCIp?;YTP z`}Y@N0y5z5Dh+A&Nm#U2lYz4j5BC0a&dPtS`?tq_|K|mne;$OSMw=%fIAem9zW*`# z={)_g%0D;e4}G<{`nxGNy<x`g2v*0ZGT@ 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 Xm!3$hP|G2GAlmK;wi(;ij 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