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