From f410ffa4ee443655076260e7ffa4eb5865232321 Mon Sep 17 00:00:00 2001 From: JaiOCP Date: Fri, 2 May 2025 12:31:36 -0700 Subject: [PATCH 1/2] MACSec and IPSec FIPS Compliance Signed-off-by: JaiOCP --- doc/fips/SAI-Proposal-FIPS-Compliance.md | 467 +++++++++++++++++++++++ doc/fips/ipsecFig2.png | Bin 0 -> 34145 bytes inc/saiipsec.h | 67 ++++ inc/saimacsec.h | 67 ++++ inc/saiswitch.h | 132 +++++++ 5 files changed, 733 insertions(+) create mode 100755 doc/fips/SAI-Proposal-FIPS-Compliance.md create mode 100755 doc/fips/ipsecFig2.png diff --git a/doc/fips/SAI-Proposal-FIPS-Compliance.md b/doc/fips/SAI-Proposal-FIPS-Compliance.md new file mode 100755 index 000000000..053ceca8e --- /dev/null +++ b/doc/fips/SAI-Proposal-FIPS-Compliance.md @@ -0,0 +1,467 @@ +# MACSec and IPSec FIPS Compliance +------------------------------------------------------------------------------- + Title | MACSec and IPSec FIPS Compliance +-------------|----------------------------------------------------------------- + Authors | Jai Kumar (Broadcom Inc.) + Status | In review + Type | Standards track + Created | 2025-03-31 + SAI-Version | 1.17 +------------------------------------------------------------------------------- + +## 1.0 Introduction + +This document describes the SAI API interaction and enhancements for triggering POST for FIPS 140-3 standard compliance to overall security level 1. + + +Networking Operating System (NOS) need to have cryptographic software components. "Library" which is a module providing cryptographic algorithms implies “FIPS inside” approach in the NOS. The “FIPS inside” is a way of designating one or more crypto modules with smaller boundaries, instead of one product-wise perimeter, which would encompass non-cryptographic components inside, all of them having code freeze caveat. + +POST trigger is defined at the switch, MACSEC, and, IPSEC engine level. This is done to support different hardware architectures where POST can be run during the switch init or it can be run during the MACSEC, IPSEC engine init. + +Existing MACSec/IPSec SAI specification already supports the concept of MACSec and IPSec objects and MACSec/IPSec ports. It supports the concept of single logical instance of MACSEc/IPSec in each direction and abstracts out the number of hardware engines present. + +This document proposes a SAI specification that maintains the current MACSec/IPSec SAI spec construct of single logical engine. + +Bring up sequence of MACSec and IPSec engine without FIPS compliance at a object boundary is as follows + +1. Switch create +2. MACSec/IPSec object create +3. MACSec/IPSec port object create +4. Once the ports are created and SA association and other attributes are set, the port is ready to rx/tx traffic. + +This document introduces a trigger called as Pre-Operational Self-Test "POST" before the MACSec/IPSec engine enables the MACSec/IPSec port for forwarding traffic. + +FIPS-103 compliance requires that POST is executed on each MACSec/IPSec port and only if POST completes with ‘success’, the MACSec/IPSec port must be enabled for admitting traffic. +Note that this specification will provide POST at the MACSec/IPSec single logical instance level or at the switch level. + +As shown in Fig-1, there are two physical security engines and are represented by single logical instance in SAI. Enabling of POST happens at the logical intance level and in turn will trigger POST for all the physical instances present in a given hardware. +1. Each MACSec/IPSec serving ‘n’ number of ports (1:n) +2. Each port has its corresponding MACSec/IPSec engine (1:1) + +![Fig-1](./ipsecFig2.png) + + +## 2.0 Enhancements +SAI_OBJECT_TYPE_MACSEC and SAI_OBJECT_TYPE_ IPSEC already exists +SAI_MACSEC_ATTR_SUPPORTED_PORT_LIST and SAI_IPSEC_ATTR_SUPPORTED_PORT_LIST provides the list of MACSec/IPSec ports being service by an instance of MACSEC and IPSEC objects respectively. Each MACSec/IPSec port has a correspoding binding to the physical port SAI_MACSEC_PORT_ATTR_PORT_ID. +``` +SAI_OBJECT_TYPE_SWITCH -> SAI_SWITCH_ATTR_MACSEC_OBJECT_LIST[x] -> SAI_MACSEC_ATTR_SUPPORTED_PORT_LIST[] -> SAI_MACSEC_PORT_ATTR_PORT_ID + +SAI_OBJECT_TYPE_SWITCH -> SAI_SWITCH_ATTR_IPSEC_OBJECT_LIST[x] -> SAI_IPSEC_ATTR_SUPPORTED_PORT_LIST[] -> SAI_IPSEC_PORT_ATTR_PORT_ID +``` + +### 2.1 MACSec +Following sections describes the attributes for MACSec engine + +#### 2.1.1 MACSec Engine +All physical MACSec engines are represented by a single MACSec SAI object id. Single SAI MACSec object id can be serving one or more physical MACSec engines and ports. + +New attribute is introduced to trigger POST at the SAI MACSec engine id. +Setting the attribute to true will start POST on all the physical MACSec engines and ports associated with the MACSec engine id. + +``` + /** + * @brief Setting the value to true will start the post on all the ports serviced by this MACSEC engine + * + * @type bool + * @flags CREATE_ONLY + * @default false + */ + SAI_MACSEC_ATTR_ENABLE_POST, +``` + +Status of the POST can be queried using SAI_MACSEC_ATTR_POST_STATUS attribute. Note that status reflects the aggregate status of all the engines and ports serviced by this MACSec object id. Even if a single MACSec port fails the POST, status of the MACSec object will be returned as SAI_MACSEC_POST_STATUS_FAIL. +Subsequently NOS has to query individual MACSec engines/ports serviced by the MACSec object id to figure out which MACSec engine/port has failed the POST. + +``` + /** + * @brief MACSEC POST status + * Attribute to query the status of POST for a MACSEC engine + * + * @type sai_macsec_post_status_t + * @flags READ_ONLY + */ + SAI_MACSEC_ATTR_POST_STATUS, +``` +Following POST status values are defined. SAI_MACSEC_POST_STATUS_IN_PROGRESS means that POST is still running and is not yet complete. +``` +/** + * @brief Attribute data for #SAI_MACSEC_ATTR_POST_STATUS, + */ +typedef enum _sai_macsec_post_status_t +{ + /** Unknown */ + SAI_MACSEC_POST_STATUS_UNKNOWN, + + /** Pass */ + SAI_MACSEC_POST_STATUS_PASS, + + /** In Progress */ + SAI_MACSEC_POST_STATUS_IN_PROGRESS, + + /** Fail */ + SAI_MACSEC_POST_STATUS_FAIL, +} sai_macsec_post_status_t; +``` + + +#### 2.1.2 MACSec Port +New READ only attribute SAI_MACSEC_PORT_ATTR_POST_STATUS is introduced to read the status of POST for a given MACSec port. +This attribute can be read after the POST is completed for the MACSec object hosting this port. +``` +/** + * @brief Attribute data for #SAI_MACSEC_PORT_ATTR_POST_STATUS + */ +typedef enum _sai_macsec_port_post_status_t +{ + /** Unknown */ + SAI_MACSEC_PORT_POST_STATUS_UNKNOWN, + + /** Pass */ + SAI_MACSEC_PORT_POST_STATUS_PASS, + + /** Fail */ + SAI_MACSEC_PORT_POST_STATUS_FAIL, + +} sai_macsec_port_post_status_t; + +/** + * @brief Attribute Id for sai_macsec_port + */ +typedef enum _sai_macsec_port_attr_t +{ + . . . + + /** + * @brief MACSEC Port POST completion status + * + * Attribute to query the status of POST for a MACSEC port + * + * @type sai_macsec_port_post_status_t + * @flags READ_ONLY + */ + SAI_MACSEC_PORT_ATTR_POST_STATUS, + + . . . + +} sai_macsec_port_attr_t; +``` + +#### 2.1.3 POST Completion Callback +Single aggregate callback function is provided to return the status of POST status for the entire MACSec engine. + +If the engine is servicing a single port then this callback essentially becomes a per port callback. + +If the engine is servicing multiple ports then each port needs to be queried for its POST status using the READ only attribute of the port. +``` +/** + * @brief MACSEC post status notification + * + * @objects switch_id SAI_OBJECT_TYPE_MACSEC + * + * @param[in] macsec_id MACSEC Id + * @param[in] macsec_post_status MACSEC post status + */ +typedef void (*sai_macsec_post_status_notification_fn)( + _In_ sai_object_id_t macsec_id, + _In_ sai_macsec_post_status_t macsec_post_status); + +/** + * @brief Attribute Id in sai_set_switch_attribute() and + * sai_get_switch_attribute() calls. + */ +typedef enum _sai_switch_attr_t +{ + /** + * @brief Callback for completion status of all the MACSEC ports serviced by this MACSEC engine + * + * Use sai_macsec_post_status_notification_fn as notification function. + * + * @type sai_pointer_t sai_macsec_post_status_notification_fn + * @flags CREATE_AND_SET + * @default NULL + */ + SAI_SWITCH_ATTR_MACSEC_POST_STATUS_NOTIFY, + +``` + +### 2.2 IPSec +Following sections describes the attributes for IPSec engine. +It is identical in the specification as MACSec. +SAI IPSec specification makes and assumption that there is only single physical IPSec engine. This specifications maintians the assumption and if there is a need to support more than one physical IPSec engines then the IPSEc SAI specification will be enhanced accordingly. + +#### 2.2.1 IPSec Engine +New attribute is introduced to trigger POST at the IPSec engine granularity. +Setting the attribute to true will start POST on all the IPSec ports associated with the IPSec engine id. +``` + /** + * @brief Setting the value to true will start the post on all the ports serviced by this IPSEC engine + * + * @type bool + * @flags CREATE_ONLY + * @default false + */ + SAI_IPSEC_ATTR_ENABLE_POST, +``` +Status of the POST can be queried using SAI_IPSEC_ATTR_POST_STATUS attribute. Note that status reflects the aggregate status of all the ports services by this IPSec object id. Even if a single IPSec port fails the POST, status of the IPSec object will be returned as SAI_IPSEC_POST_STATUS_FAIL. +Subsequently NOS has to query individual IPSec ports serviced by the IPSec object id to figure out which IPSec port has failed the POST. This approach works for both, one engine to one port and one engine to many ports, kinds of IPSec engines. +``` + + /** + * @brief IPSEC POST status + * Attribute to query the status of POST for an IPSEC engine + * + * @type sai_ipsec_post_status_t + * @flags READ_ONLY + */ + SAI_IPSEC_ATTR_POST_STATUS, +``` +Following POST status values are defined. SAI_MACSEC_POST_STATUS_IN_PROGRESS means that POST is still running and is not yet complete. +``` +/** + * @brief Attribute data for #SAI_IPSEC_ATTR_POST_STATUS, + */ +typedef enum _sai_ipsec_post_status_t +{ + /** Unknown */ + SAI_IPSEC_POST_STATUS_UNKNOWN, + + /** Pass */ + SAI_IPSEC_POST_STATUS_PASS, + + /** In Progress */ + SAI_IPSEC_POST_STATUS_IN_PROGRESS, + + /** Fail */ + SAI_IPSEC_POST_STATUS_FAIL, +} sai_ipsec_post_status_t; +``` + +#### 2.2.2 IPSec Port +New READ only attribute SAI_IPSEC_PORT_ATTR_POST_STATUS is introduced to read the status of POST for a given IPSec port. +This attribute can be read after the POST is completed for the IPSec object hosting this port. +``` +/** + * @brief Attribute data for #SAI_IPSEC_PORT_ATTR_POST_STATUS + */ +typedef enum _sai_ipsec_port_post_status_t +{ + /** Unknown */ + SAI_IPSEC_PORT_POST_STATUS_UNKNOWN, + + /** Pass */ + SAI_IPSEC_PORT_POST_STATUS_PASS, + + /** Fail */ + SAI_IPSEC_PORT_POST_STATUS_FAIL, + +} sai_ipsec_port_post_status_t; + +/** + * @brief Attribute Id for sai_ipsec_port + */ +typedef enum _sai_ipsec_port_attr_t +{ + . . . + + /** + * @brief IPSEC Port POST completion status + * + * Attribute to query the status of POST for a IPSEC port + * + * @type sai_ipsec_port_post_status_t + * @flags READ_ONLY + */ + SAI_IPSEC_PORT_ATTR_POST_STATUS, + . . . + +} sai_ipsec_port_attr_t; + +``` +#### 2.2.3 Post Completion Callback + +Single aggregate callback function is provided to return the status of POST status for the entire IPSec engine. + +If the engine is servicing a single port then this callback essentially becomes a per port callback. + +If the engine is servicing multiple ports then each port needs to be queried for its POST status using the READ only attribute of the port. +``` +/** + * @brief IPSEC post status notification + * + * @objects switch_id SAI_OBJECT_TYPE_IPSEC + * + * @param[in] ipsec_id IPSEC Id + * @param[in] ipsec_post_status IPSEC post status + */ +typedef void (*sai_ipsec_post_status_notification_fn)( + _In_ sai_object_id_t ipsec_id, + _In_ sai_ipsec_post_status_t ipsec_post_status); + +/** + * @brief Attribute Id in sai_set_switch_attribute() and + * sai_get_switch_attribute() calls. + */ +typedef enum _sai_switch_attr_t +{ + /** + * @brief Callback for completion status of all the IPSEC ports serviced by this IPSEC engine + * + * Use sai_ipsec_post_status_notification_fn as notification function. + * + * @type sai_pointer_t sai_ipsec_post_status_notification_fn + * @flags CREATE_AND_SET + * @default NULL + */ + SAI_SWITCH_ATTR_IPSEC_POST_STATUS_NOTIFY, +``` + +### 2.3 Switch + +POST can be trigerred at the switch level. This is done by setting the SAI_SWITCH_ATTR_MACSEC_ENABLE_POST for MACSec engine and SAI_SWITCH_ATTR_IPSEC_ENABLE_POST for IPSec engine. Setting this attribute to true will trigger POST for all the instances of MACSec/IPSec engine in a given hardware. + +Completion status is reported by a callback as an aggregate status for the switch. Callback need to be registered for MACSec and IPSec POST status. + +System can be queried using capability APIs to figure out if the systen support POST at the switch level or at the engine level or not at all. + +``` + /** + * @brief MACSEC POST status + * Attribute to query the status of POST for all the MACSEC engines + * + * @type sai_switch_macsec_post_status_t + * @flags READ_ONLY + */ + SAI_SWITCH_ATTR_MACSEC_POST_STATUS, + + /** + * @brief IPSEC POST status + * Attribute to query the status of POST for all the IPSEC engines + * + * @type sai_switch_ipsec_post_status_t + * @flags READ_ONLY + */ + SAI_SWITCH_ATTR_IPSEC_POST_STATUS, + + /** + * @brief Setting the value to true will start the post on all MACSEC engines + * + * @type bool + * @flags CREATE_ONLY + * @default false + */ + SAI_SWITCH_ATTR_MACSEC_ENABLE_POST, + + /** + * @brief Setting the value to true will start the post on all IPSEC engines + * + * @type bool + * @flags CREATE_ONLY + * @default false + */ + SAI_SWITCH_ATTR_IPSEC_ENABLE_POST, + + /** + * @brief Callback for completion status of all the MACSEC engines on the switch + * + * Use sai_switch_macsec_post_status_notification_fn as notification function. + * + * @type sai_pointer_t sai_switch_macsec_post_status_notification_fn + * @flags CREATE_AND_SET + * @default NULL + */ + SAI_SWITCH_ATTR_SWITCH_MACSEC_POST_STATUS_NOTIFY, + + /** + * @brief Callback for completion status of all the IPSEC engines on the switch + * + * Use sai_switch_ipsec_post_status_notification_fn as notification function. + * + * @type sai_pointer_t sai_switch_ipsec_post_status_notification_fn + * @flags CREATE_AND_SET + * @default NULL + */ + SAI_SWITCH_ATTR_SWITCH_IPSEC_POST_STATUS_NOTIFY, +``` +### 3.0 Capability Query +Switch attributes SAI_SWITCH_ATTR_MACSEC_ENABLE_POST and SAI_SWITCH_ATTR_IPSEC_ENABLE_POST, can be queried to find out if the system supports IPSec and/or MACSec compliance at a switch level or not. +Similarly MACSec/IPSec SAI attributes SAI_MACSEC_ATTR_ENABLE_POST and SAI_IPEC_ATTR_ENABLE_POST, can be queried to find out if the MACSec/IPSec engine support IPSec and/or MACSec compliance at a engine level or not. + +If both the querires return as unsupported, this means that system does not support FIPS compliance. + +Query API is used to determine if POST is supported at switch level or engine level granuarity. +``` + sai_status_t status = SAI_STATUS_SUCCESS; + sai_attr_capability_t post_capability={0}; + + // Query if MACSec POST is supported at Switch level + status = sai_query_attribute_capability(gSwitchId, SAI_OBJECT_TYPE_SWITCH, + SAI_SWITCH_ATTR_MACSEC_ENABLE_POST, &post_capability); + + // Query if IPSec POST is supported at Switch level + status = sai_query_attribute_capability(gSwitchId, SAI_OBJECT_TYPE_SWITCH, + SAI_SWITCH_ATTR_IPSEC_ENABLE_POST, &post_capability); + + // Query if MACSec POST is supported at engine level + status = sai_query_attribute_capability(gSwitchId, SAI_OBJECT_TYPE_MACSEC, + SAI_MACSEC_ATTR_ENABLE_POST, &post_capability); + + // Query if IPSec POST is supported at engine level + status = sai_query_attribute_capability(gSwitchId, SAI_OBJECT_TYPE_IPSEC, + SAI_IPSEC_ATTR_ENABLE_POST, &post_capability); +``` +### 3.0 Example Workflow +Following steps are completed before enabling POST on the MACSec engine. + +**Step 1:** +Switch create is complete and POST completion callback registraton SAI_SWITCH_ATTR_MACSEC_POST_STATUS_NOTIFY is done. +Query API us called to find out if POST is supported at switch or engine level. +Subsequent steps are captured as an example for engine level POST. + +**Step 2: ** +MACSec Object creation is complete + +**Step 3: ** +Trigger POST by setting the attribute to true. + +``` + attrs.clear(); + + sai_object_id_t macsec_obj; + + attr.id = SAI_MACSEC_ATTR_ENABLE_POST; + attr.value.bool = true; + attrs.push_back(attr); + + sai_macsec_api->create_macsec( + &macsec_obj, + switch_id, + attrs.size(), + attrs.data()); +``` + +**Step 4: ** +Once the POST is completed on all the ports hosted by the MACSec engine, registered post macsec callback will be called by the SAI adapter. +If the status is SAI_MACSEC_POST_STATUS_FAIL, NOS MUST read the post status of all the ports hosted by the engine to find out which port POST has failed. +``` +for all macsec_port_obj in macsec_obj->SAI_MACSEC_ATTR_SUPPORTED_PORT_LIST: + read(macsec_port_obj->SAI_MACSEC_PORT_ATTR_POST_STATUS) +``` +**Step 5: ** +Set the POST enable flag in the macsec object to false. This is mainly for the hw where POST can be triggered runtime after the initialization. +``` + attrs.clear(); + + sai_object_id_t macsec_obj; + + attr.id = SAI_MACSEC_ATTR_ENABLE_POST; + attr.value.bool = false; + attrs.push_back(attr); + + sai_macsec_api->create_macsec( + &macsec_obj, + switch_id, + attrs.size(), + attrs.data()); +``` + \ No newline at end of file diff --git a/doc/fips/ipsecFig2.png b/doc/fips/ipsecFig2.png new file mode 100755 index 0000000000000000000000000000000000000000..674399e49cd0fc0b01789e1853b4238aafb6c586 GIT binary patch literal 34145 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 literal 0 HcmV?d00001 diff --git a/inc/saiipsec.h b/inc/saiipsec.h index 4a64afb16..0c1544210 100644 --- a/inc/saiipsec.h +++ b/inc/saiipsec.h @@ -94,6 +94,32 @@ typedef struct _sai_ipsec_sa_status_notification_t } sai_ipsec_sa_status_notification_t; +/** + * @brief Attribute data for #SAI_IPSEC_ATTR_POST_STATUS, + */ +typedef enum _sai_ipsec_post_status_t +{ + SAI_IPSEC_POST_STATUS_UNKNOWN, + + SAI_IPSEC_POST_STATUS_PASS, + + SAI_IPSEC_POST_STATUS_IN_PROGRESS, + + SAI_IPSEC_POST_STATUS_FAIL, +} sai_ipsec_post_status_t; + +/** + * @brief IPSEC post status notification + * + * @objects switch_id SAI_OBJECT_TYPE_IPSEC + * + * @param[in] ipsec_id IPSEC Id + * @param[in] ipsec_post_status IPSEC post status + */ +typedef void (*sai_ipsec_post_status_notification_fn)( + _In_ sai_object_id_t ipsec_id, + _In_ sai_ipsec_post_status_t ipsec_post_status); + /** * @brief Attribute Id for sai_ipsec */ @@ -287,6 +313,24 @@ typedef enum _sai_ipsec_attr_t */ SAI_IPSEC_ATTR_SA_LIST, + /** + * @brief IPSEC POST status + * Attribute to query the status of POST for an IPSEC engine + * + * @type sai_ipsec_post_status_t + * @flags READ_ONLY + */ + SAI_IPSEC_ATTR_POST_STATUS, + + /** + * @brief Setting the value to true will start the post on all the ports serviced by this IPSEC engine + * + * @type bool + * @flags CREATE_ONLY + * @default false + */ + SAI_IPSEC_ATTR_ENABLE_POST, + /** * @brief End of IPsec attributes */ @@ -303,6 +347,19 @@ typedef enum _sai_ipsec_attr_t SAI_IPSEC_ATTR_CUSTOM_RANGE_END } sai_ipsec_attr_t; +/** + * @brief Attribute data for #SAI_IPSEC_PORT_ATTR_POST_STATUS + */ +typedef enum _sai_ipsec_port_post_status_t +{ + SAI_IPSEC_PORT_POST_STATUS_UNKNOWN, + + SAI_IPSEC_PORT_POST_STATUS_PASS, + + SAI_IPSEC_PORT_POST_STATUS_FAIL, + +} sai_ipsec_port_post_status_t; + /** * @brief Attribute Id for sai_ipsec_port */ @@ -394,6 +451,16 @@ typedef enum _sai_ipsec_port_attr_t */ SAI_IPSEC_PORT_ATTR_SELECTIVE_COUNTER_LIST, + /** + * @brief IPSEC Port POST completion status + * + * Attribute to query the status of POST for a IPSEC port + * + * @type sai_ipsec_port_post_status_t + * @flags READ_ONLY + */ + SAI_IPSEC_PORT_ATTR_POST_STATUS, + /** * @brief End of IPsec Port attributes */ diff --git a/inc/saimacsec.h b/inc/saimacsec.h index 05ee02c84..3b1b9d344 100644 --- a/inc/saimacsec.h +++ b/inc/saimacsec.h @@ -67,6 +67,20 @@ typedef enum _sai_macsec_max_secure_associations_per_sc_t SAI_MACSEC_MAX_SECURE_ASSOCIATIONS_PER_SC_FOUR, } sai_macsec_max_secure_associations_per_sc_t; +/** + * @brief Attribute data for #SAI_MACSEC_ATTR_POST_STATUS, + */ +typedef enum _sai_macsec_post_status_t +{ + SAI_MACSEC_POST_STATUS_UNKNOWN, + + SAI_MACSEC_POST_STATUS_PASS, + + SAI_MACSEC_POST_STATUS_IN_PROGRESS, + + SAI_MACSEC_POST_STATUS_FAIL, +} sai_macsec_post_status_t; + /** * @brief Attribute Id for sai_macsec */ @@ -313,6 +327,24 @@ typedef enum _sai_macsec_attr_t */ SAI_MACSEC_ATTR_MAX_SECURE_ASSOCIATIONS_PER_SC, + /** + * @brief MACSEC POST status + * Attribute to query the status of POST for a MACSEC engine + * + * @type sai_macsec_post_status_t + * @flags READ_ONLY + */ + SAI_MACSEC_ATTR_POST_STATUS, + + /** + * @brief Setting the value to true will start the post on all the ports serviced by this MACSEC engine + * + * @type bool + * @flags CREATE_ONLY + * @default false + */ + SAI_MACSEC_ATTR_ENABLE_POST, + /** * @brief End of MACsec attributes */ @@ -329,6 +361,19 @@ typedef enum _sai_macsec_attr_t SAI_MACSEC_ATTR_CUSTOM_RANGE_END } sai_macsec_attr_t; +/** + * @brief Attribute data for #SAI_MACSEC_PORT_ATTR_POST_STATUS + */ +typedef enum _sai_macsec_port_post_status_t +{ + SAI_MACSEC_PORT_POST_STATUS_UNKNOWN, + + SAI_MACSEC_PORT_POST_STATUS_PASS, + + SAI_MACSEC_PORT_POST_STATUS_FAIL, + +} sai_macsec_port_post_status_t; + /** * @brief Attribute Id for sai_macsec_port */ @@ -407,6 +452,16 @@ typedef enum _sai_macsec_port_attr_t */ SAI_MACSEC_PORT_ATTR_SELECTIVE_COUNTER_LIST, + /** + * @brief MACSEC Port POST completion status + * + * Attribute to query the status of POST for a MACSEC port + * + * @type sai_macsec_port_post_status_t + * @flags READ_ONLY + */ + SAI_MACSEC_PORT_ATTR_POST_STATUS, + /** * @brief End of MACsec Port attributes */ @@ -994,6 +1049,18 @@ typedef enum _sai_macsec_sa_stat_t SAI_MACSEC_SA_STAT_IN_PKTS_OK, } sai_macsec_sa_stat_t; +/** + * @brief MACSEC post status notification + * + * @objects switch_id SAI_OBJECT_TYPE_MACSEC + * + * @param[in] macsec_id MACSEC Id + * @param[in] macsec_post_status MACSEC post status + */ +typedef void (*sai_macsec_post_status_notification_fn)( + _In_ sai_object_id_t macsec_id, + _In_ sai_macsec_post_status_t macsec_post_status); + /** * @brief Create a MACsec object * diff --git a/inc/saiswitch.h b/inc/saiswitch.h index 24283e07c..0356ed5d3 100644 --- a/inc/saiswitch.h +++ b/inc/saiswitch.h @@ -659,6 +659,34 @@ typedef enum _sai_packet_trim_dscp_resolution_mode_t SAI_PACKET_TRIM_DSCP_RESOLUTION_MODE_FROM_TC } sai_packet_trim_dscp_resolution_mode_t; +/** + * @brief Attribute data for #SAI_SWITCH_ATTR_MACSEC_POST_STATUS, + */ +typedef enum _sai_switch_macsec_post_status_t +{ + SAI_SWITCH_MACSEC_POST_STATUS_UNKNOWN, + + SAI_SWITCH_MACSEC_POST_STATUS_PASS, + + SAI_SWITCH_MACSEC_POST_STATUS_IN_PROGRESS, + + SAI_SWITCH_MACSEC_POST_STATUS_FAIL, +} sai_switch_macsec_post_status_t; + +/** + * @brief Attribute data for #SAI_SWITCH_ATTR_IPSEC_POST_STATUS, + */ +typedef enum _sai_switch_ipsec_post_status_t +{ + SAI_SWITCH_IPSEC_POST_STATUS_UNKNOWN, + + SAI_SWITCH_IPSEC_POST_STATUS_PASS, + + SAI_SWITCH_IPSEC_POST_STATUS_IN_PROGRESS, + + SAI_SWITCH_IPSEC_POST_STATUS_FAIL, +} sai_switch_ipsec_post_status_t; + /** * @brief Attribute Id in sai_set_switch_attribute() and * sai_get_switch_attribute() calls. @@ -3316,6 +3344,86 @@ typedef enum _sai_switch_attr_t */ SAI_SWITCH_ATTR_PACKET_TRIM_DSCP_RESOLUTION_MODE, + /** + * @brief Callback for completion status of all the MACSEC ports serviced by this MACSEC engine + * + * Use sai_macsec_post_status_notification_fn as notification function. + * + * @type sai_pointer_t sai_macsec_post_status_notification_fn + * @flags CREATE_AND_SET + * @default NULL + */ + SAI_SWITCH_ATTR_MACSEC_POST_STATUS_NOTIFY, + + /** + * @brief Callback for completion status of all the IPSEC ports serviced by this IPSEC engine + * + * Use sai_ipsec_post_status_notification_fn as notification function. + * + * @type sai_pointer_t sai_ipsec_post_status_notification_fn + * @flags CREATE_AND_SET + * @default NULL + */ + SAI_SWITCH_ATTR_IPSEC_POST_STATUS_NOTIFY, + + /** + * @brief MACSEC POST status + * Attribute to query the status of POST for all the MACSEC engines + * + * @type sai_switch_macsec_post_status_t + * @flags READ_ONLY + */ + SAI_SWITCH_ATTR_MACSEC_POST_STATUS, + + /** + * @brief IPSEC POST status + * Attribute to query the status of POST for all the IPSEC engines + * + * @type sai_switch_ipsec_post_status_t + * @flags READ_ONLY + */ + SAI_SWITCH_ATTR_IPSEC_POST_STATUS, + + /** + * @brief Setting the value to true will start the post on all MACSEC engines + * + * @type bool + * @flags CREATE_ONLY + * @default false + */ + SAI_SWITCH_ATTR_MACSEC_ENABLE_POST, + + /** + * @brief Setting the value to true will start the post on all IPSEC engines + * + * @type bool + * @flags CREATE_ONLY + * @default false + */ + SAI_SWITCH_ATTR_IPSEC_ENABLE_POST, + + /** + * @brief Callback for completion status of all the MACSEC engines on the switch + * + * Use sai_switch_macsec_post_status_notification_fn as notification function. + * + * @type sai_pointer_t sai_switch_macsec_post_status_notification_fn + * @flags CREATE_AND_SET + * @default NULL + */ + SAI_SWITCH_ATTR_SWITCH_MACSEC_POST_STATUS_NOTIFY, + + /** + * @brief Callback for completion status of all the IPSEC engines on the switch + * + * Use sai_switch_ipsec_post_status_notification_fn as notification function. + * + * @type sai_pointer_t sai_switch_ipsec_post_status_notification_fn + * @flags CREATE_AND_SET + * @default NULL + */ + SAI_SWITCH_ATTR_SWITCH_IPSEC_POST_STATUS_NOTIFY, + /** * @brief End of attributes */ @@ -3625,6 +3733,30 @@ typedef void (*sai_switch_state_change_notification_fn)( _In_ sai_object_id_t switch_id, _In_ sai_switch_oper_status_t switch_oper_status); +/** + * @brief Switch MACSEC post status notification + * + * @objects switch_id SAI_OBJECT_TYPE_SWITCH + * + * @param[in] switch_id Switch Id + * @param[in] switch_macsec_post_status Switch MACSEC post status + */ +typedef void (*sai_switch_macsec_post_status_notification_fn)( + _In_ sai_object_id_t switch_id, + _In_ sai_switch_macsec_post_status_t switch_macsec_post_status); + +/** + * @brief Switch IPSEC post status notification + * + * @objects switch_id SAI_OBJECT_TYPE_SWITCH + * + * @param[in] switch_id Switch Id + * @param[in] switch_ipsec_post_status Switch IPSEC post status + */ +typedef void (*sai_switch_ipsec_post_status_notification_fn)( + _In_ sai_object_id_t switch_id, + _In_ sai_switch_ipsec_post_status_t switch_ipsec_post_status); + /** * @brief Platform specific device register read access * From c02890e45892e2a8c6c9f5744c1354488a2063f4 Mon Sep 17 00:00:00 2001 From: JaiOCP Date: Wed, 7 May 2025 12:54:47 -0700 Subject: [PATCH 2/2] MACSec and IPSec FIPS 140-3 Compliance Signed-off-by: JaiOCP --- doc/fips/SAI-Proposal-FIPS-Compliance.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/fips/SAI-Proposal-FIPS-Compliance.md b/doc/fips/SAI-Proposal-FIPS-Compliance.md index 053ceca8e..b67f543bb 100755 --- a/doc/fips/SAI-Proposal-FIPS-Compliance.md +++ b/doc/fips/SAI-Proposal-FIPS-Compliance.md @@ -31,7 +31,7 @@ Bring up sequence of MACSec and IPSec engine without FIPS compliance at a object This document introduces a trigger called as Pre-Operational Self-Test "POST" before the MACSec/IPSec engine enables the MACSec/IPSec port for forwarding traffic. -FIPS-103 compliance requires that POST is executed on each MACSec/IPSec port and only if POST completes with ‘success’, the MACSec/IPSec port must be enabled for admitting traffic. +FIPS 140-3 compliance requires that POST is executed on each MACSec/IPSec port and only if POST completes with ‘success’, the MACSec/IPSec port must be enabled for admitting traffic. Note that this specification will provide POST at the MACSec/IPSec single logical instance level or at the switch level. As shown in Fig-1, there are two physical security engines and are represented by single logical instance in SAI. Enabling of POST happens at the logical intance level and in turn will trigger POST for all the physical instances present in a given hardware. @@ -415,7 +415,7 @@ Following steps are completed before enabling POST on the MACSec engine. **Step 1:** Switch create is complete and POST completion callback registraton SAI_SWITCH_ATTR_MACSEC_POST_STATUS_NOTIFY is done. -Query API us called to find out if POST is supported at switch or engine level. +Query API is called to find out if POST is supported at switch or engine level. Subsequent steps are captured as an example for engine level POST. **Step 2: **