From 2c0d16d875b02cc989ad30f2d72848c2cd611ad5 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 3 Aug 2026 20:01:32 -0700 Subject: [PATCH] [rcp] handle key ID mode 0 in `LinkRawTransmitDone()` (#13466) This commit updates `NcpBase::LinkRawTransmitDone()` to safely handle frames using Key ID Mode 0 (e.g., KEK encryption for Joiner Entrust). When frame security is enabled and `headerUpdated` is true, RCP encodes the frame's key index and frame counter into the Spinel response. For Key ID Mode 0, there is no Key Index field in the Aux Security Header, so `GetKeyIndex()` can return an error. Previously, `SuccessOrExit(GetKeyIndex(keyIndex))` caused the function to exit prematurely, bypassing `mEncoder.EndFrame()`. This left the Spinel response un-ended and caused Host timeouts during joining. This commit updates the code to default `keyIndex` to `0` when `GetKeyIndex()` returns an error, ensuring the Spinel status frame is properly encoded and sent back to Host. --- src/ncp/ncp_base_radio.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ncp/ncp_base_radio.cpp b/src/ncp/ncp_base_radio.cpp index 6fb67b8d0..9eb87fcb1 100644 --- a/src/ncp/ncp_base_radio.cpp +++ b/src/ncp/ncp_base_radio.cpp @@ -195,10 +195,17 @@ void NcpBase::LinkRawTransmitDone(uint8_t aIid, otRadioFrame *aFrame, otRadioFra uint8_t keyIndex; uint32_t frameCounter; - // Transmit frame auxiliary key index and frame counter - SuccessOrExit(static_cast(aFrame)->GetKeyIndex(keyIndex)); SuccessOrExit(static_cast(aFrame)->GetFrameCounter(frameCounter)); + // If the frame uses Key ID Mode 0, there is no Key Index field in + // the Security Header, so `GetKeyIndex()` may return an error. + // We default `keyIndex` to 0 in this case. + + if (static_cast(aFrame)->GetKeyIndex(keyIndex) != OT_ERROR_NONE) + { + keyIndex = 0; + } + SuccessOrExit(mEncoder.WriteUint8(keyIndex)); SuccessOrExit(mEncoder.WriteUint32(frameCounter)); }