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