blob: 0ab248372f4a18bc93205adc4bb0fe99c68e6cb9 [file] [log] [blame]
Jean-Francois Penven105b7712023-08-31 23:02:05 -04001/*
2 * Copyright (c) 2020 Project CHIP Authors
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/**
19 * @file
20 * This file implements the Matter Checkin protocol.
21 */
22
23#pragma once
24
25#include <crypto/CHIPCryptoPAL.h>
mkardous-silabsff5b64d2023-12-14 16:36:33 -050026#include <lib/support/BufferWriter.h>
Jean-Francois Penven105b7712023-08-31 23:02:05 -040027#include <lib/support/Span.h>
28#include <stdint.h>
29
30namespace chip {
31namespace Protocols {
32namespace SecureChannel {
Jean-Francois Penven105b7712023-08-31 23:02:05 -040033
34using CounterType = uint32_t;
35
36/**
37 * @brief Implement section 4.18.2 of the spec regarding
38 * Check-in message payload
39 *
40 */
41class DLL_EXPORT CheckinMessage
42{
43public:
44 ~CheckinMessage();
45 /**
46 * @brief Generate Check-in Message payload
47 *
mkardous-silabsff5b64d2023-12-14 16:36:33 -050048 * @note Function requires two key handles to generate the Check-In message.
49 * Due to the way some key stores work, the same key handle cannot be used for AES-CCM and HMAC-SHA-256 operations.
50 *
51 * @param[in] aes128KeyHandle Key handle with which to encrypt the check-in payload (using AEAD).
52 * @param[in] hmac128KeyHandle Key handle with which to generate the nonce for the check-in payload (using HMAC).
53 * @param[in] counter Check-in counter
54 * @param[in] appData Application Data to incorporate within the Check-in message. Allowed to be empty.
55 * @param[out] output Buffer in Which to store the generated payload. SUFFICIENT SPACE MUST BE ALLOCATED by the
56 * caller Required Buffer Size is : GetCheckinPayloadSize(appData.size())
57 *
58 * @return CHIP_ERROR_BUFFER_TOO_SMALL if output buffer is too small
59 * CHIP_ERROR_INVALID_ARGUMENT if the provided arguments cannot be used to generate the Check-In message
60 * CHIP_ERROR_INTERNAL if an error occurs during the generation of the Check-In message
Jean-Francois Penven105b7712023-08-31 23:02:05 -040061 */
mkardous-silabsff5b64d2023-12-14 16:36:33 -050062 static CHIP_ERROR GenerateCheckinMessagePayload(const Crypto::Aes128KeyHandle & aes128KeyHandle,
63 const Crypto::Hmac128KeyHandle & hmacKeyHandle, const CounterType & counter,
64 const ByteSpan & appData, MutableByteSpan & output);
Jean-Francois Penven105b7712023-08-31 23:02:05 -040065
66 /**
67 * @brief Parse Check-in Message payload
68 *
mkardous-silabsff5b64d2023-12-14 16:36:33 -050069 * @note Function requires two key handles to parse the Check-In message.
70 * Due to the way some key stores work, the same key handle cannot be used for AES-CCM and HMAC-SHA-256 operations.
71 *
72 * @param[in] aes128KeyHandle Key handle with which to decrypt the received check-in payload (using AEAD).
73 * @param[in] hmac128KeyHandle Key handle with which to verify the received nonce in the check-in payload (using HMAC).
74 * @param[in] payload The received payload to decrypt and parse
75 * @param[out] counter The counter value retrieved from the payload
mkardous-silabs9643ea42023-12-19 12:54:34 -050076 * If an error occurs, no value will be set.
mkardous-silabsff5b64d2023-12-14 16:36:33 -050077 * @param[in,out] appData The optional application data decrypted. The input size of appData must be at least the
mkardous-silabs9643ea42023-12-19 12:54:34 -050078 * size of GetAppDataSize(payload) + sizeof(CounterType), because appData is used as a work
79 * buffer for the decryption process. The output size on success will be
80 * GetAppDataSize(payload). If an error occurs, appData might countain data,
81 * but the data CANNOT be used since we were not able to validate it.
mkardous-silabsff5b64d2023-12-14 16:36:33 -050082 *
83 * @return CHIP_ERROR_INVALID_MESSAGE_LENGTH if the payload is shorter than the minimum payload size
84 * CHIP_ERROR_BUFFER_TOO_SMALL if appData buffer is too small
mkardous-silabs9643ea42023-12-19 12:54:34 -050085 * CHIP_ERROR_INTERNAL if we were not able to decrypt or validate the Check-In message
Jean-Francois Penven105b7712023-08-31 23:02:05 -040086 */
thivya-amazon48384902024-01-10 13:06:48 -080087
mkardous-silabsff5b64d2023-12-14 16:36:33 -050088 static CHIP_ERROR ParseCheckinMessagePayload(const Crypto::Aes128KeyHandle & aes128KeyHandle,
thivya-amazon48384902024-01-10 13:06:48 -080089 const Crypto::Hmac128KeyHandle & hmacKeyHandle, const ByteSpan & payload,
mkardous-silabsff5b64d2023-12-14 16:36:33 -050090 CounterType & counter, MutableByteSpan & appData);
Jean-Francois Penven105b7712023-08-31 23:02:05 -040091
mkardous-silabsff5b64d2023-12-14 16:36:33 -050092 static inline size_t GetCheckinPayloadSize(size_t appDataSize) { return appDataSize + kMinPayloadSize; }
Jean-Francois Penven105b7712023-08-31 23:02:05 -040093
94 /**
95 * @brief Get the App Data Size
96 *
97 * @param payload The undecrypted payload
98 * @return size_t size in byte of the application data from the payload
99 */
thivya-amazon48384902024-01-10 13:06:48 -0800100 static size_t GetAppDataSize(const ByteSpan & payload);
Jean-Francois Penven105b7712023-08-31 23:02:05 -0400101
mkardous-silabsff5b64d2023-12-14 16:36:33 -0500102 static constexpr uint16_t kMinPayloadSize =
Boris Zbarskyc89090c2024-03-29 00:28:09 -0400103 Crypto::CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES + sizeof(CounterType) + Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;
Jean-Francois Penven105b7712023-08-31 23:02:05 -0400104
mkardous-silabsff5b64d2023-12-14 16:36:33 -0500105private:
106 /**
107 * @brief Generate the Nonce for the Check-In message
108 *
109 * @param[in] hmacKeyHandle Key handle to use with the HMAC algorithm
110 * @param[in] counter Check-In Counter value to use as message of the HMAC algorithm
111 * @param[out] output output buffer for the generated Nonce.
112 * SUFFICIENT SPACE MUST BE ALLOCATED by the caller
113 * Size must be at least CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES
114 *
115 * @return CHIP_ERROR_BUFFER_TOO_SMALL if output buffer is too small
116 * CHIP_ERROR_INVALID_ARGUMENT if the provided arguments cannot be used to generate the Check-In message Nonce
117 */
118 static CHIP_ERROR GenerateCheckInMessageNonce(const Crypto::Hmac128KeyHandle & hmacKeyHandle, CounterType counter,
119 Encoding::LittleEndian::BufferWriter & writer);
Jean-Francois Penven105b7712023-08-31 23:02:05 -0400120};
121
122} // namespace SecureChannel
123} // namespace Protocols
124} // namespace chip