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 "common/error.hpp" 42 #include "crypto/aes_ecb.hpp" 43 #include "mac/mac_types.hpp" 44 45 namespace ot { 46 namespace Crypto { 47 48 /** 49 * @addtogroup core-security 50 * 51 * @{ 52 * 53 */ 54 55 /** 56 * This class implements AES CCM computation. 57 * 58 */ 59 class AesCcm 60 { 61 public: 62 static constexpr uint8_t kMinTagLength = 4; ///< Minimum tag length (in bytes). 63 static constexpr uint8_t kMaxTagLength = AesEcb::kBlockSize; ///< Maximum tag length (in bytes). 64 static constexpr uint8_t kNonceSize = 13; ///< Size of IEEE 802.15.4 Nonce (in bytes). 65 66 /** 67 * This enumeration type represent the encryption vs decryption mode. 68 * 69 */ 70 enum Mode : uint8_t 71 { 72 kEncrypt, // Encryption mode. 73 kDecrypt, // Decryption mode. 74 }; 75 76 /** 77 * This method sets the key. 78 * 79 * @param[in] aKey A pointer to the key. 80 * @param[in] aKeyLength Length of the key in bytes. 81 * 82 */ 83 void SetKey(const uint8_t *aKey, uint16_t aKeyLength); 84 85 /** 86 * This method sets the key. 87 * 88 * @param[in] aMacKey A MAC key. 89 * 90 */ 91 void SetKey(const Mac::Key &aMacKey); 92 93 /** 94 * This method initializes the AES CCM computation. 95 * 96 * @param[in] aHeaderLength Length of header in bytes. 97 * @param[in] aPlainTextLength Length of plaintext in bytes. 98 * @param[in] aTagLength Length of tag in bytes (must be even and in `[kMinTagLength, kMaxTagLength]`). 99 * @param[in] aNonce A pointer to the nonce. 100 * @param[in] aNonceLength Length of nonce in bytes. 101 * 102 */ 103 void Init(uint32_t aHeaderLength, 104 uint32_t aPlainTextLength, 105 uint8_t aTagLength, 106 const void *aNonce, 107 uint8_t aNonceLength); 108 109 /** 110 * This method processes the header. 111 * 112 * @param[in] aHeader A pointer to the header. 113 * @param[in] aHeaderLength Length of header in bytes. 114 * 115 */ 116 void Header(const void *aHeader, uint32_t aHeaderLength); 117 118 /** 119 * This method processes the payload. 120 * 121 * @param[inout] aPlainText A pointer to the plaintext. 122 * @param[inout] aCipherText A pointer to the ciphertext. 123 * @param[in] aLength Payload length in bytes. 124 * @param[in] aMode Mode to indicate whether to encrypt (`kEncrypt`) or decrypt (`kDecrypt`). 125 * 126 */ 127 void Payload(void *aPlainText, void *aCipherText, uint32_t aLength, Mode aMode); 128 129 /** 130 * This method returns the tag length in bytes. 131 * 132 * @returns The tag length in bytes. 133 * 134 */ GetTagLength(void) const135 uint8_t GetTagLength(void) const { return mTagLength; } 136 137 /** 138 * This method generates the tag. 139 * 140 * @param[out] aTag A pointer to the tag (must have `GetTagLength()` bytes). 141 * 142 */ 143 void Finalize(void *aTag); 144 145 /** 146 * This static method generates IEEE 802.15.4 nonce byte sequence. 147 * 148 * @param[in] aAddress An extended address. 149 * @param[in] aFrameCounter A frame counter. 150 * @param[in] aSecurityLevel A security level. 151 * @param[out] aNonce A buffer (with `kNonceSize` bytes) to place the generated nonce. 152 * 153 */ 154 static void GenerateNonce(const Mac::ExtAddress &aAddress, 155 uint32_t aFrameCounter, 156 uint8_t aSecurityLevel, 157 uint8_t * aNonce); 158 159 private: 160 AesEcb mEcb; 161 uint8_t mBlock[AesEcb::kBlockSize]; 162 uint8_t mCtr[AesEcb::kBlockSize]; 163 uint8_t mCtrPad[AesEcb::kBlockSize]; 164 uint32_t mHeaderLength; 165 uint32_t mHeaderCur; 166 uint32_t mPlainTextLength; 167 uint32_t mPlainTextCur; 168 uint16_t mBlockLength; 169 uint16_t mCtrLength; 170 uint8_t mNonceLength; 171 uint8_t mTagLength; 172 }; 173 174 /** 175 * @} 176 * 177 */ 178 179 } // namespace Crypto 180 } // namespace ot 181 182 #endif // AES_CCM_HPP_ 183