Bluetooth: Add timing information to ECDH test case runs
[cascardo/linux.git] / net / bluetooth / selftest.c
1 /*
2    BlueZ - Bluetooth protocol stack for Linux
3
4    Copyright (C) 2014 Intel Corporation
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License version 2 as
8    published by the Free Software Foundation;
9
10    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
13    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
14    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
19    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
20    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
21    SOFTWARE IS DISCLAIMED.
22 */
23
24 #include <net/bluetooth/bluetooth.h>
25 #include <net/bluetooth/hci_core.h>
26
27 #include "ecc.h"
28 #include "smp.h"
29 #include "selftest.h"
30
31 #if IS_ENABLED(CONFIG_BT_SELFTEST_ECDH)
32
33 static const u8 priv_a_1[32] __initconst = {
34         0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
35         0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
36         0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
37         0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
38 };
39 static const u8 priv_b_1[32] __initconst = {
40         0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
41         0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
42         0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
43         0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55,
44 };
45 static const u8 pub_a_1[64] __initconst = {
46         0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
47         0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
48         0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
49         0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
50
51         0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
52         0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
53         0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
54         0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
55 };
56 static const u8 pub_b_1[64] __initconst = {
57         0x90, 0xa1, 0xaa, 0x2f, 0xb2, 0x77, 0x90, 0x55,
58         0x9f, 0xa6, 0x15, 0x86, 0xfd, 0x8a, 0xb5, 0x47,
59         0x00, 0x4c, 0x9e, 0xf1, 0x84, 0x22, 0x59, 0x09,
60         0x96, 0x1d, 0xaf, 0x1f, 0xf0, 0xf0, 0xa1, 0x1e,
61
62         0x4a, 0x21, 0xb1, 0x15, 0xf9, 0xaf, 0x89, 0x5f,
63         0x76, 0x36, 0x8e, 0xe2, 0x30, 0x11, 0x2d, 0x47,
64         0x60, 0x51, 0xb8, 0x9a, 0x3a, 0x70, 0x56, 0x73,
65         0x37, 0xad, 0x9d, 0x42, 0x3e, 0xf3, 0x55, 0x4c,
66 };
67 static const u8 dhkey_1[32] __initconst = {
68         0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
69         0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
70         0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
71         0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec,
72 };
73
74 static const u8 priv_a_2[32] __initconst = {
75         0x63, 0x76, 0x45, 0xd0, 0xf7, 0x73, 0xac, 0xb7,
76         0xff, 0xdd, 0x03, 0x72, 0xb9, 0x72, 0x85, 0xb4,
77         0x41, 0xb6, 0x5d, 0x0c, 0x5d, 0x54, 0x84, 0x60,
78         0x1a, 0xa3, 0x9a, 0x3c, 0x69, 0x16, 0xa5, 0x06,
79 };
80 static const u8 priv_b_2[32] __initconst = {
81         0xba, 0x30, 0x55, 0x50, 0x19, 0xa2, 0xca, 0xa3,
82         0xa5, 0x29, 0x08, 0xc6, 0xb5, 0x03, 0x88, 0x7e,
83         0x03, 0x2b, 0x50, 0x73, 0xd4, 0x2e, 0x50, 0x97,
84         0x64, 0xcd, 0x72, 0x0d, 0x67, 0xa0, 0x9a, 0x52,
85 };
86 static const u8 pub_a_2[64] __initconst = {
87         0xdd, 0x78, 0x5c, 0x74, 0x03, 0x9b, 0x7e, 0x98,
88         0xcb, 0x94, 0x87, 0x4a, 0xad, 0xfa, 0xf8, 0xd5,
89         0x43, 0x3e, 0x5c, 0xaf, 0xea, 0xb5, 0x4c, 0xf4,
90         0x9e, 0x80, 0x79, 0x57, 0x7b, 0xa4, 0x31, 0x2c,
91
92         0x4f, 0x5d, 0x71, 0x43, 0x77, 0x43, 0xf8, 0xea,
93         0xd4, 0x3e, 0xbd, 0x17, 0x91, 0x10, 0x21, 0xd0,
94         0x1f, 0x87, 0x43, 0x8e, 0x40, 0xe2, 0x52, 0xcd,
95         0xbe, 0xdf, 0x98, 0x38, 0x18, 0x12, 0x95, 0x91,
96 };
97 static const u8 pub_b_2[64] __initconst = {
98         0xcc, 0x00, 0x65, 0xe1, 0xf5, 0x6c, 0x0d, 0xcf,
99         0xec, 0x96, 0x47, 0x20, 0x66, 0xc9, 0xdb, 0x84,
100         0x81, 0x75, 0xa8, 0x4d, 0xc0, 0xdf, 0xc7, 0x9d,
101         0x1b, 0x3f, 0x3d, 0xf2, 0x3f, 0xe4, 0x65, 0xf4,
102
103         0x79, 0xb2, 0xec, 0xd8, 0xca, 0x55, 0xa1, 0xa8,
104         0x43, 0x4d, 0x6b, 0xca, 0x10, 0xb0, 0xc2, 0x01,
105         0xc2, 0x33, 0x4e, 0x16, 0x24, 0xc4, 0xef, 0xee,
106         0x99, 0xd8, 0xbb, 0xbc, 0x48, 0xd0, 0x01, 0x02,
107 };
108 static const u8 dhkey_2[32] __initconst = {
109         0x69, 0xeb, 0x21, 0x32, 0xf2, 0xc6, 0x05, 0x41,
110         0x60, 0x19, 0xcd, 0x5e, 0x94, 0xe1, 0xe6, 0x5f,
111         0x33, 0x07, 0xe3, 0x38, 0x4b, 0x68, 0xe5, 0x62,
112         0x3f, 0x88, 0x6d, 0x2f, 0x3a, 0x84, 0x85, 0xab,
113 };
114
115 static const u8 priv_a_3[32] __initconst = {
116         0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
117         0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
118         0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
119         0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
120 };
121 static const u8 pub_a_3[64] __initconst = {
122         0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
123         0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
124         0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
125         0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
126
127         0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
128         0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
129         0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
130         0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
131 };
132 static const u8 dhkey_3[32] __initconst = {
133         0x2d, 0xab, 0x00, 0x48, 0xcb, 0xb3, 0x7b, 0xda,
134         0x55, 0x7b, 0x8b, 0x72, 0xa8, 0x57, 0x87, 0xc3,
135         0x87, 0x27, 0x99, 0x32, 0xfc, 0x79, 0x5f, 0xae,
136         0x7c, 0x1c, 0xf9, 0x49, 0xe6, 0xd7, 0xaa, 0x70,
137 };
138
139 static int __init test_ecdh_sample(const u8 priv_a[32], const u8 priv_b[32],
140                                    const u8 pub_a[64], const u8 pub_b[64],
141                                    const u8 dhkey[32])
142 {
143         u8 dhkey_a[32], dhkey_b[32];
144
145         ecdh_shared_secret(pub_b, priv_a, dhkey_a);
146         ecdh_shared_secret(pub_a, priv_b, dhkey_b);
147
148         if (memcmp(dhkey_a, dhkey, 32))
149                 return -EINVAL;
150
151         if (memcmp(dhkey_b, dhkey, 32))
152                 return -EINVAL;
153
154         return 0;
155 }
156
157 static int __init test_ecdh(void)
158 {
159         ktime_t calltime, delta, rettime;
160         unsigned long long duration;
161         int err;
162
163         calltime = ktime_get();
164
165         err = test_ecdh_sample(priv_a_1, priv_b_1, pub_a_1, pub_b_1, dhkey_1);
166         if (err) {
167                 BT_ERR("ECDH sample 1 failed");
168                 return err;
169         }
170
171         err = test_ecdh_sample(priv_a_2, priv_b_2, pub_a_2, pub_b_2, dhkey_2);
172         if (err) {
173                 BT_ERR("ECDH sample 2 failed");
174                 return err;
175         }
176
177         err = test_ecdh_sample(priv_a_3, priv_a_3, pub_a_3, pub_a_3, dhkey_3);
178         if (err) {
179                 BT_ERR("ECDH sample 3 failed");
180                 return err;
181         }
182
183         rettime = ktime_get();
184         delta = ktime_sub(rettime, calltime);
185         duration = (unsigned long long) ktime_to_ns(delta) >> 10;
186
187         BT_INFO("ECDH test passed in %lld usecs", duration);
188
189         return 0;
190 }
191
192 #else
193
194 static inline int test_ecdh(void)
195 {
196         return 0;
197 }
198
199 #endif
200
201 static int __init run_selftest(void)
202 {
203         int err;
204
205         BT_INFO("Starting self testing");
206
207         err = test_ecdh();
208         if (err)
209                 goto done;
210
211         err = bt_selftest_smp();
212
213 done:
214         BT_INFO("Finished self testing");
215
216         return err;
217 }
218
219 #if IS_MODULE(CONFIG_BT)
220
221 /* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=m and is just a
222  * wrapper to allow running this at module init.
223  *
224  * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all.
225  */
226 int __init bt_selftest(void)
227 {
228         return run_selftest();
229 }
230
231 #else
232
233 /* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=y and is run
234  * via late_initcall() as last item in the initialization sequence.
235  *
236  * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all.
237  */
238 static int __init bt_selftest_init(void)
239 {
240         return run_selftest();
241 }
242 late_initcall(bt_selftest_init);
243
244 #endif