xref: /openbmc/linux/net/bluetooth/selftest.c (revision 8be98d2f2a0a262f8bf8a0bc1fdf522b3c7aab17)
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 
246de50f9fSMarcel Holtmann #include <linux/debugfs.h>
256de50f9fSMarcel Holtmann 
26ee485290SMarcel Holtmann #include <net/bluetooth/bluetooth.h>
270a2b0f04SJohan Hedberg #include <net/bluetooth/hci_core.h>
28ee485290SMarcel Holtmann 
2958771c1cSSalvatore Benedetto #include "ecdh_helper.h"
300a2b0f04SJohan Hedberg #include "smp.h"
31ee485290SMarcel Holtmann #include "selftest.h"
32ee485290SMarcel Holtmann 
330b6415b6SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_ECDH)
340b6415b6SJohan Hedberg 
350b6415b6SJohan Hedberg static const u8 priv_a_1[32] __initconst = {
360b6415b6SJohan Hedberg 	0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
370b6415b6SJohan Hedberg 	0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
380b6415b6SJohan Hedberg 	0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
390b6415b6SJohan Hedberg 	0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
400b6415b6SJohan Hedberg };
410b6415b6SJohan Hedberg static const u8 priv_b_1[32] __initconst = {
420b6415b6SJohan Hedberg 	0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
430b6415b6SJohan Hedberg 	0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
440b6415b6SJohan Hedberg 	0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
450b6415b6SJohan Hedberg 	0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55,
460b6415b6SJohan Hedberg };
470b6415b6SJohan Hedberg static const u8 pub_a_1[64] __initconst = {
480b6415b6SJohan Hedberg 	0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
490b6415b6SJohan Hedberg 	0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
500b6415b6SJohan Hedberg 	0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
510b6415b6SJohan Hedberg 	0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
520b6415b6SJohan Hedberg 
530b6415b6SJohan Hedberg 	0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
540b6415b6SJohan Hedberg 	0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
550b6415b6SJohan Hedberg 	0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
560b6415b6SJohan Hedberg 	0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
570b6415b6SJohan Hedberg };
580b6415b6SJohan Hedberg static const u8 pub_b_1[64] __initconst = {
590b6415b6SJohan Hedberg 	0x90, 0xa1, 0xaa, 0x2f, 0xb2, 0x77, 0x90, 0x55,
600b6415b6SJohan Hedberg 	0x9f, 0xa6, 0x15, 0x86, 0xfd, 0x8a, 0xb5, 0x47,
610b6415b6SJohan Hedberg 	0x00, 0x4c, 0x9e, 0xf1, 0x84, 0x22, 0x59, 0x09,
620b6415b6SJohan Hedberg 	0x96, 0x1d, 0xaf, 0x1f, 0xf0, 0xf0, 0xa1, 0x1e,
630b6415b6SJohan Hedberg 
640b6415b6SJohan Hedberg 	0x4a, 0x21, 0xb1, 0x15, 0xf9, 0xaf, 0x89, 0x5f,
650b6415b6SJohan Hedberg 	0x76, 0x36, 0x8e, 0xe2, 0x30, 0x11, 0x2d, 0x47,
660b6415b6SJohan Hedberg 	0x60, 0x51, 0xb8, 0x9a, 0x3a, 0x70, 0x56, 0x73,
670b6415b6SJohan Hedberg 	0x37, 0xad, 0x9d, 0x42, 0x3e, 0xf3, 0x55, 0x4c,
680b6415b6SJohan Hedberg };
690b6415b6SJohan Hedberg static const u8 dhkey_1[32] __initconst = {
700b6415b6SJohan Hedberg 	0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
710b6415b6SJohan Hedberg 	0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
720b6415b6SJohan Hedberg 	0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
730b6415b6SJohan Hedberg 	0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec,
740b6415b6SJohan Hedberg };
750b6415b6SJohan Hedberg 
760b6415b6SJohan Hedberg static const u8 priv_a_2[32] __initconst = {
770b6415b6SJohan Hedberg 	0x63, 0x76, 0x45, 0xd0, 0xf7, 0x73, 0xac, 0xb7,
780b6415b6SJohan Hedberg 	0xff, 0xdd, 0x03, 0x72, 0xb9, 0x72, 0x85, 0xb4,
790b6415b6SJohan Hedberg 	0x41, 0xb6, 0x5d, 0x0c, 0x5d, 0x54, 0x84, 0x60,
800b6415b6SJohan Hedberg 	0x1a, 0xa3, 0x9a, 0x3c, 0x69, 0x16, 0xa5, 0x06,
810b6415b6SJohan Hedberg };
820b6415b6SJohan Hedberg static const u8 priv_b_2[32] __initconst = {
830b6415b6SJohan Hedberg 	0xba, 0x30, 0x55, 0x50, 0x19, 0xa2, 0xca, 0xa3,
840b6415b6SJohan Hedberg 	0xa5, 0x29, 0x08, 0xc6, 0xb5, 0x03, 0x88, 0x7e,
850b6415b6SJohan Hedberg 	0x03, 0x2b, 0x50, 0x73, 0xd4, 0x2e, 0x50, 0x97,
860b6415b6SJohan Hedberg 	0x64, 0xcd, 0x72, 0x0d, 0x67, 0xa0, 0x9a, 0x52,
870b6415b6SJohan Hedberg };
880b6415b6SJohan Hedberg static const u8 pub_a_2[64] __initconst = {
890b6415b6SJohan Hedberg 	0xdd, 0x78, 0x5c, 0x74, 0x03, 0x9b, 0x7e, 0x98,
900b6415b6SJohan Hedberg 	0xcb, 0x94, 0x87, 0x4a, 0xad, 0xfa, 0xf8, 0xd5,
910b6415b6SJohan Hedberg 	0x43, 0x3e, 0x5c, 0xaf, 0xea, 0xb5, 0x4c, 0xf4,
920b6415b6SJohan Hedberg 	0x9e, 0x80, 0x79, 0x57, 0x7b, 0xa4, 0x31, 0x2c,
930b6415b6SJohan Hedberg 
940b6415b6SJohan Hedberg 	0x4f, 0x5d, 0x71, 0x43, 0x77, 0x43, 0xf8, 0xea,
950b6415b6SJohan Hedberg 	0xd4, 0x3e, 0xbd, 0x17, 0x91, 0x10, 0x21, 0xd0,
960b6415b6SJohan Hedberg 	0x1f, 0x87, 0x43, 0x8e, 0x40, 0xe2, 0x52, 0xcd,
970b6415b6SJohan Hedberg 	0xbe, 0xdf, 0x98, 0x38, 0x18, 0x12, 0x95, 0x91,
980b6415b6SJohan Hedberg };
990b6415b6SJohan Hedberg static const u8 pub_b_2[64] __initconst = {
1000b6415b6SJohan Hedberg 	0xcc, 0x00, 0x65, 0xe1, 0xf5, 0x6c, 0x0d, 0xcf,
1010b6415b6SJohan Hedberg 	0xec, 0x96, 0x47, 0x20, 0x66, 0xc9, 0xdb, 0x84,
1020b6415b6SJohan Hedberg 	0x81, 0x75, 0xa8, 0x4d, 0xc0, 0xdf, 0xc7, 0x9d,
1030b6415b6SJohan Hedberg 	0x1b, 0x3f, 0x3d, 0xf2, 0x3f, 0xe4, 0x65, 0xf4,
1040b6415b6SJohan Hedberg 
1050b6415b6SJohan Hedberg 	0x79, 0xb2, 0xec, 0xd8, 0xca, 0x55, 0xa1, 0xa8,
1060b6415b6SJohan Hedberg 	0x43, 0x4d, 0x6b, 0xca, 0x10, 0xb0, 0xc2, 0x01,
1070b6415b6SJohan Hedberg 	0xc2, 0x33, 0x4e, 0x16, 0x24, 0xc4, 0xef, 0xee,
1080b6415b6SJohan Hedberg 	0x99, 0xd8, 0xbb, 0xbc, 0x48, 0xd0, 0x01, 0x02,
1090b6415b6SJohan Hedberg };
1100b6415b6SJohan Hedberg static const u8 dhkey_2[32] __initconst = {
1110b6415b6SJohan Hedberg 	0x69, 0xeb, 0x21, 0x32, 0xf2, 0xc6, 0x05, 0x41,
1120b6415b6SJohan Hedberg 	0x60, 0x19, 0xcd, 0x5e, 0x94, 0xe1, 0xe6, 0x5f,
1130b6415b6SJohan Hedberg 	0x33, 0x07, 0xe3, 0x38, 0x4b, 0x68, 0xe5, 0x62,
1140b6415b6SJohan Hedberg 	0x3f, 0x88, 0x6d, 0x2f, 0x3a, 0x84, 0x85, 0xab,
1150b6415b6SJohan Hedberg };
1160b6415b6SJohan Hedberg 
1170b6415b6SJohan Hedberg static const u8 priv_a_3[32] __initconst = {
1180b6415b6SJohan Hedberg 	0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
1190b6415b6SJohan Hedberg 	0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
1200b6415b6SJohan Hedberg 	0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
1210b6415b6SJohan Hedberg 	0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
1220b6415b6SJohan Hedberg };
1230b6415b6SJohan Hedberg static const u8 pub_a_3[64] __initconst = {
1240b6415b6SJohan Hedberg 	0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
1250b6415b6SJohan Hedberg 	0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
1260b6415b6SJohan Hedberg 	0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
1270b6415b6SJohan Hedberg 	0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
1280b6415b6SJohan Hedberg 
1290b6415b6SJohan Hedberg 	0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
1300b6415b6SJohan Hedberg 	0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
1310b6415b6SJohan Hedberg 	0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
1320b6415b6SJohan Hedberg 	0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
1330b6415b6SJohan Hedberg };
1340b6415b6SJohan Hedberg static const u8 dhkey_3[32] __initconst = {
1350b6415b6SJohan Hedberg 	0x2d, 0xab, 0x00, 0x48, 0xcb, 0xb3, 0x7b, 0xda,
1360b6415b6SJohan Hedberg 	0x55, 0x7b, 0x8b, 0x72, 0xa8, 0x57, 0x87, 0xc3,
1370b6415b6SJohan Hedberg 	0x87, 0x27, 0x99, 0x32, 0xfc, 0x79, 0x5f, 0xae,
1380b6415b6SJohan Hedberg 	0x7c, 0x1c, 0xf9, 0x49, 0xe6, 0xd7, 0xaa, 0x70,
1390b6415b6SJohan Hedberg };
1400b6415b6SJohan Hedberg 
test_ecdh_sample(struct crypto_kpp * tfm,const u8 priv_a[32],const u8 priv_b[32],const u8 pub_a[64],const u8 pub_b[64],const u8 dhkey[32])14147eb2ac8STudor Ambarus static int __init test_ecdh_sample(struct crypto_kpp *tfm, const u8 priv_a[32],
14247eb2ac8STudor Ambarus 				   const u8 priv_b[32], const u8 pub_a[64],
14347eb2ac8STudor Ambarus 				   const u8 pub_b[64], const u8 dhkey[32])
1440b6415b6SJohan Hedberg {
145763d9a30SSalvatore Benedetto 	u8 *tmp, *dhkey_a, *dhkey_b;
1463814baf3STudor Ambarus 	int ret;
147763d9a30SSalvatore Benedetto 
148763d9a30SSalvatore Benedetto 	tmp = kmalloc(64, GFP_KERNEL);
149763d9a30SSalvatore Benedetto 	if (!tmp)
150763d9a30SSalvatore Benedetto 		return -EINVAL;
151763d9a30SSalvatore Benedetto 
152763d9a30SSalvatore Benedetto 	dhkey_a = &tmp[0];
153763d9a30SSalvatore Benedetto 	dhkey_b = &tmp[32];
1540b6415b6SJohan Hedberg 
155c0153b0bSTudor Ambarus 	ret = set_ecdh_privkey(tfm, priv_a);
1563814baf3STudor Ambarus 	if (ret)
1573814baf3STudor Ambarus 		goto out;
1583814baf3STudor Ambarus 
159c0153b0bSTudor Ambarus 	ret = compute_ecdh_secret(tfm, pub_b, dhkey_a);
1603814baf3STudor Ambarus 	if (ret)
1613814baf3STudor Ambarus 		goto out;
1620b6415b6SJohan Hedberg 
163763d9a30SSalvatore Benedetto 	if (memcmp(dhkey_a, dhkey, 32)) {
164763d9a30SSalvatore Benedetto 		ret = -EINVAL;
165763d9a30SSalvatore Benedetto 		goto out;
166763d9a30SSalvatore Benedetto 	}
1670b6415b6SJohan Hedberg 
168c0153b0bSTudor Ambarus 	ret = set_ecdh_privkey(tfm, priv_b);
169c0153b0bSTudor Ambarus 	if (ret)
170c0153b0bSTudor Ambarus 		goto out;
171c0153b0bSTudor Ambarus 
172c0153b0bSTudor Ambarus 	ret = compute_ecdh_secret(tfm, pub_a, dhkey_b);
173c0153b0bSTudor Ambarus 	if (ret)
174c0153b0bSTudor Ambarus 		goto out;
175c0153b0bSTudor Ambarus 
1760b6415b6SJohan Hedberg 	if (memcmp(dhkey_b, dhkey, 32))
177763d9a30SSalvatore Benedetto 		ret = -EINVAL;
178c0153b0bSTudor Ambarus 	/* fall through*/
179763d9a30SSalvatore Benedetto out:
1803dfe55d9SColin Ian King 	kfree(tmp);
181763d9a30SSalvatore Benedetto 	return ret;
1820b6415b6SJohan Hedberg }
1830b6415b6SJohan Hedberg 
1846de50f9fSMarcel Holtmann static char test_ecdh_buffer[32];
1856de50f9fSMarcel Holtmann 
test_ecdh_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1866de50f9fSMarcel Holtmann static ssize_t test_ecdh_read(struct file *file, char __user *user_buf,
1876de50f9fSMarcel Holtmann 			      size_t count, loff_t *ppos)
1886de50f9fSMarcel Holtmann {
1896de50f9fSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, test_ecdh_buffer,
1906de50f9fSMarcel Holtmann 				       strlen(test_ecdh_buffer));
1916de50f9fSMarcel Holtmann }
1926de50f9fSMarcel Holtmann 
1936de50f9fSMarcel Holtmann static const struct file_operations test_ecdh_fops = {
1946de50f9fSMarcel Holtmann 	.open		= simple_open,
1956de50f9fSMarcel Holtmann 	.read		= test_ecdh_read,
1966de50f9fSMarcel Holtmann 	.llseek		= default_llseek,
1976de50f9fSMarcel Holtmann };
1986de50f9fSMarcel Holtmann 
test_ecdh(void)1990b6415b6SJohan Hedberg static int __init test_ecdh(void)
2000b6415b6SJohan Hedberg {
20147eb2ac8STudor Ambarus 	struct crypto_kpp *tfm;
202e64b4fb6SMarcel Holtmann 	ktime_t calltime, delta, rettime;
203b49ef29dSMarcel Holtmann 	unsigned long long duration = 0;
2040b6415b6SJohan Hedberg 	int err;
2050b6415b6SJohan Hedberg 
206e64b4fb6SMarcel Holtmann 	calltime = ktime_get();
207e64b4fb6SMarcel Holtmann 
208*6763f5eaSMeng Yu 	tfm = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
20947eb2ac8STudor Ambarus 	if (IS_ERR(tfm)) {
21047eb2ac8STudor Ambarus 		BT_ERR("Unable to create ECDH crypto context");
21147eb2ac8STudor Ambarus 		err = PTR_ERR(tfm);
21247eb2ac8STudor Ambarus 		goto done;
21347eb2ac8STudor Ambarus 	}
21447eb2ac8STudor Ambarus 
21547eb2ac8STudor Ambarus 	err = test_ecdh_sample(tfm, priv_a_1, priv_b_1, pub_a_1, pub_b_1,
21647eb2ac8STudor Ambarus 			       dhkey_1);
2170b6415b6SJohan Hedberg 	if (err) {
2180b6415b6SJohan Hedberg 		BT_ERR("ECDH sample 1 failed");
2196de50f9fSMarcel Holtmann 		goto done;
2200b6415b6SJohan Hedberg 	}
2210b6415b6SJohan Hedberg 
22247eb2ac8STudor Ambarus 	err = test_ecdh_sample(tfm, priv_a_2, priv_b_2, pub_a_2, pub_b_2,
22347eb2ac8STudor Ambarus 			       dhkey_2);
2240b6415b6SJohan Hedberg 	if (err) {
2250b6415b6SJohan Hedberg 		BT_ERR("ECDH sample 2 failed");
2266de50f9fSMarcel Holtmann 		goto done;
2270b6415b6SJohan Hedberg 	}
2280b6415b6SJohan Hedberg 
22947eb2ac8STudor Ambarus 	err = test_ecdh_sample(tfm, priv_a_3, priv_a_3, pub_a_3, pub_a_3,
23047eb2ac8STudor Ambarus 			       dhkey_3);
2310b6415b6SJohan Hedberg 	if (err) {
2320b6415b6SJohan Hedberg 		BT_ERR("ECDH sample 3 failed");
2336de50f9fSMarcel Holtmann 		goto done;
2340b6415b6SJohan Hedberg 	}
2350b6415b6SJohan Hedberg 
23647eb2ac8STudor Ambarus 	crypto_free_kpp(tfm);
23747eb2ac8STudor Ambarus 
238e64b4fb6SMarcel Holtmann 	rettime = ktime_get();
239e64b4fb6SMarcel Holtmann 	delta = ktime_sub(rettime, calltime);
240e64b4fb6SMarcel Holtmann 	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
241e64b4fb6SMarcel Holtmann 
2425ced2464SMarcel Holtmann 	BT_INFO("ECDH test passed in %llu usecs", duration);
2430b6415b6SJohan Hedberg 
2446de50f9fSMarcel Holtmann done:
2456de50f9fSMarcel Holtmann 	if (!err)
2466de50f9fSMarcel Holtmann 		snprintf(test_ecdh_buffer, sizeof(test_ecdh_buffer),
2476de50f9fSMarcel Holtmann 			 "PASS (%llu usecs)\n", duration);
2486de50f9fSMarcel Holtmann 	else
2496de50f9fSMarcel Holtmann 		snprintf(test_ecdh_buffer, sizeof(test_ecdh_buffer), "FAIL\n");
2506de50f9fSMarcel Holtmann 
2516de50f9fSMarcel Holtmann 	debugfs_create_file("selftest_ecdh", 0444, bt_debugfs, NULL,
2526de50f9fSMarcel Holtmann 			    &test_ecdh_fops);
2536de50f9fSMarcel Holtmann 
2546de50f9fSMarcel Holtmann 	return err;
2550b6415b6SJohan Hedberg }
2560b6415b6SJohan Hedberg 
2570b6415b6SJohan Hedberg #else
2580b6415b6SJohan Hedberg 
test_ecdh(void)2590b6415b6SJohan Hedberg static inline int test_ecdh(void)
2600b6415b6SJohan Hedberg {
2610b6415b6SJohan Hedberg 	return 0;
2620b6415b6SJohan Hedberg }
2630b6415b6SJohan Hedberg 
2640b6415b6SJohan Hedberg #endif
2650b6415b6SJohan Hedberg 
run_selftest(void)266ee485290SMarcel Holtmann static int __init run_selftest(void)
267ee485290SMarcel Holtmann {
2680b6415b6SJohan Hedberg 	int err;
2690b6415b6SJohan Hedberg 
270ee485290SMarcel Holtmann 	BT_INFO("Starting self testing");
271ee485290SMarcel Holtmann 
2720b6415b6SJohan Hedberg 	err = test_ecdh();
2730a2b0f04SJohan Hedberg 	if (err)
2740a2b0f04SJohan Hedberg 		goto done;
2750b6415b6SJohan Hedberg 
2760a2b0f04SJohan Hedberg 	err = bt_selftest_smp();
2770a2b0f04SJohan Hedberg 
2780a2b0f04SJohan Hedberg done:
279ee485290SMarcel Holtmann 	BT_INFO("Finished self testing");
280ee485290SMarcel Holtmann 
2810b6415b6SJohan Hedberg 	return err;
282ee485290SMarcel Holtmann }
283ee485290SMarcel Holtmann 
284ee485290SMarcel Holtmann #if IS_MODULE(CONFIG_BT)
285ee485290SMarcel Holtmann 
286ee485290SMarcel Holtmann /* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=m and is just a
287ee485290SMarcel Holtmann  * wrapper to allow running this at module init.
288ee485290SMarcel Holtmann  *
289ee485290SMarcel Holtmann  * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all.
290ee485290SMarcel Holtmann  */
bt_selftest(void)291ee485290SMarcel Holtmann int __init bt_selftest(void)
292ee485290SMarcel Holtmann {
293ee485290SMarcel Holtmann 	return run_selftest();
294ee485290SMarcel Holtmann }
295ee485290SMarcel Holtmann 
296ee485290SMarcel Holtmann #else
297ee485290SMarcel Holtmann 
298ee485290SMarcel Holtmann /* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=y and is run
299ee485290SMarcel Holtmann  * via late_initcall() as last item in the initialization sequence.
300ee485290SMarcel Holtmann  *
301ee485290SMarcel Holtmann  * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all.
302ee485290SMarcel Holtmann  */
bt_selftest_init(void)303ee485290SMarcel Holtmann static int __init bt_selftest_init(void)
304ee485290SMarcel Holtmann {
305ee485290SMarcel Holtmann 	return run_selftest();
306ee485290SMarcel Holtmann }
307ee485290SMarcel Holtmann late_initcall(bt_selftest_init);
308ee485290SMarcel Holtmann 
309ee485290SMarcel Holtmann #endif
310