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 #include <openthread/config.h>
30 
31 #include "common/array.hpp"
32 #include "common/debug.hpp"
33 #include "common/message.hpp"
34 #include "crypto/hmac_sha256.hpp"
35 #include "crypto/sha256.hpp"
36 
37 #include "test_platform.h"
38 #include "test_util.h"
39 
40 namespace ot {
41 
TestSha256(void)42 void TestSha256(void)
43 {
44     const char kData1[] = "abc";
45 
46     const otCryptoSha256Hash kHash1 = {{
47         0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
48         0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad,
49     }};
50 
51     const char kData2[] = "";
52 
53     const otCryptoSha256Hash kHash2 = {{
54         0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
55         0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
56     }};
57 
58     const char kData3[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
59 
60     const otCryptoSha256Hash kHash3 = {{
61         0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
62         0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1,
63     }};
64 
65     const char kData4[] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmno"
66                           "pqrsmnopqrstnopqrstu";
67 
68     const otCryptoSha256Hash kHash4 = {{
69         0xcf, 0x5b, 0x16, 0xa7, 0x78, 0xaf, 0x83, 0x80, 0x03, 0x6c, 0xe5, 0x9e, 0x7b, 0x04, 0x92, 0x37,
70         0x0b, 0x24, 0x9b, 0x11, 0xe8, 0xf0, 0x7a, 0x51, 0xaf, 0xac, 0x45, 0x03, 0x7a, 0xfe, 0xe9, 0xd1,
71     }};
72 
73     struct TestCase
74     {
75         const char        *mData; // (null-terminated string).
76         otCryptoSha256Hash mHash;
77     };
78 
79     static const TestCase kTestCases[] = {
80         {kData1, kHash1},
81         {kData2, kHash2},
82         {kData3, kHash3},
83         {kData4, kHash4},
84     };
85 
86     printf("TestSha256\n");
87 
88     Instance    *instance = testInitInstance();
89     MessagePool *messagePool;
90     Message     *message;
91     uint16_t     offsets[GetArrayLength(kTestCases)];
92     uint8_t      index;
93 
94     VerifyOrQuit(instance != nullptr);
95 
96     messagePool = &instance->Get<MessagePool>();
97     VerifyOrQuit((message = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
98 
99     for (const TestCase &testCase : kTestCases)
100     {
101         Crypto::Sha256       sha256;
102         Crypto::Sha256::Hash hash;
103 
104         sha256.Start();
105         sha256.Update(testCase.mData, static_cast<uint16_t>(strlen(testCase.mData)));
106         sha256.Finish(hash);
107 
108         VerifyOrQuit(hash == static_cast<const Crypto::HmacSha256::Hash &>(testCase.mHash));
109     }
110 
111     // Append all test case `mData` in the message.
112 
113     index = 0;
114 
115     for (const TestCase &testCase : kTestCases)
116     {
117         SuccessOrQuit(message->Append("Hello"));
118         offsets[index++] = message->GetLength();
119         SuccessOrQuit(message->AppendBytes(testCase.mData, static_cast<uint16_t>(strlen(testCase.mData))));
120         SuccessOrQuit(message->Append("There!"));
121     }
122 
123     index = 0;
124 
125     for (const TestCase &testCase : kTestCases)
126     {
127         Crypto::Sha256       sha256;
128         Crypto::Sha256::Hash hash;
129 
130         sha256.Start();
131         sha256.Update(*message, offsets[index++], static_cast<uint16_t>(strlen(testCase.mData)));
132         sha256.Finish(hash);
133 
134         VerifyOrQuit(hash == static_cast<const Crypto::HmacSha256::Hash &>(testCase.mHash));
135     }
136 
137     testFreeInstance(instance);
138 }
139 
TestHmacSha256(void)140 void TestHmacSha256(void)
141 {
142     struct TestCase
143     {
144         otCryptoKey        mKey;
145         const void        *mData;
146         uint16_t           mDataLength;
147         otCryptoSha256Hash mHash;
148     };
149 
150     // Test-cases from RFC 4231.
151 
152     const uint8_t kKey1[] = {
153         0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
154         0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
155     };
156 
157     const char kData1[] = "Hi There";
158 
159     const otCryptoSha256Hash kHash1 = {{
160         0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
161         0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7,
162     }};
163 
164     const char kKey2[]  = "Jefe";
165     const char kData2[] = "what do ya want for nothing?";
166 
167     const otCryptoSha256Hash kHash2 = {{
168         0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
169         0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43,
170     }};
171 
172     const uint8_t kKey3[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
173                              0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
174 
175     const uint8_t kData3[] = {
176         0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
177         0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
178         0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
179     };
180 
181     const otCryptoSha256Hash kHash3 = {{
182         0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
183         0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe,
184     }};
185 
186     const uint8_t kKey4[] = {
187         0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
188         0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
189     };
190 
191     const uint8_t kData4[] = {
192         0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
193         0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
194         0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
195     };
196 
197     const otCryptoSha256Hash kHash4 = {{
198         0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
199         0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07, 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b,
200     }};
201 
202     const uint8_t kKey5[] = {
203         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
204         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
205         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
206         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
207         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
208         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
209         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
210         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
211     };
212 
213     const char kData5[] = "This is a test using a larger than block-size key and a larger than block-size data. The "
214                           "key needs to be hashed before being used by the HMAC algorithm.";
215 
216     const otCryptoSha256Hash kHash5 = {{
217         0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
218         0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2,
219     }};
220 
221     static const TestCase kTestCases[] = {
222         {{&kKey1[0], sizeof(kKey1), 0}, kData1, sizeof(kData1) - 1, kHash1},
223         {{reinterpret_cast<const uint8_t *>(&kKey2[0]), sizeof(kKey2) - 1, 0}, kData2, sizeof(kData2) - 1, kHash2},
224         {{&kKey3[0], sizeof(kKey3), 0}, kData3, sizeof(kData3), kHash3},
225         {{&kKey4[0], sizeof(kKey4), 0}, kData4, sizeof(kData4), kHash4},
226         {{&kKey5[0], sizeof(kKey5), 0}, kData5, sizeof(kData5) - 1, kHash5},
227     };
228 
229     Instance    *instance = testInitInstance();
230     MessagePool *messagePool;
231     Message     *message;
232     uint16_t     offsets[GetArrayLength(kTestCases)];
233     uint8_t      index;
234 
235     printf("TestHmacSha256\n");
236 
237     VerifyOrQuit(instance != nullptr);
238 
239     messagePool = &instance->Get<MessagePool>();
240     VerifyOrQuit((message = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
241 
242     for (const TestCase &testCase : kTestCases)
243     {
244         Crypto::HmacSha256       hmac;
245         Crypto::HmacSha256::Hash hash;
246 
247         hmac.Start(static_cast<const Crypto::Key &>(testCase.mKey));
248         hmac.Update(testCase.mData, testCase.mDataLength);
249         hmac.Finish(hash);
250 
251         VerifyOrQuit(hash == static_cast<const Crypto::HmacSha256::Hash &>(testCase.mHash));
252     }
253 
254     // Append all test case `mData` in the message.
255 
256     index = 0;
257 
258     for (const TestCase &testCase : kTestCases)
259     {
260         SuccessOrQuit(message->Append("Hello"));
261         offsets[index++] = message->GetLength();
262         SuccessOrQuit(message->AppendBytes(testCase.mData, testCase.mDataLength));
263         SuccessOrQuit(message->Append("There"));
264     }
265 
266     index = 0;
267 
268     for (const TestCase &testCase : kTestCases)
269     {
270         Crypto::HmacSha256       hmac;
271         Crypto::HmacSha256::Hash hash;
272 
273         hmac.Start(static_cast<const Crypto::Key &>(testCase.mKey));
274         hmac.Update(*message, offsets[index++], testCase.mDataLength);
275         hmac.Finish(hash);
276 
277         VerifyOrQuit(hash == static_cast<const Crypto::HmacSha256::Hash &>(testCase.mHash));
278     }
279 
280     message->Free();
281 
282     testFreeInstance(instance);
283 }
284 
285 } // namespace ot
286 
main(void)287 int main(void)
288 {
289     ot::TestSha256();
290     ot::TestHmacSha256();
291     printf("All tests passed\n");
292     return 0;
293 }
294