Blame view

net/bluetooth/selftest.c 8.05 KB
ee485290c   Marcel Holtmann   Bluetooth: Add su...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  /*
     BlueZ - Bluetooth protocol stack for Linux
  
     Copyright (C) 2014 Intel Corporation
  
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2 as
     published by the Free Software Foundation;
  
     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
     IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
     CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
     WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  
     ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
     COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
     SOFTWARE IS DISCLAIMED.
  */
6de50f9fd   Marcel Holtmann   Bluetooth: Export...
23
  #include <linux/debugfs.h>
ee485290c   Marcel Holtmann   Bluetooth: Add su...
24
  #include <net/bluetooth/bluetooth.h>
0a2b0f045   Johan Hedberg   Bluetooth: Add sk...
25
  #include <net/bluetooth/hci_core.h>
ee485290c   Marcel Holtmann   Bluetooth: Add su...
26

58771c1cb   Salvatore Benedetto   Bluetooth: conver...
27
  #include "ecdh_helper.h"
0a2b0f045   Johan Hedberg   Bluetooth: Add sk...
28
  #include "smp.h"
ee485290c   Marcel Holtmann   Bluetooth: Add su...
29
  #include "selftest.h"
0b6415b65   Johan Hedberg   Bluetooth: Add su...
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  #if IS_ENABLED(CONFIG_BT_SELFTEST_ECDH)
  
  static const u8 priv_a_1[32] __initconst = {
  	0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
  	0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
  	0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
  	0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
  };
  static const u8 priv_b_1[32] __initconst = {
  	0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
  	0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
  	0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
  	0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55,
  };
  static const u8 pub_a_1[64] __initconst = {
  	0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
  	0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
  	0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
  	0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
  
  	0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
  	0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
  	0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
  	0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
  };
  static const u8 pub_b_1[64] __initconst = {
  	0x90, 0xa1, 0xaa, 0x2f, 0xb2, 0x77, 0x90, 0x55,
  	0x9f, 0xa6, 0x15, 0x86, 0xfd, 0x8a, 0xb5, 0x47,
  	0x00, 0x4c, 0x9e, 0xf1, 0x84, 0x22, 0x59, 0x09,
  	0x96, 0x1d, 0xaf, 0x1f, 0xf0, 0xf0, 0xa1, 0x1e,
  
  	0x4a, 0x21, 0xb1, 0x15, 0xf9, 0xaf, 0x89, 0x5f,
  	0x76, 0x36, 0x8e, 0xe2, 0x30, 0x11, 0x2d, 0x47,
  	0x60, 0x51, 0xb8, 0x9a, 0x3a, 0x70, 0x56, 0x73,
  	0x37, 0xad, 0x9d, 0x42, 0x3e, 0xf3, 0x55, 0x4c,
  };
  static const u8 dhkey_1[32] __initconst = {
  	0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
  	0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
  	0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
  	0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec,
  };
  
  static const u8 priv_a_2[32] __initconst = {
  	0x63, 0x76, 0x45, 0xd0, 0xf7, 0x73, 0xac, 0xb7,
  	0xff, 0xdd, 0x03, 0x72, 0xb9, 0x72, 0x85, 0xb4,
  	0x41, 0xb6, 0x5d, 0x0c, 0x5d, 0x54, 0x84, 0x60,
  	0x1a, 0xa3, 0x9a, 0x3c, 0x69, 0x16, 0xa5, 0x06,
  };
  static const u8 priv_b_2[32] __initconst = {
  	0xba, 0x30, 0x55, 0x50, 0x19, 0xa2, 0xca, 0xa3,
  	0xa5, 0x29, 0x08, 0xc6, 0xb5, 0x03, 0x88, 0x7e,
  	0x03, 0x2b, 0x50, 0x73, 0xd4, 0x2e, 0x50, 0x97,
  	0x64, 0xcd, 0x72, 0x0d, 0x67, 0xa0, 0x9a, 0x52,
  };
  static const u8 pub_a_2[64] __initconst = {
  	0xdd, 0x78, 0x5c, 0x74, 0x03, 0x9b, 0x7e, 0x98,
  	0xcb, 0x94, 0x87, 0x4a, 0xad, 0xfa, 0xf8, 0xd5,
  	0x43, 0x3e, 0x5c, 0xaf, 0xea, 0xb5, 0x4c, 0xf4,
  	0x9e, 0x80, 0x79, 0x57, 0x7b, 0xa4, 0x31, 0x2c,
  
  	0x4f, 0x5d, 0x71, 0x43, 0x77, 0x43, 0xf8, 0xea,
  	0xd4, 0x3e, 0xbd, 0x17, 0x91, 0x10, 0x21, 0xd0,
  	0x1f, 0x87, 0x43, 0x8e, 0x40, 0xe2, 0x52, 0xcd,
  	0xbe, 0xdf, 0x98, 0x38, 0x18, 0x12, 0x95, 0x91,
  };
  static const u8 pub_b_2[64] __initconst = {
  	0xcc, 0x00, 0x65, 0xe1, 0xf5, 0x6c, 0x0d, 0xcf,
  	0xec, 0x96, 0x47, 0x20, 0x66, 0xc9, 0xdb, 0x84,
  	0x81, 0x75, 0xa8, 0x4d, 0xc0, 0xdf, 0xc7, 0x9d,
  	0x1b, 0x3f, 0x3d, 0xf2, 0x3f, 0xe4, 0x65, 0xf4,
  
  	0x79, 0xb2, 0xec, 0xd8, 0xca, 0x55, 0xa1, 0xa8,
  	0x43, 0x4d, 0x6b, 0xca, 0x10, 0xb0, 0xc2, 0x01,
  	0xc2, 0x33, 0x4e, 0x16, 0x24, 0xc4, 0xef, 0xee,
  	0x99, 0xd8, 0xbb, 0xbc, 0x48, 0xd0, 0x01, 0x02,
  };
  static const u8 dhkey_2[32] __initconst = {
  	0x69, 0xeb, 0x21, 0x32, 0xf2, 0xc6, 0x05, 0x41,
  	0x60, 0x19, 0xcd, 0x5e, 0x94, 0xe1, 0xe6, 0x5f,
  	0x33, 0x07, 0xe3, 0x38, 0x4b, 0x68, 0xe5, 0x62,
  	0x3f, 0x88, 0x6d, 0x2f, 0x3a, 0x84, 0x85, 0xab,
  };
  
  static const u8 priv_a_3[32] __initconst = {
  	0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
  	0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
  	0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
  	0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
  };
  static const u8 pub_a_3[64] __initconst = {
  	0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
  	0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
  	0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
  	0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
  
  	0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
  	0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
  	0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
  	0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
  };
  static const u8 dhkey_3[32] __initconst = {
  	0x2d, 0xab, 0x00, 0x48, 0xcb, 0xb3, 0x7b, 0xda,
  	0x55, 0x7b, 0x8b, 0x72, 0xa8, 0x57, 0x87, 0xc3,
  	0x87, 0x27, 0x99, 0x32, 0xfc, 0x79, 0x5f, 0xae,
  	0x7c, 0x1c, 0xf9, 0x49, 0xe6, 0xd7, 0xaa, 0x70,
  };
  
  static int __init test_ecdh_sample(const u8 priv_a[32], const u8 priv_b[32],
  				   const u8 pub_a[64], const u8 pub_b[64],
  				   const u8 dhkey[32])
  {
763d9a302   Salvatore Benedetto   Bluetooth: alloca...
142
143
144
145
146
147
148
149
150
  	u8 *tmp, *dhkey_a, *dhkey_b;
  	int ret = 0;
  
  	tmp = kmalloc(64, GFP_KERNEL);
  	if (!tmp)
  		return -EINVAL;
  
  	dhkey_a = &tmp[0];
  	dhkey_b = &tmp[32];
0b6415b65   Johan Hedberg   Bluetooth: Add su...
151

58771c1cb   Salvatore Benedetto   Bluetooth: conver...
152
153
  	compute_ecdh_secret(pub_b, priv_a, dhkey_a);
  	compute_ecdh_secret(pub_a, priv_b, dhkey_b);
0b6415b65   Johan Hedberg   Bluetooth: Add su...
154

763d9a302   Salvatore Benedetto   Bluetooth: alloca...
155
156
157
158
  	if (memcmp(dhkey_a, dhkey, 32)) {
  		ret = -EINVAL;
  		goto out;
  	}
0b6415b65   Johan Hedberg   Bluetooth: Add su...
159
160
  
  	if (memcmp(dhkey_b, dhkey, 32))
763d9a302   Salvatore Benedetto   Bluetooth: alloca...
161
  		ret = -EINVAL;
0b6415b65   Johan Hedberg   Bluetooth: Add su...
162

763d9a302   Salvatore Benedetto   Bluetooth: alloca...
163
  out:
3dfe55d9c   Colin Ian King   Bluetooth: kfree ...
164
  	kfree(tmp);
763d9a302   Salvatore Benedetto   Bluetooth: alloca...
165
  	return ret;
0b6415b65   Johan Hedberg   Bluetooth: Add su...
166
  }
