This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
soc:2009:oremanj:journal:week5 [2009/06/22 13:51]
soc:2009:oremanj:journal:week5 [2009/06/26 22:26] (current)
Line 1: Line 1:
 ====== Joshua Oreman: 802.11 wireless development ====== ====== Joshua Oreman: 802.11 wireless development ======
- +===== Journal Week =====
-===== Journal Week =====+
 ==== Monday, 22 June ==== ==== Monday, 22 June ====
Line 11: Line 10:
   * Some interesting preliminary discussion about the possibility of [[..:​notes:​modules|loading part of gPXE as a module]]. If I do any work on this it'll be after encryption, and won't impact gPXE's current uses.   * Some interesting preliminary discussion about the possibility of [[..:​notes:​modules|loading part of gPXE as a module]]. If I do any work on this it'll be after encryption, and won't impact gPXE's current uses.
 +I did not get any coding done today to speak of; I worked rather fervently to get wireless done by the end of last week, and I needed some time to recharge. :-) Encryption support will commence tomorrow.
 +==== Tuesday, 23 June ====
 +WEP support is done and some of my supporting changes from early last week have been merged in. Current state-of-the-branches,​ in logical order of application:​
 +  * **Merged** in gPXE mainline:
 +    * [[http://​git.etherboot.org/?​p=gpxe.git;​a=commit;​h=743ebc2f4b056673efb26f294ab39a661d77d1a8|
 +[nvs] Add init function for Atmel 93C66 EEPROM]] (was [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=18e6470d06d8846d531d97d881be6f1278bd2f15|18e6470...]])
 +    * [[http://​git.etherboot.org/?​p=gpxe.git;​a=commit;​h=eb3ca2a36f0c613aea5c2f02762bc608d5ec785c|
 +[netdevice] Add netdev argument to link-layer push and pull handlers]] (was [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=d429b31ac28760004e753dc79178400d507975e2|d429b31...]])
 +    * [[http://​git.etherboot.org/?​p=gpxe.git;​a=commit;​h=f8448735b09af59760eb10fa4c8e759274d0830c|
 +[image] Modify imgfree command to accept an argument]] (was [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=a9a0567225493046f70e6252e21ab5c6d8219e87|a9a0567...]])
 +  * Merged with significant modifications:​
 +    * [[http://​git.etherboot.org/?​p=gpxe.git;​a=commit;​h=558c1a45fe30ffe3d6c67b2321e0fc973f13e9b7|
 +[tcp] Improve robustness in the presence of duplicated received packets]] and following commits
 +    * [[http://​git.etherboot.org/?​p=gpxe.git;​a=commit;​h=a310d00d37f8362b48913972927bfb78e7d7586d|
 +[netdevice] Add mechanism for reporting detailed link status codes]] (was [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=4602299f4b96f7692766553d5972066dfd567b4e|4602299...]]) [//6/24//]
 +  * More merged: [//6/24//]
 +    * [[http://​git.etherboot.org/?​p=gpxe.git;​a=commit;​h=4125216a2f88c1e4c9fd33931d1249b8afc2f923|
 +[ifmgmt] Move link-up status messages from autoboot() to iflinkwait()]] (was [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=30df822acbf6a207201f111d886effa0e4fc97d3|30df822...]])
 +    * [[http://​git.etherboot.org/?​p=gpxe.git;​a=commit;​h=62549983274af297c65fed369d9f5a2ea795cd99|
 +[dhcp] Await link-up before starting DHCP]] (was [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=6d63a4a5f928b46422e2eb79837a8aba103e5bb7|6d63a4a...]])
 +    * [[http://​git.etherboot.org/?​p=gpxe.git;​a=commit;​h=15ce2fb851067eb64543859737e2d42f8a271ed6|
 +[hci] Expose ifcommon_exec() in a local header so wireless commands can use it]] (was [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=22c261e77bda0984f4cb052037008f487a4bcaa6|22c261e...]])
 +  * The three big commits on mainline-review,​ needing updates against recent modifications by Michael and I: (//as of 6/24, updated and ready for review//)
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=42a0c88f51e1f264821ffbf07cbc31ff3e8c47ca|
 +[802.11] Add support for 802.11 devices with software MAC layer]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=5d8f27b800e4a8ed1ae07c58992774cb7eb64e53|
 +[rtl818x] Add driver for Realtek 8180/8185 wireless cards]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=dad63b2de90bd50efada44b747200c2e7f7b302f|
 +[iwmgmt] Add user-level 802.11 management commands and common error tables]]
 +  * Patches to those three, based on discussion with Michael and bug-hunting:​ (//as of 6/24, included in the above three//)
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=650e7435c813a9ed33727613dea6a1628727d93f|
 +[802.11] Automatically retry association if it fails]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=980c569f0929bbe33d91ae51c13caa432d538085|
 +[iwmgmt] Remove iwassoc; do not display association error in iwstat]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=60a483bc65a8d76aeac78122a391afaedca87c32|
 +[802.11] Add measure of link quality based on received beacons]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=85d58caa58f942b6ec2dab79d3dc0a6e7b832c57|
 +[iwmgmt] Print link quality in iwstat output]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=567214147fa3c059485011163f2abc0ae574040a|
 +[802.11] Remove spurious assert()]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=d255c2e33c1cdd4e1cb9c814ea54045cdfb9d25c|
 +[802.11] Properly handle return code of fetch_setting()]]
 +I will update the above list as things change this week. After we've decided what to do with the non-802.11 commits (up to "Make DHCP wait for link-up"​),​ I'll reformat all the mainline-ready 802.11 code into three commits like the three I committed on Saturday, rebased off the then-current gPXE trunk.
 +  * New encryption commits on branch **wireless**,​ not ready for mainline review yet:
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=cf92b5abf1b6c6b038daa00f5c975d35a301e27c|
 +[digest] Add generic CRC32 function]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=65713460717fd710d6dcf0eebdd8826cd0489514|
 +[cipher] Add the ARC4 stream cipher]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=d16c336a8ec188fa24e0fe4d52cde377482da776|
 +[802.11] Add core support for encryption hooks]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=aa4b9767418c373a1e8294222b1b328daa03f4a2|
 +[802.11] Add support for WEP-protected networks]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=5bbb35902dae90b187a5d0bf026fd130ba9ef0b8|
 +[802.11] Add errortab entry for the error returned by unsuccessful decryption]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=bc416e6e2216d9c2075c9ccaf11f1398b393f12f|
 +[config] Move linker massaging for 802.11 options to new file config_80211.o]]
 +    * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=b319881e68c287127bb765db2226c4b01c6ec266|
 +[config] Add 802.11 encryption options to config/​general.h]]
 +Encryption is looking like it will be at least reasonably elegant to support. Of course, WEP is the easiest of the three methods in use; WPA may well have me tearing out my hair by this time tomorrow :-) The WEP code has been tested with hostapd and seems to work very well.
 +==== Wednesday, 24 June ====
 +Spent all day researching the security protocols used in WPA-based setups. They'​re over an order of magnitude more complicated than WEP, taking up about 70 pages in the IEEE 802.11-2007 standard, with reference needed to 802.1X-2004 and various RFCs. The bits I will need to implement include:
 +  * Algorithmic:​
 +    * Generation of pairwise master key (PMK) from passphrase salted with SSID
 +    * Generation of pairwise transient key (PTK) from PMK and nonces
 +    * The Michael message integrity code for TKIP (WPA) frames
 +    * TKIP key mixing stages (the encryption is just ARC4)
 +    * CCMP (CTR [counter mode] with CBC-MAC [cipher-block chaining message authentication code] protocol, used in WPA2) encryption and encapsulation
 +    * NIST AES key wrap for 4-Way Handshake frames on CCMP networks
 +    * HMAC-MD5 and HMAC-SHA1, for 4-Way Handshake MIC [I think gPXE already has implementations of these]
 +  * Protocol:
 +    * EAPOL decapsulation (packets of EtherType 0x888E with defined header format)
 +    * Processing of 4-Way Handshake contained in EAPOL frames
 +    * Processing of Group Key Handshake contained in EAPOL frames and rekeyed occasionally
 +I've got a busy week and a half ahead of me!
 +Earlier today Michael finished reviewing all the commits on my mainline-review branch except the three 802.11-specific ones; I've updated yesterday'​s commit list with the current state of things.
 +==== Thursday, 25 June ====
 +WPA is truly a horribly complicated beast. The more I learn about it, the more I realize I need to implement... ah well. I do feel as though I'm getting a handle on things, at least, and spent today working on ancillary code:
 +  * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=f16216a4e4382d1e0b680ac917f4e290eaa1b602|
 +[802.11] Detect secured networks properly, and find errors better]]
 +  * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=8c249f0dc339bc416f5acf1b73a546dcb8591275|
 +[digest] Add HMAC-SHA1 based pseudorandom function and PBKDF2]]
 +  * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=f358af4c5266b654b4572ffcd9306eb24593a7f2|
 +[eap] Add handlers for EAPOL decapsulation and EAP demultiplexing]]
 +Things I still need to do include implementing the 4-Way Handshake, generating the PTK, checking the Michael MIC, and the nuts-and-bolts methods of TKIP key mixing and CCMP encryption.
 +One thing I discovered today while browsing the Linux ''​wpa_supplicant''​ source code is that the RSN information element and 4-Way Handshake documented in the IEEE standard are not supported by many "​WPA"​ devices that were shipped prior to the time IEEE 802.11i (the WPA amendment) was finalized. Instead, they use an information element under the "​vendor-specific"​ heading with a different format, and a slightly different handshake as well. Judging by ''​wpa_supplicant''​ the old way seems to be simpler, but I haven'​t been able to find any documentation on it other than the source code. When I run hostapd in WPA1 mode, gPXE thinks it's WEP, so that's another thing I'll need to figure out and fix.
 +==== Friday, 26 June ====
 +Most of the major bits of WPA have yet to be completed, but I've got enough ancillary stuff written that I think I should be able to dive in and have at least one WPA encryption scheme implemented by mid-next week. Commits:
 +  * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=7fe87e2161ebd947a39ff8015fb45486a7140f0b|[802.11] Revamp RSN IE processing]]
 +  * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=b17f562c91ff1745f50d0ba58eea385fcd7cf732|[802.11] Miscellaneous structural and API changes for encryption code]]
 +  * [[http://​git.etherboot.org/?​p=people/​oremanj/​gpxe.git;​a=commit;​h=ec70a5225b8062d11b4b2161af91f0ec21527161|[802.11] Start hashing out how WPA is going to work]]
 +The issue I noted in the last paragraph of yesterday'​s entry was not quite so bad as it seemed; after accounting for different header bytes and different version numbers, for gPXE's purposes the bulk of the WPA and RSN information elements can be parsed identically. Huzzah. The two versions still have some respective idiosyncracies in the handling of the 4-Way Handshake (which is next up on the list of things to write), but the ''​wpa_supplicant''​ code is a good reference for that.
 +I now offer an interlude of Cool Linker Tricks.
 +One of the things I did today was move all the helper functions that will only be needed when some encryption method is supported into a separate file, ''​sec80211.c'',​ so they don't bloat the code size in wireless builds that don't use encryption. There'​s one chink in that: the main wireless probe code needs to be able to differentiate fully between the various types of secured network even if they'​re not all supported, as WPA looks like WEP to a client that knows nothing about WPA. So ''​net80211_probe_step()''​ has to call ''​sec80211_detect()'',​ but we don't want that call to pull in ''​sec80211.c''​ if nothing else needs it.
 +Enter a very handy and underused linker feature: weak symbols!
 +Suppose you have a function, ''​check_snazzy()'',​ that needs to be called from the ''​base.o''​ module only if the module containing it, ''​snazzy.o'',​ is compiled in for another reason. It's a one-off, so using a linker table would be overkill; instead, you can do in ''​snazzy.h''​
 +  int check_snazzy() __attribute__ (( weak ));
 +In ''​snazzy.c''​ the function is defined as normal, without the weak attribute; it's only the external declaration that's weak, not the definition. But in ''​base.c''​ you can do
 +  void check_things() {
 +          /* ... */
 +          if ( check_snazzy ) {
 +                  int snazziness = check_snazzy();​
 +                  /* ... */
 +          } else {
 +                  DBG ( "​snazziness not enabled"​ );
 +          }
 +          /* ... */
 +  }
 +If ''​snazzy.o''​ would not be pulled into the link by an ordinary ("​strong"​) symbol reference, a weak reference alone isn't going to be enough to pull it in. Instead, the linker defines ''​snazzy.o'''​s referenced weak symbols to be ''​NULL''​ pointers, and code that wants to conditionally use ''​check_snazzy()''​ just needs to test it against ''​NULL''​ before using it. While this example is obviously contrived, the technique can be very useful.
 +This is rather messy, of course; the fewer symbols with an implicit "​might-be-NULL"​ attached the better. But for fairly tightly-coupled source files that need to be separated for size reasons, one or two weak functions can provide an excellent interface between the two.
 +While we're in the Cool Linker Tricks department, there'​s also something called a "weak alias",​ which serves a completely different purpose: providing one implementation of an API function while allowing it to be superseded without complaint by another object file. I haven'​t seen anything in gPXE that really needs this, but to give an example of how it //could// be used, gPXE core defines a simple ''​memcpy()''​ function that doesn'​t know about any architecture-specific optimizations,​ but only declares its prototype if the preprocessor macro ''​%%__HAVE_ARCH_MEMCPY%%''​ hasn't been defined by architecture-specific includes; that allows architecture-specific string functions to be used instead, using either ''#​define''​ or an inline implementation,​ but no symbol can be named ''​memcpy''​ because the linker would complain. A way around that would be:
 +  /* in core string code */
 +  void * core_memcpy ( void *dest, const void *src, int len ) {
 +          /* ... */
 +  }
 +  ​
 +  void * memcpy ( void *dest, const void *src, int len )
 +          __attribute__ (( weak, alias ( "​core_memcpy"​ ) ));
 +Then architecture-specific code could just define ''​memcpy''​ directly, no preprocessor tricks needed, and it would supersede the core version. Again, I don't think anything needs this at this point, but it's cool to know - maybe it'll even come in handy someday! :-)

QR Code
QR Code soc:2009:oremanj:journal:week5 (generated for current page)