linux/net/bluetooth/selftest.c
<<
>>
Prefs
   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 <linux/debugfs.h>
  25
  26#include <net/bluetooth/bluetooth.h>
  27#include <net/bluetooth/hci_core.h>
  28
  29#include "ecc.h"
  30#include "smp.h"
  31#include "selftest.h"
  32
  33#if IS_ENABLED(CONFIG_BT_SELFTEST_ECDH)
  34
  35static const u8 priv_a_1[32] __initconst = {
  36        0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
  37        0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
  38        0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
  39        0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
  40};
  41static const u8 priv_b_1[32] __initconst = {
  42        0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
  43        0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
  44        0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
  45        0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55,
  46};
  47static const u8 pub_a_1[64] __initconst = {
  48        0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
  49        0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
  50        0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
  51        0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
  52
  53        0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
  54        0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
  55        0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
  56        0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
  57};
  58static const u8 pub_b_1[64] __initconst = {
  59        0x90, 0xa1, 0xaa, 0x2f, 0xb2, 0x77, 0x90, 0x55,
  60        0x9f, 0xa6, 0x15, 0x86, 0xfd, 0x8a, 0xb5, 0x47,
  61        0x00, 0x4c, 0x9e, 0xf1, 0x84, 0x22, 0x59, 0x09,
  62        0x96, 0x1d, 0xaf, 0x1f, 0xf0, 0xf0, 0xa1, 0x1e,
  63
  64        0x4a, 0x21, 0xb1, 0x15, 0xf9, 0xaf, 0x89, 0x5f,
  65        0x76, 0x36, 0x8e, 0xe2, 0x30, 0x11, 0x2d, 0x47,
  66        0x60, 0x51, 0xb8, 0x9a, 0x3a, 0x70, 0x56, 0x73,
  67        0x37, 0xad, 0x9d, 0x42, 0x3e, 0xf3, 0x55, 0x4c,
  68};
  69static const u8 dhkey_1[32] __initconst = {
  70        0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
  71        0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
  72        0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
  73        0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec,
  74};
  75
  76static const u8 priv_a_2[32] __initconst = {
  77        0x63, 0x76, 0x45, 0xd0, 0xf7, 0x73, 0xac, 0xb7,
  78        0xff, 0xdd, 0x03, 0x72, 0xb9, 0x72, 0x85, 0xb4,
  79        0x41, 0xb6, 0x5d, 0x0c, 0x5d, 0x54, 0x84, 0x60,
  80        0x1a, 0xa3, 0x9a, 0x3c, 0x69, 0x16, 0xa5, 0x06,
  81};
  82static const u8 priv_b_2[32] __initconst = {
  83        0xba, 0x30, 0x55, 0x50, 0x19, 0xa2, 0xca, 0xa3,
  84        0xa5, 0x29, 0x08, 0xc6, 0xb5, 0x03, 0x88, 0x7e,
  85        0x03, 0x2b, 0x50, 0x73, 0xd4, 0x2e, 0x50, 0x97,
  86        0x64, 0xcd, 0x72, 0x0d, 0x67, 0xa0, 0x9a, 0x52,
  87};
  88static const u8 pub_a_2[64] __initconst = {
  89        0xdd, 0x78, 0x5c, 0x74, 0x03, 0x9b, 0x7e, 0x98,
  90        0xcb, 0x94, 0x87, 0x4a, 0xad, 0xfa, 0xf8, 0xd5,
  91        0x43, 0x3e, 0x5c, 0xaf, 0xea, 0xb5, 0x4c, 0xf4,
  92        0x9e, 0x80, 0x79, 0x57, 0x7b, 0xa4, 0x31, 0x2c,
  93
  94        0x4f, 0x5d, 0x71, 0x43, 0x77, 0x43, 0xf8, 0xea,
  95        0xd4, 0x3e, 0xbd, 0x17, 0x91, 0x10, 0x21, 0xd0,
  96        0x1f, 0x87, 0x43, 0x8e, 0x40, 0xe2, 0x52, 0xcd,
  97        0xbe, 0xdf, 0x98, 0x38, 0x18, 0x12, 0x95, 0x91,
  98};
  99static const u8 pub_b_2[64] __initconst = {
 100        0xcc, 0x00, 0x65, 0xe1, 0xf5, 0x6c, 0x0d, 0xcf,
 101        0xec, 0x96, 0x47, 0x20, 0x66, 0xc9, 0xdb, 0x84,
 102        0x81, 0x75, 0xa8, 0x4d, 0xc0, 0xdf, 0xc7, 0x9d,
 103        0x1b, 0x3f, 0x3d, 0xf2, 0x3f, 0xe4, 0x65, 0xf4,
 104
 105        0x79, 0xb2, 0xec, 0xd8, 0xca, 0x55, 0xa1, 0xa8,
 106        0x43, 0x4d, 0x6b, 0xca, 0x10, 0xb0, 0xc2, 0x01,
 107        0xc2, 0x33, 0x4e, 0x16, 0x24, 0xc4, 0xef, 0xee,
 108        0x99, 0xd8, 0xbb, 0xbc, 0x48, 0xd0, 0x01, 0x02,
 109};
 110static const u8 dhkey_2[32] __initconst = {
 111        0x69, 0xeb, 0x21, 0x32, 0xf2, 0xc6, 0x05, 0x41,
 112        0x60, 0x19, 0xcd, 0x5e, 0x94, 0xe1, 0xe6, 0x5f,
 113        0x33, 0x07, 0xe3, 0x38, 0x4b, 0x68, 0xe5, 0x62,
 114        0x3f, 0x88, 0x6d, 0x2f, 0x3a, 0x84, 0x85, 0xab,
 115};
 116
 117static const u8 priv_a_3[32] __initconst = {
 118        0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
 119        0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
 120        0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
 121        0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
 122};
 123static const u8 pub_a_3[64] __initconst = {
 124        0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
 125        0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
 126        0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
 127        0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
 128
 129        0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
 130        0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
 131        0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
 132        0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
 133};
 134static const u8 dhkey_3[32] __initconst = {
 135        0x2d, 0xab, 0x00, 0x48, 0xcb, 0xb3, 0x7b, 0xda,
 136        0x55, 0x7b, 0x8b, 0x72, 0xa8, 0x57, 0x87, 0xc3,
 137        0x87, 0x27, 0x99, 0x32, 0xfc, 0x79, 0x5f, 0xae,
 138        0x7c, 0x1c, 0xf9, 0x49, 0xe6, 0xd7, 0xaa, 0x70,
 139};
 140
 141static int __init test_ecdh_sample(const u8 priv_a[32], const u8 priv_b[32],
 142                                   const u8 pub_a[64], const u8 pub_b[64],
 143                                   const u8 dhkey[32])
 144{
 145        u8 dhkey_a[32], dhkey_b[32];
 146
 147        ecdh_shared_secret(pub_b, priv_a, dhkey_a);
 148        ecdh_shared_secret(pub_a, priv_b, dhkey_b);
 149
 150        if (memcmp(dhkey_a, dhkey, 32))
 151                return -EINVAL;
 152
 153        if (memcmp(dhkey_b, dhkey, 32))
 154                return -EINVAL;
 155
 156        return 0;
 157}
 158
 159static char test_ecdh_buffer[32];
 160
 161static ssize_t test_ecdh_read(struct file *file, char __user *user_buf,
 162                              size_t count, loff_t *ppos)
 163{
 164        return simple_read_from_buffer(user_buf, count, ppos, test_ecdh_buffer,
 165                                       strlen(test_ecdh_buffer));
 166}
 167
 168static const struct file_operations test_ecdh_fops = {
 169        .open           = simple_open,
 170        .read           = test_ecdh_read,
 171        .llseek         = default_llseek,
 172};
 173
 174static int __init test_ecdh(void)
 175{
 176        ktime_t calltime, delta, rettime;
 177        unsigned long long duration;
 178        int err;
 179
 180        calltime = ktime_get();
 181
 182        err = test_ecdh_sample(priv_a_1, priv_b_1, pub_a_1, pub_b_1, dhkey_1);
 183        if (err) {
 184                BT_ERR("ECDH sample 1 failed");
 185                goto done;
 186        }
 187
 188        err = test_ecdh_sample(priv_a_2, priv_b_2, pub_a_2, pub_b_2, dhkey_2);
 189        if (err) {
 190                BT_ERR("ECDH sample 2 failed");
 191                goto done;
 192        }
 193
 194        err = test_ecdh_sample(priv_a_3, priv_a_3, pub_a_3, pub_a_3, dhkey_3);
 195        if (err) {
 196                BT_ERR("ECDH sample 3 failed");
 197                goto done;
 198        }
 199
 200        rettime = ktime_get();
 201        delta = ktime_sub(rettime, calltime);
 202        duration = (unsigned long long) ktime_to_ns(delta) >> 10;
 203
 204        BT_INFO("ECDH test passed in %llu usecs", duration);
 205
 206done:
 207        if (!err)
 208                snprintf(test_ecdh_buffer, sizeof(test_ecdh_buffer),
 209                         "PASS (%llu usecs)\n", duration);
 210        else
 211                snprintf(test_ecdh_buffer, sizeof(test_ecdh_buffer), "FAIL\n");
 212
 213        debugfs_create_file("selftest_ecdh", 0444, bt_debugfs, NULL,
 214                            &test_ecdh_fops);
 215
 216        return err;
 217}
 218
 219#else
 220
 221static inline int test_ecdh(void)
 222{
 223        return 0;
 224}
 225
 226#endif
 227
 228static int __init run_selftest(void)
 229{
 230        int err;
 231
 232        BT_INFO("Starting self testing");
 233
 234        err = test_ecdh();
 235        if (err)
 236                goto done;
 237
 238        err = bt_selftest_smp();
 239
 240done:
 241        BT_INFO("Finished self testing");
 242
 243        return err;
 244}
 245
 246#if IS_MODULE(CONFIG_BT)
 247
 248/* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=m and is just a
 249 * wrapper to allow running this at module init.
 250 *
 251 * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all.
 252 */
 253int __init bt_selftest(void)
 254{
 255        return run_selftest();
 256}
 257
 258#else
 259
 260/* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=y and is run
 261 * via late_initcall() as last item in the initialization sequence.
 262 *
 263 * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all.
 264 */
 265static int __init bt_selftest_init(void)
 266{
 267        return run_selftest();
 268}
 269late_initcall(bt_selftest_init);
 270
 271#endif
 272