Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : * All rights reserved.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * This file defines functions for encoding and decoding CHIP messages.
22 : * The encoded messages contain CHIP packet header, encrypted payload
23 : * header, encrypted payload and message authentication code, as per
24 : * CHIP specifications.
25 : *
26 : */
27 :
28 : #include <lib/support/CodeUtils.h>
29 : #include <lib/support/SafeInt.h>
30 : #include <transport/SecureMessageCodec.h>
31 :
32 : namespace chip {
33 :
34 : using System::PacketBuffer;
35 : using System::PacketBufferHandle;
36 :
37 : namespace SecureMessageCodec {
38 :
39 9725 : CHIP_ERROR Encrypt(const CryptoContext & context, CryptoContext::ConstNonceView nonce, PayloadHeader & payloadHeader,
40 : PacketHeader & packetHeader, System::PacketBufferHandle & msgBuf)
41 : {
42 9725 : VerifyOrReturnError(!msgBuf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT);
43 9725 : VerifyOrReturnError(!msgBuf->HasChainedBuffer(), CHIP_ERROR_INVALID_MESSAGE_LENGTH);
44 :
45 9725 : ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(msgBuf));
46 :
47 9725 : uint8_t * data = msgBuf->Start();
48 9725 : size_t totalLen = msgBuf->TotalLength();
49 :
50 : MessageAuthenticationCode mac;
51 9725 : ReturnErrorOnFailure(context.Encrypt(data, totalLen, data, nonce, packetHeader, mac));
52 :
53 9725 : uint16_t taglen = 0;
54 9725 : ReturnErrorOnFailure(mac.Encode(packetHeader, &data[totalLen], msgBuf->AvailableDataLength(), &taglen));
55 :
56 9725 : msgBuf->SetDataLength(totalLen + taglen);
57 :
58 9725 : return CHIP_NO_ERROR;
59 : }
60 :
61 9638 : CHIP_ERROR Decrypt(const CryptoContext & context, CryptoContext::ConstNonceView nonce, PayloadHeader & payloadHeader,
62 : const PacketHeader & packetHeader, System::PacketBufferHandle & msg)
63 : {
64 9638 : VerifyOrReturnError(!msg.IsNull(), CHIP_ERROR_INVALID_ARGUMENT);
65 :
66 9638 : uint8_t * data = msg->Start();
67 9638 : size_t len = msg->DataLength();
68 :
69 9638 : PacketBufferHandle origMsg;
70 : #if CHIP_SYSTEM_CONFIG_USE_LWIP
71 : /* This is a workaround for the case where PacketBuffer payload is not
72 : allocated as an inline buffer to PacketBuffer structure */
73 : origMsg = std::move(msg);
74 : msg = PacketBufferHandle::New(len);
75 : VerifyOrReturnError(!msg.IsNull(), CHIP_ERROR_NO_MEMORY);
76 : msg->SetDataLength(len);
77 : #endif
78 :
79 9638 : uint16_t footerLen = packetHeader.MICTagLength();
80 9638 : VerifyOrReturnError(footerLen <= len, CHIP_ERROR_INVALID_MESSAGE_LENGTH);
81 :
82 9638 : uint16_t taglen = 0;
83 : MessageAuthenticationCode mac;
84 9638 : ReturnErrorOnFailure(mac.Decode(packetHeader, &data[len - footerLen], footerLen, &taglen));
85 9638 : VerifyOrReturnError(taglen == footerLen, CHIP_ERROR_INTERNAL);
86 :
87 9638 : len = len - taglen;
88 9638 : msg->SetDataLength(len);
89 :
90 9638 : uint8_t * plainText = msg->Start();
91 9638 : ReturnErrorOnFailure(context.Decrypt(data, len, plainText, nonce, packetHeader, mac));
92 :
93 9635 : ReturnErrorOnFailure(payloadHeader.DecodeAndConsume(msg));
94 9635 : return CHIP_NO_ERROR;
95 9638 : }
96 :
97 : } // namespace SecureMessageCodec
98 :
99 : } // namespace chip
|