1 /* 2 * Copyright (c) 2016, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions for performing AES-CCM computations. 32 */ 33 34 #ifndef AES_CCM_HPP_ 35 #define AES_CCM_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <stdint.h> 40 41 #include <openthread/platform/crypto.h> 42 #include "common/error.hpp" 43 #include "common/message.hpp" 44 #include "common/type_traits.hpp" 45 #include "crypto/aes_ecb.hpp" 46 #include "crypto/storage.hpp" 47 #include "mac/mac_types.hpp" 48 49 namespace ot { 50 namespace Crypto { 51 52 /** 53 * @addtogroup core-security 54 * 55 * @{ 56 * 57 */ 58 59 /** 60 * Implements AES CCM computation. 61 * 62 */ 63 class AesCcm 64 { 65 public: 66 static constexpr uint8_t kMinTagLength = 4; ///< Minimum tag length (in bytes). 67 static constexpr uint8_t kMaxTagLength = AesEcb::kBlockSize; ///< Maximum tag length (in bytes). 68 static constexpr uint8_t kNonceSize = 13; ///< Size of IEEE 802.15.4 Nonce (in bytes). 69 70 /** 71 * Type represent the encryption vs decryption mode. 72 * 73 */ 74 enum Mode : uint8_t 75 { 76 kEncrypt, // Encryption mode. 77 kDecrypt, // Decryption mode. 78 }; 79 80 /** 81 * Sets the key. 82 * 83 * @param[in] aKey Crypto Key used in AES operation 84 * 85 */ SetKey(const Key & aKey)86 void SetKey(const Key &aKey) { mEcb.SetKey(aKey); } 87 88 /** 89 * Sets the key. 90 * 91 * @param[in] aKey A pointer to the key. 92 * @param[in] aKeyLength Length of the key in bytes. 93 * 94 */ 95 void SetKey(const uint8_t *aKey, uint16_t aKeyLength); 96 97 /** 98 * Sets the key. 99 * 100 * @param[in] aMacKey Key Material for AES operation. 101 * 102 */ 103 void SetKey(const Mac::KeyMaterial &aMacKey); 104 105 /** 106 * Initializes the AES CCM computation. 107 * 108 * @param[in] aHeaderLength Length of header in bytes. 109 * @param[in] aPlainTextLength Length of plaintext in bytes. 110 * @param[in] aTagLength Length of tag in bytes (must be even and in `[kMinTagLength, kMaxTagLength]`). 111 * @param[in] aNonce A pointer to the nonce. 112 * @param[in] aNonceLength Length of nonce in bytes. 113 * 114 */ 115 void Init(uint32_t aHeaderLength, 116 uint32_t aPlainTextLength, 117 uint8_t aTagLength, 118 const void *aNonce, 119 uint8_t aNonceLength); 120 121 /** 122 * Processes the header. 123 * 124 * @param[in] aHeader A pointer to the header. 125 * @param[in] aHeaderLength Length of header in bytes. 126 * 127 */ 128 void Header(const void *aHeader, uint32_t aHeaderLength); 129 130 /** 131 * Processes the header. 132 * 133 * @tparam ObjectType The object type. 134 * 135 * @param[in] aObject A reference to the object to add to header. 136 * 137 */ Header(const ObjectType & aObject)138 template <typename ObjectType> void Header(const ObjectType &aObject) 139 { 140 static_assert(!TypeTraits::IsPointer<ObjectType>::kValue, "ObjectType must not be a pointer"); 141 142 Header(&aObject, sizeof(ObjectType)); 143 } 144 145 /** 146 * Processes the payload. 147 * 148 * @param[in,out] aPlainText A pointer to the plaintext. 149 * @param[in,out] aCipherText A pointer to the ciphertext. 150 * @param[in] aLength Payload length in bytes. 151 * @param[in] aMode Mode to indicate whether to encrypt (`kEncrypt`) or decrypt (`kDecrypt`). 152 * 153 */ 154 void Payload(void *aPlainText, void *aCipherText, uint32_t aLength, Mode aMode); 155 156 #if !OPENTHREAD_RADIO 157 /** 158 * Processes the payload within a given message. 159 * 160 * Encrypts/decrypts the payload content in place within the @p aMessage. 161 * 162 * @param[in,out] aMessage The message to read from and update. 163 * @param[in] aOffset The offset in @p aMessage to start of payload. 164 * @param[in] aLength Payload length in bytes. 165 * @param[in] aMode Mode to indicate whether to encrypt (`kEncrypt`) or decrypt (`kDecrypt`). 166 * 167 */ 168 void Payload(Message &aMessage, uint16_t aOffset, uint16_t aLength, Mode aMode); 169 #endif 170 171 /** 172 * Returns the tag length in bytes. 173 * 174 * @returns The tag length in bytes. 175 * 176 */ GetTagLength(void) const177 uint8_t GetTagLength(void) const { return mTagLength; } 178 179 /** 180 * Generates the tag. 181 * 182 * @param[out] aTag A pointer to the tag (must have `GetTagLength()` bytes). 183 * 184 */ 185 void Finalize(void *aTag); 186 187 /** 188 * Generates IEEE 802.15.4 nonce byte sequence. 189 * 190 * @param[in] aAddress An extended address. 191 * @param[in] aFrameCounter A frame counter. 192 * @param[in] aSecurityLevel A security level. 193 * @param[out] aNonce A buffer (with `kNonceSize` bytes) to place the generated nonce. 194 * 195 */ 196 static void GenerateNonce(const Mac::ExtAddress &aAddress, 197 uint32_t aFrameCounter, 198 uint8_t aSecurityLevel, 199 uint8_t *aNonce); 200 201 private: 202 AesEcb mEcb; 203 uint8_t mBlock[AesEcb::kBlockSize]; 204 uint8_t mCtr[AesEcb::kBlockSize]; 205 uint8_t mCtrPad[AesEcb::kBlockSize]; 206 uint32_t mHeaderLength; 207 uint32_t mHeaderCur; 208 uint32_t mPlainTextLength; 209 uint32_t mPlainTextCur; 210 uint16_t mBlockLength; 211 uint16_t mCtrLength; 212 uint8_t mNonceLength; 213 uint8_t mTagLength; 214 }; 215 216 /** 217 * @} 218 * 219 */ 220 221 } // namespace Crypto 222 } // namespace ot 223 224 #endif // AES_CCM_HPP_ 225