diff --git a/core/macseccfg.cpp b/core/macseccfg.cpp index 40a9764..674696c 100644 --- a/core/macseccfg.cpp +++ b/core/macseccfg.cpp @@ -144,7 +144,7 @@ typedef union _MACSecSa { uint8_t index; /*!< SA index */ uint8_t - sak[32]; /*!< 256b SAK: Define the encryption key to be used to encrypte this packet. The lower 128 bits are used for 128-bit ciphers. */ + sak[32]; /*!< SAK: All 32 bytes are written to the firmware. For AES-128 the firmware requires bytes [0..15] == bytes [16..31] (mirrored); serialize() handles this automatically. */ uint8_t hashKey[16]; /*!< 128b Hash Key: Key used for authentication. */ uint8_t salt[12]; /*!< 96b Salt value: Salt value used in XPN ciphers. */ uint32_t ssci; /*!< 32b SSCI value: Short Secure Channel Identifier, used in XPN ciphers. */ @@ -740,6 +740,34 @@ std::vector MACsecConfig::serialize() const { } } + // AES-128 SAK normalization: the firmware expects the 16-byte SAK mirrored + // into both halves of the 32-byte hardware SAK field. Callers only populate + // bytes [0..15]; copy them into [16..31] here, transparent to all callers. + for(uint8_t i = 0; i < static_cast(rxSecY.size()); i++) { + if(rxSecY[i].cipher == MACsecCipherSuite::GcmAes128 || rxSecY[i].cipher == MACsecCipherSuite::GcmAes128Xpn) { + uint8_t primaryIdx = rxSecYSaIndices[i].first; + if(primaryIdx < maxSa) + memcpy(hwSettings->macsec.rx.sa[primaryIdx].sak + 16, hwSettings->macsec.rx.sa[primaryIdx].sak, 16); + if(rxSecYRekey[i]) { + uint8_t rekeyIdx = rxSecYSaIndices[i].second; + if(rekeyIdx < maxSa) + memcpy(hwSettings->macsec.rx.sa[rekeyIdx].sak + 16, hwSettings->macsec.rx.sa[rekeyIdx].sak, 16); + } + } + } + for(uint8_t i = 0; i < static_cast(txSecY.size()); i++) { + if(txSecY[i].cipher == MACsecCipherSuite::GcmAes128 || txSecY[i].cipher == MACsecCipherSuite::GcmAes128Xpn) { + uint8_t primaryIdx = txSecYSaIndices[i].first; + if(primaryIdx < maxSa) + memcpy(hwSettings->macsec.tx.sa[primaryIdx].sak + 16, hwSettings->macsec.tx.sa[primaryIdx].sak, 16); + if(txSecYRekey[i]) { + uint8_t rekeyIdx = txSecYSaIndices[i].second; + if(rekeyIdx < maxSa) + memcpy(hwSettings->macsec.tx.sa[rekeyIdx].sak + 16, hwSettings->macsec.tx.sa[rekeyIdx].sak, 16); + } + } + } + if(rxRule.size() == 0) { MACsecRxRule defaultRule; MACSecRule_t* hwRxRule = &hwSettings->macsec.rx.rule[0]; diff --git a/include/icsneo/core/macseccfg.h b/include/icsneo/core/macseccfg.h index 2548922..cbf2deb 100644 --- a/include/icsneo/core/macseccfg.h +++ b/include/icsneo/core/macseccfg.h @@ -122,7 +122,7 @@ struct MACsecTxSecY { struct MACsecTxSa { std::array sak = {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, - 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}; /*!< 256b SAK: Define the encryption key to be used to encrypte this packet. The lower 128 bits are used for 128-bit ciphers. */ + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}; /*!< SAK: For AES-256 fill all 32 bytes. For AES-128 fill only bytes [0..15]; serialize() will mirror them into [16..31] as required by the firmware. */ std::array hashKey = {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}; /*!< 128b Hash Key: Key used for authentication. */ std::array salt = {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}; /*!< 96b Salt value: Salt value used in XPN ciphers. */ uint32_t ssci = 0x01u; /*!< 32b SSCI value: Short Secure Channel Identifier, used in XPN ciphers. */ @@ -132,7 +132,7 @@ struct MACsecTxSa { struct MACsecRxSa { std::array sak = {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, - 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}; /*!< 256b SAK: Define the encryption key to be used to encrypte this packet. The lower 128 bits are used for 128-bit ciphers. */ + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}; /*!< SAK: For AES-256 fill all 32 bytes. For AES-128 fill only bytes [0..15]; serialize() will mirror them into [16..31] as required by the firmware. */ std::array hashKey = {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}; /*!< 128b Hash Key: Key used for authentication. */ std::array salt = {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}; /*!< 96b Salt value: Salt value used in XPN ciphers. */ uint32_t ssci = 0x01u; /*!< 32b SSCI value: Short Secure Channel Identifier, used in XPN ciphers. */