WPS: Added helper functions for generating and validating PINs
authorJouni Malinen <j@w1.fi>
Sat, 29 Nov 2008 12:02:09 +0000 (14:02 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 29 Nov 2008 12:02:09 +0000 (14:02 +0200)
src/wps/wps.h
src/wps/wps_common.c

index ca6da58..c0ea694 100644 (file)
@@ -133,4 +133,8 @@ int wps_registrar_button_pushed(struct wps_registrar *reg);
 void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
                                const struct wpabuf *wps_data);
 
+unsigned int wps_pin_checksum(unsigned int pin);
+unsigned int wps_pin_valid(unsigned int pin);
+unsigned int wps_generate_pin(void);
+
 #endif /* WPS_H */
index 1c37565..7ac3c03 100644 (file)
@@ -247,3 +247,54 @@ struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
 
        return decrypted;
 }
+
+
+/**
+ * wps_pin_checksum - Compute PIN checksum
+ * @pin: Seven digit PIN (i.e., eight digit PIN without the checksum digit)
+ * Returns: Checksum digit
+ */
+unsigned int wps_pin_checksum(unsigned int pin)
+{
+       unsigned int accum = 0;
+       while (pin) {
+               accum += 3 * (pin % 10);
+               pin /= 10;
+               accum += pin % 10;
+               pin /= 10;
+       }
+
+       return (10 - accum % 10) % 10;
+}
+
+
+/**
+ * wps_pin_valid - Check whether a PIN has a valid checksum
+ * @pin: Eight digit PIN (i.e., including the checksum digit)
+ * Returns: 1 if checksum digit is valid, or 0 if not
+ */
+unsigned int wps_pin_valid(unsigned int pin)
+{
+       return wps_pin_checksum(pin / 10) == (pin % 10);
+}
+
+
+/**
+ * wps_generate_pin - Generate a random PIN
+ * Returns: Eight digit PIN (i.e., including the checksum digit)
+ */
+unsigned int wps_generate_pin(void)
+{
+       unsigned int val;
+
+       /* Generate seven random digits for the PIN */
+       if (os_get_random((unsigned char *) &val, sizeof(val)) < 0) {
+               struct os_time now;
+               os_get_time(&now);
+               val = os_random() ^ now.sec ^ now.usec;
+       }
+       val %= 10000000;
+
+       /* Append checksum digit */
+       return val * 10 + wps_pin_checksum(val);
+}