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 %llu 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 245