Back to home page

OSCL-LXR

 
 

    


0001 /*
0002    BlueZ - Bluetooth protocol stack for Linux
0003 
0004    Copyright (C) 2014 Intel Corporation
0005 
0006    This program is free software; you can redistribute it and/or modify
0007    it under the terms of the GNU General Public License version 2 as
0008    published by the Free Software Foundation;
0009 
0010    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0011    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0012    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
0013    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
0014    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
0015    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0016    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0017    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0018 
0019    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
0020    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
0021    SOFTWARE IS DISCLAIMED.
0022 */
0023 
0024 #include <linux/debugfs.h>
0025 
0026 #include <net/bluetooth/bluetooth.h>
0027 #include <net/bluetooth/hci_core.h>
0028 
0029 #include "ecdh_helper.h"
0030 #include "smp.h"
0031 #include "selftest.h"
0032 
0033 #if IS_ENABLED(CONFIG_BT_SELFTEST_ECDH)
0034 
0035 static const u8 priv_a_1[32] __initconst = {
0036     0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
0037     0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
0038     0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
0039     0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
0040 };
0041 static const u8 priv_b_1[32] __initconst = {
0042     0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
0043     0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
0044     0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
0045     0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55,
0046 };
0047 static const u8 pub_a_1[64] __initconst = {
0048     0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
0049     0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
0050     0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
0051     0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
0052 
0053     0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
0054     0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
0055     0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
0056     0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
0057 };
0058 static const u8 pub_b_1[64] __initconst = {
0059     0x90, 0xa1, 0xaa, 0x2f, 0xb2, 0x77, 0x90, 0x55,
0060     0x9f, 0xa6, 0x15, 0x86, 0xfd, 0x8a, 0xb5, 0x47,
0061     0x00, 0x4c, 0x9e, 0xf1, 0x84, 0x22, 0x59, 0x09,
0062     0x96, 0x1d, 0xaf, 0x1f, 0xf0, 0xf0, 0xa1, 0x1e,
0063 
0064     0x4a, 0x21, 0xb1, 0x15, 0xf9, 0xaf, 0x89, 0x5f,
0065     0x76, 0x36, 0x8e, 0xe2, 0x30, 0x11, 0x2d, 0x47,
0066     0x60, 0x51, 0xb8, 0x9a, 0x3a, 0x70, 0x56, 0x73,
0067     0x37, 0xad, 0x9d, 0x42, 0x3e, 0xf3, 0x55, 0x4c,
0068 };
0069 static const u8 dhkey_1[32] __initconst = {
0070     0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
0071     0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
0072     0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
0073     0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec,
0074 };
0075 
0076 static const u8 priv_a_2[32] __initconst = {
0077     0x63, 0x76, 0x45, 0xd0, 0xf7, 0x73, 0xac, 0xb7,
0078     0xff, 0xdd, 0x03, 0x72, 0xb9, 0x72, 0x85, 0xb4,
0079     0x41, 0xb6, 0x5d, 0x0c, 0x5d, 0x54, 0x84, 0x60,
0080     0x1a, 0xa3, 0x9a, 0x3c, 0x69, 0x16, 0xa5, 0x06,
0081 };
0082 static const u8 priv_b_2[32] __initconst = {
0083     0xba, 0x30, 0x55, 0x50, 0x19, 0xa2, 0xca, 0xa3,
0084     0xa5, 0x29, 0x08, 0xc6, 0xb5, 0x03, 0x88, 0x7e,
0085     0x03, 0x2b, 0x50, 0x73, 0xd4, 0x2e, 0x50, 0x97,
0086     0x64, 0xcd, 0x72, 0x0d, 0x67, 0xa0, 0x9a, 0x52,
0087 };
0088 static const u8 pub_a_2[64] __initconst = {
0089     0xdd, 0x78, 0x5c, 0x74, 0x03, 0x9b, 0x7e, 0x98,
0090     0xcb, 0x94, 0x87, 0x4a, 0xad, 0xfa, 0xf8, 0xd5,
0091     0x43, 0x3e, 0x5c, 0xaf, 0xea, 0xb5, 0x4c, 0xf4,
0092     0x9e, 0x80, 0x79, 0x57, 0x7b, 0xa4, 0x31, 0x2c,
0093 
0094     0x4f, 0x5d, 0x71, 0x43, 0x77, 0x43, 0xf8, 0xea,
0095     0xd4, 0x3e, 0xbd, 0x17, 0x91, 0x10, 0x21, 0xd0,
0096     0x1f, 0x87, 0x43, 0x8e, 0x40, 0xe2, 0x52, 0xcd,
0097     0xbe, 0xdf, 0x98, 0x38, 0x18, 0x12, 0x95, 0x91,
0098 };
0099 static const u8 pub_b_2[64] __initconst = {
0100     0xcc, 0x00, 0x65, 0xe1, 0xf5, 0x6c, 0x0d, 0xcf,
0101     0xec, 0x96, 0x47, 0x20, 0x66, 0xc9, 0xdb, 0x84,
0102     0x81, 0x75, 0xa8, 0x4d, 0xc0, 0xdf, 0xc7, 0x9d,
0103     0x1b, 0x3f, 0x3d, 0xf2, 0x3f, 0xe4, 0x65, 0xf4,
0104 
0105     0x79, 0xb2, 0xec, 0xd8, 0xca, 0x55, 0xa1, 0xa8,
0106     0x43, 0x4d, 0x6b, 0xca, 0x10, 0xb0, 0xc2, 0x01,
0107     0xc2, 0x33, 0x4e, 0x16, 0x24, 0xc4, 0xef, 0xee,
0108     0x99, 0xd8, 0xbb, 0xbc, 0x48, 0xd0, 0x01, 0x02,
0109 };
0110 static const u8 dhkey_2[32] __initconst = {
0111     0x69, 0xeb, 0x21, 0x32, 0xf2, 0xc6, 0x05, 0x41,
0112     0x60, 0x19, 0xcd, 0x5e, 0x94, 0xe1, 0xe6, 0x5f,
0113     0x33, 0x07, 0xe3, 0x38, 0x4b, 0x68, 0xe5, 0x62,
0114     0x3f, 0x88, 0x6d, 0x2f, 0x3a, 0x84, 0x85, 0xab,
0115 };
0116 
0117 static const u8 priv_a_3[32] __initconst = {
0118     0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
0119     0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
0120     0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
0121     0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
0122 };
0123 static const u8 pub_a_3[64] __initconst = {
0124     0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
0125     0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
0126     0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
0127     0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
0128 
0129     0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
0130     0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
0131     0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
0132     0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
0133 };
0134 static const u8 dhkey_3[32] __initconst = {
0135     0x2d, 0xab, 0x00, 0x48, 0xcb, 0xb3, 0x7b, 0xda,
0136     0x55, 0x7b, 0x8b, 0x72, 0xa8, 0x57, 0x87, 0xc3,
0137     0x87, 0x27, 0x99, 0x32, 0xfc, 0x79, 0x5f, 0xae,
0138     0x7c, 0x1c, 0xf9, 0x49, 0xe6, 0xd7, 0xaa, 0x70,
0139 };
0140 
0141 static int __init test_ecdh_sample(struct crypto_kpp *tfm, const u8 priv_a[32],
0142                    const u8 priv_b[32], const u8 pub_a[64],
0143                    const u8 pub_b[64], const u8 dhkey[32])
0144 {
0145     u8 *tmp, *dhkey_a, *dhkey_b;
0146     int ret;
0147 
0148     tmp = kmalloc(64, GFP_KERNEL);
0149     if (!tmp)
0150         return -EINVAL;
0151 
0152     dhkey_a = &tmp[0];
0153     dhkey_b = &tmp[32];
0154 
0155     ret = set_ecdh_privkey(tfm, priv_a);
0156     if (ret)
0157         goto out;
0158 
0159     ret = compute_ecdh_secret(tfm, pub_b, dhkey_a);
0160     if (ret)
0161         goto out;
0162 
0163     if (memcmp(dhkey_a, dhkey, 32)) {
0164         ret = -EINVAL;
0165         goto out;
0166     }
0167 
0168     ret = set_ecdh_privkey(tfm, priv_b);
0169     if (ret)
0170         goto out;
0171 
0172     ret = compute_ecdh_secret(tfm, pub_a, dhkey_b);
0173     if (ret)
0174         goto out;
0175 
0176     if (memcmp(dhkey_b, dhkey, 32))
0177         ret = -EINVAL;
0178     /* fall through*/
0179 out:
0180     kfree(tmp);
0181     return ret;
0182 }
0183 
0184 static char test_ecdh_buffer[32];
0185 
0186 static ssize_t test_ecdh_read(struct file *file, char __user *user_buf,
0187                   size_t count, loff_t *ppos)
0188 {
0189     return simple_read_from_buffer(user_buf, count, ppos, test_ecdh_buffer,
0190                        strlen(test_ecdh_buffer));
0191 }
0192 
0193 static const struct file_operations test_ecdh_fops = {
0194     .open       = simple_open,
0195     .read       = test_ecdh_read,
0196     .llseek     = default_llseek,
0197 };
0198 
0199 static int __init test_ecdh(void)
0200 {
0201     struct crypto_kpp *tfm;
0202     ktime_t calltime, delta, rettime;
0203     unsigned long long duration = 0;
0204     int err;
0205 
0206     calltime = ktime_get();
0207 
0208     tfm = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
0209     if (IS_ERR(tfm)) {
0210         BT_ERR("Unable to create ECDH crypto context");
0211         err = PTR_ERR(tfm);
0212         goto done;
0213     }
0214 
0215     err = test_ecdh_sample(tfm, priv_a_1, priv_b_1, pub_a_1, pub_b_1,
0216                    dhkey_1);
0217     if (err) {
0218         BT_ERR("ECDH sample 1 failed");
0219         goto done;
0220     }
0221 
0222     err = test_ecdh_sample(tfm, priv_a_2, priv_b_2, pub_a_2, pub_b_2,
0223                    dhkey_2);
0224     if (err) {
0225         BT_ERR("ECDH sample 2 failed");
0226         goto done;
0227     }
0228 
0229     err = test_ecdh_sample(tfm, priv_a_3, priv_a_3, pub_a_3, pub_a_3,
0230                    dhkey_3);
0231     if (err) {
0232         BT_ERR("ECDH sample 3 failed");
0233         goto done;
0234     }
0235 
0236     crypto_free_kpp(tfm);
0237 
0238     rettime = ktime_get();
0239     delta = ktime_sub(rettime, calltime);
0240     duration = (unsigned long long) ktime_to_ns(delta) >> 10;
0241 
0242     BT_INFO("ECDH test passed in %llu usecs", duration);
0243 
0244 done:
0245     if (!err)
0246         snprintf(test_ecdh_buffer, sizeof(test_ecdh_buffer),
0247              "PASS (%llu usecs)\n", duration);
0248     else
0249         snprintf(test_ecdh_buffer, sizeof(test_ecdh_buffer), "FAIL\n");
0250 
0251     debugfs_create_file("selftest_ecdh", 0444, bt_debugfs, NULL,
0252                 &test_ecdh_fops);
0253 
0254     return err;
0255 }
0256 
0257 #else
0258 
0259 static inline int test_ecdh(void)
0260 {
0261     return 0;
0262 }
0263 
0264 #endif
0265 
0266 static int __init run_selftest(void)
0267 {
0268     int err;
0269 
0270     BT_INFO("Starting self testing");
0271 
0272     err = test_ecdh();
0273     if (err)
0274         goto done;
0275 
0276     err = bt_selftest_smp();
0277 
0278 done:
0279     BT_INFO("Finished self testing");
0280 
0281     return err;
0282 }
0283 
0284 #if IS_MODULE(CONFIG_BT)
0285 
0286 /* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=m and is just a
0287  * wrapper to allow running this at module init.
0288  *
0289  * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all.
0290  */
0291 int __init bt_selftest(void)
0292 {
0293     return run_selftest();
0294 }
0295 
0296 #else
0297 
0298 /* This is run when CONFIG_BT_SELFTEST=y and CONFIG_BT=y and is run
0299  * via late_initcall() as last item in the initialization sequence.
0300  *
0301  * If CONFIG_BT_SELFTEST=n, then this code is not compiled at all.
0302  */
0303 static int __init bt_selftest_init(void)
0304 {
0305     return run_selftest();
0306 }
0307 late_initcall(bt_selftest_init);
0308 
0309 #endif