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> 25*0a2b0f04SJohan Hedberg #include <net/bluetooth/hci_core.h> 26ee485290SMarcel Holtmann 270b6415b6SJohan Hedberg #include "ecc.h" 28*0a2b0f04SJohan Hedberg #include "smp.h" 29ee485290SMarcel Holtmann #include "selftest.h" 30ee485290SMarcel Holtmann 310b6415b6SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_ECDH) 320b6415b6SJohan Hedberg 330b6415b6SJohan Hedberg static const u8 priv_a_1[32] __initconst = { 340b6415b6SJohan Hedberg 0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58, 350b6415b6SJohan Hedberg 0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a, 360b6415b6SJohan Hedberg 0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74, 370b6415b6SJohan Hedberg 0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f, 380b6415b6SJohan Hedberg }; 390b6415b6SJohan Hedberg static const u8 priv_b_1[32] __initconst = { 400b6415b6SJohan Hedberg 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, 410b6415b6SJohan Hedberg 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59, 420b6415b6SJohan Hedberg 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90, 430b6415b6SJohan Hedberg 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55, 440b6415b6SJohan Hedberg }; 450b6415b6SJohan Hedberg static const u8 pub_a_1[64] __initconst = { 460b6415b6SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 470b6415b6SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 480b6415b6SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 490b6415b6SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20, 500b6415b6SJohan Hedberg 510b6415b6SJohan Hedberg 0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74, 520b6415b6SJohan Hedberg 0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76, 530b6415b6SJohan Hedberg 0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63, 540b6415b6SJohan Hedberg 0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc, 550b6415b6SJohan Hedberg }; 560b6415b6SJohan Hedberg static const u8 pub_b_1[64] __initconst = { 570b6415b6SJohan Hedberg 0x90, 0xa1, 0xaa, 0x2f, 0xb2, 0x77, 0x90, 0x55, 580b6415b6SJohan Hedberg 0x9f, 0xa6, 0x15, 0x86, 0xfd, 0x8a, 0xb5, 0x47, 590b6415b6SJohan Hedberg 0x00, 0x4c, 0x9e, 0xf1, 0x84, 0x22, 0x59, 0x09, 600b6415b6SJohan Hedberg 0x96, 0x1d, 0xaf, 0x1f, 0xf0, 0xf0, 0xa1, 0x1e, 610b6415b6SJohan Hedberg 620b6415b6SJohan Hedberg 0x4a, 0x21, 0xb1, 0x15, 0xf9, 0xaf, 0x89, 0x5f, 630b6415b6SJohan Hedberg 0x76, 0x36, 0x8e, 0xe2, 0x30, 0x11, 0x2d, 0x47, 640b6415b6SJohan Hedberg 0x60, 0x51, 0xb8, 0x9a, 0x3a, 0x70, 0x56, 0x73, 650b6415b6SJohan Hedberg 0x37, 0xad, 0x9d, 0x42, 0x3e, 0xf3, 0x55, 0x4c, 660b6415b6SJohan Hedberg }; 670b6415b6SJohan Hedberg static const u8 dhkey_1[32] __initconst = { 680b6415b6SJohan Hedberg 0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86, 690b6415b6SJohan Hedberg 0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99, 700b6415b6SJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 710b6415b6SJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec, 720b6415b6SJohan Hedberg }; 730b6415b6SJohan Hedberg 740b6415b6SJohan Hedberg static const u8 priv_a_2[32] __initconst = { 750b6415b6SJohan Hedberg 0x63, 0x76, 0x45, 0xd0, 0xf7, 0x73, 0xac, 0xb7, 760b6415b6SJohan Hedberg 0xff, 0xdd, 0x03, 0x72, 0xb9, 0x72, 0x85, 0xb4, 770b6415b6SJohan Hedberg 0x41, 0xb6, 0x5d, 0x0c, 0x5d, 0x54, 0x84, 0x60, 780b6415b6SJohan Hedberg 0x1a, 0xa3, 0x9a, 0x3c, 0x69, 0x16, 0xa5, 0x06, 790b6415b6SJohan Hedberg }; 800b6415b6SJohan Hedberg static const u8 priv_b_2[32] __initconst = { 810b6415b6SJohan Hedberg 0xba, 0x30, 0x55, 0x50, 0x19, 0xa2, 0xca, 0xa3, 820b6415b6SJohan Hedberg 0xa5, 0x29, 0x08, 0xc6, 0xb5, 0x03, 0x88, 0x7e, 830b6415b6SJohan Hedberg 0x03, 0x2b, 0x50, 0x73, 0xd4, 0x2e, 0x50, 0x97, 840b6415b6SJohan Hedberg 0x64, 0xcd, 0x72, 0x0d, 0x67, 0xa0, 0x9a, 0x52, 850b6415b6SJohan Hedberg }; 860b6415b6SJohan Hedberg static const u8 pub_a_2[64] __initconst = { 870b6415b6SJohan Hedberg 0xdd, 0x78, 0x5c, 0x74, 0x03, 0x9b, 0x7e, 0x98, 880b6415b6SJohan Hedberg 0xcb, 0x94, 0x87, 0x4a, 0xad, 0xfa, 0xf8, 0xd5, 890b6415b6SJohan Hedberg 0x43, 0x3e, 0x5c, 0xaf, 0xea, 0xb5, 0x4c, 0xf4, 900b6415b6SJohan Hedberg 0x9e, 0x80, 0x79, 0x57, 0x7b, 0xa4, 0x31, 0x2c, 910b6415b6SJohan Hedberg 920b6415b6SJohan Hedberg 0x4f, 0x5d, 0x71, 0x43, 0x77, 0x43, 0xf8, 0xea, 930b6415b6SJohan Hedberg 0xd4, 0x3e, 0xbd, 0x17, 0x91, 0x10, 0x21, 0xd0, 940b6415b6SJohan Hedberg 0x1f, 0x87, 0x43, 0x8e, 0x40, 0xe2, 0x52, 0xcd, 950b6415b6SJohan Hedberg 0xbe, 0xdf, 0x98, 0x38, 0x18, 0x12, 0x95, 0x91, 960b6415b6SJohan Hedberg }; 970b6415b6SJohan Hedberg static const u8 pub_b_2[64] __initconst = { 980b6415b6SJohan Hedberg 0xcc, 0x00, 0x65, 0xe1, 0xf5, 0x6c, 0x0d, 0xcf, 990b6415b6SJohan Hedberg 0xec, 0x96, 0x47, 0x20, 0x66, 0xc9, 0xdb, 0x84, 1000b6415b6SJohan Hedberg 0x81, 0x75, 0xa8, 0x4d, 0xc0, 0xdf, 0xc7, 0x9d, 1010b6415b6SJohan Hedberg 0x1b, 0x3f, 0x3d, 0xf2, 0x3f, 0xe4, 0x65, 0xf4, 1020b6415b6SJohan Hedberg 1030b6415b6SJohan Hedberg 0x79, 0xb2, 0xec, 0xd8, 0xca, 0x55, 0xa1, 0xa8, 1040b6415b6SJohan Hedberg 0x43, 0x4d, 0x6b, 0xca, 0x10, 0xb0, 0xc2, 0x01, 1050b6415b6SJohan Hedberg 0xc2, 0x33, 0x4e, 0x16, 0x24, 0xc4, 0xef, 0xee, 1060b6415b6SJohan Hedberg 0x99, 0xd8, 0xbb, 0xbc, 0x48, 0xd0, 0x01, 0x02, 1070b6415b6SJohan Hedberg }; 1080b6415b6SJohan Hedberg static const u8 dhkey_2[32] __initconst = { 1090b6415b6SJohan Hedberg 0x69, 0xeb, 0x21, 0x32, 0xf2, 0xc6, 0x05, 0x41, 1100b6415b6SJohan Hedberg 0x60, 0x19, 0xcd, 0x5e, 0x94, 0xe1, 0xe6, 0x5f, 1110b6415b6SJohan Hedberg 0x33, 0x07, 0xe3, 0x38, 0x4b, 0x68, 0xe5, 0x62, 1120b6415b6SJohan Hedberg 0x3f, 0x88, 0x6d, 0x2f, 0x3a, 0x84, 0x85, 0xab, 1130b6415b6SJohan Hedberg }; 1140b6415b6SJohan Hedberg 1150b6415b6SJohan Hedberg static const u8 priv_a_3[32] __initconst = { 1160b6415b6SJohan Hedberg 0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58, 1170b6415b6SJohan Hedberg 0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a, 1180b6415b6SJohan Hedberg 0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74, 1190b6415b6SJohan Hedberg 0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f, 1200b6415b6SJohan Hedberg }; 1210b6415b6SJohan Hedberg static const u8 pub_a_3[64] __initconst = { 1220b6415b6SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 1230b6415b6SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 1240b6415b6SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 1250b6415b6SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20, 1260b6415b6SJohan Hedberg 1270b6415b6SJohan Hedberg 0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74, 1280b6415b6SJohan Hedberg 0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76, 1290b6415b6SJohan Hedberg 0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63, 1300b6415b6SJohan Hedberg 0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc, 1310b6415b6SJohan Hedberg }; 1320b6415b6SJohan Hedberg static const u8 dhkey_3[32] __initconst = { 1330b6415b6SJohan Hedberg 0x2d, 0xab, 0x00, 0x48, 0xcb, 0xb3, 0x7b, 0xda, 1340b6415b6SJohan Hedberg 0x55, 0x7b, 0x8b, 0x72, 0xa8, 0x57, 0x87, 0xc3, 1350b6415b6SJohan Hedberg 0x87, 0x27, 0x99, 0x32, 0xfc, 0x79, 0x5f, 0xae, 1360b6415b6SJohan Hedberg 0x7c, 0x1c, 0xf9, 0x49, 0xe6, 0xd7, 0xaa, 0x70, 1370b6415b6SJohan Hedberg }; 1380b6415b6SJohan Hedberg 1390b6415b6SJohan Hedberg static int __init test_ecdh_sample(const u8 priv_a[32], const u8 priv_b[32], 1400b6415b6SJohan Hedberg const u8 pub_a[64], const u8 pub_b[64], 1410b6415b6SJohan Hedberg const u8 dhkey[32]) 1420b6415b6SJohan Hedberg { 1430b6415b6SJohan Hedberg u8 dhkey_a[32], dhkey_b[32]; 1440b6415b6SJohan Hedberg 1450b6415b6SJohan Hedberg ecdh_shared_secret(pub_b, priv_a, dhkey_a); 1460b6415b6SJohan Hedberg ecdh_shared_secret(pub_a, priv_b, dhkey_b); 1470b6415b6SJohan Hedberg 1480b6415b6SJohan Hedberg if (memcmp(dhkey_a, dhkey, 32)) 1490b6415b6SJohan Hedberg return -EINVAL; 1500b6415b6SJohan Hedberg 1510b6415b6SJohan Hedberg if (memcmp(dhkey_b, dhkey, 32)) 1520b6415b6SJohan Hedberg return -EINVAL; 1530b6415b6SJohan Hedberg 1540b6415b6SJohan Hedberg return 0; 1550b6415b6SJohan Hedberg } 1560b6415b6SJohan Hedberg 1570b6415b6SJohan Hedberg static int __init test_ecdh(void) 1580b6415b6SJohan Hedberg { 1590b6415b6SJohan Hedberg int err; 1600b6415b6SJohan Hedberg 1610b6415b6SJohan Hedberg err = test_ecdh_sample(priv_a_1, priv_b_1, pub_a_1, pub_b_1, dhkey_1); 1620b6415b6SJohan Hedberg if (err) { 1630b6415b6SJohan Hedberg BT_ERR("ECDH sample 1 failed"); 1640b6415b6SJohan Hedberg return err; 1650b6415b6SJohan Hedberg } 1660b6415b6SJohan Hedberg 1670b6415b6SJohan Hedberg err = test_ecdh_sample(priv_a_2, priv_b_2, pub_a_2, pub_b_2, dhkey_2); 1680b6415b6SJohan Hedberg if (err) { 1690b6415b6SJohan Hedberg BT_ERR("ECDH sample 2 failed"); 1700b6415b6SJohan Hedberg return err; 1710b6415b6SJohan Hedberg } 1720b6415b6SJohan Hedberg 1730b6415b6SJohan Hedberg err = test_ecdh_sample(priv_a_3, priv_a_3, pub_a_3, pub_a_3, dhkey_3); 1740b6415b6SJohan Hedberg if (err) { 1750b6415b6SJohan Hedberg BT_ERR("ECDH sample 3 failed"); 1760b6415b6SJohan Hedberg return err; 1770b6415b6SJohan Hedberg } 1780b6415b6SJohan Hedberg 1790b6415b6SJohan Hedberg BT_INFO("ECDH test passed"); 1800b6415b6SJohan Hedberg 1810b6415b6SJohan Hedberg return 0; 1820b6415b6SJohan Hedberg } 1830b6415b6SJohan Hedberg 1840b6415b6SJohan Hedberg #else 1850b6415b6SJohan Hedberg 1860b6415b6SJohan Hedberg static inline int test_ecdh(void) 1870b6415b6SJohan Hedberg { 1880b6415b6SJohan Hedberg return 0; 1890b6415b6SJohan Hedberg } 1900b6415b6SJohan Hedberg 1910b6415b6SJohan Hedberg #endif 1920b6415b6SJohan Hedberg 193ee485290SMarcel Holtmann static int __init run_selftest(void) 194ee485290SMarcel Holtmann { 1950b6415b6SJohan Hedberg int err; 1960b6415b6SJohan Hedberg 197ee485290SMarcel Holtmann BT_INFO("Starting self testing"); 198ee485290SMarcel Holtmann 1990b6415b6SJohan Hedberg err = test_ecdh(); 200*0a2b0f04SJohan Hedberg if (err) 201*0a2b0f04SJohan Hedberg goto done; 2020b6415b6SJohan Hedberg 203*0a2b0f04SJohan Hedberg err = bt_selftest_smp(); 204*0a2b0f04SJohan Hedberg 205*0a2b0f04SJohan Hedberg done: 206ee485290SMarcel Holtmann BT_INFO("Finished self testing"); 207ee485290SMarcel Holtmann 2080b6415b6SJohan Hedberg return err; 209ee485290SMarcel Holtmann } 210ee485290SMarcel Holtmann 211ee485290SMarcel Holtmann #if IS_MODULE(CONFIG_BT) 212ee485290SMarcel Holtmann 213ee485290SMarcel Holtmann /* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=m and is just a 214ee485290SMarcel Holtmann * wrapper to allow running this at module init. 215ee485290SMarcel Holtmann * 216ee485290SMarcel Holtmann * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all. 217ee485290SMarcel Holtmann */ 218ee485290SMarcel Holtmann int __init bt_selftest(void) 219ee485290SMarcel Holtmann { 220ee485290SMarcel Holtmann return run_selftest(); 221ee485290SMarcel Holtmann } 222ee485290SMarcel Holtmann 223ee485290SMarcel Holtmann #else 224ee485290SMarcel Holtmann 225ee485290SMarcel Holtmann /* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=y and is run 226ee485290SMarcel Holtmann * via late_initcall() as last item in the initialization sequence. 227ee485290SMarcel Holtmann * 228ee485290SMarcel Holtmann * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all. 229ee485290SMarcel Holtmann */ 230ee485290SMarcel Holtmann static int __init bt_selftest_init(void) 231ee485290SMarcel Holtmann { 232ee485290SMarcel Holtmann return run_selftest(); 233ee485290SMarcel Holtmann } 234ee485290SMarcel Holtmann late_initcall(bt_selftest_init); 235ee485290SMarcel Holtmann 236ee485290SMarcel Holtmann #endif 237