From e5d3f9e9c0408961269b911422a12ded3591f657 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Fri, 8 Aug 2025 10:38:01 -0700 Subject: [PATCH] [crypto] allow null buffer in `AesCcm::Payload()` (#11799) This commit updates `AesCcm::Payload()` to support a `nullptr` for the output buffer. When decrypting, the `aPlainText` can be null, and when encrypting, `aCipherText` can be null. This change is useful when the caller only needs the authentication tag and does not require the actual decrypted or encrypted payload, thus avoiding the need to provide a temporary output buffer. This is leveraged to simplify the MAC frame processing under fuzzing build (`OPENTHREAD_FUZZ_FUZZER_BUILD`), removing a large stack-allocated buffer (`kFuzzMaxFrameSize`). --- src/core/crypto/aes_ccm.cpp | 16 ++++++++++++---- src/core/crypto/aes_ccm.hpp | 3 +++ src/core/mac/mac_frame.cpp | 7 +------ src/core/mac/mac_frame.hpp | 3 --- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/core/crypto/aes_ccm.cpp b/src/core/crypto/aes_ccm.cpp index 4301d318f..a160749ea 100644 --- a/src/core/crypto/aes_ccm.cpp +++ b/src/core/crypto/aes_ccm.cpp @@ -214,13 +214,21 @@ void AesCcm::Payload(void *aPlainText, void *aCipherText, uint32_t aLength, Mode if (aMode == kEncrypt) { - byte = plaintextBytes[i]; - ciphertextBytes[i] = byte ^ mCtrPad[mCtrLength++]; + byte = plaintextBytes[i]; + + if (ciphertextBytes != nullptr) + { + ciphertextBytes[i] = byte ^ mCtrPad[mCtrLength++]; + } } else { - byte = ciphertextBytes[i] ^ mCtrPad[mCtrLength++]; - plaintextBytes[i] = byte; + byte = ciphertextBytes[i] ^ mCtrPad[mCtrLength++]; + + if (plaintextBytes != nullptr) + { + plaintextBytes[i] = byte; + } } if (mBlockLength == sizeof(mBlock)) diff --git a/src/core/crypto/aes_ccm.hpp b/src/core/crypto/aes_ccm.hpp index 2dbef93c9..8f8af575a 100644 --- a/src/core/crypto/aes_ccm.hpp +++ b/src/core/crypto/aes_ccm.hpp @@ -136,6 +136,9 @@ public: /** * Processes the payload. * + * When decrypting (`kDecrypt`), @p aPlainText can be `nullptr` if the decrypted plaintext is not needed. + * Similarly, when encrypting (`kEncrypt`), @p aCipherText can be `nullptr` if the ciphertext is not needed. + * * @param[in,out] aPlainText A pointer to the plaintext. * @param[in,out] aCipherText A pointer to the ciphertext. * @param[in] aLength Payload length in bytes. diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index 9c8d2492a..1cafa255e 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -1573,12 +1573,7 @@ Error RxFrame::ProcessReceiveAesCcm(const ExtAddress &aExtAddress, const KeyMate aesCcm.Payload(GetPayload(), GetPayload(), GetPayloadLength(), Crypto::AesCcm::kDecrypt); #else // For fuzz tests, execute AES but do not alter the payload. A large - // temporary buffer (kFuzzMaxFrameSize = 1280 bytes) is used to - // account for TREL frames. - uint8_t fuzz[kFuzzMaxFrameSize]; - - OT_ASSERT(GetPayloadLength() <= sizeof(fuzz)); - aesCcm.Payload(fuzz, GetPayload(), GetPayloadLength(), Crypto::AesCcm::kDecrypt); + aesCcm.Payload(nullptr, GetPayload(), GetPayloadLength(), Crypto::AesCcm::kDecrypt); #endif aesCcm.Finalize(tag); diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index 96b7797ed..830239693 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -1016,9 +1016,6 @@ public: */ uint8_t ReadTimeSyncSeq(void) const { return GetTimeIe()->GetSequence(); } #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE - -private: - static constexpr uint16_t kFuzzMaxFrameSize = 1280; // 1280 bytes to account for TREL frame size. }; /**