diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2014-02-18 03:19:31 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-02-18 03:47:02 -0500 |
commit | 60478054a6af7aa8cceb8218d29d27f165f1c9d3 (patch) | |
tree | cf713df16202dade0f90d6c00fd6eb8dd2d24592 /net/bluetooth/smp.c | |
parent | 6bfdfe3cd68d5a797e0ebfb57068fe7f9c20c93a (diff) |
Bluetooth: Add smp_irk_matches helper function
This patch adds a helper function to check whether a given IRK matches a
given Resolvable Private Address (RPA). The function will be needed for
implementing the rest of address resolving support.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r-- | net/bluetooth/smp.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index ae487e17380e..5f500b479f45 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -78,6 +78,52 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) | |||
78 | return err; | 78 | return err; |
79 | } | 79 | } |
80 | 80 | ||
81 | static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3]) | ||
82 | { | ||
83 | u8 _res[16], k[16]; | ||
84 | int err; | ||
85 | |||
86 | /* r' = padding || r */ | ||
87 | memset(_res, 0, 13); | ||
88 | _res[13] = r[2]; | ||
89 | _res[14] = r[1]; | ||
90 | _res[15] = r[0]; | ||
91 | |||
92 | swap128(irk, k); | ||
93 | err = smp_e(tfm, k, _res); | ||
94 | if (err) { | ||
95 | BT_ERR("Encrypt error"); | ||
96 | return err; | ||
97 | } | ||
98 | |||
99 | /* The output of the random address function ah is: | ||
100 | * ah(h, r) = e(k, r') mod 2^24 | ||
101 | * The output of the security function e is then truncated to 24 bits | ||
102 | * by taking the least significant 24 bits of the output of e as the | ||
103 | * result of ah. | ||
104 | */ | ||
105 | res[0] = _res[15]; | ||
106 | res[1] = _res[14]; | ||
107 | res[2] = _res[13]; | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16], | ||
113 | bdaddr_t *bdaddr) | ||
114 | { | ||
115 | u8 hash[3]; | ||
116 | int err; | ||
117 | |||
118 | BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk); | ||
119 | |||
120 | err = smp_ah(tfm, irk, &bdaddr->b[3], hash); | ||
121 | if (err) | ||
122 | return false; | ||
123 | |||
124 | return !memcmp(bdaddr->b, hash, 3); | ||
125 | } | ||
126 | |||
81 | static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16], | 127 | static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16], |
82 | u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, | 128 | u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, |
83 | u8 _rat, bdaddr_t *ra, u8 res[16]) | 129 | u8 _rat, bdaddr_t *ra, u8 res[16]) |