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 9488 : CHIP_ERROR Encrypt(const CryptoContext & context, CryptoContext::ConstNonceView nonce, PayloadHeader & payloadHeader, 40 : PacketHeader & packetHeader, System::PacketBufferHandle & msgBuf) 41 : { 42 9488 : VerifyOrReturnError(!msgBuf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT); 43 9488 : VerifyOrReturnError(!msgBuf->HasChainedBuffer(), CHIP_ERROR_INVALID_MESSAGE_LENGTH); 44 9488 : VerifyOrReturnError(msgBuf->TotalLength() <= kMaxAppMessageLen, CHIP_ERROR_MESSAGE_TOO_LONG); 45 : 46 : static_assert(std::is_same<decltype(msgBuf->TotalLength()), uint16_t>::value, 47 : "Addition to generate payloadLength might overflow"); 48 : 49 9487 : ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(msgBuf)); 50 : 51 9487 : uint8_t * data = msgBuf->Start(); 52 9487 : uint16_t totalLen = msgBuf->TotalLength(); 53 : 54 : MessageAuthenticationCode mac; 55 9487 : ReturnErrorOnFailure(context.Encrypt(data, totalLen, data, nonce, packetHeader, mac)); 56 : 57 9487 : uint16_t taglen = 0; 58 9487 : ReturnErrorOnFailure(mac.Encode(packetHeader, &data[totalLen], msgBuf->AvailableDataLength(), &taglen)); 59 : 60 9487 : VerifyOrReturnError(CanCastTo<uint16_t>(totalLen + taglen), CHIP_ERROR_INTERNAL); 61 9487 : msgBuf->SetDataLength(static_cast<uint16_t>(totalLen + taglen)); 62 : 63 9487 : return CHIP_NO_ERROR; 64 : } 65 : 66 9399 : CHIP_ERROR Decrypt(const CryptoContext & context, CryptoContext::ConstNonceView nonce, PayloadHeader & payloadHeader, 67 : const PacketHeader & packetHeader, System::PacketBufferHandle & msg) 68 : { 69 9399 : ReturnErrorCodeIf(msg.IsNull(), CHIP_ERROR_INVALID_ARGUMENT); 70 : 71 9399 : uint8_t * data = msg->Start(); 72 9399 : uint16_t len = msg->DataLength(); 73 : 74 9399 : PacketBufferHandle origMsg; 75 : #if CHIP_SYSTEM_CONFIG_USE_LWIP 76 : /* This is a workaround for the case where PacketBuffer payload is not 77 : allocated as an inline buffer to PacketBuffer structure */ 78 : origMsg = std::move(msg); 79 : msg = PacketBufferHandle::New(len); 80 : VerifyOrReturnError(!msg.IsNull(), CHIP_ERROR_NO_MEMORY); 81 : msg->SetDataLength(len); 82 : #endif 83 : 84 9399 : uint16_t footerLen = packetHeader.MICTagLength(); 85 9399 : VerifyOrReturnError(footerLen <= len, CHIP_ERROR_INVALID_MESSAGE_LENGTH); 86 : 87 9399 : uint16_t taglen = 0; 88 : MessageAuthenticationCode mac; 89 9399 : ReturnErrorOnFailure(mac.Decode(packetHeader, &data[len - footerLen], footerLen, &taglen)); 90 9399 : VerifyOrReturnError(taglen == footerLen, CHIP_ERROR_INTERNAL); 91 : 92 9399 : len = static_cast<uint16_t>(len - taglen); 93 9399 : msg->SetDataLength(len); 94 : 95 9399 : uint8_t * plainText = msg->Start(); 96 9399 : ReturnErrorOnFailure(context.Decrypt(data, len, plainText, nonce, packetHeader, mac)); 97 : 98 9396 : ReturnErrorOnFailure(payloadHeader.DecodeAndConsume(msg)); 99 9396 : return CHIP_NO_ERROR; 100 9399 : } 101 : 102 : } // namespace SecureMessageCodec 103 : 104 : } // namespace chip