Changeset 1dcc0b9 in mainline for uspace/lib/ieee80211/src/ieee80211_impl.c
- Timestamp:
- 2015-04-06T10:47:51Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d7dadcb4
- Parents:
- 59fa7ab
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ieee80211/src/ieee80211_impl.c
r59fa7ab r1dcc0b9 36 36 */ 37 37 38 #include <stdio.h> 39 #include <crypto.h> 40 #include <stdlib.h> 38 41 #include <errno.h> 39 42 … … 81 84 82 85 /** 86 * Default implementation of IEEE802.11 BSSID change function. 87 * 88 * @param ieee80211_dev Structure of IEEE802.11 device. 89 * 90 * @return EOK. 91 */ 92 int ieee80211_bssid_change_impl(ieee80211_dev_t *ieee80211_dev) 93 { 94 return EOK; 95 } 96 97 /** 98 * Default implementation of IEEE802.11 key config function. 99 * 100 * @param ieee80211_dev Structure of IEEE802.11 device. 101 * 102 * @return EOK. 103 */ 104 int ieee80211_key_config_impl(ieee80211_dev_t *ieee80211_dev, 105 ieee80211_key_config_t *key_conf, bool insert) 106 { 107 return EOK; 108 } 109 110 /** 83 111 * Default implementation of IEEE802.11 scan function. 84 112 * 85 113 * @param ieee80211_dev Structure of IEEE802.11 device. 86 * @param results Pointer to structure where should be scan results stored.114 * @param clear Whether to clear current scan results. 87 115 * 88 116 * @return EOK if succeed, negative error code otherwise. … … 90 118 int ieee80211_scan_impl(ieee80211_dev_t *ieee80211_dev) 91 119 { 120 if(ieee80211_is_connected(ieee80211_dev)) 121 return EOK; 122 123 fibril_mutex_lock(&ieee80211_dev->ap_list.scan_mutex); 124 125 /* Remove old entries we don't receive beacons from. */ 126 ieee80211_scan_result_list_t *result_list = 127 &ieee80211_dev->ap_list; 128 list_foreach_safe(result_list->list, cur_link, next_link) { 129 ieee80211_scan_result_link_t *cur_result = 130 list_get_instance(cur_link, 131 ieee80211_scan_result_link_t, 132 link); 133 if((time(NULL) - cur_result->last_beacon) > 134 MAX_KEEP_SCAN_SPAN_SEC) { 135 ieee80211_scan_result_list_remove(result_list, 136 cur_result); 137 } 138 } 139 140 fibril_mutex_unlock(&ieee80211_dev->ap_list.scan_mutex); 141 92 142 uint16_t orig_freq = ieee80211_dev->current_freq; 93 143 … … 96 146 freq += IEEE80211_CHANNEL_GAP) { 97 147 ieee80211_dev->ops->set_freq(ieee80211_dev, freq); 98 ieee80211_probe_request(ieee80211_dev );148 ieee80211_probe_request(ieee80211_dev, NULL); 99 149 100 150 /* Wait for probe responses. */ … … 104 154 ieee80211_dev->ops->set_freq(ieee80211_dev, orig_freq); 105 155 106 return EOK; 156 fibril_mutex_lock(&ieee80211_dev->ap_list.scan_mutex); 157 time(&ieee80211_dev->ap_list.last_scan); 158 fibril_mutex_unlock(&ieee80211_dev->ap_list.scan_mutex); 159 160 return EOK; 161 } 162 163 /** 164 * Pseudorandom function used for IEEE 802.11 pairwise key computation. 165 * 166 * @param key Key with PBKDF2 encrypted passphrase. 167 * @param data Concatenated sequence of both mac addresses and nonces. 168 * @param hash Output parameter for result hash (48 byte value). 169 * @param hash_sel Hash function selector. 170 * 171 * @return EINVAL when key or data not specified, ENOMEM when pointer for 172 * output hash result is not allocated, otherwise EOK. 173 */ 174 int ieee80211_prf(uint8_t *key, uint8_t *data, uint8_t *hash, 175 hash_func_t hash_sel) 176 { 177 if(!key || !data) 178 return EINVAL; 179 180 if(!hash) 181 return ENOMEM; 182 183 size_t hash_length, result_length; 184 switch(hash_sel) { 185 case HASH_MD5: 186 hash_length = MD5_HASH_LENGTH; 187 result_length = IEEE80211_PTK_TKIP_LENGTH; 188 break; 189 case HASH_SHA1: 190 hash_length = SHA1_HASH_LENGTH; 191 result_length = IEEE80211_PTK_CCMP_LENGTH; 192 break; 193 default: 194 hash_length = 0; 195 result_length = 0; 196 } 197 198 size_t iters = ((result_length * 8) + 159) / 160; 199 200 const char *a = "Pairwise key expansion"; 201 uint8_t result[hash_length*iters]; 202 uint8_t temp[hash_length]; 203 size_t data_size = PRF_CRYPT_DATA_LENGTH + str_size(a) + 2; 204 uint8_t work_arr[data_size]; 205 memset(work_arr, 0, data_size); 206 207 memcpy(work_arr, a, str_size(a)); 208 memcpy(work_arr + str_size(a) + 1, data, PRF_CRYPT_DATA_LENGTH); 209 210 for(uint8_t i = 0; i < iters; i++) { 211 memcpy(work_arr + data_size - 1, &i, 1); 212 hmac(key, PBKDF2_KEY_LENGTH, work_arr, data_size, temp, 213 hash_sel); 214 memcpy(result + i*hash_length, temp, hash_length); 215 } 216 217 memcpy(hash, result, result_length); 218 219 return EOK; 220 } 221 222 int ieee80211_aes_key_unwrap(uint8_t *kek, uint8_t *data, size_t data_size, 223 uint8_t *output) 224 { 225 if(!kek || !data) 226 return EINVAL; 227 228 if(!output) 229 return ENOMEM; 230 231 uint32_t n = data_size/8 - 1; 232 uint8_t work_data[n*8]; 233 uint8_t work_input[AES_CIPHER_LENGTH]; 234 uint8_t work_output[AES_CIPHER_LENGTH]; 235 uint8_t *work_block; 236 uint8_t a[8]; 237 memcpy(a, data, 8); 238 uint64_t mask = 0xFF; 239 uint8_t shift, shb; 240 241 memcpy(work_data, data + 8, n*8); 242 for(int j = 5; j >=0; j--) { 243 for(int i = n; i > 0; i--) { 244 for(size_t k = 0; k < 8; k++) { 245 shift = 56 - 8*k; 246 shb = ((n*j+i) & (mask << shift)) >> shift; 247 a[k] ^= shb; 248 } 249 work_block = work_data + (i-1)*8; 250 memcpy(work_input, a, 8); 251 memcpy(work_input + 8, work_block, 8); 252 aes_decrypt(kek, work_input, work_output); 253 memcpy(a, work_output, 8); 254 memcpy(work_data + (i-1)*8, work_output + 8, 8); 255 } 256 } 257 258 size_t it; 259 for(it = 0; it < 8; it++) { 260 if(a[it] != 0xA6) 261 break; 262 } 263 264 if(it == 8) { 265 memcpy(output, work_data, n*8); 266 return EOK; 267 } else { 268 return EINVAL; 269 } 270 } 271 272 int rnd_sequence(uint8_t *sequence, size_t length) 273 { 274 if(!sequence) 275 return ENOMEM; 276 277 for(size_t i = 0; i < length; i++) { 278 sequence[i] = (uint8_t) rand(); 279 } 280 281 return EOK; 282 } 283 284 uint8_t *min_sequence(uint8_t *seq1, uint8_t *seq2, size_t size) 285 { 286 if(!seq1 || !seq2) 287 return NULL; 288 289 for(size_t i = 0; i < size; i++) { 290 if(seq1[i] < seq2[i]) { 291 return seq1; 292 } else if(seq1[i] > seq2[i]) { 293 return seq2; 294 } 295 } 296 297 return seq1; 298 } 299 300 uint8_t *max_sequence(uint8_t *seq1, uint8_t *seq2, size_t size) 301 { 302 uint8_t *min = min_sequence(seq1, seq2, size); 303 if(min == seq1) { 304 return seq2; 305 } else { 306 return seq1; 307 } 107 308 } 108 309
Note:
See TracChangeset
for help on using the changeset viewer.