6de50f9fd   Marcel Holtmann   Bluetooth: Export...
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  static char test_ecdh_buffer[32];
  
  static ssize_t test_ecdh_read(struct file *file, char __user *user_buf,
  			      size_t count, loff_t *ppos)
  {
  	return simple_read_from_buffer(user_buf, count, ppos, test_ecdh_buffer,
  				       strlen(test_ecdh_buffer));
  }
  
  static const struct file_operations test_ecdh_fops = {
  	.open		= simple_open,
  	.read		= test_ecdh_read,
  	.llseek		= default_llseek,
  };
0b6415b65   Johan Hedberg   Bluetooth: Add su...
181
182
  static int __init test_ecdh(void)
  {
e64b4fb66   Marcel Holtmann   Bluetooth: Add ti...
183
184
  	ktime_t calltime, delta, rettime;
  	unsigned long long duration;
0b6415b65   Johan Hedberg   Bluetooth: Add su...
185
  	int err;
e64b4fb66   Marcel Holtmann   Bluetooth: Add ti...
186
  	calltime = ktime_get();
0b6415b65   Johan Hedberg   Bluetooth: Add su...
187
188
189
  	err = test_ecdh_sample(priv_a_1, priv_b_1, pub_a_1, pub_b_1, dhkey_1);
  	if (err) {
  		BT_ERR("ECDH sample 1 failed");
6de50f9fd   Marcel Holtmann   Bluetooth: Export...
190
  		goto done;
0b6415b65   Johan Hedberg   Bluetooth: Add su...
191
192
193
194
195
  	}
  
  	err = test_ecdh_sample(priv_a_2, priv_b_2, pub_a_2, pub_b_2, dhkey_2);
  	if (err) {
  		BT_ERR("ECDH sample 2 failed");
6de50f9fd   Marcel Holtmann   Bluetooth: Export...
196
  		goto done;
0b6415b65   Johan Hedberg   Bluetooth: Add su...
197
198
199
200
201
  	}
  
  	err = test_ecdh_sample(priv_a_3, priv_a_3, pub_a_3, pub_a_3, dhkey_3);
  	if (err) {
  		BT_ERR("ECDH sample 3 failed");
6de50f9fd   Marcel Holtmann   Bluetooth: Export...
202
  		goto done;
0b6415b65   Johan Hedberg   Bluetooth: Add su...
203
  	}
e64b4fb66   Marcel Holtmann   Bluetooth: Add ti...
204
205
206
  	rettime = ktime_get();
  	delta = ktime_sub(rettime, calltime);
  	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
5ced24644   Marcel Holtmann   Bluetooth: Use %l...
207
  	BT_INFO("ECDH test passed in %llu usecs", duration);
0b6415b65   Johan Hedberg   Bluetooth: Add su...
208

6de50f9fd   Marcel Holtmann   Bluetooth: Export...
209
210
211
212
213
214
215
216
217
218
219
220
221
  done:
  	if (!err)
  		snprintf(test_ecdh_buffer, sizeof(test_ecdh_buffer),
  			 "PASS (%llu usecs)
  ", duration);
  	else
  		snprintf(test_ecdh_buffer, sizeof(test_ecdh_buffer), "FAIL
  ");
  
  	debugfs_create_file("selftest_ecdh", 0444, bt_debugfs, NULL,
  			    &test_ecdh_fops);
  
  	return err;
0b6415b65   Johan Hedberg   Bluetooth: Add su...
222
223
224
225
226
227
228
229
230
231
  }
  
  #else
  
  static inline int test_ecdh(void)
  {
  	return 0;
  }
  
  #endif
ee485290c   Marcel Holtmann   Bluetooth: Add su...
232
233
  static int __init run_selftest(void)
  {
0b6415b65   Johan Hedberg   Bluetooth: Add su...
234
  	int err;
ee485290c   Marcel Holtmann   Bluetooth: Add su...
235
  	BT_INFO("Starting self testing");
0b6415b65   Johan Hedberg   Bluetooth: Add su...
236
  	err = test_ecdh();
0a2b0f045   Johan Hedberg   Bluetooth: Add sk...
237
238
  	if (err)
  		goto done;
0b6415b65   Johan Hedberg   Bluetooth: Add su...
239

0a2b0f045   Johan Hedberg   Bluetooth: Add sk...
240
241
242
  	err = bt_selftest_smp();
  
  done:
ee485290c   Marcel Holtmann   Bluetooth: Add su...
243
  	BT_INFO("Finished self testing");
0b6415b65   Johan Hedberg   Bluetooth: Add su...
244
  	return err;
ee485290c   Marcel Holtmann   Bluetooth: Add su...
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
  }
  
  #if IS_MODULE(CONFIG_BT)
  
  /* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=m and is just a
   * wrapper to allow running this at module init.
   *
   * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all.
   */
  int __init bt_selftest(void)
  {
  	return run_selftest();
  }
  
  #else
  
  /* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=y and is run
   * via late_initcall() as last item in the initialization sequence.
   *
   * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all.
   */
  static int __init bt_selftest_init(void)
  {
  	return run_selftest();
  }
  late_initcall(bt_selftest_init);
  
  #endif