Blame view
net/bluetooth/selftest.c
8.05 KB
ee485290c 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 Bluetooth: Export... |
23 |
#include <linux/debugfs.h> |
ee485290c Bluetooth: Add su... |
24 |
#include <net/bluetooth/bluetooth.h> |
0a2b0f045 Bluetooth: Add sk... |
25 |
#include <net/bluetooth/hci_core.h> |
ee485290c Bluetooth: Add su... |
26 |
|
58771c1cb Bluetooth: conver... |
27 |
#include "ecdh_helper.h" |
0a2b0f045 Bluetooth: Add sk... |
28 |
#include "smp.h" |
ee485290c Bluetooth: Add su... |
29 |
#include "selftest.h" |
0b6415b65 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 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 Bluetooth: Add su... |
151 |
|
58771c1cb Bluetooth: conver... |
152 153 |
compute_ecdh_secret(pub_b, priv_a, dhkey_a); compute_ecdh_secret(pub_a, priv_b, dhkey_b); |
0b6415b65 Bluetooth: Add su... |
154 |
|
763d9a302 Bluetooth: alloca... |
155 156 157 158 |
if (memcmp(dhkey_a, dhkey, 32)) { ret = -EINVAL; goto out; } |
0b6415b65 Bluetooth: Add su... |
159 160 |
if (memcmp(dhkey_b, dhkey, 32)) |
763d9a302 Bluetooth: alloca... |
161 |
ret = -EINVAL; |
0b6415b65 Bluetooth: Add su... |
162 |
|
763d9a302 Bluetooth: alloca... |
163 |
out: |
3dfe55d9c Bluetooth: kfree ... |
164 |
kfree(tmp); |
763d9a302 Bluetooth: alloca... |
165 |
return ret; |
0b6415b65 Bluetooth: Add su... |
166 |
} |
6de50f9fd 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 Bluetooth: Add su... |
181 182 |
static int __init test_ecdh(void) { |
e64b4fb66 Bluetooth: Add ti... |
183 184 |
ktime_t calltime, delta, rettime; unsigned long long duration; |
0b6415b65 Bluetooth: Add su... |
185 |
int err; |
e64b4fb66 Bluetooth: Add ti... |
186 |
calltime = ktime_get(); |
0b6415b65 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 Bluetooth: Export... |
190 |
goto done; |
0b6415b65 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 Bluetooth: Export... |
196 |
goto done; |
0b6415b65 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 Bluetooth: Export... |
202 |
goto done; |
0b6415b65 Bluetooth: Add su... |
203 |
} |
e64b4fb66 Bluetooth: Add ti... |
204 205 206 |
rettime = ktime_get(); delta = ktime_sub(rettime, calltime); duration = (unsigned long long) ktime_to_ns(delta) >> 10; |
5ced24644 Bluetooth: Use %l... |
207 |
BT_INFO("ECDH test passed in %llu usecs", duration); |
0b6415b65 Bluetooth: Add su... |
208 |
|
6de50f9fd 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 Bluetooth: Add su... |
222 223 224 225 226 227 228 229 230 231 |
} #else static inline int test_ecdh(void) { return 0; } #endif |
ee485290c Bluetooth: Add su... |
232 233 |
static int __init run_selftest(void) { |
0b6415b65 Bluetooth: Add su... |
234 |
int err; |
ee485290c Bluetooth: Add su... |
235 |
BT_INFO("Starting self testing"); |
0b6415b65 Bluetooth: Add su... |
236 |
err = test_ecdh(); |
0a2b0f045 Bluetooth: Add sk... |
237 238 |
if (err) goto done; |
0b6415b65 Bluetooth: Add su... |
239 |
|
0a2b0f045 Bluetooth: Add sk... |
240 241 242 |
err = bt_selftest_smp(); done: |
ee485290c Bluetooth: Add su... |
243 |
BT_INFO("Finished self testing"); |
0b6415b65 Bluetooth: Add su... |
244 |
return err; |
ee485290c 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 |