Make `wifi setclient` fast again.

PyCrypto's PBKDF2 implementation does a lot of work in Python. This is
OK on a powerful workstation, but not OK (it takes 8 seconds!) on a TV
box.

Use OpenSSL's PBKDF2 implementation instead, via ctypes. This takes 0.25
seconds in a microbenchmark, of which ~half is the time to load the
Python interpreter.

Change-Id: I7ae4805f4aa9971d59c495037aa8b7a3e61352d3
diff --git a/wifi/configs.py b/wifi/configs.py
index 4dcdaab..e83ee68 100644
--- a/wifi/configs.py
+++ b/wifi/configs.py
@@ -2,16 +2,18 @@
 
 """Utils for hostapd and wpa_supplicant configuration."""
 
+import ctypes
 import subprocess
 
-import Crypto.Protocol.KDF
-
 # pylint: disable=g-bad-import-order
 import autochannel
 import experiment
 import utils
 
 
+crypto = ctypes.CDLL('libcrypto.so')
+
+
 EXPERIMENTS = [
     'NoSwapWifiPrimaryChannel',  # checked by hostapd itself
     'NoAutoNarrowWifiChannel',  # checked by hostapd itself
@@ -357,8 +359,11 @@
   if len(clean_passphrase) == 64:
     network_lines += ['\tpsk=%s' % clean_passphrase]
   else:
-    raw_psk = Crypto.Protocol.KDF.PBKDF2(clean_passphrase, clean_ssid, 32, 4096)
-    hex_psk = ''.join(ch.encode('hex') for ch in raw_psk)
+    psk_buf = ctypes.create_string_buffer(32)
+    crypto.PKCS5_PBKDF2_HMAC_SHA1(clean_passphrase, len(clean_passphrase),
+                                  clean_ssid, len(clean_ssid),
+                                  4096, 32, psk_buf)
+    hex_psk = ''.join(ch.encode('hex') for ch in psk_buf.raw)
     network_lines += ['\t#psk="%s"' % clean_passphrase, '\tpsk=%s' % hex_psk]
 
   return network_lines