WPS: Use os_memcmp_const() for hash/password comparisons

This makes the implementation less likely to provide useful timing
information to potential attackers from comparisons of information
received from a remote device and private material known only by the
authorized devices.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2014-06-29 19:38:17 +03:00
parent afc3c8b07f
commit ce9c9bcc38
3 changed files with 12 additions and 11 deletions

View file

@ -41,7 +41,7 @@ int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN;
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
if (os_memcmp(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
if (os_memcmp_const(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator");
return -1;
}
@ -71,7 +71,7 @@ int wps_process_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg,
}
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash);
if (os_memcmp(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
if (os_memcmp_const(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Invalid KWA");
return -1;
}

View file

@ -525,8 +525,8 @@ static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
if (wps->peer_pubkey_hash_set) {
u8 hash[WPS_HASH_LEN];
sha256_vector(1, &pk, &pk_len, hash);
if (os_memcmp(hash, wps->peer_pubkey_hash,
WPS_OOB_PUBKEY_HASH_LEN) != 0) {
if (os_memcmp_const(hash, wps->peer_pubkey_hash,
WPS_OOB_PUBKEY_HASH_LEN) != 0) {
wpa_printf(MSG_ERROR, "WPS: Public Key hash mismatch");
wpa_hexdump(MSG_DEBUG, "WPS: Received public key",
pk, pk_len);
@ -605,7 +605,7 @@ static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1)
len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
"not match with the pre-committed value");
wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
@ -645,7 +645,7 @@ static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
"not match with the pre-committed value");
wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;

View file

@ -826,7 +826,7 @@ static int wps_registrar_invalidate_wildcard_pin(struct wps_registrar *reg,
{
if (dev_pw && pin->pin &&
(dev_pw_len != pin->pin_len ||
os_memcmp(dev_pw, pin->pin, dev_pw_len) != 0))
os_memcmp_const(dev_pw, pin->pin, dev_pw_len) != 0))
continue; /* different PIN */
if (pin->wildcard_uuid) {
wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
@ -2211,7 +2211,7 @@ static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1)
len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
"not match with the pre-committed value");
wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
@ -2251,7 +2251,7 @@ static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2)
len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
"not match with the pre-committed value");
wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
@ -2591,8 +2591,9 @@ static enum wps_process_res wps_process_m1(struct wps_data *wps,
addr[0] = attr->public_key;
sha256_vector(1, addr, &attr->public_key_len, hash);
if (os_memcmp(hash, wps->nfc_pw_token->pubkey_hash,
WPS_OOB_PUBKEY_HASH_LEN) != 0) {
if (os_memcmp_const(hash,
wps->nfc_pw_token->pubkey_hash,
WPS_OOB_PUBKEY_HASH_LEN) != 0) {
wpa_printf(MSG_ERROR, "WPS: Public Key hash "
"mismatch");
wps->state = SEND_M2D;