Changeset 8a64320e in mainline for uspace/lib
- Timestamp:
- 2015-04-23T23:40:14Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- dcba819
- Parents:
- 09044cb
- Location:
- uspace/lib
- Files:
-
- 16 edited
-
c/include/ieee80211/ieee80211.h (modified) (2 diffs)
-
crypto/aes.c (modified) (20 diffs)
-
crypto/crypto.c (modified) (12 diffs)
-
crypto/crypto.h (modified) (1 diff)
-
crypto/rc4.c (modified) (5 diffs)
-
drv/generic/remote_ieee80211.c (modified) (15 diffs)
-
drv/include/ieee80211_iface.h (modified) (2 diffs)
-
drv/include/ops/ieee80211.h (modified) (1 diff)
-
ieee80211/Makefile (modified) (1 diff)
-
ieee80211/include/ieee80211.h (modified) (4 diffs)
-
ieee80211/include/ieee80211_iface_impl.h (modified) (2 diffs)
-
ieee80211/include/ieee80211_impl.h (modified) (2 diffs)
-
ieee80211/include/ieee80211_private.h (modified) (12 diffs)
-
ieee80211/src/ieee80211.c (modified) (67 diffs)
-
ieee80211/src/ieee80211_iface_impl.c (modified) (9 diffs)
-
ieee80211/src/ieee80211_impl.c (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/include/ieee80211/ieee80211.h
r09044cb r8a64320e 44 44 45 45 /** Max length of scan results array. */ 46 #define IEEE80211_MAX_RESULTS_LENGTH 3246 #define IEEE80211_MAX_RESULTS_LENGTH 32 47 47 48 48 /** Max SSID length including null character. */ 49 #define IEEE80211_MAX_SSID_LENGTH 3549 #define IEEE80211_MAX_SSID_LENGTH 35 50 50 51 51 /** WiFi security authentication method indicator. */ … … 97 97 /** @} 98 98 */ 99 -
uspace/lib/crypto/aes.c
r09044cb r8a64320e 28 28 29 29 /** @file aes.c 30 * 30 * 31 31 * Implementation of AES-128 symmetric cipher cryptographic algorithm. 32 * 32 * 33 33 * Based on FIPS 197. 34 34 */ … … 37 37 #include <errno.h> 38 38 #include <mem.h> 39 40 39 #include "crypto.h" 41 40 42 41 /* Number of elements in rows/columns in AES arrays. */ 43 #define ELEMS 442 #define ELEMS 4 44 43 45 44 /* Number of elements (words) in cipher. */ 46 #define CIPHER_ELEMS 445 #define CIPHER_ELEMS 4 47 46 48 47 /* Length of AES block. */ 49 #define BLOCK_LEN 1648 #define BLOCK_LEN 16 50 49 51 50 /* Number of iterations in AES algorithm. */ 52 #define ROUNDS 10 53 54 /* 55 * Irreducible polynomial used in AES algorithm. 56 * 51 #define ROUNDS 10 52 53 /** Irreducible polynomial used in AES algorithm. 54 * 57 55 * NOTE: x^8 + x^4 + x^3 + x + 1. 58 */ 59 #define AES_IP 0x1B 60 61 /* Precomputed values for AES sub_byte transformation. */ 56 * 57 */ 58 #define AES_IP 0x1b 59 60 /** Precomputed values for AES sub_byte transformation. */ 62 61 static const uint8_t sbox[BLOCK_LEN][BLOCK_LEN] = { 63 62 { 64 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 63 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 65 64 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 66 65 }, 67 66 { 68 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 67 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 69 68 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 70 69 }, … … 74 73 }, 75 74 { 76 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 75 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 77 76 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 78 77 }, 79 78 { 80 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 79 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 81 80 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 82 81 }, 83 82 { 84 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 83 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 85 84 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf 86 85 }, 87 86 { 88 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 87 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 89 88 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 90 89 }, 91 90 { 92 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 91 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 93 92 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 94 93 }, 95 94 { 96 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 95 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 97 96 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 98 97 }, 99 98 { 100 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 99 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 101 100 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb 102 101 }, 103 102 { 104 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 103 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 105 104 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 106 105 }, 107 106 { 108 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 107 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 109 108 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 110 109 }, 111 110 { 112 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 111 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 113 112 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a 114 113 }, 115 114 { 116 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 115 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 117 116 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e 118 117 }, 119 118 { 120 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 119 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 121 120 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf 122 121 }, 123 122 { 124 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 123 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 125 124 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 126 125 } 127 126 }; 128 127 129 /* Precomputed values for AES inv_sub_byte transformation. */128 /** Precomputed values for AES inv_sub_byte transformation. */ 130 129 static uint8_t inv_sbox[BLOCK_LEN][BLOCK_LEN] = { 131 130 { 132 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 131 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 133 132 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb 134 133 }, 135 134 { 136 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 135 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 137 136 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb 138 137 }, 139 138 { 140 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 139 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 141 140 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e 142 141 }, 143 142 { 144 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 143 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 145 144 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 146 145 }, 147 146 { 148 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 147 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 149 148 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 150 149 }, 151 150 { 152 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 151 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 153 152 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 154 153 }, 155 154 { 156 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 155 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 157 156 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 158 157 }, 159 158 { 160 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 159 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 161 160 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b 162 161 }, 163 162 { 164 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 163 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 165 164 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 166 165 }, 167 166 { 168 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 167 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 169 168 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e 170 169 }, 171 170 { 172 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 171 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 173 172 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b 174 173 }, 175 174 { 176 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 175 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 177 176 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 178 177 }, 179 178 { 180 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 179 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 181 180 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f 182 181 }, 183 182 { 184 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 183 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 185 184 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef 186 185 }, 187 186 { 188 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 187 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 189 188 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 190 189 }, 191 190 { 192 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 191 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 193 192 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d 194 193 } 195 194 }; 196 195 197 /* Precomputed values of powers of 2 in GF(2^8) left shifted by 24b. */196 /** Precomputed values of powers of 2 in GF(2^8) left shifted by 24b. */ 198 197 static const uint32_t r_con_array[] = { 199 0x01000000, 0x02000000, 0x04000000, 0x08000000,198 0x01000000, 0x02000000, 0x04000000, 0x08000000, 200 199 0x10000000, 0x20000000, 0x40000000, 0x80000000, 201 0x1 B000000, 0x36000000200 0x1b000000, 0x36000000 202 201 }; 203 202 204 /** 205 * Perform substitution transformation on given byte. 206 * 203 /** Perform substitution transformation on given byte. 204 * 207 205 * @param byte Input byte. 208 * @param inv Flag indicating whether to use inverse table.209 * 206 * @param inv Flag indicating whether to use inverse table. 207 * 210 208 * @return Substituted value. 209 * 211 210 */ 212 211 static uint8_t sub_byte(uint8_t byte, bool inv) … … 215 214 uint8_t j = byte & 0xF; 216 215 217 if (!inv) {216 if (!inv) 218 217 return sbox[i][j]; 219 } else { 220 return inv_sbox[i][j]; 221 } 222 } 223 224 /** 225 * Perform substitution transformation on state table. 226 * 218 219 return inv_sbox[i][j]; 220 } 221 222 /** Perform substitution transformation on state table. 223 * 227 224 * @param state State table to be modified. 228 * @param inv Flag indicating whether to use inverse table. 225 * @param inv Flag indicating whether to use inverse table. 226 * 229 227 */ 230 228 static void sub_bytes(uint8_t state[ELEMS][ELEMS], bool inv) … … 232 230 uint8_t val; 233 231 234 for (size_t i = 0; i < ELEMS; i++) {235 for (size_t j = 0; j < ELEMS; j++) {232 for (size_t i = 0; i < ELEMS; i++) { 233 for (size_t j = 0; j < ELEMS; j++) { 236 234 val = state[i][j]; 237 235 state[i][j] = sub_byte(val, inv); … … 240 238 } 241 239 242 /** 243 * Perform shift rows transformation on state table. 244 * 240 /** Perform shift rows transformation on state table. 241 * 245 242 * @param state State table to be modified. 243 * 246 244 */ 247 245 static void shift_rows(uint8_t state[ELEMS][ELEMS]) … … 249 247 uint8_t temp[ELEMS]; 250 248 251 for (size_t i = 1; i < ELEMS; i++) {249 for (size_t i = 1; i < ELEMS; i++) { 252 250 memcpy(temp, state[i], i); 253 251 memcpy(state[i], state[i] + i, ELEMS - i); … … 256 254 } 257 255 258 /** 259 * Perform inverted shift rows transformation on state table. 260 * 256 /** Perform inverted shift rows transformation on state table. 257 * 261 258 * @param state State table to be modified. 259 * 262 260 */ 263 261 static void inv_shift_rows(uint8_t state[ELEMS][ELEMS]) … … 265 263 uint8_t temp[ELEMS]; 266 264 267 for (size_t i = 1; i < ELEMS; i++) {265 for (size_t i = 1; i < ELEMS; i++) { 268 266 memcpy(temp, state[i], ELEMS - i); 269 267 memcpy(state[i], state[i] + ELEMS - i, i); … … 272 270 } 273 271 274 /** 275 * Multiplication in GF(2^8). 276 * 272 /** Multiplication in GF(2^8). 273 * 277 274 * @param x First factor. 278 275 * @param y Second factor. 279 * 276 * 280 277 * @return Multiplication of given factors in GF(2^8). 281 */ 282 static uint8_t galois_mult(uint8_t x, uint8_t y) { 283 uint8_t result = 0; 284 uint8_t F_bitH; 285 286 for(size_t i = 0; i < 8; i++) { 287 if (y & 1) 278 * 279 */ 280 static uint8_t galois_mult(uint8_t x, uint8_t y) 281 { 282 uint8_t result = 0; 283 uint8_t f_bith; 284 285 for (size_t i = 0; i < 8; i++) { 286 if (y & 1) 288 287 result ^= x; 289 F_bitH = (x & 0x80); 290 x <<= 1; 291 if (F_bitH) 292 x ^= AES_IP; 293 y >>= 1; 294 } 295 296 return result; 297 } 298 299 /** 300 * Perform mix columns transformation on state table. 301 * 288 289 f_bith = (x & 0x80); 290 x <<= 1; 291 292 if (f_bith) 293 x ^= AES_IP; 294 295 y >>= 1; 296 } 297 298 return result; 299 } 300 301 /** Perform mix columns transformation on state table. 302 * 302 303 * @param state State table to be modified. 304 * 303 305 */ 304 306 static void mix_columns(uint8_t state[ELEMS][ELEMS]) … … 307 309 memcpy(orig_state, state, BLOCK_LEN); 308 310 309 for(size_t j = 0; j < ELEMS; j++) { 310 state[0][j] = 311 galois_mult(0x2, orig_state[0][j]) ^ 312 galois_mult(0x3, orig_state[1][j]) ^ 313 orig_state[2][j] ^ 314 orig_state[3][j]; 315 state[1][j] = 316 orig_state[0][j] ^ 317 galois_mult(0x2, orig_state[1][j]) ^ 318 galois_mult(0x3, orig_state[2][j]) ^ 319 orig_state[3][j]; 320 state[2][j] = 321 orig_state[0][j] ^ 322 orig_state[1][j] ^ 323 galois_mult(0x2, orig_state[2][j]) ^ 324 galois_mult(0x3, orig_state[3][j]); 325 state[3][j] = 326 galois_mult(0x3, orig_state[0][j]) ^ 327 orig_state[1][j] ^ 328 orig_state[2][j] ^ 329 galois_mult(0x2, orig_state[3][j]); 330 } 331 } 332 333 /** 334 * Perform inverted mix columns transformation on state table. 335 * 311 for (size_t j = 0; j < ELEMS; j++) { 312 state[0][j] = 313 galois_mult(0x2, orig_state[0][j]) ^ 314 galois_mult(0x3, orig_state[1][j]) ^ 315 orig_state[2][j] ^ 316 orig_state[3][j]; 317 state[1][j] = 318 orig_state[0][j] ^ 319 galois_mult(0x2, orig_state[1][j]) ^ 320 galois_mult(0x3, orig_state[2][j]) ^ 321 orig_state[3][j]; 322 state[2][j] = 323 orig_state[0][j] ^ 324 orig_state[1][j] ^ 325 galois_mult(0x2, orig_state[2][j]) ^ 326 galois_mult(0x3, orig_state[3][j]); 327 state[3][j] = 328 galois_mult(0x3, orig_state[0][j]) ^ 329 orig_state[1][j] ^ 330 orig_state[2][j] ^ 331 galois_mult(0x2, orig_state[3][j]); 332 } 333 } 334 335 /** Perform inverted mix columns transformation on state table. 336 * 336 337 * @param state State table to be modified. 338 * 337 339 */ 338 340 static void inv_mix_columns(uint8_t state[ELEMS][ELEMS]) … … 341 343 memcpy(orig_state, state, BLOCK_LEN); 342 344 343 for(size_t j = 0; j < ELEMS; j++) { 344 state[0][j] = 345 galois_mult(0x0E, orig_state[0][j]) ^ 346 galois_mult(0x0B, orig_state[1][j]) ^ 347 galois_mult(0x0D, orig_state[2][j]) ^ 348 galois_mult(0x09, orig_state[3][j]); 349 state[1][j] = 350 galois_mult(0x09, orig_state[0][j]) ^ 351 galois_mult(0x0E, orig_state[1][j]) ^ 352 galois_mult(0x0B, orig_state[2][j]) ^ 353 galois_mult(0x0D, orig_state[3][j]); 354 state[2][j] = 355 galois_mult(0x0D, orig_state[0][j]) ^ 356 galois_mult(0x09, orig_state[1][j]) ^ 357 galois_mult(0x0E, orig_state[2][j]) ^ 358 galois_mult(0x0B, orig_state[3][j]); 359 state[3][j] = 360 galois_mult(0x0B, orig_state[0][j]) ^ 361 galois_mult(0x0D, orig_state[1][j]) ^ 362 galois_mult(0x09, orig_state[2][j]) ^ 363 galois_mult(0x0E, orig_state[3][j]); 364 } 365 } 366 367 /** 368 * Perform round key transformation on state table. 369 * 370 * @param state State table to be modified. 345 for (size_t j = 0; j < ELEMS; j++) { 346 state[0][j] = 347 galois_mult(0x0e, orig_state[0][j]) ^ 348 galois_mult(0x0b, orig_state[1][j]) ^ 349 galois_mult(0x0d, orig_state[2][j]) ^ 350 galois_mult(0x09, orig_state[3][j]); 351 state[1][j] = 352 galois_mult(0x09, orig_state[0][j]) ^ 353 galois_mult(0x0e, orig_state[1][j]) ^ 354 galois_mult(0x0b, orig_state[2][j]) ^ 355 galois_mult(0x0d, orig_state[3][j]); 356 state[2][j] = 357 galois_mult(0x0d, orig_state[0][j]) ^ 358 galois_mult(0x09, orig_state[1][j]) ^ 359 galois_mult(0x0e, orig_state[2][j]) ^ 360 galois_mult(0x0b, orig_state[3][j]); 361 state[3][j] = 362 galois_mult(0x0b, orig_state[0][j]) ^ 363 galois_mult(0x0d, orig_state[1][j]) ^ 364 galois_mult(0x09, orig_state[2][j]) ^ 365 galois_mult(0x0e, orig_state[3][j]); 366 } 367 } 368 369 /** Perform round key transformation on state table. 370 * 371 * @param state State table to be modified. 371 372 * @param round_key Round key to be applied on state table. 373 * 372 374 */ 373 375 static void add_round_key(uint8_t state[ELEMS][ELEMS], uint32_t *round_key) … … 375 377 uint8_t byte_round; 376 378 uint8_t shift; 377 uint32_t mask = 0x FF;378 379 for (size_t j = 0; j < ELEMS; j++) {380 for (size_t i = 0; i < ELEMS; i++) {381 shift = 24 - 8 *i;379 uint32_t mask = 0xff; 380 381 for (size_t j = 0; j < ELEMS; j++) { 382 for (size_t i = 0; i < ELEMS; i++) { 383 shift = 24 - 8 * i; 382 384 byte_round = (round_key[j] & (mask << shift)) >> shift; 383 385 state[i][j] = state[i][j] ^ byte_round; … … 386 388 } 387 389 388 /** 389 * Perform substitution transformation on given word. 390 * 390 /** Perform substitution transformation on given word. 391 * 391 392 * @param byte Input word. 392 * 393 * 393 394 * @return Substituted word. 395 * 394 396 */ 395 397 static uint32_t sub_word(uint32_t word) … … 398 400 uint8_t *start = (uint8_t *) &temp; 399 401 400 for(size_t i = 0; i < 4; i++) { 401 *(start+i) = sub_byte(*(start+i), false); 402 } 402 for (size_t i = 0; i < 4; i++) 403 *(start + i) = sub_byte(*(start + i), false); 403 404 404 405 return temp; 405 406 } 406 407 407 /** 408 * Perform left rotation by one byte on given word. 409 * 408 /** Perform left rotation by one byte on given word. 409 * 410 410 * @param byte Input word. 411 * 411 * 412 412 * @return Rotated word. 413 * 413 414 */ 414 415 static uint32_t rot_word(uint32_t word) … … 417 418 } 418 419 419 /** 420 * Key expansion procedure for AES algorithm. 421 * 422 * @param key Input key. 420 /** Key expansion procedure for AES algorithm. 421 * 422 * @param key Input key. 423 423 * @param key_exp Result key expansion. 424 * 424 425 */ 425 426 static void key_expansion(uint8_t *key, uint32_t *key_exp) … … 427 428 uint32_t temp; 428 429 429 for (size_t i = 0; i < CIPHER_ELEMS; i++) {430 key_exp[i] = 431 (key[4*i] << 24) +432 (key[4*i+1] << 16) +433 (key[4*i+2] << 8) +434 (key[4*i+3]);435 } 436 437 for (size_t i = CIPHER_ELEMS; i < ELEMS * (ROUNDS + 1); i++) {438 temp = key_exp[i -1];439 440 if ((i % CIPHER_ELEMS) == 0) {441 temp = sub_word(rot_word(temp)) ^ 442 r_con_array[i/CIPHER_ELEMS - 1];430 for (size_t i = 0; i < CIPHER_ELEMS; i++) { 431 key_exp[i] = 432 (key[4 * i] << 24) + 433 (key[4 * i + 1] << 16) + 434 (key[4 * i + 2] << 8) + 435 (key[4 * i + 3]); 436 } 437 438 for (size_t i = CIPHER_ELEMS; i < ELEMS * (ROUNDS + 1); i++) { 439 temp = key_exp[i - 1]; 440 441 if ((i % CIPHER_ELEMS) == 0) { 442 temp = sub_word(rot_word(temp)) ^ 443 r_con_array[i / CIPHER_ELEMS - 1]; 443 444 } 444 445 … … 447 448 } 448 449 449 /** 450 * AES-128 encryption algorithm. 451 * 452 * @param key Input key. 453 * @param input Input data sequence to be encrypted. 450 /** AES-128 encryption algorithm. 451 * 452 * @param key Input key. 453 * @param input Input data sequence to be encrypted. 454 454 * @param output Encrypted data sequence. 455 * 456 * @return EINVAL when input or key not specified, ENOMEM when pointer for 457 * output is not allocated, otherwise EOK. 455 * 456 * @return EINVAL when input or key not specified, 457 * ENOMEM when pointer for output is not allocated, 458 * otherwise EOK. 459 * 458 460 */ 459 461 int aes_encrypt(uint8_t *key, uint8_t *input, uint8_t *output) 460 462 { 461 if (!key || !input)463 if ((!key) || (!input)) 462 464 return EINVAL; 463 465 464 if (!output)466 if (!output) 465 467 return ENOMEM; 466 468 467 469 /* Create key expansion. */ 468 uint32_t key_exp[ELEMS * (ROUNDS +1)];470 uint32_t key_exp[ELEMS * (ROUNDS + 1)]; 469 471 key_expansion(key, key_exp); 470 472 471 473 /* Copy input into state array. */ 472 474 uint8_t state[ELEMS][ELEMS]; 473 for(size_t i = 0; i < ELEMS; i++) { 474 for(size_t j = 0; j < ELEMS; j++) { 475 state[i][j] = input[i + ELEMS*j]; 476 } 475 for (size_t i = 0; i < ELEMS; i++) { 476 for (size_t j = 0; j < ELEMS; j++) 477 state[i][j] = input[i + ELEMS * j]; 477 478 } 478 479 … … 480 481 add_round_key(state, key_exp); 481 482 482 for (size_t k = 1; k <= ROUNDS; k++) {483 for (size_t k = 1; k <= ROUNDS; k++) { 483 484 sub_bytes(state, false); 484 485 shift_rows(state); 485 if(k < ROUNDS) 486 487 if (k < ROUNDS) 486 488 mix_columns(state); 487 add_round_key(state, key_exp + k*ELEMS); 489 490 add_round_key(state, key_exp + k * ELEMS); 488 491 } 489 492 490 493 /* Copy state array into output. */ 491 for(size_t i = 0; i < ELEMS; i++) { 492 for(size_t j = 0; j < ELEMS; j++) { 493 output[i + j*ELEMS] = state[i][j]; 494 } 494 for (size_t i = 0; i < ELEMS; i++) { 495 for (size_t j = 0; j < ELEMS; j++) 496 output[i + j * ELEMS] = state[i][j]; 495 497 } 496 498 … … 498 500 } 499 501 500 /** 501 * AES-128 decryption algorithm. 502 * 503 * @param key Input key. 504 * @param input Input data sequence to be decrypted. 502 /** AES-128 decryption algorithm. 503 * 504 * @param key Input key. 505 * @param input Input data sequence to be decrypted. 505 506 * @param output Decrypted data sequence. 506 * 507 * @return EINVAL when input or key not specified, ENOMEM when pointer for 508 * output is not allocated, otherwise EOK. 507 * 508 * @return EINVAL when input or key not specified, 509 * ENOMEM when pointer for output is not allocated, 510 * otherwise EOK. 511 * 509 512 */ 510 513 int aes_decrypt(uint8_t *key, uint8_t *input, uint8_t *output) 511 514 { 512 if (!key || !input)515 if ((!key) || (!input)) 513 516 return EINVAL; 514 517 515 if (!output)518 if (!output) 516 519 return ENOMEM; 517 520 518 521 /* Create key expansion. */ 519 uint32_t key_exp[ELEMS * (ROUNDS +1)];522 uint32_t key_exp[ELEMS * (ROUNDS + 1)]; 520 523 key_expansion(key, key_exp); 521 524 522 525 /* Copy input into state array. */ 523 526 uint8_t state[ELEMS][ELEMS]; 524 for(size_t i = 0; i < ELEMS; i++) { 525 for(size_t j = 0; j < ELEMS; j++) { 526 state[i][j] = input[i + ELEMS*j]; 527 } 527 for (size_t i = 0; i < ELEMS; i++) { 528 for (size_t j = 0; j < ELEMS; j++) 529 state[i][j] = input[i + ELEMS * j]; 528 530 } 529 531 530 532 /* Processing loop. */ 531 add_round_key(state, key_exp + ROUNDS *ELEMS);532 533 for (int k = ROUNDS - 1; k >= 0; k--) {533 add_round_key(state, key_exp + ROUNDS * ELEMS); 534 535 for (int k = ROUNDS - 1; k >= 0; k--) { 534 536 inv_shift_rows(state); 535 537 sub_bytes(state, true); 536 add_round_key(state, key_exp + k*ELEMS); 537 if(k > 0) 538 add_round_key(state, key_exp + k * ELEMS); 539 540 if (k > 0) 538 541 inv_mix_columns(state); 539 542 } 540 543 541 544 /* Copy state array into output. */ 542 for(size_t i = 0; i < ELEMS; i++) { 543 for(size_t j = 0; j < ELEMS; j++) { 544 output[i + j*ELEMS] = state[i][j]; 545 } 545 for (size_t i = 0; i < ELEMS; i++) { 546 for (size_t j = 0; j < ELEMS; j++) 547 output[i + j * ELEMS] = state[i][j]; 546 548 } 547 549 -
uspace/lib/crypto/crypto.c
r09044cb r8a64320e 28 28 29 29 /** @file crypto.c 30 * 30 * 31 31 * Cryptographic functions library. 32 32 */ … … 37 37 #include <errno.h> 38 38 #include <byteorder.h> 39 40 39 #include "crypto.h" 41 40 42 /* Hash function procedure definition. */ 43 typedef void (*HASH_FUNC)(uint32_t*, uint32_t*); 44 45 /* Length of HMAC block. */ 46 #define HMAC_BLOCK_LENGTH 64 47 48 /* Ceiling for UINT32. */ 49 #define ceil_uint32(val) (((val) - (uint32_t)(val)) > 0 ? \ 50 (uint32_t)((val) + 1) : (uint32_t)(val)) 51 52 /* Floor for UINT32. */ 53 #define floor_uint32(val) (((val) - (uint32_t)(val)) < 0 ? \ 54 (uint32_t)((val) - 1) : (uint32_t)(val)) 55 56 /* Pick value at specified index from array or zero if out of bounds. */ 57 #define get_at(input, size, i) (i < size ? input[i] : 0) 58 59 /* Init values used in SHA1 and MD5 functions. */ 41 /** Hash function procedure definition. */ 42 typedef void (*hash_fnc_t)(uint32_t *, uint32_t *); 43 44 /** Length of HMAC block. */ 45 #define HMAC_BLOCK_LENGTH 64 46 47 /** Ceiling for uint32_t. */ 48 #define ceil_uint32(val) \ 49 (((val) - (uint32_t) (val)) > 0 ? \ 50 (uint32_t) ((val) + 1) : (uint32_t) (val)) 51 52 /** Floor for uint32_t. */ 53 #define floor_uint32(val) \ 54 (((val) - (uint32_t) (val)) < 0 ? \ 55 (uint32_t) ((val) - 1) : (uint32_t) (val)) 56 57 /** Pick value at specified index from array or zero if out of bounds. */ 58 #define get_at(input, size, i) \ 59 ((i) < (size) ? (input[i]) : 0) 60 61 /** Init values used in SHA1 and MD5 functions. */ 60 62 static const uint32_t hash_init[] = { 61 0x67452301, 0x EFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F063 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 62 64 }; 63 65 64 /* Shift amount array for MD5 algorithm. */66 /** Shift amount array for MD5 algorithm. */ 65 67 static const uint32_t md5_shift[] = { 66 68 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, … … 70 72 }; 71 73 72 /* Substitution box for MD5 algorithm. */74 /** Substitution box for MD5 algorithm. */ 73 75 static const uint32_t md5_sbox[] = { 74 76 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, … … 90 92 }; 91 93 92 /** 93 * Working procedure of MD5 cryptographic hash function. 94 * 95 * @param h Working array with interim hash parts values. 94 /** Working procedure of MD5 cryptographic hash function. 95 * 96 * @param h Working array with interim hash parts values. 96 97 * @param sched_arr Input array with scheduled values from input string. 98 * 97 99 */ 98 100 static void md5_proc(uint32_t *h, uint32_t *sched_arr) 99 101 { 100 102 uint32_t f, g, temp; 101 uint32_t w[HASH_MD5 /4];102 103 memcpy(w, h, (HASH_MD5 /4) * sizeof(uint32_t));104 105 for (size_t k = 0; k < 64; k++) {106 if (k < 16) {103 uint32_t w[HASH_MD5 / 4]; 104 105 memcpy(w, h, (HASH_MD5 / 4) * sizeof(uint32_t)); 106 107 for (size_t k = 0; k < 64; k++) { 108 if (k < 16) { 107 109 f = (w[1] & w[2]) | (~w[1] & w[3]); 108 110 g = k; 109 } else if (k >= 16 && k < 32) {111 } else if ((k >= 16) && (k < 32)) { 110 112 f = (w[1] & w[3]) | (w[2] & ~w[3]); 111 g = (5 *k + 1) % 16;112 } else if (k >= 32 && k < 48) {113 g = (5 * k + 1) % 16; 114 } else if ((k >= 32) && (k < 48)) { 113 115 f = w[1] ^ w[2] ^ w[3]; 114 g = (3 *k + 5) % 16;116 g = (3 * k + 5) % 16; 115 117 } else { 116 118 f = w[2] ^ (w[1] | ~w[3]); 117 g = 7 *k % 16;119 g = 7 * k % 16; 118 120 } 121 119 122 temp = w[3]; 120 123 w[3] = w[2]; 121 124 w[2] = w[1]; 122 w[1] += rotl_uint32(w[0] + f + md5_sbox[k] + 123 uint32_t_byteorder_swap(sched_arr[g]),124 md5_shift[k]);125 w[1] += rotl_uint32(w[0] + f + md5_sbox[k] + 126 uint32_t_byteorder_swap(sched_arr[g]), 127 md5_shift[k]); 125 128 w[0] = temp; 126 129 } 127 130 128 for (uint8_t k = 0; k < HASH_MD5/4; k++)131 for (uint8_t k = 0; k < HASH_MD5 / 4; k++) 129 132 h[k] += w[k]; 130 133 } 131 134 132 /** 133 * Working procedure of SHA-1 cryptographic hash function. 134 * 135 * @param h Working array with interim hash parts values. 135 /** Working procedure of SHA-1 cryptographic hash function. 136 * 137 * @param h Working array with interim hash parts values. 136 138 * @param sched_arr Input array with scheduled values from input string. 139 * 137 140 */ 138 141 static void sha1_proc(uint32_t *h, uint32_t *sched_arr) 139 142 { 140 143 uint32_t f, cf, temp; 141 uint32_t w[HASH_SHA1 /4];142 143 for (size_t k = 16; k < 80; k++) {144 uint32_t w[HASH_SHA1 / 4]; 145 146 for (size_t k = 16; k < 80; k++) { 144 147 sched_arr[k] = rotl_uint32( 145 sched_arr[k-3] ^146 sched_arr[k-8] ^147 sched_arr[k-14] ^148 sched_arr[k-16],149 1);150 } 151 152 memcpy(w, h, (HASH_SHA1 /4) * sizeof(uint32_t));153 154 for (size_t k = 0; k < 80; k++) {155 if (k < 20) {148 sched_arr[k-3] ^ 149 sched_arr[k-8] ^ 150 sched_arr[k-14] ^ 151 sched_arr[k-16], 152 1); 153 } 154 155 memcpy(w, h, (HASH_SHA1 / 4) * sizeof(uint32_t)); 156 157 for (size_t k = 0; k < 80; k++) { 158 if (k < 20) { 156 159 f = (w[1] & w[2]) | (~w[1] & w[3]); 157 160 cf = 0x5A827999; 158 } else if (k >= 20 && k < 40) {161 } else if ((k >= 20) && (k < 40)) { 159 162 f = w[1] ^ w[2] ^ w[3]; 160 cf = 0x6 ED9EBA1;161 } else if (k >= 40 && k < 60) {163 cf = 0x6ed9eba1; 164 } else if ((k >= 40) && (k < 60)) { 162 165 f = (w[1] & w[2]) | (w[1] & w[3]) | (w[2] & w[3]); 163 cf = 0x8 F1BBCDC;166 cf = 0x8f1bbcdc; 164 167 } else { 165 168 f = w[1] ^ w[2] ^ w[3]; 166 cf = 0x CA62C1D6;169 cf = 0xca62c1d6; 167 170 } 168 171 169 172 temp = rotl_uint32(w[0], 5) + f + w[4] + cf + sched_arr[k]; 170 173 171 174 w[4] = w[3]; 172 175 w[3] = w[2]; … … 175 178 w[0] = temp; 176 179 } 177 178 for (uint8_t k = 0; k < HASH_SHA1/4; k++)180 181 for (uint8_t k = 0; k < HASH_SHA1 / 4; k++) 179 182 h[k] += w[k]; 180 183 } 181 184 182 /** 183 * Create hash based on selected algorithm. 184 * 185 * @param input Input message byte sequence. 185 /** Create hash based on selected algorithm. 186 * 187 * @param input Input message byte sequence. 186 188 * @param input_size Size of message sequence. 187 * @param output Result hash byte sequence. 188 * @param hash_sel Hash function selector. 189 * 190 * @return EINVAL when input not specified, ENOMEM when pointer for 191 * output hash result is not allocated, otherwise EOK. 189 * @param output Result hash byte sequence. 190 * @param hash_sel Hash function selector. 191 * 192 * @return EINVAL when input not specified, 193 * ENOMEM when pointer for output hash result 194 * is not allocated, otherwise EOK. 195 * 192 196 */ 193 197 int create_hash(uint8_t *input, size_t input_size, uint8_t *output, 194 hash_func_t hash_sel)195 { 196 if (!input)198 hash_func_t hash_sel) 199 { 200 if (!input) 197 201 return EINVAL; 198 202 199 if (!output)203 if (!output) 200 204 return ENOMEM; 201 205 202 HASH_FUNChash_func = (hash_sel == HASH_MD5) ? md5_proc : sha1_proc;206 hash_fnc_t hash_func = (hash_sel == HASH_MD5) ? md5_proc : sha1_proc; 203 207 204 208 /* Prepare scheduled input. */ … … 207 211 work_input[input_size] = 0x80; 208 212 209 size_t blocks = ceil_uint32((((double)input_size + 1) / 4 + 2) / 16); 213 // FIXME: double? 214 size_t blocks = ceil_uint32((((double) input_size + 1) / 4 + 2) / 16); 210 215 uint32_t work_arr[blocks * 16]; 211 for (size_t i = 0; i < blocks; i++) {212 for (size_t j = 0; j < 16; j++) {213 work_arr[i*16 + j] = 214 (get_at(work_input, input_size+1, i*64+j*4) << 24) |215 (get_at(work_input, input_size+1, i*64+j*4+1) << 16) |216 (get_at(work_input, input_size+1, i*64+j*4+2) << 8) |217 get_at(work_input, input_size+1, i*64+j*4+3);216 for (size_t i = 0; i < blocks; i++) { 217 for (size_t j = 0; j < 16; j++) { 218 work_arr[i*16 + j] = 219 (get_at(work_input, input_size + 1, i * 64 + j * 4) << 24) | 220 (get_at(work_input, input_size + 1, i * 64 + j * 4 + 1) << 16) | 221 (get_at(work_input, input_size + 1, i * 64 + j * 4 + 2) << 8) | 222 get_at(work_input, input_size + 1, i * 64 + j * 4 + 3); 218 223 } 219 224 } 220 225 221 uint64_t bits_size = (uint64_t) (input_size * 8);222 if (hash_sel == HASH_MD5)226 uint64_t bits_size = (uint64_t) (input_size * 8); 227 if (hash_sel == HASH_MD5) 223 228 bits_size = uint64_t_byteorder_swap(bits_size); 224 229 225 230 work_arr[(blocks - 1) * 16 + 14] = bits_size >> 32; 226 work_arr[(blocks - 1) * 16 + 15] = bits_size & 0x FFFFFFFF;231 work_arr[(blocks - 1) * 16 + 15] = bits_size & 0xffffffff; 227 232 228 233 /* Hash computation. */ 229 uint32_t h[hash_sel /4];230 memcpy(h, hash_init, (hash_sel /4) * sizeof(uint32_t));234 uint32_t h[hash_sel / 4]; 235 memcpy(h, hash_init, (hash_sel / 4) * sizeof(uint32_t)); 231 236 uint32_t sched_arr[80]; 232 for(size_t i = 0; i < blocks; i++) { 233 for(size_t k = 0; k < 16; k++) { 234 sched_arr[k] = work_arr[i*16 + k]; 235 } 237 for (size_t i = 0; i < blocks; i++) { 238 for (size_t k = 0; k < 16; k++) 239 sched_arr[k] = work_arr[i * 16 + k]; 236 240 237 241 hash_func(h, sched_arr); … … 239 243 240 244 /* Copy hash parts into final result. */ 241 for (size_t i = 0; i < hash_sel/4; i++) {242 if (hash_sel == HASH_SHA1)245 for (size_t i = 0; i < hash_sel / 4; i++) { 246 if (hash_sel == HASH_SHA1) 243 247 h[i] = uint32_t_byteorder_swap(h[i]); 244 memcpy(output + i*sizeof(uint32_t), &h[i], sizeof(uint32_t)); 248 249 memcpy(output + i * sizeof(uint32_t), &h[i], sizeof(uint32_t)); 245 250 } 246 251 … … 248 253 } 249 254 250 /** 251 * Hash-based message authentication code. 252 * 253 * @param key Cryptographic key sequence. 255 /** Hash-based message authentication code. 256 * 257 * @param key Cryptographic key sequence. 254 258 * @param key_size Size of key sequence. 255 * @param msg Message sequence.259 * @param msg Message sequence. 256 260 * @param msg_size Size of message sequence. 257 * @param hash Output parameter for result hash.261 * @param hash Output parameter for result hash. 258 262 * @param hash_sel Hash function selector. 259 * 260 * @return EINVAL when key or message not specified, ENOMEM when pointer for 261 * output hash result is not allocated, otherwise EOK. 263 * 264 * @return EINVAL when key or message not specified, 265 * ENOMEM when pointer for output hash result 266 * is not allocated, otherwise EOK. 267 * 262 268 */ 263 269 int hmac(uint8_t *key, size_t key_size, uint8_t *msg, size_t msg_size, 264 uint8_t *hash, hash_func_t hash_sel)265 { 266 if (!key || !msg)270 uint8_t *hash, hash_func_t hash_sel) 271 { 272 if ((!key) || (!msg)) 267 273 return EINVAL; 268 274 269 if (!hash)275 if (!hash) 270 276 return ENOMEM; 271 277 … … 276 282 memset(work_key, 0, HMAC_BLOCK_LENGTH); 277 283 278 if(key_size > HMAC_BLOCK_LENGTH) {284 if(key_size > HMAC_BLOCK_LENGTH) 279 285 create_hash(key, key_size, work_key, hash_sel); 280 } else {286 else 281 287 memcpy(work_key, key, key_size); 282 } 283 284 for(size_t i = 0; i < HMAC_BLOCK_LENGTH; i++) { 285 o_key_pad[i] = work_key[i] ^ 0x5C; 288 289 for (size_t i = 0; i < HMAC_BLOCK_LENGTH; i++) { 290 o_key_pad[i] = work_key[i] ^ 0x5c; 286 291 i_key_pad[i] = work_key[i] ^ 0x36; 287 292 } … … 291 296 memcpy(temp_work + HMAC_BLOCK_LENGTH, msg, msg_size); 292 297 293 create_hash(temp_work, HMAC_BLOCK_LENGTH + msg_size, temp_hash, 294 hash_sel);298 create_hash(temp_work, HMAC_BLOCK_LENGTH + msg_size, temp_hash, 299 hash_sel); 295 300 296 301 memcpy(temp_work, o_key_pad, HMAC_BLOCK_LENGTH); … … 302 307 } 303 308 304 /** 305 * Password-Based Key Derivation Function 2 as defined in RFC 2898,306 * using HMAC-SHA1 with 4096 iterations and 32 bytes key result used307 * for WPA/WPA2.308 * 309 * @param pass Password sequence.309 /** Password-Based Key Derivation Function 2. 310 * 311 * As defined in RFC 2898, using HMAC-SHA1 with 4096 iterations 312 * and 32 bytes key result used for WPA/WPA2. 313 * 314 * @param pass Password sequence. 310 315 * @param pass_size Password sequence length. 311 * @param salt Salt sequence to be used with password.316 * @param salt Salt sequence to be used with password. 312 317 * @param salt_size Salt sequence length. 313 * @param hash Output parameter for result hash (32 byte value). 314 * 315 * @return EINVAL when pass or salt not specified, ENOMEM when pointer for 316 * output hash result is not allocated, otherwise EOK. 317 */ 318 int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, size_t salt_size, 319 uint8_t *hash) 320 { 321 if(!pass || !salt) 318 * @param hash Output parameter for result hash (32 byte value). 319 * 320 * @return EINVAL when pass or salt not specified, 321 * ENOMEM when pointer for output hash result 322 * is not allocated, otherwise EOK. 323 * 324 */ 325 int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, size_t salt_size, 326 uint8_t *hash) 327 { 328 if ((!pass) || (!salt)) 322 329 return EINVAL; 323 330 324 if (!hash)331 if (!hash) 325 332 return ENOMEM; 326 333 … … 330 337 uint8_t temp_hmac[HASH_SHA1]; 331 338 uint8_t xor_hmac[HASH_SHA1]; 332 uint8_t temp_hash[HASH_SHA1*2]; 333 334 for(size_t i = 0; i < 2; i++) { 335 uint32_t be_i = host2uint32_t_be(i+1); 339 uint8_t temp_hash[HASH_SHA1 * 2]; 340 341 for (size_t i = 0; i < 2; i++) { 342 uint32_t be_i = host2uint32_t_be(i + 1); 343 336 344 memcpy(work_salt + salt_size, &be_i, 4); 337 345 hmac(pass, pass_size, work_salt, salt_size + 4, 338 work_hmac, HASH_SHA1);346 work_hmac, HASH_SHA1); 339 347 memcpy(xor_hmac, work_hmac, HASH_SHA1); 340 348 341 for (size_t k = 1; k < 4096; k++) {349 for (size_t k = 1; k < 4096; k++) { 342 350 memcpy(temp_hmac, work_hmac, HASH_SHA1); 343 hmac(pass, pass_size, temp_hmac, HASH_SHA1, 344 work_hmac, HASH_SHA1); 345 for(size_t t = 0; t < HASH_SHA1; t++) { 351 hmac(pass, pass_size, temp_hmac, HASH_SHA1, 352 work_hmac, HASH_SHA1); 353 354 for (size_t t = 0; t < HASH_SHA1; t++) 346 355 xor_hmac[t] ^= work_hmac[t]; 347 }348 356 } 349 memcpy(temp_hash + i*HASH_SHA1, xor_hmac, HASH_SHA1); 357 358 memcpy(temp_hash + i * HASH_SHA1, xor_hmac, HASH_SHA1); 350 359 } 351 360 -
uspace/lib/crypto/crypto.h
r09044cb r8a64320e 32 32 #include <sys/types.h> 33 33 34 #define AES_CIPHER_LENGTH 1635 #define PBKDF2_KEY_LENGTH 3234 #define AES_CIPHER_LENGTH 16 35 #define PBKDF2_KEY_LENGTH 32 36 36 37 /* Left rotation for UINT32. */ 38 #define rotl_uint32(val, shift) (((val) << shift) | ((val) >> (32 - shift))) 37 /* Left rotation for uint32_t. */ 38 #define rotl_uint32(val, shift) \ 39 (((val) << shift) | ((val) >> (32 - shift))) 39 40 40 /* Right rotation for UINT32. */ 41 #define rotr_uint32(val, shift) (((val) >> shift) | ((val) << (32 - shift))) 41 /* Right rotation for uint32_t. */ 42 #define rotr_uint32(val, shift) \ 43 (((val) >> shift) | ((val) << (32 - shift))) 42 44 43 45 /** Hash function selector and also result hash length indicator. */ 44 46 typedef enum { 45 HASH_MD5 = 16,46 HASH_SHA1 = 2047 HASH_MD5 = 16, 48 HASH_SHA1 = 20 47 49 } hash_func_t; 48 50 49 extern int rc4(uint8_t *key, size_t key_size, uint8_t *input, size_t input_size, 50 size_t skip, uint8_t *output); 51 extern int aes_encrypt(uint8_t *key, uint8_t *input, uint8_t *output); 52 extern int aes_decrypt(uint8_t *key, uint8_t *input, uint8_t *output); 53 extern int create_hash(uint8_t *input, size_t input_size, uint8_t *output, 54 hash_func_t hash_sel); 55 extern int hmac(uint8_t *key, size_t key_size, uint8_t *msg, size_t msg_size, 56 uint8_t *hash, hash_func_t hash_sel); 57 extern int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, 58 size_t salt_size, uint8_t *hash); 51 extern int rc4(uint8_t *, size_t, uint8_t *, size_t, size_t, uint8_t *); 52 extern int aes_encrypt(uint8_t *, uint8_t *, uint8_t *); 53 extern int aes_decrypt(uint8_t *, uint8_t *, uint8_t *); 54 extern int create_hash(uint8_t *, size_t, uint8_t *, hash_func_t); 55 extern int hmac(uint8_t *, size_t, uint8_t *, size_t, uint8_t *, hash_func_t); 56 extern int pbkdf2(uint8_t *, size_t, uint8_t *, size_t, uint8_t *); 59 57 60 58 #endif -
uspace/lib/crypto/rc4.c
r09044cb r8a64320e 28 28 29 29 /** @file rc4.c 30 * 30 * 31 31 * Implementation of ARC4 symmetric cipher cryptographic algorithm. 32 * 32 * 33 33 */ 34 34 35 35 #include <errno.h> 36 36 #include <mem.h> 37 38 37 #include "crypto.h" 39 38 40 39 /* Sbox table size. */ 41 #define SBOX_SIZE 25640 #define SBOX_SIZE 256 42 41 43 /** 44 * Swap two values in sbox. 45 * 46 * @param i First index of value in sbox to be swapped. 47 * @param j Second index of value in sbox to be swapped. 42 /** Swap two values in sbox. 43 * 44 * @param i First index of value in sbox to be swapped. 45 * @param j Second index of value in sbox to be swapped. 48 46 * @param sbox Sbox to be modified. 47 * 49 48 */ 50 49 static void swap(size_t i, size_t j, uint8_t *sbox) … … 55 54 } 56 55 57 /** 58 * Sbox initialization procedure. 59 * 60 * @param key Input key. 56 /** Sbox initialization procedure. 57 * 58 * @param key Input key. 61 59 * @param key_size Size of key sequence. 62 * @param sbox Place for result sbox. 60 * @param sbox Place for result sbox. 61 * 63 62 */ 64 63 static void create_sbox(uint8_t *key, size_t key_size, uint8_t *sbox) 65 64 { 66 for (size_t i = 0; i < SBOX_SIZE; i++) {65 for (size_t i = 0; i < SBOX_SIZE; i++) 67 66 sbox[i] = i; 68 }69 67 70 68 uint8_t j = 0; 71 for (size_t i = 0; i < SBOX_SIZE; i++) {69 for (size_t i = 0; i < SBOX_SIZE; i++) { 72 70 j = j + sbox[i] + key[i % key_size]; 73 71 swap(i, j, sbox); … … 75 73 } 76 74 77 /** 78 * ARC4 encryption/decryption algorithm. 79 * 80 * @param key Input key. 81 * @param key_size Size of key sequence. 82 * @param input Input data sequence to be processed. 75 /** ARC4 encryption/decryption algorithm. 76 * 77 * @param key Input key. 78 * @param key_size Size of key sequence. 79 * @param input Input data sequence to be processed. 83 80 * @param input_size Size of input data sequence. 84 * @param skip Number of bytes to be skipped from the beginning of key stream. 85 * @param output Result data sequence. 86 * 87 * @return EINVAL when input or key not specified, ENOMEM when pointer for 88 * output is not allocated, otherwise EOK. 81 * @param skip Number of bytes to be skipped from 82 * the beginning of key stream. 83 * @param output Result data sequence. 84 * 85 * @return EINVAL when input or key not specified, 86 * ENOMEM when pointer for output is not allocated, 87 * otherwise EOK. 88 * 89 89 */ 90 int rc4(uint8_t *key, size_t key_size, uint8_t *input, size_t input_size, 91 size_t skip, uint8_t *output)90 int rc4(uint8_t *key, size_t key_size, uint8_t *input, size_t input_size, 91 size_t skip, uint8_t *output) 92 92 { 93 if (!key || !input)93 if ((!key) || (!input)) 94 94 return EINVAL; 95 95 96 if (!output)96 if (!output) 97 97 return ENOMEM; 98 98 … … 102 102 103 103 /* Skip first x bytes. */ 104 uint8_t i = 0, j = 0; 105 for(size_t k = 0; k < skip; k++) { 104 uint8_t i = 0; 105 uint8_t j = 0; 106 for (size_t k = 0; k < skip; k++) { 106 107 i = i + 1; 107 108 j = j + sbox[i]; … … 111 112 /* Processing loop. */ 112 113 uint8_t val; 113 for (size_t k = 0; k < input_size; k++) {114 for (size_t k = 0; k < input_size; k++) { 114 115 i = i + 1; 115 116 j = j + sbox[i]; -
uspace/lib/drv/generic/remote_ieee80211.c
r09044cb r8a64320e 40 40 #include <inet/dhcp.h> 41 41 #include <inet/inetcfg.h> 42 43 42 #include "ops/ieee80211.h" 44 43 #include "ieee80211_iface.h" 45 44 #include "nic_iface.h" 46 45 47 #define MAX_STRING_SIZE 3246 #define MAX_STRING_SIZE 32 48 47 49 48 /** IEEE 802.11 RPC functions IDs. */ … … 56 55 /** Get scan results from IEEE 802.11 device 57 56 * 58 * @param[in] dev_sess Device session.59 * @param[out] results Structure where to put scan results.57 * @param[in] dev_sess Device session. 58 * @param[out] results Structure where to put scan results. 60 59 * 61 60 * @return EOK If the operation was successfully completed, 62 * negative error code otherwise. 63 */ 64 int ieee80211_get_scan_results(async_sess_t *dev_sess, 65 ieee80211_scan_results_t *results, bool now) 61 * negative error code otherwise. 62 * 63 */ 64 int ieee80211_get_scan_results(async_sess_t *dev_sess, 65 ieee80211_scan_results_t *results, bool now) 66 66 { 67 67 assert(results); … … 71 71 aid_t aid = async_send_2(exch, DEV_IFACE_ID(IEEE80211_DEV_IFACE), 72 72 IEEE80211_GET_SCAN_RESULTS, now, NULL); 73 int rc = async_data_read_start(exch, results, sizeof(ieee80211_scan_results_t)); 73 int rc = async_data_read_start(exch, results, 74 sizeof(ieee80211_scan_results_t)); 74 75 async_exchange_end(exch); 75 76 76 77 sysarg_t res; 77 78 async_wait_for(aid, &res); … … 79 80 if(res != EOK) 80 81 return (int) res; 81 else82 return rc;82 83 return rc; 83 84 } 84 85 85 86 static bool mac_matches(uint8_t *mac1, uint8_t *mac2) 86 87 { 87 for (size_t i = 0; i < ETH_ADDR; i++) {88 if (mac1[i] != mac2[i])88 for (size_t i = 0; i < ETH_ADDR; i++) { 89 if (mac1[i] != mac2[i]) 89 90 return false; 90 91 } … … 108 109 return -1; 109 110 110 if (mac_matches(mac, link_info.mac_addr)) {111 if (mac_matches(mac, link_info.mac_addr)) 111 112 return link_list[i]; 112 }113 113 } 114 114 … … 118 118 /** Connect to specified network. 119 119 * 120 * @param[in] dev_sess Device session.120 * @param[in] dev_sess Device session. 121 121 * @param[in] ssid_start Network SSID prefix. 122 * @param[in] password Network password (pass empty string if not needed).122 * @param[in] password Network password (pass empty string if not needed). 123 123 * 124 124 * @return EOK If the operation was successfully completed, 125 * negative error code otherwise. 125 * negative error code otherwise. 126 * 126 127 */ 127 128 int ieee80211_connect(async_sess_t *dev_sess, char *ssid_start, char *password) … … 136 137 IEEE80211_CONNECT, NULL); 137 138 138 sysarg_t rc = async_data_write_start(exch, ssid_start, 139 str_size(ssid_start) + 1);139 sysarg_t rc = async_data_write_start(exch, ssid_start, 140 str_size(ssid_start) + 1); 140 141 if (rc != EOK) { 141 142 async_exchange_end(exch); … … 144 145 if (rc_orig == EOK) 145 146 return (int) rc; 146 else 147 return (int) rc_orig; 148 } 149 150 if(password == NULL) { 147 148 return (int) rc_orig; 149 } 150 151 // FIXME: Typecasting string literal 152 if (password == NULL) 151 153 password = (char *) ""; 152 }153 154 154 155 rc = async_data_write_start(exch, password, str_size(password) + 1); … … 159 160 if (rc_orig == EOK) 160 161 return (int) rc; 161 else162 return (int) rc_orig;162 163 return (int) rc_orig; 163 164 } 164 165 165 166 async_exchange_end(exch); 166 167 167 168 async_wait_for(aid, &rc); 168 169 if (rc != EOK) … … 176 177 177 178 sysarg_t link_id = get_link_id(wifi_mac.address); 178 if (link_id == ((sysarg_t) -1))179 if (link_id == ((sysarg_t) -1)) 179 180 return EINVAL; 180 181 … … 189 190 * 190 191 * @return EOK If the operation was successfully completed, 191 * negative error code otherwise. 192 * negative error code otherwise. 193 * 192 194 */ 193 195 int ieee80211_disconnect(async_sess_t *dev_sess) … … 198 200 async_exchange_end(exch); 199 201 200 if (rc != EOK)202 if (rc != EOK) 201 203 return rc; 202 204 … … 227 229 return rc; 228 230 229 if (mac_matches(wifi_mac.address, link_info.mac_addr)) {230 if (str_test_prefix(addr_info.name, "dhcp")) {231 if (mac_matches(wifi_mac.address, link_info.mac_addr)) { 232 if (str_test_prefix(addr_info.name, "dhcp")) { 231 233 rc = inetcfg_addr_delete(addr_list[i]); 232 if (rc != EOK)234 if (rc != EOK) 233 235 return rc; 236 234 237 break; 235 238 } … … 237 240 } 238 241 239 /* 242 /* 240 243 * TODO: At this moment there can be only one DHCP route, 241 244 * so it must be reimplemented after this limitation will be … … 252 255 return rc; 253 256 254 if (str_test_prefix(route_info.name, "dhcp")) {257 if (str_test_prefix(route_info.name, "dhcp")) { 255 258 rc = inetcfg_sroute_delete(route_list[i]); 256 if (rc != EOK)259 if (rc != EOK) 257 260 return rc; 261 258 262 break; 259 263 } -
uspace/lib/drv/include/ieee80211_iface.h
r09044cb r8a64320e 27 27 */ 28 28 29 /** @addtogroup libc29 /** @addtogroup libc 30 30 * @{ 31 31 */ … … 39 39 #include <async.h> 40 40 41 extern int ieee80211_get_scan_results(async_sess_t *, 42 ieee80211_scan_results_t *, bool);41 extern int ieee80211_get_scan_results(async_sess_t *, 42 ieee80211_scan_results_t *, bool); 43 43 extern int ieee80211_connect(async_sess_t *, char *, char *); 44 44 extern int ieee80211_disconnect(async_sess_t *); -
uspace/lib/drv/include/ops/ieee80211.h
r09044cb r8a64320e 42 42 /** IEEE 802.11 interface functions definition. */ 43 43 typedef struct ieee80211_iface { 44 /** 45 * Fetch scan results from IEEE 802.11 device. 46 * 47 * @param fun IEEE 802.11 function. 44 /** Fetch scan results from IEEE 802.11 device. 45 * 46 * @param fun IEEE 802.11 function. 48 47 * @param results Structure where to put scan results. 49 * @param now Whether to initiate scan immediately.50 * 48 * @param now Whether to initiate scan immediately. 49 * 51 50 * @return EOK if succeed, negative error code otherwise. 51 * 52 52 */ 53 53 int (*get_scan_results)(ddf_fun_t *, ieee80211_scan_results_t *, bool); 54 54 55 /** 56 * Connect IEEE 802.11 device to specified network. 55 /** Connect IEEE 802.11 device to specified network. 57 56 * 58 * @param fun IEEE 802.11 function.59 * @param ssid Network SSID.57 * @param fun IEEE 802.11 function. 58 * @param ssid Network SSID. 60 59 * @param password Network password (empty string if not needed). 61 * 60 * 62 61 * @return EOK if succeed, negative error code otherwise. 62 * 63 63 */ 64 64 int (*connect)(ddf_fun_t *, char *, char *); 65 65 66 /** 67 * Disconnect IEEE 802.11 device from network. 66 /** Disconnect IEEE 802.11 device from network. 68 67 * 69 68 * @param fun IEEE 802.11 function. 70 * 69 * 71 70 * @return EOK if succeed, negative error code otherwise. 71 * 72 72 */ 73 73 int (*disconnect)(ddf_fun_t *); -
uspace/lib/ieee80211/Makefile
r09044cb r8a64320e 45 45 src/ieee80211_impl.c \ 46 46 src/ieee80211_iface_impl.c \ 47 48 47 49 48 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/ieee80211/include/ieee80211.h
r09044cb r8a64320e 27 27 */ 28 28 29 /** 29 /** 30 30 * @addtogroup libieee80211 31 31 * @{ … … 43 43 #include <ops/ieee80211.h> 44 44 45 #define DEVICE_CATEGORY_IEEE80211 "ieee80211"45 #define DEVICE_CATEGORY_IEEE80211 "ieee80211" 46 46 47 47 struct ieee80211_dev; … … 49 49 50 50 /** Initial channel frequency. */ 51 #define IEEE80211_FIRST_FREQ 241251 #define IEEE80211_FIRST_FREQ 2412 52 52 53 53 /** Max supported channel frequency. */ 54 #define IEEE80211_MAX_FREQ 247255 56 /* Gap between IEEE80211 channels in MHz. */57 #define IEEE80211_CHANNEL_GAP 558 59 /* Max AMPDU factor. */60 #define IEEE80211_MAX_AMPDU_FACTOR 1361 62 /* Max authentication password length. */63 #define IEEE80211_MAX_PASSW_LEN 6454 #define IEEE80211_MAX_FREQ 2472 55 56 /** Gap between IEEE80211 channels in MHz. */ 57 #define IEEE80211_CHANNEL_GAP 5 58 59 /** Max AMPDU factor. */ 60 #define IEEE80211_MAX_AMPDU_FACTOR 13 61 62 /** Max authentication password length. */ 63 #define IEEE80211_MAX_PASSW_LEN 64 64 64 65 65 /** IEEE 802.11 b/g supported data rates in units of 500 kb/s. */ … … 97 97 /** IEEE 802.11 callback functions. */ 98 98 typedef struct { 99 /** 100 * Function that is called at device initalization. This should 101 * get device into running state. 102 * 103 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 104 * 105 * @return EOK if succeed, negative error code otherwise. 99 /** unction that is called at device initalization. 100 * 101 * This should get device into running state. 102 * 103 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 104 * 105 * @return EOK if succeed, negative error code otherwise. 106 * 106 107 */ 107 108 int (*start)(struct ieee80211_dev *); 108 109 109 /** 110 * Scan neighborhood for networks. There should be implemented 111 * scanning of whole bandwidth. Incoming results are processed by 112 * IEEE 802.11 framework itself. 113 * 114 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 115 * 116 * @return EOK if succeed, negative error code otherwise. 110 /** Scan neighborhood for networks. 111 * 112 * There should be implemented scanning of whole bandwidth. 113 * Incoming results are processed by IEEE 802.11 framework itself. 114 * 115 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 116 * 117 * @return EOK if succeed, negative error code otherwise. 118 * 117 119 */ 118 120 int (*scan)(struct ieee80211_dev *); 119 121 120 /** 121 * Handler for TX frames to be send from device. This should be 122 * called for every frame that has to be send from IEEE 802.11 device. 123 * 124 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 125 * @param buffer Buffer with data to be send. 126 * @param buffer_size Size of buffer. 127 * 128 * @return EOK if succeed, negative error code otherwise. 122 /** Handler for TX frames to be send from device. 123 * 124 * This should be called for every frame that has to be send 125 * from IEEE 802.11 device. 126 * 127 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 128 * @param buffer Buffer with data to be send. 129 * @param buffer_size Size of buffer. 130 * 131 * @return EOK if succeed, negative error code otherwise. 132 * 129 133 */ 130 134 int (*tx_handler)(struct ieee80211_dev *, void *, size_t); 131 135 132 /** 133 * Set device operating frequency to given value.134 * 135 * @param ieee80211_dev Pointer to IEEE 802.11 device structure.136 * @param freq New device operating frequency.137 * 138 * @return EOK if succeed, negative error code otherwise.136 /** Set device operating frequency to given value. 137 * 138 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 139 * @param freq New device operating frequency. 140 * 141 * @return EOK if succeed, negative error code otherwise. 142 * 139 143 */ 140 144 int (*set_freq)(struct ieee80211_dev *, uint16_t); 141 145 142 /** 143 * Callback to inform device about BSSID change.144 * 145 * @param ieee80211_dev Pointer to IEEE 802.11 device structure.146 * @param connected True if connected to new BSSID, otherwise false.147 * 148 * @return EOK if succeed, negative error code otherwise.146 /** Callback to inform device about BSSID change. 147 * 148 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 149 * @param connected True if connected to new BSSID, otherwise false. 150 * 151 * @return EOK if succeed, negative error code otherwise. 152 * 149 153 */ 150 154 int (*bssid_change)(struct ieee80211_dev *, bool); 151 155 152 /** 153 * Callback to setup encryption key in IEEE 802.11 device. 154 * 155 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 156 * @param key_conf Key config structure. 157 * @param insert True to insert this key to device, false to remove it. 158 * 159 * @return EOK if succeed, negative error code otherwise. 160 */ 161 int (*key_config)(struct ieee80211_dev *, 162 ieee80211_key_config_t *key_conf, bool); 156 /** Callback to setup encryption key in IEEE 802.11 device. 157 * 158 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 159 * @param key_conf Key config structure. 160 * @param insert True to insert this key to device, 161 * false to remove it. 162 * 163 * @return EOK if succeed, negative error code otherwise. 164 * 165 */ 166 int (*key_config)(struct ieee80211_dev *, 167 ieee80211_key_config_t *key_conf, bool); 163 168 } ieee80211_ops_t; 164 169 165 170 /* Initialization functions. */ 166 171 extern ieee80211_dev_t *ieee80211_device_create(void); 167 extern int ieee80211_device_init(ieee80211_dev_t *ieee80211_dev, 168 ddf_dev_t *ddf_dev); 169 extern int ieee80211_init(ieee80211_dev_t *ieee80211_dev, 170 ieee80211_ops_t *ieee80211_ops, ieee80211_iface_t *ieee80211_iface, 171 nic_iface_t *ieee80211_nic_iface, ddf_dev_ops_t *ieee80211_dev_ops); 172 extern int ieee80211_device_init(ieee80211_dev_t *, ddf_dev_t *); 173 extern int ieee80211_init(ieee80211_dev_t *, ieee80211_ops_t *, 174 ieee80211_iface_t *, nic_iface_t *, ddf_dev_ops_t *); 172 175 173 176 /* Getters & setters, queries & reports. */ 174 extern void *ieee80211_get_specific(ieee80211_dev_t *ieee80211_dev); 175 extern void ieee80211_set_specific(ieee80211_dev_t *ieee80211_dev, 176 void *specific); 177 extern ddf_dev_t *ieee80211_get_ddf_dev(ieee80211_dev_t* ieee80211_dev); 178 extern ieee80211_operating_mode_t 179 ieee80211_query_current_op_mode(ieee80211_dev_t *ieee80211_dev); 180 extern uint16_t ieee80211_query_current_freq(ieee80211_dev_t *ieee80211_dev); 181 extern void ieee80211_query_bssid(ieee80211_dev_t* ieee80211_dev, 182 nic_address_t *bssid); 183 extern bool ieee80211_is_connected(ieee80211_dev_t* ieee80211_dev); 184 extern void ieee80211_report_current_op_mode(ieee80211_dev_t *ieee80211_dev, 185 ieee80211_operating_mode_t op_mode); 186 extern void ieee80211_report_current_freq(ieee80211_dev_t *ieee80211_dev, 187 uint16_t freq); 188 extern uint16_t ieee80211_get_aid(ieee80211_dev_t* ieee80211_dev); 189 extern int ieee80211_get_pairwise_security(ieee80211_dev_t* ieee80211_dev); 190 extern bool ieee80211_is_ready(ieee80211_dev_t* ieee80211_dev); 191 extern void ieee80211_set_ready(ieee80211_dev_t* ieee80211_dev, bool ready); 192 extern bool ieee80211_query_using_key(ieee80211_dev_t* ieee80211_dev); 193 extern void ieee80211_setup_key_confirm(ieee80211_dev_t* ieee80211_dev, 194 bool using_key); 195 196 extern bool ieee80211_is_data_frame(uint16_t frame_ctrl); 197 extern bool ieee80211_is_mgmt_frame(uint16_t frame_ctrl); 198 extern bool ieee80211_is_beacon_frame(uint16_t frame_ctrl); 199 extern bool ieee80211_is_probe_response_frame(uint16_t frame_ctrl); 200 extern bool ieee80211_is_auth_frame(uint16_t frame_ctrl); 201 extern bool ieee80211_is_assoc_response_frame(uint16_t frame_ctrl); 177 extern void *ieee80211_get_specific(ieee80211_dev_t *); 178 extern void ieee80211_set_specific(ieee80211_dev_t *, void *); 179 extern ddf_dev_t *ieee80211_get_ddf_dev(ieee80211_dev_t *); 180 extern ieee80211_operating_mode_t 181 ieee80211_query_current_op_mode(ieee80211_dev_t *); 182 extern uint16_t ieee80211_query_current_freq(ieee80211_dev_t *); 183 extern void ieee80211_query_bssid(ieee80211_dev_t *, nic_address_t *); 184 extern bool ieee80211_is_connected(ieee80211_dev_t *); 185 extern void ieee80211_report_current_op_mode(ieee80211_dev_t *, 186 ieee80211_operating_mode_t); 187 extern void ieee80211_report_current_freq(ieee80211_dev_t *, uint16_t); 188 extern uint16_t ieee80211_get_aid(ieee80211_dev_t *); 189 extern int ieee80211_get_pairwise_security(ieee80211_dev_t *); 190 extern bool ieee80211_is_ready(ieee80211_dev_t *); 191 extern void ieee80211_set_ready(ieee80211_dev_t *, bool); 192 extern bool ieee80211_query_using_key(ieee80211_dev_t *); 193 extern void ieee80211_setup_key_confirm(ieee80211_dev_t *, bool); 194 195 extern bool ieee80211_is_data_frame(uint16_t); 196 extern bool ieee80211_is_mgmt_frame(uint16_t); 197 extern bool ieee80211_is_beacon_frame(uint16_t); 198 extern bool ieee80211_is_probe_response_frame(uint16_t); 199 extern bool ieee80211_is_auth_frame(uint16_t); 200 extern bool ieee80211_is_assoc_response_frame(uint16_t); 202 201 203 202 /* Worker functions. */ 204 extern int ieee80211_rx_handler(ieee80211_dev_t *ieee80211_dev, void *buffer, 205 size_t buffer_size); 206 207 #endif // LIB_IEEE80211_H 203 extern int ieee80211_rx_handler(ieee80211_dev_t *, void *, size_t); 204 205 #endif 208 206 209 207 /** @} -
uspace/lib/ieee80211/include/ieee80211_iface_impl.h
r09044cb r8a64320e 27 27 */ 28 28 29 /** 29 /** 30 30 * @addtogroup libieee80211 31 31 * @{ … … 33 33 34 34 /** @file ieee80211_iface_impl.h 35 * 35 * 36 36 * IEEE 802.11 default interface functions definition. 37 37 */ 38 38 39 39 #ifndef LIB_IEEE80211_IFACE_IMPL_H 40 #define LIB_IEEE80211_IFACE_IMPL_H40 #define LIB_IEEE80211_IFACE_IMPL_H 41 41 42 42 #include <ddf/driver.h> 43 44 43 #include "ieee80211.h" 45 44 46 extern int ieee80211_get_scan_results_impl(ddf_fun_t *fun, 47 ieee80211_scan_results_t *results, bool now); 48 extern int ieee80211_connect_impl(ddf_fun_t *fun, char *ssid_start, 49 char *password); 50 extern int ieee80211_disconnect_impl(ddf_fun_t *fun); 45 extern int ieee80211_get_scan_results_impl(ddf_fun_t *, 46 ieee80211_scan_results_t *, bool); 47 extern int ieee80211_connect_impl(ddf_fun_t *, char *, char *); 48 extern int ieee80211_disconnect_impl(ddf_fun_t *); 51 49 52 #endif /* LIB_IEEE80211_IFACE_IMPL_H */50 #endif /* LIB_IEEE80211_IFACE_IMPL_H */ 53 51 54 52 /** @} -
uspace/lib/ieee80211/include/ieee80211_impl.h
r09044cb r8a64320e 27 27 */ 28 28 29 /** 29 /** 30 30 * @addtogroup libieee80211 31 31 * @{ … … 33 33 34 34 /** @file ieee80211_impl.h 35 * 35 * 36 36 * IEEE 802.11 default device functions definition. 37 37 */ 38 38 39 39 #ifndef LIB_IEEE80211_IMPL_H 40 #define LIB_IEEE80211_IMPL_H40 #define LIB_IEEE80211_IMPL_H 41 41 42 42 #include "ieee80211_private.h" 43 43 44 extern int ieee80211_start_impl(ieee80211_dev_t *ieee80211_dev); 45 extern int ieee80211_tx_handler_impl(ieee80211_dev_t *ieee80211_dev, 46 void *buffer, size_t buffer_size); 47 extern int ieee80211_set_freq_impl(ieee80211_dev_t *ieee80211_dev, 48 uint16_t freq); 49 extern int ieee80211_bssid_change_impl(ieee80211_dev_t *ieee80211_dev, 50 bool connected); 51 extern int ieee80211_key_config_impl(ieee80211_dev_t *ieee80211_dev, 52 ieee80211_key_config_t *key_conf, bool insert); 53 extern int ieee80211_scan_impl(ieee80211_dev_t *ieee80211_dev); 54 extern int ieee80211_prf(uint8_t *key, uint8_t *data, uint8_t *hash, 55 size_t output_size); 56 extern int ieee80211_rc4_key_unwrap(uint8_t *key, uint8_t *data, 57 size_t data_size, uint8_t *output); 58 extern int ieee80211_aes_key_unwrap(uint8_t *kek, uint8_t *data, 59 size_t data_size, uint8_t *output); 60 extern int ieee80211_michael_mic(uint8_t *key, uint8_t *data, size_t data_size, 61 uint8_t *mic); 62 extern uint16_t uint16le_from_seq(void *seq); 63 extern uint32_t uint32le_from_seq(void *seq); 64 extern uint16_t uint16be_from_seq(void *seq); 65 extern uint32_t uint32be_from_seq(void *seq); 66 extern int rnd_sequence(uint8_t *sequence, size_t length); 67 extern uint8_t *min_sequence(uint8_t *seq1, uint8_t *seq2, size_t size); 68 extern uint8_t *max_sequence(uint8_t *seq1, uint8_t *seq2, size_t size); 44 extern int ieee80211_start_impl(ieee80211_dev_t *); 45 extern int ieee80211_tx_handler_impl(ieee80211_dev_t *, void *, size_t); 46 extern int ieee80211_set_freq_impl(ieee80211_dev_t *, uint16_t); 47 extern int ieee80211_bssid_change_impl(ieee80211_dev_t *, bool); 48 extern int ieee80211_key_config_impl(ieee80211_dev_t *, 49 ieee80211_key_config_t *, bool); 50 extern int ieee80211_scan_impl(ieee80211_dev_t *); 51 extern int ieee80211_prf(uint8_t *, uint8_t *, uint8_t *, size_t); 52 extern int ieee80211_rc4_key_unwrap(uint8_t *, uint8_t *, size_t, uint8_t *); 53 extern int ieee80211_aes_key_unwrap(uint8_t *, uint8_t *, size_t, uint8_t *); 54 extern int ieee80211_michael_mic(uint8_t *, uint8_t *, size_t, uint8_t *); 55 extern uint16_t uint16le_from_seq(void *); 56 extern uint32_t uint32le_from_seq(void *); 57 extern uint16_t uint16be_from_seq(void *); 58 extern uint32_t uint32be_from_seq(void *); 59 extern int rnd_sequence(uint8_t *, size_t); 60 extern uint8_t *min_sequence(uint8_t *, uint8_t *, size_t); 61 extern uint8_t *max_sequence(uint8_t *, uint8_t *, size_t); 69 62 70 #endif /* LIB_IEEE80211_IMPL_H */63 #endif /* LIB_IEEE80211_IMPL_H */ 71 64 72 65 /** @} -
uspace/lib/ieee80211/include/ieee80211_private.h
r09044cb r8a64320e 27 27 */ 28 28 29 /** 29 /** 30 30 * @addtogroup libieee80211 31 31 * @{ … … 33 33 34 34 /** @file ieee80211.h 35 * 35 * 36 36 * Internal IEEE 802.11 header that should not be included. 37 37 */ 38 38 39 #ifndef LIB NET_IEEE80211_PRIVATE_H40 #define LIB NET_IEEE80211_PRIVATE_H39 #ifndef LIB_IEEE80211_PRIVATE_H 40 #define LIB_IEEE80211_PRIVATE_H 41 41 42 42 #include <fibril_synch.h> … … 44 44 #include <ddf/driver.h> 45 45 #include <sys/types.h> 46 47 46 #include <ieee80211/ieee80211.h> 48 47 #include "ieee80211.h" 49 48 50 /* Timeout in us for waiting to authentication/association response. */ 51 #define AUTH_TIMEOUT 200000 52 53 /* Timeout in us for waiting to finish 4-way handshake process. */ 54 #define HANDSHAKE_TIMEOUT 5000000 55 56 /* Scanning period. */ 57 #define SCAN_PERIOD_USEC 35000000 58 59 /* Time to wait for beacons on channel. */ 60 #define SCAN_CHANNEL_WAIT_USEC 200000 61 62 /* Max time to keep scan result. */ 63 #define MAX_KEEP_SCAN_SPAN_SEC 120 64 65 /* Security bit in capability info field. */ 66 #define CAP_SECURITY 0x10 67 68 /* Protocol type used in EAPOL frames. */ 69 #define ETH_TYPE_PAE 0x888E 70 71 /* WPA OUI used in vendor specific IE. */ 72 #define WPA_OUI 0x0050F201 73 74 /* GTK OUI used in vendor specific IE. */ 75 #define GTK_OUI 0x000FAC01 76 77 /* Max PTK key length. */ 78 #define MAX_PTK_LENGTH 64 79 80 /* Max GTK key length. */ 81 #define MAX_GTK_LENGTH 64 82 83 /* KEK offset inside PTK. */ 84 #define KEK_OFFSET 16 85 86 /* TK offset inside PTK. */ 87 #define TK_OFFSET 32 88 89 /* Length of Michael MIC code used in TKIP security suite. */ 90 #define MIC_LENGTH 8 91 92 /* 93 * Length of data to be encrypted by PRF function: 94 * NONCE + SNONCE (2 * 32) + DEST_MAC + SOURCE_MAC (2 * ETH_ADDR) 49 /** Timeout in us for waiting to authentication/association response. */ 50 #define AUTH_TIMEOUT 200000 51 52 /** Timeout in us for waiting to finish 4-way handshake process. */ 53 #define HANDSHAKE_TIMEOUT 5000000 54 55 /** Scanning period. */ 56 #define SCAN_PERIOD_USEC 35000000 57 58 /** Time to wait for beacons on channel. */ 59 #define SCAN_CHANNEL_WAIT_USEC 200000 60 61 /** Max time to keep scan result. */ 62 #define MAX_KEEP_SCAN_SPAN_SEC 120 63 64 /** Security bit in capability info field. */ 65 #define CAP_SECURITY 0x10 66 67 /** Protocol type used in EAPOL frames. */ 68 #define ETH_TYPE_PAE 0x888e 69 70 /** WPA OUI used in vendor specific IE. */ 71 #define WPA_OUI 0x0050f201 72 73 /** GTK OUI used in vendor specific IE. */ 74 #define GTK_OUI 0x000fac01 75 76 /** Max PTK key length. */ 77 #define MAX_PTK_LENGTH 64 78 79 /** Max GTK key length. */ 80 #define MAX_GTK_LENGTH 64 81 82 /** KEK offset inside PTK. */ 83 #define KEK_OFFSET 16 84 85 /** TK offset inside PTK. */ 86 #define TK_OFFSET 32 87 88 /** Length of Michael MIC code used in TKIP security suite. */ 89 #define MIC_LENGTH 8 90 91 /** Length of data to be encrypted by PRF function. 92 * 93 * NONCE + SNONCE (2 * 32) + DEST_MAC + SOURCE_MAC (2 * ETH_ADDR) 94 * 95 95 */ 96 #define PRF_CRYPT_DATA_LENGTH 2*32 + 2*ETH_ADDR97 98 /* Special room in header reserved for encryption. */96 #define PRF_CRYPT_DATA_LENGTH (2 * 32 + 2 * ETH_ADDR) 97 98 /** Special room in header reserved for encryption. */ 99 99 typedef enum { 100 100 IEEE80211_TKIP_HEADER_LENGTH = 8, … … 184 184 /** IEEE 802.11 information element types. */ 185 185 typedef enum { 186 IEEE80211_SSID_IE = 0, /**< Target SSID. */187 IEEE80211_RATES_IE = 1, /**< Supported data rates. */188 IEEE80211_CHANNEL_IE = 3, /**< Current channel number. */189 IEEE80211_CHALLENGE_IE = 16, /**< Challenge text. */190 IEEE80211_RSN_IE = 48, /**< RSN. */191 IEEE80211_EXT_RATES_IE = 50, /**< Extended data rates. */192 IEEE80211_VENDOR_IE = 221 /**< Vendor specific IE. */186 IEEE80211_SSID_IE = 0, /**< Target SSID. */ 187 IEEE80211_RATES_IE = 1, /**< Supported data rates. */ 188 IEEE80211_CHANNEL_IE = 3, /**< Current channel number. */ 189 IEEE80211_CHALLENGE_IE = 16, /**< Challenge text. */ 190 IEEE80211_RSN_IE = 48, /**< RSN. */ 191 IEEE80211_EXT_RATES_IE = 50, /**< Extended data rates. */ 192 IEEE80211_VENDOR_IE = 221 /**< Vendor specific IE. */ 193 193 } ieee80211_ie_type_t; 194 194 … … 249 249 ieee80211_bssid_info_t bssid_info; 250 250 251 /** 251 /** 252 252 * Flag indicating that data traffic is encrypted by HW key 253 * that is set up in device. 253 * that is set up in device. 254 254 */ 255 255 bool using_hw_key; … … 290 290 uint8_t dest_addr[ETH_ADDR]; 291 291 uint8_t src_addr[ETH_ADDR]; 292 uint16_t proto; /**< Big Endian value! */293 } __attribute__((packed)) __attribute__ ((aligned(2)))294 eth_header_t;292 uint16_t proto; /**< Big Endian value! */ 293 } __attribute__((packed)) __attribute__((aligned(2))) 294 eth_header_t; 295 295 296 296 /** IEEE 802.11 management header structure. */ 297 297 typedef struct { 298 uint16_t frame_ctrl; /**< Little Endian value! */299 uint16_t duration_id; /**< Little Endian value! */298 uint16_t frame_ctrl; /**< Little Endian value! */ 299 uint16_t duration_id; /**< Little Endian value! */ 300 300 uint8_t dest_addr[ETH_ADDR]; 301 301 uint8_t src_addr[ETH_ADDR]; 302 302 uint8_t bssid[ETH_ADDR]; 303 uint16_t seq_ctrl; /**< Little Endian value! */304 } __attribute__((packed)) __attribute__ ((aligned(2)))305 ieee80211_mgmt_header_t;303 uint16_t seq_ctrl; /**< Little Endian value! */ 304 } __attribute__((packed)) __attribute__((aligned(2))) 305 ieee80211_mgmt_header_t; 306 306 307 307 /** IEEE 802.11 data header structure. */ 308 308 typedef struct { 309 uint16_t frame_ctrl; /**< Little Endian value! */310 uint16_t duration_id; /**< Little Endian value! */309 uint16_t frame_ctrl; /**< Little Endian value! */ 310 uint16_t duration_id; /**< Little Endian value! */ 311 311 uint8_t address1[ETH_ADDR]; 312 312 uint8_t address2[ETH_ADDR]; 313 313 uint8_t address3[ETH_ADDR]; 314 uint16_t seq_ctrl; /**< Little Endian value! */315 } __attribute__((packed)) __attribute__ ((aligned(2)))316 ieee80211_data_header_t;314 uint16_t seq_ctrl; /**< Little Endian value! */ 315 } __attribute__((packed)) __attribute__((aligned(2))) 316 ieee80211_data_header_t; 317 317 318 318 /** IEEE 802.11 information element header. */ … … 320 320 uint8_t element_id; 321 321 uint8_t length; 322 } __attribute__((packed)) __attribute__ ((aligned(2)))323 ieee80211_ie_header_t;322 } __attribute__((packed)) __attribute__((aligned(2))) 323 ieee80211_ie_header_t; 324 324 325 325 /** IEEE 802.11 authentication frame body. */ 326 326 typedef struct { 327 uint16_t auth_alg; /**< Little Endian value! */328 uint16_t auth_trans_no; /**< Little Endian value! */329 uint16_t status; /**< Little Endian value! */330 } __attribute__((packed)) __attribute__ ((aligned(2)))331 ieee80211_auth_body_t;327 uint16_t auth_alg; /**< Little Endian value! */ 328 uint16_t auth_trans_no; /**< Little Endian value! */ 329 uint16_t status; /**< Little Endian value! */ 330 } __attribute__((packed)) __attribute__((aligned(2))) 331 ieee80211_auth_body_t; 332 332 333 333 /** IEEE 802.11 deauthentication frame body. */ 334 334 typedef struct { 335 uint16_t reason; /**< Little Endian value! */336 } __attribute__((packed)) __attribute__ ((aligned(2)))337 ieee80211_deauth_body_t;335 uint16_t reason; /**< Little Endian value! */ 336 } __attribute__((packed)) __attribute__((aligned(2))) 337 ieee80211_deauth_body_t; 338 338 339 339 /** IEEE 802.11 association request frame body. */ 340 340 typedef struct { 341 uint16_t capability; /**< Little Endian value! */342 uint16_t listen_interval; /**< Little Endian value! */343 } __attribute__((packed)) __attribute__ ((aligned(2)))344 ieee80211_assoc_req_body_t;341 uint16_t capability; /**< Little Endian value! */ 342 uint16_t listen_interval; /**< Little Endian value! */ 343 } __attribute__((packed)) __attribute__((aligned(2))) 344 ieee80211_assoc_req_body_t; 345 345 346 346 /** IEEE 802.11 association response frame body. */ 347 347 typedef struct { 348 uint16_t capability; /**< Little Endian value! */349 uint16_t status; /**< Little Endian value! */350 uint16_t aid; /**< Little Endian value! */351 } __attribute__((packed)) __attribute__ ((aligned(2)))352 ieee80211_assoc_resp_body_t;348 uint16_t capability; /**< Little Endian value! */ 349 uint16_t status; /**< Little Endian value! */ 350 uint16_t aid; /**< Little Endian value! */ 351 } __attribute__((packed)) __attribute__((aligned(2))) 352 ieee80211_assoc_resp_body_t; 353 353 354 354 /** IEEE 802.11 beacon frame body start. */ 355 355 typedef struct { 356 356 uint8_t timestamp[8]; 357 uint16_t beacon_interval; /**< Little Endian value! */358 uint16_t capability; /**< Little Endian value! */359 } __attribute__((packed)) __attribute__ ((aligned(2)))360 ieee80211_beacon_start_t;357 uint16_t beacon_interval; /**< Little Endian value! */ 358 uint16_t capability; /**< Little Endian value! */ 359 } __attribute__((packed)) __attribute__((aligned(2))) 360 ieee80211_beacon_start_t; 361 361 362 362 /** IEEE 802.11i EAPOL-Key frame format. */ … … 364 364 uint8_t proto_version; 365 365 uint8_t packet_type; 366 uint16_t body_length; /**< Big Endian value! */366 uint16_t body_length; /**< Big Endian value! */ 367 367 uint8_t descriptor_type; 368 uint16_t key_info; /**< Big Endian value! */369 uint16_t key_length; /**< Big Endian value! */368 uint16_t key_info; /**< Big Endian value! */ 369 uint16_t key_length; /**< Big Endian value! */ 370 370 uint8_t key_replay_counter[8]; 371 371 uint8_t key_nonce[32]; … … 374 374 uint8_t reserved[8]; 375 375 uint8_t key_mic[16]; 376 uint16_t key_data_length; /**< Big Endian value! */376 uint16_t key_data_length; /**< Big Endian value! */ 377 377 } __attribute__((packed)) ieee80211_eapol_key_frame_t; 378 378 379 379 #define ieee80211_scan_result_list_foreach(results, iter) \ 380 list_foreach((results).list, link, ieee80211_scan_result_link_t, (iter))381 382 static inline void ieee80211_scan_result_list_init(383 ieee80211_scan_result_list_t *results) 380 list_foreach((results).list, link, ieee80211_scan_result_link_t, (iter)) 381 382 static inline void 383 ieee80211_scan_result_list_init(ieee80211_scan_result_list_t *results) 384 384 { 385 385 list_initialize(&results->list); … … 387 387 } 388 388 389 static inline void ieee80211_scan_result_list_remove(390 ieee80211_scan_result_list_t *results,391 ieee80211_scan_result_link_t *result)389 static inline void 390 ieee80211_scan_result_list_remove(ieee80211_scan_result_list_t *results, 391 ieee80211_scan_result_link_t *result) 392 392 { 393 393 list_remove(&result->link); … … 395 395 } 396 396 397 static inline void ieee80211_scan_result_list_append(398 ieee80211_scan_result_list_t *results,399 ieee80211_scan_result_link_t *result)397 static inline void 398 ieee80211_scan_result_list_append(ieee80211_scan_result_list_t *results, 399 ieee80211_scan_result_link_t *result) 400 400 { 401 401 list_append(&result->link, &results->list); … … 403 403 } 404 404 405 extern bool ieee80211_is_fromds_frame(uint16_t frame_ctrl); 406 extern bool ieee80211_is_tods_frame(uint16_t frame_ctrl); 407 extern void ieee80211_set_connect_request(ieee80211_dev_t *ieee80211_dev); 408 extern bool ieee80211_pending_connect_request(ieee80211_dev_t *ieee80211_dev); 409 extern ieee80211_auth_phase_t ieee80211_get_auth_phase(ieee80211_dev_t 410 *ieee80211_dev); 411 extern void ieee80211_set_auth_phase(ieee80211_dev_t *ieee80211_dev, 412 ieee80211_auth_phase_t auth_phase); 413 extern int ieee80211_probe_request(ieee80211_dev_t *ieee80211_dev, 414 char *ssid); 415 extern int ieee80211_authenticate(ieee80211_dev_t *ieee80211_dev); 416 extern int ieee80211_associate(ieee80211_dev_t *ieee80211_dev, 417 char *password); 418 extern int ieee80211_deauthenticate(ieee80211_dev_t *ieee80211_dev); 419 420 #endif /* LIBN_IEEE80211_H */ 405 extern bool ieee80211_is_fromds_frame(uint16_t); 406 extern bool ieee80211_is_tods_frame(uint16_t); 407 extern void ieee80211_set_connect_request(ieee80211_dev_t *); 408 extern bool ieee80211_pending_connect_request(ieee80211_dev_t *); 409 extern ieee80211_auth_phase_t ieee80211_get_auth_phase(ieee80211_dev_t *); 410 extern void ieee80211_set_auth_phase(ieee80211_dev_t *, ieee80211_auth_phase_t); 411 extern int ieee80211_probe_request(ieee80211_dev_t *, char *); 412 extern int ieee80211_authenticate(ieee80211_dev_t *); 413 extern int ieee80211_associate(ieee80211_dev_t *, char *); 414 extern int ieee80211_deauthenticate(ieee80211_dev_t *); 415 416 #endif 421 417 422 418 /** @} -
uspace/lib/ieee80211/src/ieee80211.c
r09044cb r8a64320e 32 32 33 33 /** @file ieee80211.c 34 * 34 * 35 35 * IEEE 802.11 interface implementation. 36 36 */ … … 41 41 #include <macros.h> 42 42 #include <errno.h> 43 44 43 #include <ieee80211.h> 45 44 #include <ieee80211_impl.h> … … 48 47 #include <ops/ieee80211.h> 49 48 50 #define IEEE80211_DATA_RATES_SIZE 851 #define IEEE80211_EXT_DATA_RATES_SIZE 449 #define IEEE80211_DATA_RATES_SIZE 8 50 #define IEEE80211_EXT_DATA_RATES_SIZE 4 52 51 53 52 #define ATOMIC_GET(state) 54 53 55 54 /** Frame encapsulation used in IEEE 802.11. */ 56 static const uint8_t rfc1042_header[] = { 57 0x AA, 0xAA, 0x03, 0x00, 0x00, 0x0055 static const uint8_t rfc1042_header[] = { 56 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 58 57 }; 59 58 60 59 /** Broadcast MAC address. */ 61 60 static const uint8_t ieee80211_broadcast_mac_addr[] = { 62 0x FF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF61 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 63 62 }; 64 63 65 /** 66 * Check data frame. 67 * 64 /** Check data frame. 65 * 68 66 * @param frame_ctrl Frame control field in little endian (!). 69 * 67 * 70 68 * @return True if it is data frame, otherwise false. 69 * 71 70 */ 72 71 inline bool ieee80211_is_data_frame(uint16_t frame_ctrl) … … 74 73 frame_ctrl = uint16_t_le2host(frame_ctrl); 75 74 76 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_TYPE) 77 == IEEE80211_DATA_FRAME; 78 } 79 80 /** 81 * Check management frame. 82 * 75 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_TYPE) == 76 IEEE80211_DATA_FRAME; 77 } 78 79 /** Check management frame. 80 * 83 81 * @param frame_ctrl Frame control field in little endian (!). 84 * 82 * 85 83 * @return True if it is management frame, otherwise false. 84 * 86 85 */ 87 86 inline bool ieee80211_is_mgmt_frame(uint16_t frame_ctrl) … … 89 88 frame_ctrl = uint16_t_le2host(frame_ctrl); 90 89 91 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_TYPE) 92 == IEEE80211_MGMT_FRAME; 93 } 94 95 /** 96 * Check management beacon frame. 97 * 90 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_TYPE) == 91 IEEE80211_MGMT_FRAME; 92 } 93 94 /** Check management beacon frame. 95 * 98 96 * @param frame_ctrl Frame control field in little endian (!). 99 * 97 * 100 98 * @return True if it is beacon frame, otherwise false. 99 * 101 100 */ 102 101 inline bool ieee80211_is_beacon_frame(uint16_t frame_ctrl) … … 104 103 frame_ctrl = uint16_t_le2host(frame_ctrl); 105 104 106 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) 107 == IEEE80211_MGMT_BEACON_FRAME; 108 } 109 110 /** 111 * Check management probe response frame. 112 * 105 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) == 106 IEEE80211_MGMT_BEACON_FRAME; 107 } 108 109 /** Check management probe response frame. 110 * 113 111 * @param frame_ctrl Frame control field in little endian (!). 114 * 112 * 115 113 * @return True if it is probe resp frame, otherwise false. 114 * 116 115 */ 117 116 inline bool ieee80211_is_probe_response_frame(uint16_t frame_ctrl) … … 119 118 frame_ctrl = uint16_t_le2host(frame_ctrl); 120 119 121 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) 122 == IEEE80211_MGMT_PROBE_RESP_FRAME; 123 } 124 125 /** 126 * Check management authentication frame. 127 * 120 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) == 121 IEEE80211_MGMT_PROBE_RESP_FRAME; 122 } 123 124 /** Check management authentication frame. 125 * 128 126 * @param frame_ctrl Frame control field in little endian (!). 129 * 127 * 130 128 * @return True if it is auth frame, otherwise false. 129 * 131 130 */ 132 131 inline bool ieee80211_is_auth_frame(uint16_t frame_ctrl) … … 134 133 frame_ctrl = uint16_t_le2host(frame_ctrl); 135 134 136 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) 137 == IEEE80211_MGMT_AUTH_FRAME; 138 } 139 140 /** 141 * Check management association response frame. 142 * 135 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) == 136 IEEE80211_MGMT_AUTH_FRAME; 137 } 138 139 /** Check management association response frame. 140 * 143 141 * @param frame_ctrl Frame control field in little endian (!). 144 * 142 * 145 143 * @return True if it is assoc resp frame, otherwise false. 144 * 146 145 */ 147 146 inline bool ieee80211_is_assoc_response_frame(uint16_t frame_ctrl) … … 149 148 frame_ctrl = uint16_t_le2host(frame_ctrl); 150 149 151 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) 152 == IEEE80211_MGMT_ASSOC_RESP_FRAME; 153 } 154 155 /** 156 * Check data frame "to distribution system" direction. 157 * 150 return (frame_ctrl & IEEE80211_FRAME_CTRL_FRAME_SUBTYPE) == 151 IEEE80211_MGMT_ASSOC_RESP_FRAME; 152 } 153 154 /** Check data frame "to distribution system" direction. 155 * 158 156 * @param frame_ctrl Frame control field in little endian (!). 159 * 157 * 160 158 * @return True if it is TODS frame, otherwise false. 159 * 161 160 */ 162 161 inline bool ieee80211_is_tods_frame(uint16_t frame_ctrl) … … 167 166 } 168 167 169 /** 170 * Check data frame "from distribution system" direction. 171 * 168 /** Check data frame "from distribution system" direction. 169 * 172 170 * @param frame_ctrl Frame control field in little endian (!). 173 * 171 * 174 172 * @return True if it is FROMDS frame, otherwise false. 173 * 175 174 */ 176 175 inline bool ieee80211_is_fromds_frame(uint16_t frame_ctrl) … … 181 180 } 182 181 183 /** 184 * Check if it is data frame containing payload data. 185 * 182 /** Check if it is data frame containing payload data. 183 * 186 184 * @param frame_ctrl Frame control field in little endian (!). 187 * 185 * 188 186 * @return True if it has payload data, otherwise false. 187 * 189 188 */ 190 189 static inline bool ieee80211_has_data_frame(uint16_t frame_ctrl) … … 192 191 frame_ctrl = uint16_t_le2host(frame_ctrl); 193 192 194 return (frame_ctrl & (IEEE80211_FRAME_CTRL_FRAME_TYPE | 0x40)) 195 == IEEE80211_DATA_FRAME; 196 } 197 198 /** 199 * Check if it is encrypted frame. 200 * 193 return (frame_ctrl & (IEEE80211_FRAME_CTRL_FRAME_TYPE | 0x40)) == 194 IEEE80211_DATA_FRAME; 195 } 196 197 /** Check if it is encrypted frame. 198 * 201 199 * @param frame_ctrl Frame control field in little endian (!). 202 * 200 * 203 201 * @return True if the frame is encrypted, otherwise false. 202 * 204 203 */ 205 204 static inline bool ieee80211_is_encrypted_frame(uint16_t frame_ctrl) … … 210 209 } 211 210 212 /** 213 * Check if PAE packet is EAPOL-Key frame. 214 * 211 /** Check if PAE packet is EAPOL-Key frame. 212 * 215 213 * @param key_frame Pointer to start of EAPOL frame. 216 * 214 * 217 215 * @return True if it is EAPOL-Key frame, otherwise false. 218 */ 219 static inline bool ieee80211_is_eapol_key_frame(ieee80211_eapol_key_frame_t 220 *key_frame) 216 * 217 */ 218 static inline bool 219 ieee80211_is_eapol_key_frame(ieee80211_eapol_key_frame_t *key_frame) 221 220 { 222 221 return (key_frame->packet_type == IEEE80211_EAPOL_KEY); 223 222 } 224 223 225 226 /** 227 * Generate packet sequence number. 228 * 224 /** Generate packet sequence number. 225 * 229 226 * @param ieee80211_dev IEEE 802.11 device. 230 * 227 * 231 228 * @return True if it has payload data, otherwise false. 229 * 232 230 */ 233 231 static uint16_t ieee80211_get_sequence_number(ieee80211_dev_t *ieee80211_dev) … … 235 233 uint16_t ret_val = ieee80211_dev->sequence_number; 236 234 ieee80211_dev->sequence_number += (1 << 4); 235 237 236 return ret_val; 238 237 } 239 238 240 /** 241 * Get driver-specific structure for IEEE 802.11 device. 242 * 239 /** Get driver-specific structure for IEEE 802.11 device. 240 * 243 241 * @param ieee80211_dev IEEE 802.11 device. 244 * 242 * 245 243 * @return Driver-specific structure. 246 */ 247 void *ieee80211_get_specific(ieee80211_dev_t* ieee80211_dev) 244 * 245 */ 246 void *ieee80211_get_specific(ieee80211_dev_t *ieee80211_dev) 248 247 { 249 248 return ieee80211_dev->specific; 250 249 } 251 250 252 /** 253 * Set driver-specific structure for IEEE 802.11 device. 254 * 251 /** Set driver-specific structure for IEEE 802.11 device. 252 * 255 253 * @param ieee80211_dev IEEE 802.11 device. 256 * @param specific Driver-specific structure. 257 */ 258 void ieee80211_set_specific(ieee80211_dev_t* ieee80211_dev, 259 void *specific) 254 * @param specific Driver-specific structure. 255 * 256 */ 257 void ieee80211_set_specific(ieee80211_dev_t *ieee80211_dev, 258 void *specific) 260 259 { 261 260 ieee80211_dev->specific = specific; 262 261 } 263 262 264 /** 265 * Get related DDF device. 266 * 263 /** Get related DDF device. 264 * 267 265 * @param ieee80211_dev IEEE 802.11 device. 268 * 266 * 269 267 * @return DDF device. 270 */ 271 ddf_dev_t *ieee80211_get_ddf_dev(ieee80211_dev_t* ieee80211_dev) 268 * 269 */ 270 ddf_dev_t *ieee80211_get_ddf_dev(ieee80211_dev_t *ieee80211_dev) 272 271 { 273 272 return ieee80211_dev->ddf_dev; 274 273 } 275 274 276 /** 277 * Query current operating mode of IEEE 802.11 device. 278 * 275 /** Query current operating mode of IEEE 802.11 device. 276 * 279 277 * @param ieee80211_dev IEEE 802.11 device. 280 * 278 * 281 279 * @return Current IEEE 802.11 operating mode. 282 */ 283 ieee80211_operating_mode_t ieee80211_query_current_op_mode(ieee80211_dev_t* 284 ieee80211_dev) 280 * 281 */ 282 ieee80211_operating_mode_t 283 ieee80211_query_current_op_mode(ieee80211_dev_t *ieee80211_dev) 285 284 { 286 285 fibril_mutex_lock(&ieee80211_dev->gen_mutex); … … 291 290 } 292 291 293 /** 294 * Query current frequency of IEEE 802.11 device. 295 * 292 /** Query current frequency of IEEE 802.11 device. 293 * 296 294 * @param ieee80211_dev IEEE 802.11 device. 297 * 295 * 298 296 * @return Current device operating frequency. 299 */ 300 uint16_t ieee80211_query_current_freq(ieee80211_dev_t* ieee80211_dev) 297 * 298 */ 299 uint16_t ieee80211_query_current_freq(ieee80211_dev_t *ieee80211_dev) 301 300 { 302 301 fibril_mutex_lock(&ieee80211_dev->gen_mutex); … … 307 306 } 308 307 309 /** 310 * Query BSSID the device is connected to. 311 * 308 /** Query BSSID the device is connected to. 309 * 312 310 * Note: Expecting locked results_mutex. 313 * 311 * 314 312 * @param ieee80211_dev IEEE 802.11 device. 315 * @param bssid Pointer to structure where should be stored BSSID. 316 */ 317 void ieee80211_query_bssid(ieee80211_dev_t* ieee80211_dev, 318 nic_address_t *bssid) 313 * @param bssid Pointer to structure where should be stored BSSID. 314 * 315 */ 316 void ieee80211_query_bssid(ieee80211_dev_t *ieee80211_dev, 317 nic_address_t *bssid) 319 318 { 320 319 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 321 320 322 if (bssid) {323 ieee80211_scan_result_link_t *res_link = 324 ieee80211_dev->bssid_info.res_link;325 326 if (res_link) {327 memcpy(bssid, &res_link->scan_result.bssid, 328 sizeof(nic_address_t));321 if (bssid) { 322 ieee80211_scan_result_link_t *res_link = 323 ieee80211_dev->bssid_info.res_link; 324 325 if (res_link) { 326 memcpy(bssid, &res_link->scan_result.bssid, 327 sizeof(nic_address_t)); 329 328 } else { 330 329 nic_address_t broadcast_addr; 331 330 memcpy(broadcast_addr.address, 332 ieee80211_broadcast_mac_addr, 333 ETH_ADDR); 331 ieee80211_broadcast_mac_addr, ETH_ADDR); 334 332 memcpy(bssid, &broadcast_addr, sizeof(nic_address_t)); 335 333 } … … 339 337 } 340 338 341 /** 342 * Get AID of network we are connected to. 343 * 339 /** Get AID of network we are connected to. 340 * 344 341 * @param ieee80211_dev IEEE 802.11 device. 345 * 342 * 346 343 * @return AID. 347 */ 348 uint16_t ieee80211_get_aid(ieee80211_dev_t* ieee80211_dev) 344 * 345 */ 346 uint16_t ieee80211_get_aid(ieee80211_dev_t *ieee80211_dev) 349 347 { 350 348 fibril_mutex_lock(&ieee80211_dev->gen_mutex); … … 355 353 } 356 354 357 /** 358 * Get pairwise security suite used for HW encryption. 359 * 355 /** Get pairwise security suite used for HW encryption. 356 * 360 357 * @param ieee80211_dev IEEE 802.11 device. 361 * 358 * 362 359 * @return Security suite indicator. 363 */ 364 int ieee80211_get_pairwise_security(ieee80211_dev_t* ieee80211_dev) 360 * 361 */ 362 int ieee80211_get_pairwise_security(ieee80211_dev_t *ieee80211_dev) 365 363 { 366 364 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 367 ieee80211_scan_result_link_t *auth_link = 368 ieee80211_dev->bssid_info.res_link;365 ieee80211_scan_result_link_t *auth_link = 366 ieee80211_dev->bssid_info.res_link; 369 367 int suite = auth_link->scan_result.security.pair_alg; 370 368 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); … … 373 371 } 374 372 375 /** 376 * Check if IEEE 802.11 device is connected to network. 377 * 373 /** Check if IEEE 802.11 device is connected to network. 374 * 378 375 * @param ieee80211_dev IEEE 802.11 device. 379 * 376 * 380 377 * @return True if device is connected to network, otherwise false. 381 */ 382 bool ieee80211_is_connected(ieee80211_dev_t* ieee80211_dev) 378 * 379 */ 380 bool ieee80211_is_connected(ieee80211_dev_t *ieee80211_dev) 383 381 { 384 382 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 385 bool conn_state = 386 ieee80211_dev->current_auth_phase == IEEE80211_AUTH_CONNECTED;383 bool conn_state = 384 ieee80211_dev->current_auth_phase == IEEE80211_AUTH_CONNECTED; 387 385 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 386 388 387 return conn_state; 389 388 } 390 389 391 390 void ieee80211_set_auth_phase(ieee80211_dev_t *ieee80211_dev, 392 ieee80211_auth_phase_t auth_phase)391 ieee80211_auth_phase_t auth_phase) 393 392 { 394 393 fibril_mutex_lock(&ieee80211_dev->gen_mutex); … … 397 396 } 398 397 399 ieee80211_auth_phase_t ieee80211_get_auth_phase(ieee80211_dev_t 400 *ieee80211_dev) 398 ieee80211_auth_phase_t ieee80211_get_auth_phase(ieee80211_dev_t *ieee80211_dev) 401 399 { 402 400 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 403 401 ieee80211_auth_phase_t conn_state = ieee80211_dev->current_auth_phase; 404 402 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 403 405 404 return conn_state; 406 405 } … … 419 418 ieee80211_dev->pending_conn_req = false; 420 419 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 420 421 421 return conn_request; 422 422 } 423 423 424 /** 425 * Report current operating mode for IEEE 802.11 device. 426 * 424 /** Report current operating mode for IEEE 802.11 device. 425 * 427 426 * @param ieee80211_dev IEEE 802.11 device. 428 * @param op_mode Current IEEE 802.11 operating mode. 429 */ 430 void ieee80211_report_current_op_mode(ieee80211_dev_t* ieee80211_dev, 431 ieee80211_operating_mode_t op_mode) 427 * @param op_mode Current IEEE 802.11 operating mode. 428 * 429 */ 430 void ieee80211_report_current_op_mode(ieee80211_dev_t *ieee80211_dev, 431 ieee80211_operating_mode_t op_mode) 432 432 { 433 433 fibril_mutex_lock(&ieee80211_dev->gen_mutex); … … 436 436 } 437 437 438 /** 439 * Report current frequency for IEEE 802.11 device. 440 * 438 /** Report current frequency for IEEE 802.11 device. 439 * 441 440 * @param ieee80211_dev IEEE 802.11 device. 442 * @param freq Current device operating frequency. 443 */ 444 void ieee80211_report_current_freq(ieee80211_dev_t* ieee80211_dev, 445 uint16_t freq) 441 * @param freq Current device operating frequency. 442 * 443 */ 444 void ieee80211_report_current_freq(ieee80211_dev_t *ieee80211_dev, 445 uint16_t freq) 446 446 { 447 447 fibril_mutex_lock(&ieee80211_dev->gen_mutex); … … 450 450 } 451 451 452 /** 453 * Check if IEEE 802.11 device is ready (fully initialized). 454 * 452 /** Check if IEEE 802.11 device is ready (fully initialized). 453 * 455 454 * @param ieee80211_dev IEEE 802.11 device. 456 * 455 * 457 456 * @return True if device is ready to work, otherwise false. 458 */ 459 bool ieee80211_is_ready(ieee80211_dev_t* ieee80211_dev) 457 * 458 */ 459 bool ieee80211_is_ready(ieee80211_dev_t *ieee80211_dev) 460 460 { 461 461 fibril_mutex_lock(&ieee80211_dev->gen_mutex); … … 466 466 } 467 467 468 /** 469 * Set IEEE 802.11 device to ready state. 470 * 468 /** Set IEEE 802.11 device to ready state. 469 * 471 470 * @param ieee80211_dev IEEE 802.11 device. 472 * @param ready Ready state to be set. 473 */ 474 void ieee80211_set_ready(ieee80211_dev_t* ieee80211_dev, bool ready) 471 * @param ready Ready state to be set. 472 * 473 */ 474 void ieee80211_set_ready(ieee80211_dev_t *ieee80211_dev, bool ready) 475 475 { 476 476 fibril_mutex_lock(&ieee80211_dev->gen_mutex); … … 479 479 } 480 480 481 extern bool ieee80211_query_using_key(ieee80211_dev_t *ieee80211_dev)481 extern bool ieee80211_query_using_key(ieee80211_dev_t *ieee80211_dev) 482 482 { 483 483 fibril_mutex_lock(&ieee80211_dev->gen_mutex); … … 488 488 } 489 489 490 void ieee80211_setup_key_confirm(ieee80211_dev_t * ieee80211_dev,491 bool using_key)490 void ieee80211_setup_key_confirm(ieee80211_dev_t *ieee80211_dev, 491 bool using_key) 492 492 { 493 493 fibril_mutex_lock(&ieee80211_dev->gen_mutex); … … 502 502 ieee80211_dev_t *ieee80211_dev = (ieee80211_dev_t *) arg; 503 503 504 while (true) {504 while (true) { 505 505 ieee80211_dev->ops->scan(ieee80211_dev); 506 506 async_usleep(SCAN_PERIOD_USEC); … … 510 510 } 511 511 512 /** 513 * Implementation of NIC open callback for IEEE 802.11 devices. 514 * 512 /** Implementation of NIC open callback for IEEE 802.11 devices. 513 * 515 514 * @param fun NIC function. 516 * 515 * 517 516 * @return EOK if succeed, negative error code otherwise. 517 * 518 518 */ 519 519 static int ieee80211_open(ddf_fun_t *fun) … … 522 522 ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data); 523 523 524 if (ieee80211_dev->started) {524 if (ieee80211_dev->started) 525 525 return EOK; 526 } else { 527 ieee80211_dev->started = true; 528 } 526 527 ieee80211_dev->started = true; 529 528 530 529 int rc = ieee80211_dev->ops->start(ieee80211_dev); 531 if (rc != EOK)530 if (rc != EOK) 532 531 return rc; 533 532 534 533 /* Add scanning fibril. */ 535 534 fid_t fibril = fibril_create(ieee80211_scan, ieee80211_dev); 536 if (fibril == 0) {535 if (fibril == 0) 537 536 return ENOMEM; 538 }537 539 538 fibril_add_ready(fibril); 540 539 … … 542 541 } 543 542 544 /** 545 * Send frame handler. 546 * 547 * @param nic Pointer to NIC device. 543 /** Send frame handler. 544 * 545 * @param nic Pointer to NIC device. 548 546 * @param data Data buffer. 549 547 * @param size Data buffer size. 548 * 550 549 */ 551 550 static void ieee80211_send_frame(nic_t *nic, void *data, size_t size) 552 551 { 553 ieee80211_dev_t *ieee80211_dev = (ieee80211_dev_t *) 554 nic_get_specific(nic);555 556 ieee80211_auth_phase_t auth_phase = 557 ieee80211_get_auth_phase(ieee80211_dev);558 if (auth_phase != IEEE80211_AUTH_ASSOCIATED &&559 auth_phase != IEEE80211_AUTH_CONNECTED) {552 ieee80211_dev_t *ieee80211_dev = (ieee80211_dev_t *) 553 nic_get_specific(nic); 554 555 ieee80211_auth_phase_t auth_phase = 556 ieee80211_get_auth_phase(ieee80211_dev); 557 if ((auth_phase != IEEE80211_AUTH_ASSOCIATED) && 558 (auth_phase != IEEE80211_AUTH_CONNECTED)) 560 559 return; 561 }562 560 563 561 ieee80211_scan_result_t *auth_data = 564 &ieee80211_dev->bssid_info.res_link->scan_result;562 &ieee80211_dev->bssid_info.res_link->scan_result; 565 563 566 564 /* We drop part of IEEE 802.3 ethernet header. */ 567 565 size_t drop_bytes = sizeof(eth_header_t) - 2; 568 566 569 size_t complete_size = (size - drop_bytes) + 570 sizeof(ieee80211_data_header_t) +571 ARRAY_SIZE(rfc1042_header);567 size_t complete_size = (size - drop_bytes) + 568 sizeof(ieee80211_data_header_t) + 569 ARRAY_SIZE(rfc1042_header); 572 570 573 571 /* Init crypto data. */ … … 579 577 580 578 // TODO: Distinguish used key (pair/group) by dest address ? 581 if (ieee80211_query_using_key(ieee80211_dev)) {579 if (ieee80211_query_using_key(ieee80211_dev)) { 582 580 int sec_suite = auth_data->security.pair_alg; 583 switch (sec_suite) {584 case IEEE80211_SECURITY_SUITE_TKIP:585 head_space = IEEE80211_TKIP_HEADER_LENGTH;586 mic_space = MIC_LENGTH;587 add_mic = true;588 break;589 case IEEE80211_SECURITY_SUITE_CCMP:590 head_space = IEEE80211_CCMP_HEADER_LENGTH;591 head_data[3] = 0x20;592 break;593 default:594 break;581 switch (sec_suite) { 582 case IEEE80211_SECURITY_SUITE_TKIP: 583 head_space = IEEE80211_TKIP_HEADER_LENGTH; 584 mic_space = MIC_LENGTH; 585 add_mic = true; 586 break; 587 case IEEE80211_SECURITY_SUITE_CCMP: 588 head_space = IEEE80211_CCMP_HEADER_LENGTH; 589 head_data[3] = 0x20; 590 break; 591 default: 592 break; 595 593 } 596 594 597 595 crypto = uint16_t_le2host(IEEE80211_FRAME_CTRL_PROTECTED); 598 596 } … … 601 599 602 600 void *complete_buffer = malloc(complete_size); 601 if (!complete_buffer) 602 return; 603 603 604 memset(complete_buffer, 0, complete_size); 604 605 605 if (head_space) {606 if (head_space) 606 607 memcpy(complete_buffer + sizeof(ieee80211_data_header_t), 607 head_data, head_space); 608 } 608 head_data, head_space); 609 609 610 610 memcpy(complete_buffer + sizeof(ieee80211_data_header_t) + head_space, 611 rfc1042_header, 612 ARRAY_SIZE(rfc1042_header)); 613 614 memcpy(complete_buffer + 615 sizeof(ieee80211_data_header_t) + 616 ARRAY_SIZE(rfc1042_header) + head_space, 617 data + drop_bytes, size - drop_bytes); 611 rfc1042_header, ARRAY_SIZE(rfc1042_header)); 612 613 memcpy(complete_buffer + sizeof(ieee80211_data_header_t) + 614 ARRAY_SIZE(rfc1042_header) + head_space, 615 data + drop_bytes, size - drop_bytes); 618 616 619 617 ieee80211_data_header_t *data_header = 620 (ieee80211_data_header_t *) complete_buffer;621 data_header->frame_ctrl = 622 uint16_t_le2host(IEEE80211_DATA_FRAME) |623 uint16_t_le2host(IEEE80211_DATA_DATA_FRAME) |624 uint16_t_le2host(IEEE80211_FRAME_CTRL_TODS) |625 crypto;618 (ieee80211_data_header_t *) complete_buffer; 619 data_header->frame_ctrl = 620 uint16_t_le2host(IEEE80211_DATA_FRAME) | 621 uint16_t_le2host(IEEE80211_DATA_DATA_FRAME) | 622 uint16_t_le2host(IEEE80211_FRAME_CTRL_TODS) | 623 crypto; 626 624 data_header->seq_ctrl = ieee80211_get_sequence_number(ieee80211_dev); 627 625 628 626 /* BSSID, SA, DA. */ 629 memcpy(data_header->address1, auth_data->bssid.address, ETH_ADDR);627 memcpy(data_header->address1, auth_data->bssid.address, ETH_ADDR); 630 628 memcpy(data_header->address2, data + ETH_ADDR, ETH_ADDR); 631 629 memcpy(data_header->address3, data, ETH_ADDR); 632 630 633 if (add_mic) {631 if (add_mic) { 634 632 size_t size_wo_mic = complete_size - MIC_LENGTH; 635 633 uint8_t *tx_mic = ieee80211_dev->bssid_info.ptk + 636 TK_OFFSET + 637 IEEE80211_TKIP_TX_MIC_OFFSET; 634 TK_OFFSET + IEEE80211_TKIP_TX_MIC_OFFSET; 638 635 ieee80211_michael_mic(tx_mic, complete_buffer, size_wo_mic, 639 complete_buffer + size_wo_mic); 640 } 641 642 ieee80211_dev->ops->tx_handler(ieee80211_dev, 643 complete_buffer, 644 complete_size); 636 complete_buffer + size_wo_mic); 637 } 638 639 ieee80211_dev->ops->tx_handler(ieee80211_dev, 640 complete_buffer, complete_size); 645 641 646 642 free(complete_buffer); 647 643 } 648 644 649 /** 650 * Fill out IEEE 802.11 device functions implementations. 651 * 652 * @param ieee80211_dev IEEE 802.11 device. 653 * @param ieee80211_ops Callbacks implementation. 645 /** Fill out IEEE 802.11 device functions implementations. 646 * 647 * @param ieee80211_dev IEEE 802.11 device. 648 * @param ieee80211_ops Callbacks implementation. 654 649 * @param ieee80211_iface Interface functions implementation. 655 * @param nic_iface NIC interface functions implementation. 656 * @param nic_dev_ops NIC device functions implementation. 657 * 658 * @return EINVAL when missing pointer to ieee80211_ops or ieee80211_iface, 659 * otherwise EOK. 660 */ 661 static int ieee80211_implement(ieee80211_dev_t *ieee80211_dev, 662 ieee80211_ops_t *ieee80211_ops, ieee80211_iface_t *ieee80211_iface, 663 nic_iface_t *nic_iface, ddf_dev_ops_t *nic_dev_ops) 664 { 665 if(ieee80211_ops) { 666 if(!ieee80211_ops->start) 650 * @param nic_iface NIC interface functions implementation. 651 * @param nic_dev_ops NIC device functions implementation. 652 * 653 * @return EINVAL when missing pointer to ieee80211_ops 654 * or ieee80211_iface, otherwise EOK. 655 * 656 */ 657 static int ieee80211_implement(ieee80211_dev_t *ieee80211_dev, 658 ieee80211_ops_t *ieee80211_ops, ieee80211_iface_t *ieee80211_iface, 659 nic_iface_t *nic_iface, ddf_dev_ops_t *nic_dev_ops) 660 { 661 if (ieee80211_ops) { 662 if (!ieee80211_ops->start) 667 663 ieee80211_ops->start = ieee80211_start_impl; 668 669 if (!ieee80211_ops->tx_handler)664 665 if (!ieee80211_ops->tx_handler) 670 666 ieee80211_ops->tx_handler = ieee80211_tx_handler_impl; 671 672 if (!ieee80211_ops->set_freq)667 668 if (!ieee80211_ops->set_freq) 673 669 ieee80211_ops->set_freq = ieee80211_set_freq_impl; 674 670 675 if(!ieee80211_ops->bssid_change) 676 ieee80211_ops->bssid_change = 677 ieee80211_bssid_change_impl; 678 679 if(!ieee80211_ops->key_config) 671 if (!ieee80211_ops->bssid_change) 672 ieee80211_ops->bssid_change = ieee80211_bssid_change_impl; 673 674 if (!ieee80211_ops->key_config) 680 675 ieee80211_ops->key_config = ieee80211_key_config_impl; 681 676 682 if (!ieee80211_ops->scan)677 if (!ieee80211_ops->scan) 683 678 ieee80211_ops->scan = ieee80211_scan_impl; 684 } else {679 } else 685 680 return EINVAL; 686 }687 681 688 682 ieee80211_dev->ops = ieee80211_ops; 689 683 690 if (ieee80211_iface) {691 if (nic_dev_ops)684 if (ieee80211_iface) { 685 if (nic_dev_ops) 692 686 if (!nic_dev_ops->interfaces[IEEE80211_DEV_IFACE]) 693 nic_dev_ops->interfaces[IEEE80211_DEV_IFACE] = 694 ieee80211_iface;695 696 if (!ieee80211_iface->get_scan_results)697 ieee80211_iface->get_scan_results = 698 ieee80211_get_scan_results_impl;699 700 if (!ieee80211_iface->connect)687 nic_dev_ops->interfaces[IEEE80211_DEV_IFACE] = 688 ieee80211_iface; 689 690 if (!ieee80211_iface->get_scan_results) 691 ieee80211_iface->get_scan_results = 692 ieee80211_get_scan_results_impl; 693 694 if (!ieee80211_iface->connect) 701 695 ieee80211_iface->connect = ieee80211_connect_impl; 702 696 703 if (!ieee80211_iface->disconnect)697 if (!ieee80211_iface->disconnect) 704 698 ieee80211_iface->disconnect = ieee80211_disconnect_impl; 705 } else {699 } else 706 700 return EINVAL; 707 } 708 709 if(nic_dev_ops) { 710 if(!nic_dev_ops->open) 701 702 if (nic_dev_ops) { 703 if (!nic_dev_ops->open) 711 704 nic_dev_ops->open = ieee80211_open; 712 } else {705 } else 713 706 return EINVAL; 714 }715 707 716 708 ieee80211_dev->iface = ieee80211_iface; … … 721 713 } 722 714 723 /** 724 * Allocate IEEE802.11 device structure. 725 * 715 /** Allocate IEEE802.11 device structure. 716 * 726 717 * @return Pointer to allocated IEEE802.11 device structure. 718 * 727 719 */ 728 720 ieee80211_dev_t *ieee80211_device_create() … … 731 723 } 732 724 733 /** 734 * Initialize an IEEE802.11 framework structure. 735 * 725 /** Initialize an IEEE802.11 framework structure. 726 * 736 727 * @param ieee80211_dev Device structure to initialize. 737 * @param ddf_dev Pointer to backing DDF device structure.738 * 728 * @param ddf_dev Pointer to backing DDF device structure. 729 * 739 730 * @return EOK if succeed, negative error code otherwise. 731 * 740 732 */ 741 733 int ieee80211_device_init(ieee80211_dev_t *ieee80211_dev, ddf_dev_t *ddf_dev) … … 748 740 ieee80211_dev->current_op_mode = IEEE80211_OPMODE_STATION; 749 741 ieee80211_dev->current_auth_phase = IEEE80211_AUTH_DISCONNECTED; 750 memcpy(ieee80211_dev->bssid_mask.address, ieee80211_broadcast_mac_addr, 751 ETH_ADDR); 742 743 memcpy(ieee80211_dev->bssid_mask.address, ieee80211_broadcast_mac_addr, 744 ETH_ADDR); 752 745 753 746 ieee80211_scan_result_list_init(&ieee80211_dev->ap_list); … … 759 752 /* Bind NIC to device */ 760 753 nic_t *nic = nic_create_and_bind(ddf_dev); 761 if (!nic) {754 if (!nic) 762 755 return ENOMEM; 763 }764 756 765 757 nic_set_specific(nic, ieee80211_dev); … … 768 760 } 769 761 770 /** 771 * IEEE802.11 WiFi framework initialization.772 * 773 * @param ieee80211_ dev Device structure to initialize.774 * @param ieee80211_ops Structure with implemented IEEE802.11device operations.775 * @param ieee80211_iface Structure with implemented IEEE802.11 interface776 * operations.777 * 762 /** IEEE802.11 WiFi framework initialization. 763 * 764 * @param ieee80211_dev Device structure to initialize. 765 * @param ieee80211_ops Structure with implemented IEEE802.11 766 * device operations. 767 * @param ieee80211_iface Structure with implemented IEEE802.11 768 * interface operations. 769 * 778 770 * @return EOK if succeed, negative error code otherwise. 779 */ 780 int ieee80211_init(ieee80211_dev_t *ieee80211_dev, 781 ieee80211_ops_t *ieee80211_ops, ieee80211_iface_t *ieee80211_iface, 782 nic_iface_t *ieee80211_nic_iface, ddf_dev_ops_t *ieee80211_nic_dev_ops) 783 { 784 int rc = ieee80211_implement(ieee80211_dev, 785 ieee80211_ops, ieee80211_iface, 786 ieee80211_nic_iface, ieee80211_nic_dev_ops); 787 if(rc != EOK) { 771 * 772 */ 773 int ieee80211_init(ieee80211_dev_t *ieee80211_dev, 774 ieee80211_ops_t *ieee80211_ops, ieee80211_iface_t *ieee80211_iface, 775 nic_iface_t *ieee80211_nic_iface, ddf_dev_ops_t *ieee80211_nic_dev_ops) 776 { 777 int rc = ieee80211_implement(ieee80211_dev, 778 ieee80211_ops, ieee80211_iface, 779 ieee80211_nic_iface, ieee80211_nic_dev_ops); 780 if (rc != EOK) 788 781 return rc; 789 }790 782 791 783 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 792 784 793 /* *TODO: Set NIC handlers here. */785 /* TODO: Set NIC handlers here. */ 794 786 nic_set_send_frame_handler(nic, ieee80211_send_frame); 795 787 796 ddf_fun_t *fun = ddf_fun_create(ieee80211_dev->ddf_dev, fun_exposed, 797 "port0");798 if (fun == NULL) {788 ddf_fun_t *fun = ddf_fun_create(ieee80211_dev->ddf_dev, fun_exposed, 789 "port0"); 790 if (fun == NULL) 799 791 return EINVAL; 800 }801 792 802 793 nic_set_ddf_fun(nic, fun); … … 808 799 return rc; 809 800 } 801 810 802 rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC); 811 803 if (rc != EOK) { … … 813 805 return rc; 814 806 } 807 815 808 rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_IEEE80211); 816 809 if (rc != EOK) { … … 822 815 } 823 816 824 /** 825 * Convert frequency value to channel number. 826 * 817 /** Convert frequency value to channel number. 818 * 827 819 * @param freq IEEE 802.11 operating frequency. 828 * 820 * 829 821 * @return Operating channel number. 822 * 830 823 */ 831 824 static uint8_t ieee80211_freq_to_channel(uint16_t freq) … … 835 828 836 829 static void ieee80211_prepare_ie_header(void **ie_header, 837 uint8_t id, uint8_t length, void *data)830 uint8_t id, uint8_t length, void *data) 838 831 { 839 832 ieee80211_ie_header_t *header = 840 (ieee80211_ie_header_t *) *ie_header;833 (ieee80211_ie_header_t *) *ie_header; 841 834 842 835 header->element_id = id; … … 845 838 memcpy(*ie_header + sizeof(ieee80211_ie_header_t), data, length); 846 839 847 *ie_header = (void *) ((void *) header + 848 sizeof(ieee80211_ie_header_t) + length); 849 } 850 851 /** 852 * Probe request implementation. 853 * 840 *ie_header = (void *) ((void *) header + 841 sizeof(ieee80211_ie_header_t) + length); 842 } 843 844 /** Probe request implementation. 845 * 854 846 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 855 * @param ssid Probing SSID or NULL if broadcast.856 * 847 * @param ssid Probing SSID or NULL if broadcast. 848 * 857 849 * @return EOK if succeed, negative error code otherwise. 850 * 858 851 */ 859 852 int ieee80211_probe_request(ieee80211_dev_t *ieee80211_dev, char *ssid) … … 866 859 size_t channel_data_size = 1; 867 860 868 uint8_t channel = 869 ieee80211_freq_to_channel(ieee80211_dev->current_freq); 870 871 /* 4 headers - (ssid, rates, ext rates, current channel) and their data 872 * lengths. 861 uint8_t channel = 862 ieee80211_freq_to_channel(ieee80211_dev->current_freq); 863 864 /* 865 * 4 headers - (ssid, rates, ext rates, current channel) 866 * and their data lengths. 873 867 */ 874 size_t payload_size = 875 sizeof(ieee80211_ie_header_t) * 4 +876 ssid_data_size +877 IEEE80211_DATA_RATES_SIZE + IEEE80211_EXT_DATA_RATES_SIZE +878 channel_data_size;868 size_t payload_size = 869 sizeof(ieee80211_ie_header_t) * 4 + 870 ssid_data_size + 871 IEEE80211_DATA_RATES_SIZE + IEEE80211_EXT_DATA_RATES_SIZE + 872 channel_data_size; 879 873 880 874 size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + payload_size; 881 875 void *buffer = malloc(buffer_size); 876 if (!buffer) 877 return ENOMEM; 878 882 879 memset(buffer, 0, buffer_size); 883 880 884 ieee80211_mgmt_header_t *mgmt_header = 885 (ieee80211_mgmt_header_t *) buffer; 886 887 mgmt_header->frame_ctrl = host2uint16_t_le( 888 IEEE80211_MGMT_FRAME | 889 IEEE80211_MGMT_PROBE_REQ_FRAME 890 ); 881 ieee80211_mgmt_header_t *mgmt_header = 882 (ieee80211_mgmt_header_t *) buffer; 883 884 mgmt_header->frame_ctrl = 885 host2uint16_t_le(IEEE80211_MGMT_FRAME | 886 IEEE80211_MGMT_PROBE_REQ_FRAME); 891 887 memcpy(mgmt_header->dest_addr, ieee80211_broadcast_mac_addr, ETH_ADDR); 892 888 memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR); 893 889 memcpy(mgmt_header->bssid, ieee80211_broadcast_mac_addr, ETH_ADDR); 894 mgmt_header->seq_ctrl = 895 host2uint16_t_le(ieee80211_get_sequence_number(ieee80211_dev));890 mgmt_header->seq_ctrl = 891 host2uint16_t_le(ieee80211_get_sequence_number(ieee80211_dev)); 896 892 897 893 /* Jump to payload. */ 898 894 void *it = (void *) buffer + sizeof(ieee80211_mgmt_header_t); 899 ieee80211_prepare_ie_header(&it, IEEE80211_SSID_IE, ssid_data_size, 900 (void *) ssid); 901 ieee80211_prepare_ie_header(&it, IEEE80211_RATES_IE, 902 IEEE80211_DATA_RATES_SIZE, 903 (void *) &ieee80211bg_data_rates); 904 ieee80211_prepare_ie_header(&it, IEEE80211_EXT_RATES_IE, 905 IEEE80211_EXT_DATA_RATES_SIZE, 906 (void *) &ieee80211bg_data_rates[IEEE80211_DATA_RATES_SIZE]); 907 ieee80211_prepare_ie_header(&it, IEEE80211_CHANNEL_IE, 908 channel_data_size, (void *) &channel); 895 ieee80211_prepare_ie_header(&it, IEEE80211_SSID_IE, ssid_data_size, 896 (void *) ssid); 897 ieee80211_prepare_ie_header(&it, IEEE80211_RATES_IE, 898 IEEE80211_DATA_RATES_SIZE, (void *) &ieee80211bg_data_rates); 899 ieee80211_prepare_ie_header(&it, IEEE80211_EXT_RATES_IE, 900 IEEE80211_EXT_DATA_RATES_SIZE, 901 (void *) &ieee80211bg_data_rates[IEEE80211_DATA_RATES_SIZE]); 902 ieee80211_prepare_ie_header(&it, IEEE80211_CHANNEL_IE, 903 channel_data_size, (void *) &channel); 909 904 910 905 ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size); … … 915 910 } 916 911 917 /** 918 * IEEE 802.11 authentication implementation. 919 * 912 /** IEEE 802.11 authentication implementation. 913 * 920 914 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 921 * 915 * 922 916 * @return EOK if succeed, negative error code otherwise. 917 * 923 918 */ 924 919 int ieee80211_authenticate(ieee80211_dev_t *ieee80211_dev) … … 929 924 930 925 ieee80211_scan_result_t *auth_data = 931 &ieee80211_dev->bssid_info.res_link->scan_result;932 933 size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + 934 sizeof(ieee80211_auth_body_t);926 &ieee80211_dev->bssid_info.res_link->scan_result; 927 928 size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + 929 sizeof(ieee80211_auth_body_t); 935 930 936 931 void *buffer = malloc(buffer_size); 932 if (!buffer) 933 return ENOMEM; 934 937 935 memset(buffer, 0, buffer_size); 938 936 939 ieee80211_mgmt_header_t *mgmt_header = 940 (ieee80211_mgmt_header_t *) buffer; 941 942 mgmt_header->frame_ctrl = host2uint16_t_le( 943 IEEE80211_MGMT_FRAME | 944 IEEE80211_MGMT_AUTH_FRAME 945 ); 937 ieee80211_mgmt_header_t *mgmt_header = 938 (ieee80211_mgmt_header_t *) buffer; 939 940 mgmt_header->frame_ctrl = 941 host2uint16_t_le(IEEE80211_MGMT_FRAME | 942 IEEE80211_MGMT_AUTH_FRAME); 946 943 memcpy(mgmt_header->dest_addr, auth_data->bssid.address, ETH_ADDR); 947 944 memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR); … … 949 946 950 947 ieee80211_auth_body_t *auth_body = 951 (ieee80211_auth_body_t *)952 (buffer + sizeof(ieee80211_mgmt_header_t));948 (ieee80211_auth_body_t *) 949 (buffer + sizeof(ieee80211_mgmt_header_t)); 953 950 auth_body->auth_alg = host2uint16_t_le(0); 954 951 auth_body->auth_trans_no = host2uint16_t_le(1); … … 961 958 } 962 959 963 /** 964 * IEEE 802.11 association implementation. 965 * 960 /** IEEE 802.11 association implementation. 961 * 966 962 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 967 * @param password Passphrase to be used in encrypted communication or NULL968 * for open networks.969 * 963 * @param password Passphrase to be used in encrypted communication 964 * or NULL for open networks. 965 * 970 966 * @return EOK if succeed, negative error code otherwise. 971 */ 972 int ieee80211_associate(ieee80211_dev_t *ieee80211_dev, char *password) 967 * 968 */ 969 int ieee80211_associate(ieee80211_dev_t *ieee80211_dev, char *password) 973 970 { 974 971 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); … … 977 974 978 975 ieee80211_scan_result_link_t *auth_link = 979 ieee80211_dev->bssid_info.res_link;976 ieee80211_dev->bssid_info.res_link; 980 977 981 978 ieee80211_scan_result_t *auth_data = &auth_link->scan_result; … … 983 980 size_t ssid_data_size = str_size(auth_data->ssid); 984 981 985 size_t payload_size = 986 sizeof(ieee80211_ie_header_t) * 3 +987 ssid_data_size +988 IEEE80211_DATA_RATES_SIZE +989 IEEE80211_EXT_DATA_RATES_SIZE;990 991 size_t buffer_size = 992 sizeof(ieee80211_mgmt_header_t) +993 sizeof(ieee80211_assoc_req_body_t) +994 payload_size;995 996 if (auth_data->security.type == IEEE80211_SECURITY_WPA ||997 auth_data->security.type == IEEE80211_SECURITY_WPA2) {982 size_t payload_size = 983 sizeof(ieee80211_ie_header_t) * 3 + 984 ssid_data_size + 985 IEEE80211_DATA_RATES_SIZE + 986 IEEE80211_EXT_DATA_RATES_SIZE; 987 988 size_t buffer_size = 989 sizeof(ieee80211_mgmt_header_t) + 990 sizeof(ieee80211_assoc_req_body_t) + 991 payload_size; 992 993 if ((auth_data->security.type == IEEE80211_SECURITY_WPA) || 994 (auth_data->security.type == IEEE80211_SECURITY_WPA2)) 998 995 buffer_size += auth_link->auth_ie_len; 999 }1000 996 1001 997 void *buffer = malloc(buffer_size); 998 if (!buffer) 999 return ENOMEM; 1000 1002 1001 memset(buffer, 0, buffer_size); 1003 1002 1004 ieee80211_mgmt_header_t *mgmt_header = 1005 (ieee80211_mgmt_header_t *) buffer; 1006 1007 mgmt_header->frame_ctrl = host2uint16_t_le( 1008 IEEE80211_MGMT_FRAME | 1009 IEEE80211_MGMT_ASSOC_REQ_FRAME 1010 ); 1003 ieee80211_mgmt_header_t *mgmt_header = 1004 (ieee80211_mgmt_header_t *) buffer; 1005 1006 mgmt_header->frame_ctrl = 1007 host2uint16_t_le(IEEE80211_MGMT_FRAME | 1008 IEEE80211_MGMT_ASSOC_REQ_FRAME); 1011 1009 memcpy(mgmt_header->dest_addr, auth_data->bssid.address, ETH_ADDR); 1012 1010 memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR); … … 1014 1012 1015 1013 ieee80211_assoc_req_body_t *assoc_body = 1016 (ieee80211_assoc_req_body_t *)1017 (buffer + sizeof(ieee80211_mgmt_header_t));1014 (ieee80211_assoc_req_body_t *) 1015 (buffer + sizeof(ieee80211_mgmt_header_t)); 1018 1016 assoc_body->listen_interval = host2uint16_t_le(1); 1019 1017 1020 1018 /* Jump to payload. */ 1021 1019 void *it = buffer + sizeof(ieee80211_mgmt_header_t) + 1022 sizeof(ieee80211_assoc_req_body_t); 1023 ieee80211_prepare_ie_header(&it, IEEE80211_SSID_IE, 1024 ssid_data_size, (void *) auth_data->ssid); 1025 ieee80211_prepare_ie_header(&it, IEEE80211_RATES_IE, 1026 IEEE80211_DATA_RATES_SIZE, 1027 (void *) &ieee80211bg_data_rates); 1028 ieee80211_prepare_ie_header(&it, IEEE80211_EXT_RATES_IE, 1029 IEEE80211_EXT_DATA_RATES_SIZE, 1030 (void *) &ieee80211bg_data_rates[IEEE80211_DATA_RATES_SIZE]); 1031 1032 if(auth_data->security.type != IEEE80211_SECURITY_OPEN) { 1020 sizeof(ieee80211_assoc_req_body_t); 1021 ieee80211_prepare_ie_header(&it, IEEE80211_SSID_IE, 1022 ssid_data_size, (void *) auth_data->ssid); 1023 ieee80211_prepare_ie_header(&it, IEEE80211_RATES_IE, 1024 IEEE80211_DATA_RATES_SIZE, (void *) &ieee80211bg_data_rates); 1025 ieee80211_prepare_ie_header(&it, IEEE80211_EXT_RATES_IE, 1026 IEEE80211_EXT_DATA_RATES_SIZE, 1027 (void *) &ieee80211bg_data_rates[IEEE80211_DATA_RATES_SIZE]); 1028 1029 if (auth_data->security.type != IEEE80211_SECURITY_OPEN) 1033 1030 assoc_body->capability |= host2uint16_t_le(CAP_SECURITY); 1034 } 1035 1036 if(auth_data->security.type == IEEE80211_SECURITY_WPA || 1037 auth_data->security.type == IEEE80211_SECURITY_WPA2) { 1038 memcpy(it, auth_link->auth_ie, auth_link->auth_ie_len); 1039 } 1031 1032 if ((auth_data->security.type == IEEE80211_SECURITY_WPA) || 1033 (auth_data->security.type == IEEE80211_SECURITY_WPA2)) 1034 memcpy(it, auth_link->auth_ie, auth_link->auth_ie_len); 1040 1035 1041 1036 ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size); 1042 1037 1043 /* 1044 * Save password to be used in eventual authentication handshake. 1038 /* 1039 * Save password to be used in eventual authentication handshake. 1045 1040 */ 1046 1041 memset(ieee80211_dev->bssid_info.password, 0, IEEE80211_MAX_PASSW_LEN); 1047 memcpy(ieee80211_dev->bssid_info.password, password, 1048 str_size(password));1042 memcpy(ieee80211_dev->bssid_info.password, password, 1043 str_size(password)); 1049 1044 1050 1045 free(buffer); … … 1053 1048 } 1054 1049 1055 /** 1056 * IEEE 802.11 deauthentication implementation. 1057 * 1050 /** IEEE 802.11 deauthentication implementation. 1051 * 1058 1052 * Note: Expecting locked results_mutex or scan_mutex. 1059 * 1053 * 1060 1054 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 1061 * 1055 * 1062 1056 * @return EOK if succeed, negative error code otherwise. 1057 * 1063 1058 */ 1064 1059 int ieee80211_deauthenticate(ieee80211_dev_t *ieee80211_dev) 1065 1060 { 1066 1061 ieee80211_scan_result_t *auth_data = 1067 &ieee80211_dev->bssid_info.res_link->scan_result;1062 &ieee80211_dev->bssid_info.res_link->scan_result; 1068 1063 1069 1064 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); … … 1071 1066 nic_query_address(nic, &nic_address); 1072 1067 1073 size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + 1074 sizeof(ieee80211_deauth_body_t); 1068 size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + 1069 sizeof(ieee80211_deauth_body_t); 1070 1075 1071 void *buffer = malloc(buffer_size); 1072 if (!buffer) 1073 return ENOMEM; 1074 1076 1075 memset(buffer, 0, buffer_size); 1077 1076 1078 ieee80211_mgmt_header_t *mgmt_header = 1079 (ieee80211_mgmt_header_t *) buffer; 1080 1081 mgmt_header->frame_ctrl = host2uint16_t_le( 1082 IEEE80211_MGMT_FRAME | 1083 IEEE80211_MGMT_DEAUTH_FRAME 1084 ); 1077 ieee80211_mgmt_header_t *mgmt_header = 1078 (ieee80211_mgmt_header_t *) buffer; 1079 1080 mgmt_header->frame_ctrl = 1081 host2uint16_t_le(IEEE80211_MGMT_FRAME | 1082 IEEE80211_MGMT_DEAUTH_FRAME); 1085 1083 memcpy(mgmt_header->dest_addr, auth_data->bssid.address, ETH_ADDR); 1086 1084 memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR); … … 1094 1092 ieee80211_dev->ops->bssid_change(ieee80211_dev, false); 1095 1093 1096 if (ieee80211_query_using_key(ieee80211_dev))1094 if (ieee80211_query_using_key(ieee80211_dev)) 1097 1095 ieee80211_dev->ops->key_config(ieee80211_dev, NULL, false); 1098 1096 … … 1103 1101 1104 1102 static void ieee80211_process_auth_info(ieee80211_scan_result_link_t *ap_data, 1105 void *buffer)1103 void *buffer) 1106 1104 { 1107 1105 uint8_t *it = (uint8_t *) buffer; 1108 1106 1109 1107 uint16_t *version = (uint16_t *) it; 1110 if (uint16_t_le2host(*version) != 0x1) {1108 if (uint16_t_le2host(*version) != 0x1) { 1111 1109 ap_data->scan_result.security.type = -1; 1112 1110 return; … … 1115 1113 it += sizeof(uint16_t); 1116 1114 1117 uint32_t group_cipher = *(it +3);1118 switch (group_cipher) {1119 case IEEE80211_AUTH_CIPHER_TKIP:1120 ap_data->scan_result.security.group_alg =1121 IEEE80211_SECURITY_SUITE_TKIP;1122 break;1123 case IEEE80211_AUTH_CIPHER_CCMP:1124 ap_data->scan_result.security.group_alg =1125 IEEE80211_SECURITY_SUITE_CCMP;1126 break;1127 default:1128 ap_data->scan_result.security.group_alg = -1;1129 } 1130 1131 it += 4 *sizeof(uint8_t);1115 uint32_t group_cipher = *(it + 3); 1116 switch (group_cipher) { 1117 case IEEE80211_AUTH_CIPHER_TKIP: 1118 ap_data->scan_result.security.group_alg = 1119 IEEE80211_SECURITY_SUITE_TKIP; 1120 break; 1121 case IEEE80211_AUTH_CIPHER_CCMP: 1122 ap_data->scan_result.security.group_alg = 1123 IEEE80211_SECURITY_SUITE_CCMP; 1124 break; 1125 default: 1126 ap_data->scan_result.security.group_alg = -1; 1127 } 1128 1129 it += 4 * sizeof(uint8_t); 1132 1130 1133 1131 uint16_t *pairwise_count = (uint16_t *) it; 1134 uint32_t pairwise_cipher = *(it +sizeof(uint16_t)+3);1135 switch (pairwise_cipher) {1136 case IEEE80211_AUTH_CIPHER_TKIP:1137 ap_data->scan_result.security.pair_alg =1138 IEEE80211_SECURITY_SUITE_TKIP;1139 break;1140 case IEEE80211_AUTH_CIPHER_CCMP:1141 ap_data->scan_result.security.pair_alg =1142 IEEE80211_SECURITY_SUITE_CCMP;1143 break;1144 default:1145 ap_data->scan_result.security.pair_alg = -1;1146 } 1147 1148 it += 2 *sizeof(uint16_t) +1149 uint16_t_le2host(*pairwise_count)*sizeof(uint32_t);1150 1151 uint32_t auth_suite = *(it +3);1152 switch (auth_suite) {1153 case IEEE80211_AUTH_AKM_PSK:1154 ap_data->scan_result.security.auth =1155 IEEE80211_SECURITY_AUTH_PSK;1156 break;1157 case IEEE80211_AUTH_AKM_8021X:1158 ap_data->scan_result.security.auth =1159 IEEE80211_SECURITY_AUTH_8021X;1160 break;1161 default:1162 ap_data->scan_result.security.auth = -1;1132 uint32_t pairwise_cipher = *(it + sizeof(uint16_t) + 3); 1133 switch (pairwise_cipher) { 1134 case IEEE80211_AUTH_CIPHER_TKIP: 1135 ap_data->scan_result.security.pair_alg = 1136 IEEE80211_SECURITY_SUITE_TKIP; 1137 break; 1138 case IEEE80211_AUTH_CIPHER_CCMP: 1139 ap_data->scan_result.security.pair_alg = 1140 IEEE80211_SECURITY_SUITE_CCMP; 1141 break; 1142 default: 1143 ap_data->scan_result.security.pair_alg = -1; 1144 } 1145 1146 it += 2 * sizeof(uint16_t) + 1147 uint16_t_le2host(*pairwise_count) * sizeof(uint32_t); 1148 1149 uint32_t auth_suite = *(it + 3); 1150 switch (auth_suite) { 1151 case IEEE80211_AUTH_AKM_PSK: 1152 ap_data->scan_result.security.auth = 1153 IEEE80211_SECURITY_AUTH_PSK; 1154 break; 1155 case IEEE80211_AUTH_AKM_8021X: 1156 ap_data->scan_result.security.auth = 1157 IEEE80211_SECURITY_AUTH_8021X; 1158 break; 1159 default: 1160 ap_data->scan_result.security.auth = -1; 1163 1161 } 1164 1162 } 1165 1163 1166 1164 static void copy_auth_ie(ieee80211_ie_header_t *ie_header, 1167 ieee80211_scan_result_link_t *ap_data, void *it)1168 { 1169 ap_data->auth_ie_len = ie_header->length + 1170 sizeof(ieee80211_ie_header_t);1165 ieee80211_scan_result_link_t *ap_data, void *it) 1166 { 1167 ap_data->auth_ie_len = ie_header->length + 1168 sizeof(ieee80211_ie_header_t); 1171 1169 1172 1170 memcpy(ap_data->auth_ie, it, ap_data->auth_ie_len); … … 1174 1172 1175 1173 static uint8_t *ieee80211_process_ies(ieee80211_dev_t *ieee80211_dev, 1176 ieee80211_scan_result_link_t *ap_data, void *buffer, size_t buffer_size)1174 ieee80211_scan_result_link_t *ap_data, void *buffer, size_t buffer_size) 1177 1175 { 1178 1176 void *it = buffer; 1179 while ((it + sizeof(ieee80211_ie_header_t)) < buffer + buffer_size) {1180 ieee80211_ie_header_t *ie_header = 1181 (ieee80211_ie_header_t *) it;1177 while ((it + sizeof(ieee80211_ie_header_t)) < buffer + buffer_size) { 1178 ieee80211_ie_header_t *ie_header = 1179 (ieee80211_ie_header_t *) it; 1182 1180 uint8_t *channel; 1183 1181 uint32_t oui; 1184 switch(ie_header->element_id) { 1185 case IEEE80211_CHANNEL_IE: 1186 if(!ap_data) 1182 1183 switch (ie_header->element_id) { 1184 case IEEE80211_CHANNEL_IE: 1185 if (!ap_data) 1186 break; 1187 1188 channel = (uint8_t *) 1189 (it + sizeof(ieee80211_ie_header_t)); 1190 ap_data->scan_result.channel = *channel; 1191 break; 1192 case IEEE80211_RSN_IE: 1193 if (!ap_data) 1194 break; 1195 1196 ap_data->scan_result.security.type = 1197 IEEE80211_SECURITY_WPA2; 1198 ieee80211_process_auth_info(ap_data, 1199 it + sizeof(ieee80211_ie_header_t)); 1200 copy_auth_ie(ie_header, ap_data, it); 1201 break; 1202 case IEEE80211_VENDOR_IE: 1203 oui = uint32be_from_seq(it + 1204 sizeof(ieee80211_ie_header_t)); 1205 1206 if (oui == WPA_OUI) { 1207 if (!ap_data) 1187 1208 break; 1188 channel = (uint8_t *) 1189 (it + sizeof(ieee80211_ie_header_t)); 1190 ap_data->scan_result.channel = *channel; 1191 break; 1192 case IEEE80211_RSN_IE: 1193 if(!ap_data) 1209 1210 /* Prefering WPA2. */ 1211 if (ap_data->scan_result.security.type == 1212 IEEE80211_SECURITY_WPA2) 1194 1213 break; 1214 1195 1215 ap_data->scan_result.security.type = 1196 IEEE80211_SECURITY_WPA2; 1197 ieee80211_process_auth_info(ap_data, 1198 it + sizeof(ieee80211_ie_header_t)); 1216 IEEE80211_SECURITY_WPA; 1217 1218 ieee80211_process_auth_info(ap_data, 1219 it + sizeof(ieee80211_ie_header_t) + 1220 sizeof(uint32_t)); 1199 1221 copy_auth_ie(ie_header, ap_data, it); 1200 break; 1201 case IEEE80211_VENDOR_IE: 1202 oui = uint32be_from_seq(it + 1203 sizeof(ieee80211_ie_header_t)); 1204 if(oui == WPA_OUI) { 1205 if(!ap_data) 1206 break; 1207 /* Prefering WPA2. */ 1208 if(ap_data->scan_result.security.type == 1209 IEEE80211_SECURITY_WPA2) { 1210 break; 1211 } 1212 ap_data->scan_result.security.type = 1213 IEEE80211_SECURITY_WPA; 1214 ieee80211_process_auth_info(ap_data, 1215 it + 1216 sizeof(ieee80211_ie_header_t) + 1217 sizeof(uint32_t)); 1218 copy_auth_ie(ie_header, ap_data, it); 1219 } else if(oui == GTK_OUI) { 1220 return it + 1221 sizeof(ieee80211_ie_header_t) + 1222 sizeof(uint32_t); 1223 } 1222 } else if (oui == GTK_OUI) { 1223 return it + 1224 sizeof(ieee80211_ie_header_t) + 1225 sizeof(uint32_t); 1226 } 1224 1227 } 1228 1225 1229 it += sizeof(ieee80211_ie_header_t) + ie_header->length; 1226 1230 } … … 1229 1233 } 1230 1234 1231 /** 1232 * Process probe response and store results. 1233 * 1235 /** Process probe response and store results. 1236 * 1234 1237 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 1235 * @param mgmt_header Pointer to start of management frame header.1236 * 1238 * @param mgmt_header Pointer to start of management frame header. 1239 * 1237 1240 * @return EOK if succeed, negative error code otherwise. 1238 */ 1239 static int ieee80211_process_probe_response(ieee80211_dev_t *ieee80211_dev, 1240 ieee80211_mgmt_header_t *mgmt_header, size_t buffer_size) 1241 { 1242 ieee80211_beacon_start_t *beacon_body = (ieee80211_beacon_start_t *) 1243 ((void *)mgmt_header + sizeof(ieee80211_mgmt_header_t)); 1244 1245 ieee80211_ie_header_t *ssid_ie_header = (ieee80211_ie_header_t *) 1246 ((void *)beacon_body + sizeof(ieee80211_beacon_start_t)); 1241 * 1242 */ 1243 static int ieee80211_process_probe_response(ieee80211_dev_t *ieee80211_dev, 1244 ieee80211_mgmt_header_t *mgmt_header, size_t buffer_size) 1245 { 1246 ieee80211_beacon_start_t *beacon_body = (ieee80211_beacon_start_t *) 1247 ((void *) mgmt_header + sizeof(ieee80211_mgmt_header_t)); 1248 1249 ieee80211_ie_header_t *ssid_ie_header = (ieee80211_ie_header_t *) 1250 ((void *) beacon_body + sizeof(ieee80211_beacon_start_t)); 1247 1251 1248 1252 /* Not empty SSID. */ 1249 if (ssid_ie_header->length > 0) {1253 if (ssid_ie_header->length > 0) { 1250 1254 ieee80211_scan_result_list_t *result_list = 1251 &ieee80211_dev->ap_list;1252 1253 uint8_t *ssid_start = (uint8_t *) ((void *) ssid_ie_header +1254 sizeof(ieee80211_ie_header_t));1255 &ieee80211_dev->ap_list; 1256 1257 uint8_t *ssid_start = (uint8_t *) ((void *) ssid_ie_header + 1258 sizeof(ieee80211_ie_header_t)); 1255 1259 char ssid[IEEE80211_MAX_SSID_LENGTH]; 1260 1256 1261 memcpy(ssid, ssid_start, ssid_ie_header->length); 1257 1262 ssid[ssid_ie_header->length] = '\0'; … … 1259 1264 /* Check whether SSID is already in results. */ 1260 1265 ieee80211_scan_result_list_foreach(*result_list, result) { 1261 if (!str_cmp(ssid, result->scan_result.ssid)) {1266 if (!str_cmp(ssid, result->scan_result.ssid)) { 1262 1267 result->last_beacon = time(NULL); 1263 1268 return EOK; … … 1266 1271 1267 1272 /* Results are full. */ 1268 if (result_list->size == IEEE80211_MAX_RESULTS_LENGTH - 1) {1273 if (result_list->size == IEEE80211_MAX_RESULTS_LENGTH - 1) 1269 1274 return EOK; 1270 } 1271 1272 ieee80211_scan_result_link_t *ap_data = 1273 malloc(sizeof(ieee80211_scan_result_link_t)); 1275 1276 ieee80211_scan_result_link_t *ap_data = 1277 malloc(sizeof(ieee80211_scan_result_link_t)); 1278 if (!ap_data) 1279 return ENOMEM; 1280 1274 1281 memset(ap_data, 0, sizeof(ieee80211_scan_result_link_t)); 1275 1282 link_initialize(&ap_data->link); 1276 1283 1277 memcpy(ap_data->scan_result.bssid.address, 1278 mgmt_header->bssid, ETH_ADDR);1279 memcpy(ap_data->scan_result.ssid, ssid, 1280 ssid_ie_header->length + 1);1281 1282 if (uint16_t_le2host(beacon_body->capability) & CAP_SECURITY) {1283 ap_data->scan_result.security.type = 1284 IEEE80211_SECURITY_WEP;1284 memcpy(ap_data->scan_result.bssid.address, 1285 mgmt_header->bssid, ETH_ADDR); 1286 memcpy(ap_data->scan_result.ssid, ssid, 1287 ssid_ie_header->length + 1); 1288 1289 if (uint16_t_le2host(beacon_body->capability) & CAP_SECURITY) { 1290 ap_data->scan_result.security.type = 1291 IEEE80211_SECURITY_WEP; 1285 1292 } else { 1286 ap_data->scan_result.security.type = 1287 IEEE80211_SECURITY_OPEN;1293 ap_data->scan_result.security.type = 1294 IEEE80211_SECURITY_OPEN; 1288 1295 ap_data->scan_result.security.auth = -1; 1289 1296 ap_data->scan_result.security.pair_alg = -1; … … 1292 1299 1293 1300 void *rest_ies_start = ssid_start + ssid_ie_header->length; 1294 size_t rest_buffer_size = 1295 buffer_size -1296 sizeof(ieee80211_mgmt_header_t) -1297 sizeof(ieee80211_beacon_start_t) -1298 sizeof(ieee80211_ie_header_t) -1299 ssid_ie_header->length;1300 1301 ieee80211_process_ies(ieee80211_dev, ap_data, rest_ies_start, 1302 rest_buffer_size);1301 size_t rest_buffer_size = 1302 buffer_size - 1303 sizeof(ieee80211_mgmt_header_t) - 1304 sizeof(ieee80211_beacon_start_t) - 1305 sizeof(ieee80211_ie_header_t) - 1306 ssid_ie_header->length; 1307 1308 ieee80211_process_ies(ieee80211_dev, ap_data, rest_ies_start, 1309 rest_buffer_size); 1303 1310 1304 1311 ap_data->last_beacon = time(NULL); … … 1312 1319 } 1313 1320 1314 /** 1315 * Process authentication response. 1316 * 1321 /** Process authentication response. 1322 * 1317 1323 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 1318 * @param mgmt_header Pointer to start of management frame header.1319 * 1324 * @param mgmt_header Pointer to start of management frame header. 1325 * 1320 1326 * @return EOK if succeed, negative error code otherwise. 1327 * 1321 1328 */ 1322 1329 static int ieee80211_process_auth_response(ieee80211_dev_t *ieee80211_dev, 1323 ieee80211_mgmt_header_t *mgmt_header)1330 ieee80211_mgmt_header_t *mgmt_header) 1324 1331 { 1325 1332 ieee80211_auth_body_t *auth_body = 1326 (ieee80211_auth_body_t *) 1327 ((void *)mgmt_header + sizeof(ieee80211_mgmt_header_t)); 1328 1329 if(auth_body->status != 0) { 1330 ieee80211_set_auth_phase(ieee80211_dev, 1331 IEEE80211_AUTH_DISCONNECTED); 1332 } else { 1333 ieee80211_set_auth_phase(ieee80211_dev, 1334 IEEE80211_AUTH_AUTHENTICATED); 1335 } 1333 (ieee80211_auth_body_t *) 1334 ((void *) mgmt_header + sizeof(ieee80211_mgmt_header_t)); 1335 1336 if (auth_body->status != 0) 1337 ieee80211_set_auth_phase(ieee80211_dev, 1338 IEEE80211_AUTH_DISCONNECTED); 1339 else 1340 ieee80211_set_auth_phase(ieee80211_dev, 1341 IEEE80211_AUTH_AUTHENTICATED); 1336 1342 1337 1343 fibril_mutex_lock(&ieee80211_dev->gen_mutex); … … 1342 1348 } 1343 1349 1344 /** 1345 * Process association response. 1346 * 1350 /** Process association response. 1351 * 1347 1352 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 1348 * @param mgmt_header Pointer to start of management frame header.1349 * 1353 * @param mgmt_header Pointer to start of management frame header. 1354 * 1350 1355 * @return EOK if succeed, negative error code otherwise. 1356 * 1351 1357 */ 1352 1358 static int ieee80211_process_assoc_response(ieee80211_dev_t *ieee80211_dev, 1353 ieee80211_mgmt_header_t *mgmt_header)1359 ieee80211_mgmt_header_t *mgmt_header) 1354 1360 { 1355 1361 ieee80211_assoc_resp_body_t *assoc_resp = 1356 (ieee80211_assoc_resp_body_t *) ((void *)mgmt_header +1357 sizeof(ieee80211_mgmt_header_t));1358 1359 if (assoc_resp->status != 0) {1360 ieee80211_set_auth_phase(ieee80211_dev, 1361 IEEE80211_AUTH_DISCONNECTED);1362 }else {1363 ieee80211_dev->bssid_info.aid = 1364 uint16_t_le2host(assoc_resp->aid);1365 ieee80211_set_auth_phase(ieee80211_dev, 1366 IEEE80211_AUTH_ASSOCIATED);1362 (ieee80211_assoc_resp_body_t *) ((void *) mgmt_header + 1363 sizeof(ieee80211_mgmt_header_t)); 1364 1365 if (assoc_resp->status != 0) 1366 ieee80211_set_auth_phase(ieee80211_dev, 1367 IEEE80211_AUTH_DISCONNECTED); 1368 else { 1369 ieee80211_dev->bssid_info.aid = 1370 uint16_t_le2host(assoc_resp->aid); 1371 ieee80211_set_auth_phase(ieee80211_dev, 1372 IEEE80211_AUTH_ASSOCIATED); 1367 1373 ieee80211_dev->ops->bssid_change(ieee80211_dev, true); 1368 1374 } … … 1376 1382 1377 1383 static int ieee80211_process_4way_handshake(ieee80211_dev_t *ieee80211_dev, 1378 void *buffer, size_t buffer_size)1379 { 1380 ieee80211_eapol_key_frame_t *key_frame = 1381 (ieee80211_eapol_key_frame_t *) buffer;1382 1383 ieee80211_scan_result_link_t *auth_link = 1384 ieee80211_dev->bssid_info.res_link;1385 1384 void *buffer, size_t buffer_size) 1385 { 1386 ieee80211_eapol_key_frame_t *key_frame = 1387 (ieee80211_eapol_key_frame_t *) buffer; 1388 1389 ieee80211_scan_result_link_t *auth_link = 1390 ieee80211_dev->bssid_info.res_link; 1391 1386 1392 ieee80211_scan_result_t *auth_data = &auth_link->scan_result; 1387 1393 1388 1394 /* We don't support 802.1X authentication yet. */ 1389 if (auth_data->security.auth == IEEE80211_AUTH_AKM_8021X) {1395 if (auth_data->security.auth == IEEE80211_AUTH_AKM_8021X) 1390 1396 return ENOTSUP; 1391 }1392 1397 1393 1398 uint8_t *ptk = ieee80211_dev->bssid_info.ptk; 1394 1399 uint8_t *gtk = ieee80211_dev->bssid_info.gtk; 1395 1400 uint8_t gtk_id = 1; 1396 1401 1397 1402 bool handshake_done = false; 1398 1403 1399 bool old_wpa = 1400 auth_data->security.type == IEEE80211_SECURITY_WPA;1404 bool old_wpa = 1405 auth_data->security.type == IEEE80211_SECURITY_WPA; 1401 1406 1402 1407 bool key_phase = 1403 uint16_t_be2host(key_frame->key_info) &1404 IEEE80211_EAPOL_KEY_KEYINFO_MIC;1405 1406 bool final_phase = 1407 uint16_t_be2host(key_frame->key_info) &1408 IEEE80211_EAPOL_KEY_KEYINFO_SECURE;1409 1410 bool ccmp_used = 1411 auth_data->security.pair_alg == IEEE80211_SECURITY_SUITE_CCMP||1412 auth_data->security.group_alg == IEEE80211_SECURITY_SUITE_CCMP;1408 uint16_t_be2host(key_frame->key_info) & 1409 IEEE80211_EAPOL_KEY_KEYINFO_MIC; 1410 1411 bool final_phase = 1412 uint16_t_be2host(key_frame->key_info) & 1413 IEEE80211_EAPOL_KEY_KEYINFO_SECURE; 1414 1415 bool ccmp_used = 1416 (auth_data->security.pair_alg == IEEE80211_SECURITY_SUITE_CCMP) || 1417 (auth_data->security.group_alg == IEEE80211_SECURITY_SUITE_CCMP); 1413 1418 1414 1419 size_t ptk_key_length, gtk_key_length; 1415 1420 hash_func_t mic_hash; 1416 if (ccmp_used) {1421 if (ccmp_used) 1417 1422 mic_hash = HASH_SHA1; 1418 } else {1423 else 1419 1424 mic_hash = HASH_MD5; 1420 } 1421 1422 if(auth_data->security.pair_alg == IEEE80211_SECURITY_SUITE_CCMP) { 1425 1426 if (auth_data->security.pair_alg == IEEE80211_SECURITY_SUITE_CCMP) 1423 1427 ptk_key_length = IEEE80211_PTK_CCMP_LENGTH; 1424 } else {1428 else 1425 1429 ptk_key_length = IEEE80211_PTK_TKIP_LENGTH; 1426 } 1427 1428 if(auth_data->security.group_alg == IEEE80211_SECURITY_SUITE_CCMP) { 1430 1431 if (auth_data->security.group_alg == IEEE80211_SECURITY_SUITE_CCMP) 1429 1432 gtk_key_length = IEEE80211_GTK_CCMP_LENGTH; 1430 } else {1433 else 1431 1434 gtk_key_length = IEEE80211_GTK_TKIP_LENGTH; 1432 } 1433 1434 size_t output_size = 1435 sizeof(eth_header_t) + 1436 sizeof(ieee80211_eapol_key_frame_t); 1437 1438 if(!(uint16_t_be2host(key_frame->key_info) & 1439 IEEE80211_EAPOL_KEY_KEYINFO_MIC)) { 1435 1436 size_t output_size = 1437 sizeof(eth_header_t) + 1438 sizeof(ieee80211_eapol_key_frame_t); 1439 1440 if (!(uint16_t_be2host(key_frame->key_info) & 1441 IEEE80211_EAPOL_KEY_KEYINFO_MIC)) 1440 1442 output_size += auth_link->auth_ie_len; 1441 } 1442 1443 1443 1444 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 1444 1445 nic_address_t nic_address; 1445 1446 nic_query_address(nic, &nic_address); 1446 1447 1447 1448 void *output_buffer = malloc(output_size); 1449 if (!output_buffer) 1450 return ENOMEM; 1451 1448 1452 memset(output_buffer, 0, output_size); 1449 1453 1450 1454 /* Setup ethernet header. */ 1451 1455 eth_header_t *eth_header = (eth_header_t *) output_buffer; 1452 memcpy(eth_header->dest_addr, auth_data->bssid.address, ETH_ADDR);1456 memcpy(eth_header->dest_addr, auth_data->bssid.address, ETH_ADDR); 1453 1457 memcpy(eth_header->src_addr, nic_address.address, ETH_ADDR); 1454 1458 eth_header->proto = host2uint16_t_be(ETH_TYPE_PAE); 1455 1459 1456 1460 ieee80211_eapol_key_frame_t *output_key_frame = 1457 (ieee80211_eapol_key_frame_t *)1458 (output_buffer + sizeof(eth_header_t));1459 1461 (ieee80211_eapol_key_frame_t *) 1462 (output_buffer + sizeof(eth_header_t)); 1463 1460 1464 /* Copy content of incoming EAPOL-Key frame. */ 1461 memcpy((void *) output_key_frame, buffer, 1462 sizeof(ieee80211_eapol_key_frame_t));1463 1465 memcpy((void *) output_key_frame, buffer, 1466 sizeof(ieee80211_eapol_key_frame_t)); 1467 1464 1468 output_key_frame->proto_version = 0x1; 1465 1469 output_key_frame->body_length = 1466 host2uint16_t_be(output_size - sizeof(eth_header_t) - 4); 1467 output_key_frame->key_info &= 1468 ~host2uint16_t_be( 1469 IEEE80211_EAPOL_KEY_KEYINFO_ACK 1470 ); 1471 1472 if(key_phase) { 1473 output_key_frame->key_info &= 1474 ~host2uint16_t_be( 1475 IEEE80211_EAPOL_KEY_KEYINFO_ENCDATA 1476 ); 1477 output_key_frame->key_info &= 1478 ~host2uint16_t_be( 1479 IEEE80211_EAPOL_KEY_KEYINFO_INSTALL 1480 ); 1470 host2uint16_t_be(output_size - sizeof(eth_header_t) - 4); 1471 output_key_frame->key_info &= 1472 ~host2uint16_t_be(IEEE80211_EAPOL_KEY_KEYINFO_ACK); 1473 1474 if (key_phase) { 1475 output_key_frame->key_info &= 1476 ~host2uint16_t_be(IEEE80211_EAPOL_KEY_KEYINFO_ENCDATA); 1477 output_key_frame->key_info &= 1478 ~host2uint16_t_be(IEEE80211_EAPOL_KEY_KEYINFO_INSTALL); 1481 1479 output_key_frame->key_data_length = 0; 1482 1480 memset(output_key_frame->key_nonce, 0, 32); … … 1484 1482 memset(output_key_frame->key_rsc, 0, 8); 1485 1483 memset(output_key_frame->eapol_key_iv, 0, 16); 1486 1484 1487 1485 /* Derive GTK and save it. */ 1488 if (final_phase) {1489 uint16_t key_data_length = 1490 uint16_t_be2host(key_frame->key_data_length);1486 if (final_phase) { 1487 uint16_t key_data_length = 1488 uint16_t_be2host(key_frame->key_data_length); 1491 1489 uint8_t key_data[key_data_length]; 1492 uint8_t *data_ptr = (uint8_t *) (buffer +1493 sizeof(ieee80211_eapol_key_frame_t));1494 1490 uint8_t *data_ptr = (uint8_t *) 1491 (buffer + sizeof(ieee80211_eapol_key_frame_t)); 1492 1495 1493 int rc; 1496 1494 uint8_t work_key[32]; 1497 1498 if (ccmp_used) {1499 rc = ieee80211_aes_key_unwrap(ptk + KEK_OFFSET, 1500 data_ptr, key_data_length, key_data);1495 1496 if (ccmp_used) { 1497 rc = ieee80211_aes_key_unwrap(ptk + KEK_OFFSET, 1498 data_ptr, key_data_length, key_data); 1501 1499 } else { 1502 1500 memcpy(work_key, key_frame->eapol_key_iv, 16); 1503 1501 memcpy(work_key + 16, ptk + KEK_OFFSET, 16); 1504 rc = ieee80211_rc4_key_unwrap(work_key, 1505 data_ptr, key_data_length, key_data);1502 rc = ieee80211_rc4_key_unwrap(work_key, 1503 data_ptr, key_data_length, key_data); 1506 1504 } 1507 1505 1508 if (rc == EOK) {1506 if (rc == EOK) { 1509 1507 uint8_t *key_data_ptr = old_wpa ? key_data : 1510 ieee80211_process_ies(ieee80211_dev,1511 NULL, key_data, key_data_length);1512 1513 if (key_data_ptr) {1508 ieee80211_process_ies(ieee80211_dev, 1509 NULL, key_data, key_data_length); 1510 1511 if (key_data_ptr) { 1514 1512 uint8_t *key_ptr; 1515 if(old_wpa) { 1513 1514 if (old_wpa) 1516 1515 key_ptr = key_data_ptr; 1517 }else {1516 else { 1518 1517 gtk_id = *key_data_ptr & 0x3; 1519 1518 key_ptr = key_data_ptr + 2; 1520 1519 } 1521 1520 1522 1521 memcpy(gtk, key_ptr, gtk_key_length); 1523 1522 handshake_done = true; … … 1526 1525 } 1527 1526 } else { 1528 output_key_frame->key_info |= 1529 host2uint16_t_be( 1530 IEEE80211_EAPOL_KEY_KEYINFO_MIC 1531 ); 1527 output_key_frame->key_info |= 1528 host2uint16_t_be(IEEE80211_EAPOL_KEY_KEYINFO_MIC); 1532 1529 output_key_frame->key_data_length = 1533 host2uint16_t_be(auth_link->auth_ie_len); 1534 memcpy((void *)output_key_frame + 1535 sizeof(ieee80211_eapol_key_frame_t), 1536 auth_link->auth_ie, 1537 auth_link->auth_ie_len); 1538 1530 host2uint16_t_be(auth_link->auth_ie_len); 1531 memcpy((void *) output_key_frame + 1532 sizeof(ieee80211_eapol_key_frame_t), 1533 auth_link->auth_ie, auth_link->auth_ie_len); 1534 1539 1535 /* Compute PMK. */ 1540 1536 uint8_t pmk[PBKDF2_KEY_LENGTH]; 1541 1537 pbkdf2((uint8_t *) ieee80211_dev->bssid_info.password, 1542 str_size(ieee80211_dev->bssid_info.password),1543 (uint8_t *) auth_data->ssid,1544 str_size(auth_data->ssid), pmk);1545 1538 str_size(ieee80211_dev->bssid_info.password), 1539 (uint8_t *) auth_data->ssid, 1540 str_size(auth_data->ssid), pmk); 1541 1546 1542 uint8_t *anonce = key_frame->key_nonce; 1547 1543 1548 1544 /* Generate SNONCE. */ 1549 1545 uint8_t snonce[32]; 1550 1546 rnd_sequence(snonce, 32); 1551 1547 1552 1548 memcpy(output_key_frame->key_nonce, snonce, 32); 1553 1549 1554 1550 uint8_t *dest_addr = eth_header->dest_addr; 1555 1551 uint8_t *src_addr = eth_header->src_addr; 1556 1552 1557 1553 /* Derive PTK and save it. */ 1558 1554 uint8_t crypt_data[PRF_CRYPT_DATA_LENGTH]; 1559 memcpy(crypt_data, 1560 min_sequence(dest_addr, src_addr, ETH_ADDR), 1561 ETH_ADDR); 1562 memcpy(crypt_data + ETH_ADDR, 1563 max_sequence(dest_addr, src_addr, ETH_ADDR), 1564 ETH_ADDR); 1565 memcpy(crypt_data + 2*ETH_ADDR, 1566 min_sequence(anonce, snonce, 32), 1567 32); 1568 memcpy(crypt_data + 2*ETH_ADDR + 32, 1569 max_sequence(anonce, snonce, 32), 1570 32); 1555 memcpy(crypt_data, 1556 min_sequence(dest_addr, src_addr, ETH_ADDR), ETH_ADDR); 1557 memcpy(crypt_data + ETH_ADDR, 1558 max_sequence(dest_addr, src_addr, ETH_ADDR), ETH_ADDR); 1559 memcpy(crypt_data + 2*ETH_ADDR, 1560 min_sequence(anonce, snonce, 32), 32); 1561 memcpy(crypt_data + 2*ETH_ADDR + 32, 1562 max_sequence(anonce, snonce, 32), 32); 1571 1563 ieee80211_prf(pmk, crypt_data, ptk, ptk_key_length); 1572 1564 } 1573 1565 1574 1566 /* Compute MIC of key frame data from KCK part of PTK. */ 1575 1567 uint8_t mic[mic_hash]; 1576 hmac(ptk, 16, (uint8_t *) output_key_frame, 1577 output_size - sizeof(eth_header_t), mic, mic_hash);1578 1568 hmac(ptk, 16, (uint8_t *) output_key_frame, 1569 output_size - sizeof(eth_header_t), mic, mic_hash); 1570 1579 1571 memcpy(output_key_frame->key_mic, mic, 16); 1580 1572 1581 1573 ieee80211_send_frame(nic, output_buffer, output_size); 1582 1574 1583 1575 free(output_buffer); 1584 1576 1585 1577 ieee80211_key_config_t key_config; 1586 1578 1587 1579 /* Insert Pairwise key. */ 1588 if ((key_phase && old_wpa) || (final_phase && !old_wpa)) {1580 if ((key_phase && old_wpa) || (final_phase && !old_wpa)) { 1589 1581 key_config.suite = auth_data->security.pair_alg; 1590 1582 key_config.flags = 1591 IEEE80211_KEY_FLAG_TYPE_PAIRWISE; 1592 memcpy(key_config.data, 1593 ptk + TK_OFFSET, 1594 ptk_key_length - TK_OFFSET); 1595 1583 IEEE80211_KEY_FLAG_TYPE_PAIRWISE; 1584 memcpy(key_config.data, 1585 ptk + TK_OFFSET, ptk_key_length - TK_OFFSET); 1586 1596 1587 ieee80211_dev->ops->key_config(ieee80211_dev, 1597 &key_config, true);1588 &key_config, true); 1598 1589 } 1599 1590 1600 1591 /* Insert Group key. */ 1601 if (final_phase) {1592 if (final_phase) { 1602 1593 key_config.id = gtk_id; 1603 1594 key_config.suite = auth_data->security.group_alg; 1604 key_config.flags = 1605 IEEE80211_KEY_FLAG_TYPE_GROUP; 1595 key_config.flags = IEEE80211_KEY_FLAG_TYPE_GROUP; 1606 1596 memcpy(key_config.data, gtk, gtk_key_length); 1607 1597 1608 1598 ieee80211_dev->ops->key_config(ieee80211_dev, 1609 &key_config, true);1610 } 1611 1599 &key_config, true); 1600 } 1601 1612 1602 /* Signal successful handshake completion. */ 1613 if (handshake_done) {1603 if (handshake_done) { 1614 1604 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 1615 1605 fibril_condvar_signal(&ieee80211_dev->gen_cond); … … 1621 1611 1622 1612 static int ieee80211_process_eapol_frame(ieee80211_dev_t *ieee80211_dev, 1623 void *buffer, size_t buffer_size) 1624 { 1625 ieee80211_eapol_key_frame_t *key_frame = 1626 (ieee80211_eapol_key_frame_t *) buffer; 1627 if(ieee80211_is_eapol_key_frame(key_frame)) { 1613 void *buffer, size_t buffer_size) 1614 { 1615 ieee80211_eapol_key_frame_t *key_frame = 1616 (ieee80211_eapol_key_frame_t *) buffer; 1617 1618 if (ieee80211_is_eapol_key_frame(key_frame)) 1628 1619 return ieee80211_process_4way_handshake(ieee80211_dev, buffer, 1629 buffer_size); 1630 } 1620 buffer_size); 1631 1621 1632 1622 return EOK; 1633 1623 } 1634 1624 1635 /** 1636 * Process data frame. 1637 * 1625 /** Process data frame. 1626 * 1638 1627 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 1639 * @param buffer Data buffer starting with IEEE 802.11 data header.1640 * @param buffer_size Size of buffer.1641 * 1628 * @param buffer Data buffer starting with IEEE 802.11 data header. 1629 * @param buffer_size Size of buffer. 1630 * 1642 1631 * @return EOK if succeed, negative error code otherwise. 1643 */ 1644 static int ieee80211_process_data(ieee80211_dev_t *ieee80211_dev, 1645 void *buffer, size_t buffer_size) 1646 { 1647 ieee80211_data_header_t *data_header = 1648 (ieee80211_data_header_t *) buffer; 1649 1650 if(ieee80211_has_data_frame(data_header->frame_ctrl)) { 1632 * 1633 */ 1634 static int ieee80211_process_data(ieee80211_dev_t *ieee80211_dev, 1635 void *buffer, size_t buffer_size) 1636 { 1637 ieee80211_data_header_t *data_header = 1638 (ieee80211_data_header_t *) buffer; 1639 1640 if (ieee80211_has_data_frame(data_header->frame_ctrl)) { 1651 1641 nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev); 1652 size_t strip_length = sizeof(ieee80211_data_header_t) + 1653 ARRAY_SIZE(rfc1042_header);1642 size_t strip_length = sizeof(ieee80211_data_header_t) + 1643 ARRAY_SIZE(rfc1042_header); 1654 1644 1655 1645 /* TODO: Different by used security alg. */ 1656 1646 /* TODO: Trim frame by used security alg. */ 1657 1647 // TODO: Distinguish used key (pair/group) by dest address ? 1658 if (ieee80211_is_encrypted_frame(data_header->frame_ctrl)) {1648 if (ieee80211_is_encrypted_frame(data_header->frame_ctrl)) 1659 1649 strip_length += 8; 1660 }1661 1650 1662 1651 /* Process 4-way authentication handshake. */ 1663 1652 uint16_t *proto = (uint16_t *) (buffer + strip_length); 1664 if (uint16_t_be2host(*proto) == ETH_TYPE_PAE) {1653 if (uint16_t_be2host(*proto) == ETH_TYPE_PAE) 1665 1654 return ieee80211_process_eapol_frame(ieee80211_dev, 1666 buffer + strip_length + sizeof(uint16_t), 1667 buffer_size - strip_length - sizeof(uint16_t)); 1668 } 1669 1670 /* Note: ETH protocol ID is already there, so we don't create 1671 * whole ETH header. */ 1672 size_t frame_size = 1673 buffer_size - strip_length + sizeof(eth_header_t)-2; 1655 buffer + strip_length + sizeof(uint16_t), 1656 buffer_size - strip_length - sizeof(uint16_t)); 1657 1658 /* 1659 * Note: ETH protocol ID is already there, so we don't create 1660 * whole ETH header. 1661 */ 1662 size_t frame_size = 1663 buffer_size - strip_length + sizeof(eth_header_t) - 2; 1674 1664 nic_frame_t *frame = nic_alloc_frame(nic, frame_size); 1675 1676 if(frame == NULL) {1665 1666 if(frame == NULL) 1677 1667 return ENOMEM; 1678 } 1679 1680 uint8_t *src_addr = 1681 ieee80211_is_fromds_frame(data_header->frame_ctrl) ? 1682 data_header->address3 : data_header->address2; 1683 uint8_t *dest_addr = 1684 ieee80211_is_tods_frame(data_header->frame_ctrl) ? 1685 data_header->address3 : data_header->address1; 1686 1687 eth_header_t *eth_header = 1688 (eth_header_t *) frame->data; 1668 1669 uint8_t *src_addr = 1670 ieee80211_is_fromds_frame(data_header->frame_ctrl) ? 1671 data_header->address3 : data_header->address2; 1672 uint8_t *dest_addr = 1673 ieee80211_is_tods_frame(data_header->frame_ctrl) ? 1674 data_header->address3 : data_header->address1; 1675 1676 eth_header_t *eth_header = (eth_header_t *) frame->data; 1689 1677 memcpy(eth_header->src_addr, src_addr, ETH_ADDR); 1690 1678 memcpy(eth_header->dest_addr, dest_addr, ETH_ADDR); 1691 1692 memcpy(frame->data + sizeof(eth_header_t)-2, 1693 buffer + strip_length, 1694 buffer_size - strip_length); 1695 1679 1680 memcpy(frame->data + sizeof(eth_header_t) - 2, 1681 buffer + strip_length, buffer_size - strip_length); 1682 1696 1683 nic_received_frame(nic, frame); 1697 1684 } … … 1700 1687 } 1701 1688 1702 /** 1703 * IEEE 802.11 RX frames handler. 1704 * 1689 /** IEEE 802.11 RX frames handler. 1690 * 1705 1691 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. 1706 * @param buffer Buffer with data.1707 * @param buffer_size Size of buffer.1708 * 1692 * @param buffer Buffer with data. 1693 * @param buffer_size Size of buffer. 1694 * 1709 1695 * @return EOK if succeed, negative error code otherwise. 1696 * 1710 1697 */ 1711 1698 int ieee80211_rx_handler(ieee80211_dev_t *ieee80211_dev, void *buffer, 1712 size_t buffer_size)1699 size_t buffer_size) 1713 1700 { 1714 1701 uint16_t frame_ctrl = *((uint16_t *) buffer); 1715 if(ieee80211_is_mgmt_frame(frame_ctrl)) { 1702 1703 if (ieee80211_is_mgmt_frame(frame_ctrl)) { 1716 1704 ieee80211_mgmt_header_t *mgmt_header = 1717 (ieee80211_mgmt_header_t *) buffer;1718 1719 if (ieee80211_is_probe_response_frame(mgmt_header->frame_ctrl) ||1720 ieee80211_is_beacon_frame(mgmt_header->frame_ctrl)) {1705 (ieee80211_mgmt_header_t *) buffer; 1706 1707 if ((ieee80211_is_probe_response_frame(mgmt_header->frame_ctrl)) || 1708 (ieee80211_is_beacon_frame(mgmt_header->frame_ctrl))) 1721 1709 return ieee80211_process_probe_response(ieee80211_dev, 1722 mgmt_header, buffer_size); 1723 } 1724 1725 if(ieee80211_is_auth_frame(mgmt_header->frame_ctrl)) { 1710 mgmt_header, buffer_size); 1711 1712 if (ieee80211_is_auth_frame(mgmt_header->frame_ctrl)) 1726 1713 return ieee80211_process_auth_response(ieee80211_dev, 1727 mgmt_header); 1728 } 1729 1730 if(ieee80211_is_assoc_response_frame(mgmt_header->frame_ctrl)) { 1714 mgmt_header); 1715 1716 if (ieee80211_is_assoc_response_frame(mgmt_header->frame_ctrl)) 1731 1717 return ieee80211_process_assoc_response(ieee80211_dev, 1732 mgmt_header); 1733 } 1734 } else if(ieee80211_is_data_frame(frame_ctrl)) { 1735 return ieee80211_process_data(ieee80211_dev, buffer, 1736 buffer_size); 1737 } 1718 mgmt_header); 1719 } else if (ieee80211_is_data_frame(frame_ctrl)) 1720 return ieee80211_process_data(ieee80211_dev, buffer, 1721 buffer_size); 1738 1722 1739 1723 return EOK; -
uspace/lib/ieee80211/src/ieee80211_iface_impl.c
r09044cb r8a64320e 27 27 */ 28 28 29 /** @addtogroup libieee80211 30 * @{ 31 */ 32 33 /** @file ieee80211_iface_impl.c 34 * 35 * IEEE 802.11 default interface functions implementation. 36 */ 37 29 38 #include <str.h> 30 39 #include <errno.h> 31 32 40 #include <ieee80211_private.h> 33 41 #include <ieee80211_iface_impl.h> 34 42 35 /** @addtogroup libieee80211 36 * @{ 37 */ 38 39 /** @file ieee80211_iface_impl.c 40 * 41 * IEEE 802.11 default interface functions implementation. 42 */ 43 44 /** 45 * Implementation of fetching scan results. 46 * 47 * @param fun Device function. 43 /** Implementation of fetching scan results. 44 * 45 * @param fun Device function. 48 46 * @param results Structure where should be stored scan results. 49 * 50 * @return EOK if everything went OK, EREFUSED when device is not ready yet. 51 */ 52 int ieee80211_get_scan_results_impl(ddf_fun_t *fun, 53 ieee80211_scan_results_t *results, bool now) 47 * 48 * @return EOK if everything went OK, 49 * EREFUSED when device is not ready yet. 50 * 51 */ 52 int ieee80211_get_scan_results_impl(ddf_fun_t *fun, 53 ieee80211_scan_results_t *results, bool now) 54 54 { 55 55 nic_t *nic_data = nic_get_from_ddf_fun(fun); 56 56 ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data); 57 57 58 if (!ieee80211_is_ready(ieee80211_dev))58 if (!ieee80211_is_ready(ieee80211_dev)) 59 59 return EREFUSED; 60 60 61 if (now) {61 if (now) 62 62 ieee80211_dev->ops->scan(ieee80211_dev); 63 }64 63 65 64 fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex); 66 if(results) { 65 66 if (results) { 67 67 ieee80211_scan_result_list_t *result_list = 68 &ieee80211_dev->ap_list;69 70 int i = 0;68 &ieee80211_dev->ap_list; 69 70 unsigned int i = 0; 71 71 ieee80211_scan_result_list_foreach(*result_list, result) { 72 memcpy(&results->results[i], 73 &result->scan_result,74 sizeof(ieee80211_scan_result_t));72 memcpy(&results->results[i], 73 &result->scan_result, 74 sizeof(ieee80211_scan_result_t)); 75 75 i++; 76 76 } … … 78 78 results->length = i; 79 79 } 80 80 81 fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex); 81 82 … … 88 89 } 89 90 90 /** 91 * Working procedure of connect function. 92 * 91 /** Working procedure of connect function. 92 * 93 93 * @param ieee80211_dev Pointer to IEEE 802.11 device. 94 * @param auth_data Selected AP data we want to connect to. 95 * 96 * @return EOK if everything OK, ETIMEOUT when timeout during authenticating. 94 * @param auth_data Selected AP data we want to connect to. 95 * 96 * @return EOK if everything OK, 97 * ETIMEOUT when timeout during authenticating. 98 * 97 99 */ 98 100 static int ieee80211_connect_proc(ieee80211_dev_t *ieee80211_dev, 99 ieee80211_scan_result_link_t *auth_data, char *password)101 ieee80211_scan_result_link_t *auth_data, char *password) 100 102 { 101 103 ieee80211_dev->bssid_info.res_link = auth_data; 102 104 103 105 /* Set channel. */ 104 int rc = ieee80211_dev->ops->set_freq(ieee80211_dev, 105 ieee80211_channel_to_freq(auth_data->scan_result.channel));106 if (rc != EOK)106 int rc = ieee80211_dev->ops->set_freq(ieee80211_dev, 107 ieee80211_channel_to_freq(auth_data->scan_result.channel)); 108 if (rc != EOK) 107 109 return rc; 108 110 109 111 /* Try to authenticate. */ 110 112 ieee80211_authenticate(ieee80211_dev); 113 111 114 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 112 115 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond, 113 &ieee80211_dev->gen_mutex, 114 AUTH_TIMEOUT); 116 &ieee80211_dev->gen_mutex, AUTH_TIMEOUT); 115 117 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 116 if(rc != EOK) 118 119 if (rc != EOK) 117 120 return rc; 118 if(ieee80211_get_auth_phase(ieee80211_dev) != 119 IEEE80211_AUTH_AUTHENTICATED) { 120 ieee80211_set_auth_phase(ieee80211_dev, 121 IEEE80211_AUTH_DISCONNECTED); 121 122 if (ieee80211_get_auth_phase(ieee80211_dev) != 123 IEEE80211_AUTH_AUTHENTICATED) { 124 ieee80211_set_auth_phase(ieee80211_dev, 125 IEEE80211_AUTH_DISCONNECTED); 122 126 return EINVAL; 123 127 } … … 125 129 /* Try to associate. */ 126 130 ieee80211_associate(ieee80211_dev, password); 131 127 132 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 128 133 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond, 129 &ieee80211_dev->gen_mutex, 130 AUTH_TIMEOUT); 134 &ieee80211_dev->gen_mutex, AUTH_TIMEOUT); 131 135 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 132 if(rc != EOK) 136 137 if (rc != EOK) 133 138 return rc; 134 if(ieee80211_get_auth_phase(ieee80211_dev) != 135 IEEE80211_AUTH_ASSOCIATED) { 136 ieee80211_set_auth_phase(ieee80211_dev, 137 IEEE80211_AUTH_DISCONNECTED); 139 140 if (ieee80211_get_auth_phase(ieee80211_dev) != 141 IEEE80211_AUTH_ASSOCIATED) { 142 ieee80211_set_auth_phase(ieee80211_dev, 143 IEEE80211_AUTH_DISCONNECTED); 138 144 return EINVAL; 139 145 } 140 146 141 147 /* On open network, we are finished. */ 142 if(auth_data->scan_result.security.type != IEEE80211_SECURITY_OPEN) { 148 if (auth_data->scan_result.security.type != 149 IEEE80211_SECURITY_OPEN) { 143 150 /* Otherwise wait for 4-way handshake to complete. */ 151 144 152 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 145 153 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond, 146 &ieee80211_dev->gen_mutex, 147 HANDSHAKE_TIMEOUT); 154 &ieee80211_dev->gen_mutex, HANDSHAKE_TIMEOUT); 148 155 fibril_mutex_unlock(&ieee80211_dev->gen_mutex); 149 if(rc != EOK) { 156 157 if (rc != EOK) { 150 158 ieee80211_deauthenticate(ieee80211_dev); 151 159 return rc; … … 158 166 } 159 167 160 /** 161 * Implementation of connecting to specified SSID. 162 * 163 * @param fun Device function. 168 /** Implementation of connecting to specified SSID. 169 * 170 * @param fun Device function. 164 171 * @param ssid_start SSID prefix of access point we want to connect to. 165 * 166 * @return EOK if everything OK, ETIMEOUT when timeout during authenticating, 167 * EINVAL when SSID not in scan results list, EPERM when incorrect password 168 * passed, EREFUSED when device is not ready yet. 172 * 173 * @return EOK if everything OK, 174 * ETIMEOUT when timeout during authenticating, 175 * EINVAL when SSID not in scan results list, 176 * EPERM when incorrect password passed, 177 * EREFUSED when device is not ready yet. 178 * 169 179 */ 170 180 int ieee80211_connect_impl(ddf_fun_t *fun, char *ssid_start, char *password) … … 173 183 assert(password); 174 184 175 int rc;176 177 185 nic_t *nic_data = nic_get_from_ddf_fun(fun); 178 186 ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data); 179 187 180 if (!ieee80211_is_ready(ieee80211_dev))188 if (!ieee80211_is_ready(ieee80211_dev)) 181 189 return EREFUSED; 182 190 183 if (ieee80211_is_connected(ieee80211_dev)) {184 rc = ieee80211_dev->iface->disconnect(fun);185 if (rc != EOK)191 if (ieee80211_is_connected(ieee80211_dev)) { 192 int rc = ieee80211_dev->iface->disconnect(fun); 193 if (rc != EOK) 186 194 return rc; 187 195 } … … 189 197 ieee80211_set_connect_request(ieee80211_dev); 190 198 191 rc = ENOENT;199 int rc = ENOENT; 192 200 fibril_mutex_lock(&ieee80211_dev->scan_mutex); 193 201 194 202 ieee80211_dev->pending_conn_req = false; 195 203 196 204 ieee80211_scan_result_list_foreach(ieee80211_dev->ap_list, result) { 197 if(!str_lcmp(ssid_start, 198 result->scan_result.ssid, 199 str_size(ssid_start))) { 205 if (!str_lcmp(ssid_start, result->scan_result.ssid, 206 str_size(ssid_start))) { 200 207 rc = ieee80211_connect_proc(ieee80211_dev, result, 201 password);208 password); 202 209 break; 203 210 } … … 209 216 } 210 217 211 /** 212 * Implementation of disconnecting device from network. 213 * 218 /** Implementation of disconnecting device from network. 219 * 214 220 * @param fun Device function. 215 * 216 * @return EOK if everything OK, EREFUSED if device is not ready yet. 221 * 222 * @return EOK if everything OK, 223 * EREFUSED if device is not ready yet. 224 * 217 225 */ 218 226 int ieee80211_disconnect_impl(ddf_fun_t *fun) … … 221 229 ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data); 222 230 223 if (!ieee80211_is_ready(ieee80211_dev))231 if (!ieee80211_is_ready(ieee80211_dev)) 224 232 return EREFUSED; 225 233 226 if (!ieee80211_is_connected(ieee80211_dev)) {234 if (!ieee80211_is_connected(ieee80211_dev)) 227 235 return EOK; 228 } else {229 fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex);230 int rc = ieee80211_deauthenticate(ieee80211_dev);231 fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex);232 return rc;233 }236 237 fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex); 238 int rc = ieee80211_deauthenticate(ieee80211_dev); 239 fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex); 240 241 return rc; 234 242 } 235 243 -
uspace/lib/ieee80211/src/ieee80211_impl.c
r09044cb r8a64320e 32 32 33 33 /** @file ieee80211_impl.c 34 * 34 * 35 35 * IEEE 802.11 default device functions implementation. 36 36 */ … … 40 40 #include <stdlib.h> 41 41 #include <errno.h> 42 43 42 #include <ieee80211_impl.h> 44 43 45 /** 46 * Default implementation of IEEE802.11 start function.47 * 48 * @param ieee80211_dev Structure of IEEE802.11 device.49 * 50 * @return EOK.44 /** Default implementation of IEEE802.11 start function. 45 * 46 * @param ieee80211_dev Structure of IEEE802.11 device. 47 * 48 * @return EOK. 49 * 51 50 */ 52 51 int ieee80211_start_impl(ieee80211_dev_t *ieee80211_dev) … … 55 54 } 56 55 57 /** 58 * Default implementation of IEEE802.11 TX handler function.59 * 60 * @param ieee80211_dev Structure of IEEE802.11 device.61 * @param buffer Buffer with data to send.62 * @param buffer_size Size of buffer.63 * 64 * @return EOK.65 */ 66 int ieee80211_tx_handler_impl(ieee80211_dev_t *ieee80211_dev, void *buffer, 67 size_t buffer_size)68 { 69 return EOK; 70 } 71 72 /** 73 * Default implementation of IEEE802.11 set frequency function.74 * 75 * @param ieee80211_dev Structure of IEEE802.11 device.76 * @param freq Value of frequency to be switched on.77 * 78 * @return EOK.56 /** Default implementation of IEEE802.11 TX handler function. 57 * 58 * @param ieee80211_dev Structure of IEEE802.11 device. 59 * @param buffer Buffer with data to send. 60 * @param buffer_size Size of buffer. 61 * 62 * @return EOK. 63 * 64 */ 65 int ieee80211_tx_handler_impl(ieee80211_dev_t *ieee80211_dev, void *buffer, 66 size_t buffer_size) 67 { 68 return EOK; 69 } 70 71 /** Default implementation of IEEE802.11 set frequency function. 72 * 73 * @param ieee80211_dev Structure of IEEE802.11 device. 74 * @param freq Value of frequency to be switched on. 75 * 76 * @return EOK. 77 * 79 78 */ 80 79 int ieee80211_set_freq_impl(ieee80211_dev_t *ieee80211_dev, uint16_t freq) … … 83 82 } 84 83 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 bool connected)94 { 95 return EOK; 96 } 97 98 /** 99 * Default implementation of IEEE802.11 key config function.100 * 101 * @param ieee80211_dev Structure of IEEE802.11 device.102 * 103 * @return EOK.84 /** Default implementation of IEEE802.11 BSSID change function. 85 * 86 * @param ieee80211_dev Structure of IEEE802.11 device. 87 * 88 * @return EOK. 89 * 90 */ 91 int ieee80211_bssid_change_impl(ieee80211_dev_t *ieee80211_dev, 92 bool connected) 93 { 94 return EOK; 95 } 96 97 /** Default implementation of IEEE802.11 key config function. 98 * 99 * @param ieee80211_dev Structure of IEEE802.11 device. 100 * 101 * @return EOK. 102 * 104 103 */ 105 104 int ieee80211_key_config_impl(ieee80211_dev_t *ieee80211_dev, 106 ieee80211_key_config_t *key_conf, bool insert)107 { 108 return EOK; 109 } 110 111 /** 112 * Default implementation of IEEE802.11 scan function.113 * 114 * @param ieee80211_dev Structure of IEEE802.11 device.115 * @param clear Whether to clear current scan results.116 * 117 * @return EOK if succeed, negative error code otherwise.105 ieee80211_key_config_t *key_conf, bool insert) 106 { 107 return EOK; 108 } 109 110 /** Default implementation of IEEE802.11 scan function. 111 * 112 * @param ieee80211_dev Structure of IEEE802.11 device. 113 * @param clear Whether to clear current scan results. 114 * 115 * @return EOK if succeed, negative error code otherwise. 116 * 118 117 */ 119 118 int ieee80211_scan_impl(ieee80211_dev_t *ieee80211_dev) … … 121 120 fibril_mutex_lock(&ieee80211_dev->scan_mutex); 122 121 123 if (ieee80211_get_auth_phase(ieee80211_dev) ==124 IEEE80211_AUTH_DISCONNECTED) {122 if (ieee80211_get_auth_phase(ieee80211_dev) == 123 IEEE80211_AUTH_DISCONNECTED) { 125 124 fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex); 125 126 126 /* Remove old entries we don't receive beacons from. */ 127 ieee80211_scan_result_list_t *result_list = 128 &ieee80211_dev->ap_list; 127 ieee80211_scan_result_list_t *result_list = 128 &ieee80211_dev->ap_list; 129 129 130 list_foreach_safe(result_list->list, cur_link, next_link) { 130 ieee80211_scan_result_link_t *cur_result = 131 list_get_instance(cur_link, 132 ieee80211_scan_result_link_t, 133 link); 134 if((time(NULL) - cur_result->last_beacon) > 135 MAX_KEEP_SCAN_SPAN_SEC) { 136 ieee80211_scan_result_list_remove(result_list, 137 cur_result); 138 } 131 ieee80211_scan_result_link_t *cur_result = 132 list_get_instance(cur_link, 133 ieee80211_scan_result_link_t, link); 134 135 if ((time(NULL) - cur_result->last_beacon) > 136 MAX_KEEP_SCAN_SPAN_SEC) 137 ieee80211_scan_result_list_remove(result_list, 138 cur_result); 139 139 } 140 140 141 fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex); 141 142 142 143 uint16_t orig_freq = ieee80211_dev->current_freq; 143 144 for(uint16_t freq = IEEE80211_FIRST_FREQ; 145 freq <= IEEE80211_MAX_FREQ; 146 freq += IEEE80211_CHANNEL_GAP) { 147 if(ieee80211_pending_connect_request(ieee80211_dev)) { 144 145 for (uint16_t freq = IEEE80211_FIRST_FREQ; 146 freq <= IEEE80211_MAX_FREQ; freq += IEEE80211_CHANNEL_GAP) { 147 if (ieee80211_pending_connect_request(ieee80211_dev)) 148 148 break; 149 }150 149 151 150 ieee80211_dev->ops->set_freq(ieee80211_dev, freq); 152 151 ieee80211_probe_request(ieee80211_dev, NULL); 153 152 154 153 /* Wait for probe responses. */ 155 154 async_usleep(SCAN_CHANNEL_WAIT_USEC); 156 155 } 157 156 158 157 ieee80211_dev->ops->set_freq(ieee80211_dev, orig_freq); 159 158 } … … 164 163 } 165 164 166 /** 167 * Pseudorandom function used for IEEE 802.11 pairwise key computation 168 * using SHA1 hash algorithm. 169 * 170 * @param key Key with PBKDF2 encrypted passphrase. 171 * @param data Concatenated sequence of both mac addresses and nonces. 172 * @param hash Output parameter for result hash. 165 /** Pseudorandom function used for IEEE 802.11 pairwise key computation. 166 * 167 * Using SHA1 hash algorithm. 168 * 169 * @param key Key with PBKDF2 encrypted passphrase. 170 * @param data Concatenated sequence of both MAC 171 * addresses and nonces. 172 * @param hash Output parameter for result hash. 173 173 * @param output_size Length of output sequence to be generated. 174 * 175 * @return EINVAL when key or data not specified, ENOMEM when pointer for 176 * output hash result is not allocated, otherwise EOK. 177 */ 178 int ieee80211_prf(uint8_t *key, uint8_t *data, uint8_t *hash, 179 size_t output_size) 180 { 181 if(!key || !data) 174 * 175 * @return EINVAL when key or data not specified, 176 * ENOMEM when pointer for output hash result 177 * is not allocated, otherwise EOK. 178 * 179 */ 180 int ieee80211_prf(uint8_t *key, uint8_t *data, uint8_t *hash, 181 size_t output_size) 182 { 183 if ((!key) || (!data)) 182 184 return EINVAL; 183 185 184 if (!hash)186 if (!hash) 185 187 return ENOMEM; 186 188 … … 188 190 189 191 const char *a = "Pairwise key expansion"; 190 uint8_t result[HASH_SHA1 *iters];192 uint8_t result[HASH_SHA1 * iters]; 191 193 uint8_t temp[HASH_SHA1]; 194 192 195 size_t data_size = PRF_CRYPT_DATA_LENGTH + str_size(a) + 2; 193 196 uint8_t work_arr[data_size]; … … 196 199 memcpy(work_arr, a, str_size(a)); 197 200 memcpy(work_arr + str_size(a) + 1, data, PRF_CRYPT_DATA_LENGTH); 198 199 for (uint8_t i = 0; i < iters; i++) {201 202 for (uint8_t i = 0; i < iters; i++) { 200 203 memcpy(work_arr + data_size - 1, &i, 1); 201 hmac(key, PBKDF2_KEY_LENGTH, work_arr, data_size, temp, 202 HASH_SHA1);204 hmac(key, PBKDF2_KEY_LENGTH, work_arr, data_size, temp, 205 HASH_SHA1); 203 206 memcpy(result + i*HASH_SHA1, temp, HASH_SHA1); 204 207 } … … 210 213 211 214 int ieee80211_rc4_key_unwrap(uint8_t *key, uint8_t *data, size_t data_size, 212 uint8_t *output)215 uint8_t *output) 213 216 { 214 217 return rc4(key, 32, data, data_size, 256, output); … … 216 219 217 220 int ieee80211_aes_key_unwrap(uint8_t *kek, uint8_t *data, size_t data_size, 218 uint8_t *output)219 { 220 if (!kek || !data)221 uint8_t *output) 222 { 223 if ((!kek) || (!data)) 221 224 return EINVAL; 222 225 223 if (!output)226 if (!output) 224 227 return ENOMEM; 225 226 uint32_t n = data_size /8 - 1;227 uint8_t work_data[n *8];228 229 uint32_t n = data_size / 8 - 1; 230 uint8_t work_data[n * 8]; 228 231 uint8_t work_input[AES_CIPHER_LENGTH]; 229 232 uint8_t work_output[AES_CIPHER_LENGTH]; 230 233 uint8_t *work_block; 231 234 uint8_t a[8]; 235 232 236 memcpy(a, data, 8); 233 uint64_t mask = 0xFF; 237 238 uint64_t mask = 0xff; 234 239 uint8_t shift, shb; 235 240 236 memcpy(work_data, data + 8, n *8);237 for (int j = 5; j >= 0; j--) {238 for (int i = n; i > 0; i--) {239 for (size_t k = 0; k < 8; k++) {240 shift = 56 - 8 *k;241 shb = ((n *j+i) & (mask << shift)) >> shift;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; 242 247 a[k] ^= shb; 243 248 } 244 work_block = work_data + (i-1)*8; 249 250 work_block = work_data + (i - 1) * 8; 245 251 memcpy(work_input, a, 8); 246 252 memcpy(work_input + 8, work_block, 8); 247 253 aes_decrypt(kek, work_input, work_output); 248 254 memcpy(a, work_output, 8); 249 memcpy(work_data + (i -1)*8, work_output + 8, 8);255 memcpy(work_data + (i - 1) * 8, work_output + 8, 8); 250 256 } 251 257 } 252 258 253 259 size_t it; 254 for (it = 0; it < 8; it++) {255 if (a[it] != 0xA6)260 for (it = 0; it < 8; it++) { 261 if (a[it] != 0xa6) 256 262 break; 257 263 } 258 264 259 if (it == 8) {260 memcpy(output, work_data, n *8);265 if (it == 8) { 266 memcpy(output, work_data, n * 8); 261 267 return EOK; 262 } else {263 return EINVAL;264 }265 } 266 267 static void ieee80211_michael_mic_block(uint32_t *l, uint32_t *r, 268 uint32_t value)268 } 269 270 return EINVAL; 271 } 272 273 static void ieee80211_michael_mic_block(uint32_t *l, uint32_t *r, 274 uint32_t value) 269 275 { 270 276 *l ^= value; 271 277 *r ^= rotl_uint32(*l, 17); 272 278 *l += *r; 273 *r ^= ((*l & 0x00 FF00FF) << 8) | ((*l & 0xFF00FF00) >> 8);279 *r ^= ((*l & 0x00ff00ff) << 8) | ((*l & 0xff00ff00) >> 8); 274 280 *l += *r; 275 281 *r ^= rotl_uint32(*l, 3); … … 279 285 } 280 286 281 int ieee80211_michael_mic(uint8_t *key, uint8_t *buffer, size_t size, 282 uint8_t *mic)283 { 284 if (!key || !buffer)287 int ieee80211_michael_mic(uint8_t *key, uint8_t *buffer, size_t size, 288 uint8_t *mic) 289 { 290 if ((!key) || (!buffer)) 285 291 return EINVAL; 286 292 287 if (!mic)293 if (!mic) 288 294 return ENOMEM; 289 295 … … 292 298 293 299 ieee80211_data_header_t *data_header = 294 (ieee80211_data_header_t *) buffer;295 296 uint8_t *data = buffer + sizeof(ieee80211_data_header_t) + 297 IEEE80211_TKIP_HEADER_LENGTH;300 (ieee80211_data_header_t *) buffer; 301 302 uint8_t *data = buffer + sizeof(ieee80211_data_header_t) + 303 IEEE80211_TKIP_HEADER_LENGTH; 298 304 size_t data_size = size - sizeof(ieee80211_data_header_t) - 299 IEEE80211_TKIP_HEADER_LENGTH;305 IEEE80211_TKIP_HEADER_LENGTH; 300 306 301 307 /* Process header. */ 302 uint8_t *src_addr = 303 ieee80211_is_fromds_frame(data_header->frame_ctrl) ?304 data_header->address3 : data_header->address2;305 uint8_t *dest_addr = 306 ieee80211_is_tods_frame(data_header->frame_ctrl) ?307 data_header->address3 : data_header->address1;308 uint8_t *src_addr = 309 ieee80211_is_fromds_frame(data_header->frame_ctrl) ? 310 data_header->address3 : data_header->address2; 311 uint8_t *dest_addr = 312 ieee80211_is_tods_frame(data_header->frame_ctrl) ? 313 data_header->address3 : data_header->address1; 308 314 309 315 ieee80211_michael_mic_block(&l, &r, uint32le_from_seq(dest_addr)); 310 ieee80211_michael_mic_block(&l, &r, 311 uint16le_from_seq(dest_addr + 4) |312 (uint16le_from_seq(src_addr) << 16));316 ieee80211_michael_mic_block(&l, &r, 317 uint16le_from_seq(dest_addr + 4) | 318 (uint16le_from_seq(src_addr) << 16)); 313 319 ieee80211_michael_mic_block(&l, &r, uint32le_from_seq(src_addr + 2)); 314 320 ieee80211_michael_mic_block(&l, &r, 0); … … 318 324 size_t pad = data_size % 4; 319 325 320 for (size_t k = 0; k < blocks; k++) {321 ieee80211_michael_mic_block(&l, &r, 322 uint32le_from_seq(&data[k*4]));326 for (size_t k = 0; k < blocks; k++) { 327 ieee80211_michael_mic_block(&l, &r, 328 uint32le_from_seq(&data[k * 4])); 323 329 } 324 330 325 331 /* Add padding. */ 326 uint32_t value = 0x5 A;327 for (size_t i = pad; i > 0; i--) {332 uint32_t value = 0x5a; 333 for (size_t i = pad; i > 0; i--) { 328 334 value <<= 8; 329 value |= data[blocks *4 + (i-1)];335 value |= data[blocks * 4 + (i - 1)]; 330 336 } 331 337 … … 345 351 { 346 352 uint16_t *u16 = (uint16_t *) seq; 347 return uint16_t_le2host(*u16); 353 return uint16_t_le2host(*u16); 348 354 } 349 355 … … 351 357 { 352 358 uint32_t *u32 = (uint32_t *) seq; 353 return uint32_t_le2host(*u32); 359 return uint32_t_le2host(*u32); 354 360 } 355 361 … … 357 363 { 358 364 uint16_t *u16 = (uint16_t *) seq; 359 return uint16_t_be2host(*u16); 365 return uint16_t_be2host(*u16); 360 366 } 361 367 … … 363 369 { 364 370 uint32_t *u32 = (uint32_t *) seq; 365 return uint32_t_be2host(*u32); 371 return uint32_t_be2host(*u32); 366 372 } 367 373 368 374 int rnd_sequence(uint8_t *sequence, size_t length) 369 375 { 370 if (!sequence)376 if (!sequence) 371 377 return ENOMEM; 372 378 373 for (size_t i = 0; i < length; i++) {379 for (size_t i = 0; i < length; i++) 374 380 sequence[i] = (uint8_t) rand(); 375 }376 381 377 382 return EOK; … … 380 385 uint8_t *min_sequence(uint8_t *seq1, uint8_t *seq2, size_t size) 381 386 { 382 if (!seq1 || !seq2)387 if ((!seq1) || (!seq2)) 383 388 return NULL; 384 389 385 for (size_t i = 0; i < size; i++) {386 if (seq1[i] < seq2[i]) {390 for (size_t i = 0; i < size; i++) { 391 if (seq1[i] < seq2[i]) 387 392 return seq1; 388 } else if(seq1[i] > seq2[i]) {393 else if (seq1[i] > seq2[i]) 389 394 return seq2; 390 }391 395 } 392 396 … … 397 401 { 398 402 uint8_t *min = min_sequence(seq1, seq2, size); 399 if (min == seq1) {403 if (min == seq1) 400 404 return seq2; 401 } else { 402 return seq1; 403 } 405 406 return seq1; 404 407 } 405 408
Note:
See TracChangeset
for help on using the changeset viewer.
