Skip to content

Commit

Permalink
fix comments
Browse files Browse the repository at this point in the history
  • Loading branch information
jepenven-silabs committed Aug 11, 2023
1 parent 7d67d09 commit 5810c3b
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/protocols/secure_channel/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ static_library("secure_channel") {

public_deps = [
":type_definitions",
"${chip_root}/src/lib/core",
"${chip_root}/src/crypto",
"${chip_root}/src/lib/core",
"${chip_root}/src/lib/support",
"${chip_root}/src/messaging",
"${chip_root}/src/system",
Expand Down
32 changes: 17 additions & 15 deletions src/protocols/secure_channel/CheckinMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@
#include <lib/core/CHIPCore.h>

#include <lib/core/CHIPEncoding.h>
#include <protocols/secure_channel/Constants.h>

namespace chip {
namespace Protocols {
namespace SecureChannel {

CHIP_ERROR CheckinMessage::GenerateCheckinMessagePayload(Crypto::Aes128KeyHandle & key, uint32_t counter, const ByteSpan & appData,
MutableByteSpan & output)
CHIP_ERROR CheckinMessage::GenerateCheckinMessagePayload(Crypto::Aes128KeyHandle & key, CounterType counter,
const ByteSpan & appData, MutableByteSpan & output)
{
VerifyOrReturnError(appData.size() <= CHIP_CHECK_IN_APP_DATA_MAX_SIZE, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(appData.size() <= sMaxAppDataSize, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(output.size() >= (appData.size() + sMinPayloadSize), CHIP_ERROR_INVALID_ARGUMENT);

CHIP_ERROR err = CHIP_NO_ERROR;
Expand All @@ -43,39 +44,40 @@ CHIP_ERROR CheckinMessage::GenerateCheckinMessagePayload(Crypto::Aes128KeyHandle
uint8_t nonceWorkBuffer[CHIP_CRYPTO_HASH_LEN_BYTES] = { 0 };

ReturnErrorOnFailure(shaHandler.HMAC_SHA256(key.As<Aes128KeyByteArray>(), sizeof(Aes128KeyByteArray), appDataStartPtr,
sizeof(counter), nonceWorkBuffer, CHIP_CRYPTO_HASH_LEN_BYTES));
sizeof(CounterType), nonceWorkBuffer, CHIP_CRYPTO_HASH_LEN_BYTES));

static_assert(sizeof(nonceWorkBuffer) >= CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES, "We're reading off the end of our buffer.");
memcpy(output.data(), nonceWorkBuffer, CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES);

// In place encryption to save some RAM
memcpy(appDataStartPtr + sizeof(counter), appData.data(), appData.size());
memcpy(appDataStartPtr + sizeof(CounterType), appData.data(), appData.size());

uint8_t * micPtr = appDataStartPtr + sizeof(counter) + appData.size();
ReturnErrorOnFailure(Crypto::AES_CCM_encrypt(appDataStartPtr, sizeof(counter) + appData.size(), nullptr, 0, key, output.data(),
CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES, appDataStartPtr, micPtr,
uint8_t * micPtr = appDataStartPtr + sizeof(CounterType) + appData.size();
ReturnErrorOnFailure(Crypto::AES_CCM_encrypt(appDataStartPtr, sizeof(CounterType) + appData.size(), nullptr, 0, key,
output.data(), CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES, appDataStartPtr, micPtr,
CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES));

output.reduce_size(appData.size() + sMinPayloadSize);

return err;
}

CHIP_ERROR CheckinMessage::ParseCheckinMessagePayload(Crypto::Aes128KeyHandle & key, ByteSpan & payload, uint32_t & counter,
CHIP_ERROR CheckinMessage::ParseCheckinMessagePayload(Crypto::Aes128KeyHandle & key, ByteSpan & payload, CounterType & counter,
MutableByteSpan & appData)
{
VerifyOrReturnError(payload.size() >= sMinPayloadSize, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(payload.size() <= (sMinPayloadSize + CHIP_CHECK_IN_APP_DATA_MAX_SIZE), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(payload.size() <= (sMinPayloadSize + sMaxAppDataSize), CHIP_ERROR_INVALID_ARGUMENT);

CHIP_ERROR err = CHIP_NO_ERROR;
uint16_t appDataSize = GetAppDataSize(payload);

// To prevent workbuffer usage, appData size need to be large enough to hold both the appData and the counter
VerifyOrReturnError(appData.size() >= sizeof(uint32_t) + appDataSize, CHIP_ERROR_INVALID_ARGUMENT);
// To prevent workbuffer usage, appData size needs to be large enough to hold both the appData and the counter
VerifyOrReturnError(appData.size() >= sizeof(CounterType) + appDataSize, CHIP_ERROR_INVALID_ARGUMENT);

ByteSpan nonce = payload.SubSpan(0, CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES);
ByteSpan encryptedData = payload.SubSpan(CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES, appDataSize + sizeof(counter));
ByteSpan encryptedData = payload.SubSpan(CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES, sizeof(CounterType) + appDataSize);
ByteSpan mic =
payload.SubSpan(CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES + appDataSize + sizeof(counter), CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES);
payload.SubSpan(CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES + sizeof(CounterType) + appDataSize, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES);

err = Crypto::AES_CCM_decrypt(encryptedData.data(), encryptedData.size(), nullptr, 0, mic.data(), mic.size(), key, nonce.data(),
nonce.size(), appData.data());
Expand All @@ -84,7 +86,7 @@ CHIP_ERROR CheckinMessage::ParseCheckinMessagePayload(Crypto::Aes128KeyHandle &

counter = Encoding::LittleEndian::Get32(appData.data());
// Shift to remove the counter from the appData
memcpy(appData.data(), appData.data() + sizeof(uint32_t), appDataSize);
memcpy(appData.data(), sizeof(CounterType) + appData.data(), appDataSize);

appData.reduce_size(appDataSize);
return err;
Expand Down
24 changes: 12 additions & 12 deletions src/protocols/secure_channel/CheckinMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@
#pragma once

#include <crypto/CHIPCryptoPAL.h>
#include <protocols/secure_channel/Constants.h>
#include <lib/support/Span.h>
#include <stdint.h>

namespace chip {
namespace Protocols {
namespace SecureChannel {
using namespace Crypto;

#define CHIP_CHECK_IN_APP_DATA_MAX_SIZE 1024

using CounterType = uint32_t;

/**
Expand All @@ -48,13 +47,12 @@ class DLL_EXPORT CheckinMessage
*
* @param key Key with which to encrypt the check-in payload
* @param counter Check-in counter
* @param appData Optionnal : Application Data to incorporate within the Check-in message
* @param appData Application Data to incorporate within the Check-in message. Allowed to be empty.
* @param output Buffer in Which to store the generated payload. SUFFICIENT SPACE MUST BE ALLOCATED by the caller
* Required Buffer Size is : User Data + CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES + SizeOf(uint32_t) +
* CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES
* Required Buffer Size is : GetCheckinPayloadSize(appData.size())
* @return CHIP_ERROR
*/
static CHIP_ERROR GenerateCheckinMessagePayload(Crypto::Aes128KeyHandle & key, uint32_t counter, const ByteSpan & appData,
static CHIP_ERROR GenerateCheckinMessagePayload(Crypto::Aes128KeyHandle & key, CounterType counter, const ByteSpan & appData,
MutableByteSpan & output);

/**
Expand All @@ -63,18 +61,18 @@ class DLL_EXPORT CheckinMessage
* @param key Key with which to decrypt the check-in payload
* @param payload The received payload to decrypt and parse
* @param counter The counter value retrieved from the payload
* @param appData The optional application data decrypted. Size can be retrieved prior to decryption by using the
* GetAppDataSize() method.
* @param appData The optional application data decrypted. The size of appData must be at least the size of
* GetAppDataSize(payload) + sizeof(CounterType)
* @return CHIP_ERROR
*/
static CHIP_ERROR ParseCheckinMessagePayload(Crypto::Aes128KeyHandle & key, ByteSpan & payload, uint32_t & counter,
static CHIP_ERROR ParseCheckinMessagePayload(Crypto::Aes128KeyHandle & key, ByteSpan & payload, CounterType & counter,
MutableByteSpan & appData);

static inline uint64_t GetRequiredBufferSize(uint32_t & payloadSize) { return payloadSize + sMinPayloadSize; }
static inline size_t GetCheckinPayloadSize(uint16_t & appDataSize) { return appDataSize + sMinPayloadSize; }

/**
* @brief Get the App Data Size
*
*
* @param payload The undecrypted payload
* @return uint16_t size in byte of the application data from the payload
*/
Expand All @@ -83,6 +81,8 @@ class DLL_EXPORT CheckinMessage
static constexpr uint16_t sMinPayloadSize =
CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES + sizeof(CounterType) + CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;

// Issue #28603
static constexpr uint16_t sMaxAppDataSize = 1024;
};

} // namespace SecureChannel
Expand Down
2 changes: 1 addition & 1 deletion src/protocols/secure_channel/tests/TestCheckinMsg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void TestCheckin_Generate(nlTestSuite * inSuite, void * inContext)
uint8_t data[] = { "This is some user Data. It should be encrypted" };
userData = chip::ByteSpan(data, 50);
const ccm_128_test_vector & test = *ccm_128_test_vectors[0];
uint8_t gargantuaBuffer[2 * CHIP_CHECK_IN_APP_DATA_MAX_SIZE] = { 0 };
uint8_t gargantuaBuffer[2 * CheckinMessage::sMaxAppDataSize] = { 0 };

Aes128KeyByteArray keyMaterial;
memcpy(keyMaterial, test.key, test.key_len);
Expand Down

0 comments on commit 5810c3b

Please sign in to comment.