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