struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey, struct wpabuf **privkey, struct wpabuf **dev_pw) { struct wpabuf *pw; u16 val; pw = wpabuf_alloc(WPS_OOB_DEVICE_PASSWORD_LEN); if (pw == NULL) return NULL; if (random_get_bytes(wpabuf_put(pw, WPS_OOB_DEVICE_PASSWORD_LEN), WPS_OOB_DEVICE_PASSWORD_LEN) || random_get_bytes((u8 *) &val, sizeof(val))) { wpabuf_free(pw); return NULL; } if (wps_nfc_gen_dh(pubkey, privkey) < 0) { wpabuf_free(pw); return NULL; } *id = 0x10 + val % 0xfff0; wpabuf_free(*dev_pw); *dev_pw = pw; return wps_nfc_token_build(ndef, *id, *pubkey, *dev_pw); }
int eap_eke_prot(struct eap_eke_session *sess, const u8 *data, size_t data_len, u8 *prot, size_t *prot_len) { size_t block_size, icv_len, pad; u8 *pos, *iv, *e; if (sess->encr == EAP_EKE_ENCR_AES128_CBC) block_size = AES_BLOCK_SIZE; else return -1; if (sess->mac == EAP_EKE_PRF_HMAC_SHA1) icv_len = SHA1_MAC_LEN; else if (sess->mac == EAP_EKE_PRF_HMAC_SHA2_256) icv_len = SHA256_MAC_LEN; else return -1; pad = data_len % block_size; if (pad) pad = block_size - pad; if (*prot_len < block_size + data_len + pad + icv_len) { wpa_printf(MSG_INFO, "EAP-EKE: Not enough room for Prot() data"); return -1; } pos = prot; if (random_get_bytes(pos, block_size)) return -1; iv = pos; wpa_hexdump(MSG_DEBUG, "EAP-EKE: IV for Prot()", iv, block_size); pos += block_size; e = pos; os_memcpy(pos, data, data_len); pos += data_len; if (pad) { if (random_get_bytes(pos, pad)) return -1; pos += pad; } if (aes_128_cbc_encrypt(sess->ke, iv, e, data_len + pad) < 0 || eap_eke_mac(sess->mac, sess->ki, e, data_len + pad, pos) < 0) return -1; pos += icv_len; *prot_len = pos - prot; return 0; }
static struct wpabuf * ikev2_build_sa_auth(struct ikev2_initiator_data *data) { struct wpabuf *msg, *plain; const u8 *secret; size_t secret_len; secret = data->get_shared_secret(data->cb_ctx, data->IDr, data->IDr_len, &secret_len); if (secret == NULL) { wpa_printf(MSG_INFO, "IKEV2: Could not get shared secret - " "use fake value"); /* RFC 5106, Sect. 7: * Use a random key to fake AUTH generation in order to prevent * probing of user identities. */ data->unknown_user = 1; os_free(data->shared_secret); data->shared_secret = os_malloc(16); if (data->shared_secret == NULL) return NULL; data->shared_secret_len = 16; if (random_get_bytes(data->shared_secret, 16)) return NULL; } else { os_free(data->shared_secret); data->shared_secret = os_malloc(secret_len); if (data->shared_secret == NULL) return NULL; os_memcpy(data->shared_secret, secret, secret_len); data->shared_secret_len = secret_len; } /* build IKE_SA_AUTH: HDR, SK {IDi, [CERT,] [CERTREQ,] AUTH} */ msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1000); if (msg == NULL) return NULL; ikev2_build_hdr(data, msg, IKE_SA_AUTH, IKEV2_PAYLOAD_ENCRYPTED, 1); plain = wpabuf_alloc(data->IDr_len + 1000); if (plain == NULL) { wpabuf_free(msg); return NULL; } if (ikev2_build_idi(data, plain, IKEV2_PAYLOAD_AUTHENTICATION) || ikev2_build_auth(data, plain, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) || ikev2_build_encrypted(data->proposal.encr, data->proposal.integ, &data->keys, 1, msg, plain, IKEV2_PAYLOAD_IDi)) { wpabuf_free(plain); wpabuf_free(msg); return NULL; } wpabuf_free(plain); wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_AUTH)", msg); return msg; }
static struct wpabuf * wps_build_m1(struct wps_data *wps) { struct wpabuf *msg; u16 config_methods; if (random_get_bytes(wps->nonce_e, WPS_NONCE_LEN) < 0) return NULL; wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce", wps->nonce_e, WPS_NONCE_LEN); wpa_printf(MSG_DEBUG, "WPS: Building Message M1"); msg = wpabuf_alloc(1000); if (msg == NULL) return NULL; config_methods = wps->wps->config_methods; if (wps->wps->ap && !wps->pbc_in_m1 && (wps->dev_password_len != 0 || (config_methods & WPS_CONFIG_DISPLAY))) { /* * These are the methods that the AP supports as an Enrollee * for adding external Registrars, so remove PushButton. * * As a workaround for Windows 7 mechanism for probing WPS * capabilities from M1, leave PushButton option if no PIN * method is available or if WPS configuration enables PBC * workaround. */ config_methods &= ~WPS_CONFIG_PUSHBUTTON; config_methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON | WPS_CONFIG_PHY_PUSHBUTTON); } if (wps_build_version(msg) || wps_build_msg_type(msg, WPS_M1) || wps_build_uuid_e(msg, wps->uuid_e) || wps_build_mac_addr(msg, wps->mac_addr_e) || wps_build_enrollee_nonce(wps, msg) || wps_build_public_key(wps, msg) || wps_build_auth_type_flags(wps, msg) || wps_build_encr_type_flags(wps, msg) || wps_build_conn_type_flags(wps, msg) || wps_build_config_methods(msg, config_methods) || wps_build_wps_state(wps, msg) || wps_build_device_attrs(&wps->wps->dev, msg) || wps_build_rf_bands(&wps->wps->dev, msg, wps->wps->rf_band_cb(wps->wps->cb_ctx)) || wps_build_assoc_state(wps, msg) || wps_build_dev_password_id(msg, wps->dev_pw_id) || wps_build_config_error(msg, WPS_CFG_NO_ERROR) || wps_build_os_version(&wps->wps->dev, msg) || wps_build_wfa_ext(msg, 0, NULL, 0) || wps_build_vendor_ext_m1(&wps->wps->dev, msg)) { wpabuf_free(msg); return NULL; } wps->state = RECV_M2; return msg; }
int eap_eke_dhcomp(struct eap_eke_session *sess, const u8 *key, const u8 *dhpub, u8 *ret_dhcomp) { u8 pub[EAP_EKE_MAX_DH_LEN]; int dh_len; u8 iv[AES_BLOCK_SIZE]; dh_len = eap_eke_dh_len(sess->dhgroup); if (dh_len < 0) return -1; /* * DHComponent = Encr(key, y) * * All defined DH groups use primes that have length devisible by 16, so * no need to do extra padding for y (= pub). */ if (sess->encr != EAP_EKE_ENCR_AES128_CBC) return -1; if (random_get_bytes(iv, AES_BLOCK_SIZE)) return -1; wpa_hexdump(MSG_DEBUG, "EAP-EKE: IV for Encr(key, y)", iv, AES_BLOCK_SIZE); os_memcpy(pub, dhpub, dh_len); if (aes_128_cbc_encrypt(key, iv, pub, dh_len) < 0) return -1; os_memcpy(ret_dhcomp, iv, AES_BLOCK_SIZE); os_memcpy(ret_dhcomp + AES_BLOCK_SIZE, pub, dh_len); wpa_hexdump(MSG_DEBUG, "EAP-EKE: DHComponent = Encr(key, y)", ret_dhcomp, AES_BLOCK_SIZE + dh_len); return 0; }
static struct wpabuf *eap_md5_buildReq(struct eap_sm *sm, void *priv, u8 id) { struct eap_md5_data *data = priv; struct wpabuf *req; if (random_get_bytes(data->challenge, CHALLENGE_LEN)) { wpa_printf(MSG_ERROR, "EAP-MD5: Failed to get random data"); data->state = FAILURE; return NULL; } req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, 1 + CHALLENGE_LEN, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-MD5: Failed to allocate memory for " "request"); data->state = FAILURE; return NULL; } wpabuf_put_u8(req, CHALLENGE_LEN); wpabuf_put_data(req, data->challenge, CHALLENGE_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge", data->challenge, CHALLENGE_LEN); data->state = CONTINUE; return req; }
static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg) { if ((wps->wps->ap_auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) && wps->wps->network_key_len == 0) { char hex[65]; u8 psk[32]; /* Generate a random per-device PSK */ if (random_get_bytes(psk, sizeof(psk)) < 0) return -1; wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK", psk, sizeof(psk)); wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%u)", (unsigned int) wps->new_psk_len * 2); wpa_snprintf_hex(hex, sizeof(hex), psk, sizeof(psk)); wpabuf_put_be16(msg, ATTR_NETWORK_KEY); wpabuf_put_be16(msg, sizeof(psk) * 2); wpabuf_put_data(msg, hex, sizeof(psk) * 2); if (wps->wps->registrar) { wps_cb_new_psk(wps->wps->registrar, wps->peer_dev.mac_addr, wps->p2p_dev_addr, psk, sizeof(psk)); } return 0; } wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%u)", (unsigned int) wps->wps->network_key_len); wpabuf_put_be16(msg, ATTR_NETWORK_KEY); wpabuf_put_be16(msg, wps->wps->network_key_len); wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len); return 0; }
int wps_build_oob_dev_password(struct wpabuf *msg, struct wps_context *wps) { u8 dev_password_bin[WPS_OOB_DEVICE_PASSWORD_LEN]; wpa_printf(MSG_DEBUG, "WPS: * OOB Device Password"); if (os_get_random((u8 *) &wps->oob_dev_pw_id, sizeof(u16)) < 0) { wpa_printf(MSG_ERROR, "WPS: device password id " "generation error"); return -1; } wps->oob_dev_pw_id |= 0x0010; if (random_get_bytes(dev_password_bin, WPS_OOB_DEVICE_PASSWORD_LEN) < 0) { wpa_printf(MSG_ERROR, "WPS: OOB device password " "generation error"); return -1; } wpa_snprintf_hex_uppercase( wpabuf_put(wps->oob_conf.dev_password, wpabuf_size(wps->oob_conf.dev_password)), wpabuf_size(wps->oob_conf.dev_password), dev_password_bin, WPS_OOB_DEVICE_PASSWORD_LEN); return wps_build_oob_dev_pw(msg, wps->oob_dev_pw_id, wps->dh_pubkey, dev_password_bin, WPS_OOB_DEVICE_PASSWORD_LEN); }
static int create_sem(int nsems, int permission) { key_t key; random_get_bytes(&key, sizeof(key)); return semget(key, nsems, permission | IPC_CREAT); }
int __uuid_generate_time(uuid_t out, int *num) { static unsigned char node_id[6]; static int has_init = 0; struct uuid uu; uint32_t clock_mid; int ret; if (!has_init) { if (get_node_id(node_id) <= 0) { random_get_bytes(node_id, 6); /* * Set multicast bit, to prevent conflicts * with IEEE 802 addresses obtained from * network cards */ node_id[0] |= 0x01; } has_init = 1; } ret = get_clock(&clock_mid, &uu.time_low, &uu.clock_seq, num); uu.clock_seq |= 0x8000; uu.time_mid = (uint16_t) clock_mid; uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000; memcpy(uu.node, node_id, 6); uuid_pack(&uu, out); return ret; }
int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg, struct wpabuf *plain) { size_t pad_len; const size_t block_size = 16; u8 *iv, *data; wpa_printf(MSG_DEBUG, "WPS: * Encrypted Settings"); /* PKCS#5 v2.0 pad */ pad_len = block_size - wpabuf_len(plain) % block_size; os_memset(wpabuf_put(plain, pad_len), pad_len, pad_len); wpabuf_put_be16(msg, ATTR_ENCR_SETTINGS); wpabuf_put_be16(msg, block_size + wpabuf_len(plain)); iv = wpabuf_put(msg, block_size); if (random_get_bytes(iv, block_size) < 0) return -1; data = wpabuf_put(msg, 0); wpabuf_put_buf(msg, plain); if (aes_128_cbc_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain))) return -1; return 0; }
static struct wpabuf * eap_psk_build_1(struct eap_sm *sm, struct eap_psk_data *data, u8 id) { struct wpabuf *req; struct eap_psk_hdr_1 *psk; wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-1 (sending)"); if (random_get_bytes(data->rand_s, EAP_PSK_RAND_LEN)) { wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data"); data->state = FAILURE; return NULL; } wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_S (server rand)", data->rand_s, EAP_PSK_RAND_LEN); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK, sizeof(*psk) + data->id_s_len, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory " "request"); data->state = FAILURE; return NULL; } psk = wpabuf_put(req, sizeof(*psk)); psk->flags = EAP_PSK_FLAGS_SET_T(0); /* T=0 */ os_memcpy(psk->rand_s, data->rand_s, EAP_PSK_RAND_LEN); wpabuf_put_data(req, data->id_s, data->id_s_len); return req; }
static struct wpabuf * eap_sim_build_reauth(struct eap_sm *sm, struct eap_sim_data *data, u8 id) { struct eap_sim_msg *msg; wpa_printf(MSG_DEBUG, "EAP-SIM: Generating Re-authentication"); if (random_get_bytes(data->nonce_s, EAP_SIM_NONCE_S_LEN)) return NULL; wpa_hexdump_key(MSG_MSGDUMP, "EAP-SIM: NONCE_S", data->nonce_s, EAP_SIM_NONCE_S_LEN); eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk, data->emsk); eap_sim_derive_keys_reauth(data->counter, sm->identity, sm->identity_len, data->nonce_s, data->mk, data->msk, data->emsk); msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_SIM, EAP_SIM_SUBTYPE_REAUTHENTICATION); if (eap_sim_build_encr(sm, data, msg, data->counter, data->nonce_s)) { eap_sim_msg_free(msg); return NULL; } if (sm->eap_sim_aka_result_ind) { wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); } wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); return eap_sim_msg_finish(msg, data->k_aut, NULL, 0); }
/** * wpa_ft_start_over_ds - Generate over-the-DS auth request * @sm: Pointer to WPA state machine data from wpa_sm_init() * @target_ap: Target AP Address * @mdie: Mobility Domain IE from the target AP * Returns: 0 on success, -1 on failure */ int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap, const u8 *mdie) { u8 *ft_ies; size_t ft_ies_len; wpa_printf(MSG_DEBUG, "FT: Request over-the-DS with " MACSTR, MAC2STR(target_ap)); /* Generate a new SNonce */ if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) { wpa_printf(MSG_INFO, "FT: Failed to generate a new SNonce"); return -1; } ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, NULL, sm->pmk_r0_name, NULL, 0, target_ap, NULL, 0, mdie); if (ft_ies) { sm->over_the_ds_in_progress = 1; os_memcpy(sm->target_ap, target_ap, ETH_ALEN); wpa_sm_send_ft_action(sm, 1, target_ap, ft_ies, ft_ies_len); os_free(ft_ies); } return 0; }
static int create_shm(size_t size, int permission) { key_t key; random_get_bytes(&key, sizeof(key)); return shmget(key, size, permission | IPC_CREAT); }
static int create_msg(int permission) { key_t key; random_get_bytes(&key, sizeof(key)); return msgget(key, permission | IPC_CREAT); }
void mesh_rsn_init_ampe_sta(struct wpa_supplicant *wpa_s, struct sta_info *sta) { if (random_get_bytes(sta->my_nonce, 32) < 0) { wpa_printf(MSG_INFO, "mesh: Failed to derive random nonce"); /* TODO: How to handle this more cleanly? */ } os_memset(sta->peer_nonce, 0, 32); mesh_rsn_derive_aek(wpa_s->mesh_rsn, sta); }
static struct wpabuf * eap_eke_build_confirm(struct eap_sm *sm, struct eap_eke_data *data, u8 id) { struct wpabuf *msg; size_t plen, prot_len; u8 nonces[2 * EAP_EKE_MAX_NONCE_LEN]; u8 *auth; wpa_printf(MSG_DEBUG, "EAP-EKE: Request/Confirm"); plen = data->sess.pnonce_ps_len + data->sess.prf_len; msg = eap_eke_build_msg(data, id, plen, EAP_EKE_CONFIRM); if (msg == NULL) { eap_eke_fail(data, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); return eap_eke_build_failure(data, id); } if (random_get_bytes(data->nonce_s, data->sess.nonce_len)) { wpabuf_free(msg); eap_eke_fail(data, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); return eap_eke_build_failure(data, id); } wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: Nonce_S", data->nonce_s, data->sess.nonce_len); os_memcpy(nonces, data->nonce_p, data->sess.nonce_len); os_memcpy(nonces + data->sess.nonce_len, data->nonce_s, data->sess.nonce_len); prot_len = wpabuf_tailroom(msg); if (eap_eke_prot(&data->sess, nonces, 2 * data->sess.nonce_len, wpabuf_put(msg, 0), &prot_len) < 0) { wpabuf_free(msg); eap_eke_fail(data, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); return eap_eke_build_failure(data, id); } wpabuf_put(msg, prot_len); if (eap_eke_derive_ka(&data->sess, sm->server_id, sm->server_id_len, data->peerid, data->peerid_len, data->nonce_p, data->nonce_s) < 0) { wpabuf_free(msg); eap_eke_fail(data, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); return eap_eke_build_failure(data, id); } auth = wpabuf_put(msg, data->sess.prf_len); if (eap_eke_auth(&data->sess, "EAP-EKE server", data->msgs, auth) < 0) { wpabuf_free(msg); eap_eke_fail(data, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); return eap_eke_build_failure(data, id); } wpa_hexdump(MSG_DEBUG, "EAP-EKE: Auth_S", auth, data->sess.prf_len); return msg; }
static void wpa_supplicant_send_stk_1_of_4(struct wpa_sm *sm, struct wpa_peerkey *peerkey) { size_t mlen; struct wpa_eapol_key *msg; u8 *mbuf; size_t kde_len; u16 key_info, ver; kde_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN; mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, sizeof(*msg) + kde_len, &mlen, (void *) &msg); if (mbuf == NULL) return; msg->type = EAPOL_KEY_TYPE_RSN; if (peerkey->cipher == WPA_CIPHER_CCMP) ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; else ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK; WPA_PUT_BE16(msg->key_info, key_info); if (peerkey->cipher == WPA_CIPHER_CCMP) WPA_PUT_BE16(msg->key_length, 16); else WPA_PUT_BE16(msg->key_length, 32); os_memcpy(msg->replay_counter, peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN); inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN); WPA_PUT_BE16(msg->key_data_length, kde_len); wpa_add_kde((u8 *) (msg + 1), RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN); if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) { wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "RSN: Failed to get random data for INonce (STK)"); os_free(mbuf); return; } wpa_hexdump(MSG_DEBUG, "RSN: INonce for STK 4-Way Handshake", peerkey->inonce, WPA_NONCE_LEN); os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN); wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 1/4 to " MACSTR, MAC2STR(peerkey->addr)); wpa_eapol_key_send(sm, NULL, ver, peerkey->addr, ETH_P_EAPOL, mbuf, mlen, NULL); }
int main(int argc, char *argv[]) { unsigned int v, i; /* generate and print 10 random numbers */ for (i = 0; i < 10; i++) { random_get_bytes(&v, sizeof(v)); printf("%d\n", v); } return EXIT_SUCCESS; }
zcrypt_key_t * zcrypt_key_gen(int crypt) { caddr_t genkeybuf; size_t genkeylen; zcrypt_key_t *key; /* * crypt tells us which algorithm is being used and * thus the type and size of key we need generated. * * For now we are using random_get_bytes() to generate the * raw key. Ideally use crypto_key_generate() however that needs * a crypto_provider_t so only works with hardware providers. * * This may need to change for FIPS 140-2 at levels > 2, * the key really should be generated on the hardware crypto * device as a sensitive key object and extracted in wrapped form. */ genkeylen = zio_crypt_table[crypt].ci_keylen; genkeybuf = kmem_alloc(genkeylen, KM_PUSHPAGE); // Sleep VERIFY(random_get_bytes((uchar_t *)genkeybuf, genkeylen) == 0); key = zcrypt_key_allocate(); key->zk_key.ck_format = CRYPTO_KEY_RAW; key->zk_key.ck_data = genkeybuf; key->zk_key.ck_length = (genkeylen * 8); key->zk_crypt = crypt; /* Generate an HMAC-SHA256 key for dedup IV generation as well */ genkeylen = 32; genkeybuf = kmem_alloc(genkeylen, KM_PUSHPAGE); // Sleep VERIFY(random_get_bytes((uchar_t *)genkeybuf, genkeylen) == CRYPTO_SUCCESS); key->zk_mackey.ck_format = CRYPTO_KEY_RAW; key->zk_mackey.ck_data = genkeybuf; key->zk_mackey.ck_length = (genkeylen * 8); return (key); }
/** * wps_generate_pin - Generate a random PIN * Returns: Eight digit PIN (i.e., including the checksum digit) */ int wps_generate_pin(unsigned int *pin) { unsigned int val; /* Generate seven random digits for the PIN */ if (random_get_bytes((unsigned char *) &val, sizeof(val)) < 0) return -1; val %= 10000000; /* Append checksum digit */ *pin = val * 10 + wps_pin_checksum(val); return 0; }
static void * eap_sim_init(struct eap_sm *sm) { struct eap_sim_data *data; struct eap_peer_config *config = eap_get_config(sm); data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; if (random_get_bytes(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) { wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data " "for NONCE_MT"); os_free(data); return NULL; } data->min_num_chal = 2; if (config && config->phase1) { char *pos = os_strstr(config->phase1, "sim_min_num_chal="); if (pos) { data->min_num_chal = atoi(pos + 17); if (data->min_num_chal < 2 || data->min_num_chal > 3) { wpa_printf(MSG_WARNING, "EAP-SIM: Invalid " "sim_min_num_chal configuration " "(%lu, expected 2 or 3)", (unsigned long) data->min_num_chal); os_free(data); return NULL; } wpa_printf(MSG_DEBUG, "EAP-SIM: Set minimum number of " "challenges to %lu", (unsigned long) data->min_num_chal); } data->result_ind = os_strstr(config->phase1, "result_ind=1") != NULL; } if (config && config->anonymous_identity) { data->pseudonym = os_malloc(config->anonymous_identity_len); if (data->pseudonym) { os_memcpy(data->pseudonym, config->anonymous_identity, config->anonymous_identity_len); data->pseudonym_len = config->anonymous_identity_len; } } eap_sim_state(data, CONTINUE); return data; }
static void * eap_sim_init_for_reauth(struct eap_sm *sm, void *priv) { struct eap_sim_data *data = priv; if (random_get_bytes(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) { wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data " "for NONCE_MT"); os_free(data); return NULL; } data->num_id_req = 0; data->num_notification = 0; eap_sim_state(data, CONTINUE); return priv; }
/** * 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 (random_get_bytes((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); }
struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey, struct wpabuf **privkey, struct wpabuf **dev_pw) { struct wpabuf *priv = NULL, *pub = NULL, *pw; void *dh_ctx; u16 val; pw = wpabuf_alloc(WPS_OOB_DEVICE_PASSWORD_LEN); if (pw == NULL) return NULL; if (random_get_bytes(wpabuf_put(pw, WPS_OOB_DEVICE_PASSWORD_LEN), WPS_OOB_DEVICE_PASSWORD_LEN) || random_get_bytes((u8 *) &val, sizeof(val))) { wpabuf_free(pw); return NULL; } dh_ctx = dh5_init(&priv, &pub); if (dh_ctx == NULL) { wpabuf_free(pw); return NULL; } dh5_free(dh_ctx); *id = 0x10 + val % 0xfff0; wpabuf_free(*pubkey); *pubkey = pub; wpabuf_free(*privkey); *privkey = priv; wpabuf_free(*dev_pw); *dev_pw = pw; return wps_nfc_token_build(ndef, *id, *pubkey, *dev_pw); }
static struct wpabuf * eap_leap_process_success(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, const struct wpabuf *reqData) { struct eap_leap_data *data = priv; struct wpabuf *resp; u8 *pos; const u8 *identity; size_t identity_len; wpa_printf(MSG_DEBUG, "EAP-LEAP: Processing EAP-Success"); identity = eap_get_config_identity(sm, &identity_len); if (identity == NULL) return NULL; if (data->state != LEAP_WAIT_SUCCESS) { wpa_printf(MSG_INFO, "EAP-LEAP: EAP-Success received in " "unexpected state (%d) - ignored", data->state); ret->ignore = TRUE; return NULL; } resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_LEAP, 3 + LEAP_CHALLENGE_LEN + identity_len, EAP_CODE_REQUEST, eap_get_id(reqData)); if (resp == NULL) return NULL; wpabuf_put_u8(resp, LEAP_VERSION); wpabuf_put_u8(resp, 0); /* unused */ wpabuf_put_u8(resp, LEAP_CHALLENGE_LEN); pos = wpabuf_put(resp, LEAP_CHALLENGE_LEN); if (random_get_bytes(pos, LEAP_CHALLENGE_LEN)) { wpa_printf(MSG_WARNING, "EAP-LEAP: Failed to read random data " "for challenge"); wpabuf_free(resp); ret->ignore = TRUE; return NULL; } os_memcpy(data->ap_challenge, pos, LEAP_CHALLENGE_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-LEAP: Challenge to AP/AS", pos, LEAP_CHALLENGE_LEN); wpabuf_put_data(resp, identity, identity_len); data->state = LEAP_WAIT_RESPONSE; return resp; }
static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr) { struct wpa_auth_config conf; struct wpa_auth_callbacks cb; u8 seq[6] = {}; wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine"); os_memset(&conf, 0, sizeof(conf)); conf.wpa = 2; conf.wpa_key_mgmt = WPA_KEY_MGMT_SAE; conf.wpa_pairwise = WPA_CIPHER_CCMP; conf.rsn_pairwise = WPA_CIPHER_CCMP; conf.wpa_group = WPA_CIPHER_CCMP; conf.eapol_version = 0; conf.wpa_group_rekey = -1; os_memset(&cb, 0, sizeof(cb)); cb.ctx = rsn; cb.logger = auth_logger; cb.get_psk = auth_get_psk; cb.set_key = auth_set_key; cb.start_ampe = auth_start_ampe; rsn->auth = wpa_init(addr, &conf, &cb); if (rsn->auth == NULL) { wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed"); return -1; } /* TODO: support rekeying */ if (random_get_bytes(rsn->mgtk, 16) < 0) { wpa_deinit(rsn->auth); return -1; } /* group mgmt */ wpa_drv_set_key(rsn->wpa_s, WPA_ALG_IGTK, NULL, 4, 1, seq, sizeof(seq), rsn->mgtk, sizeof(rsn->mgtk)); /* group privacy / data frames */ wpa_drv_set_key(rsn->wpa_s, WPA_ALG_CCMP, NULL, 1, 1, seq, sizeof(seq), rsn->mgtk, sizeof(rsn->mgtk)); return 0; }
static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg) { u8 *hash; const u8 *addr[4]; size_t len[4]; if (random_get_bytes(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0) return -1; wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "WPS: E-S2", wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN); if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) { wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for " "E-Hash derivation"); return -1; } wpa_printf(MSG_DEBUG, "WPS: * E-Hash1"); wpabuf_put_be16(msg, ATTR_E_HASH1); wpabuf_put_be16(msg, SHA256_MAC_LEN); hash = wpabuf_put(msg, SHA256_MAC_LEN); /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */ addr[0] = wps->snonce; len[0] = WPS_SECRET_NONCE_LEN; addr[1] = wps->psk1; len[1] = WPS_PSK_LEN; addr[2] = wpabuf_head(wps->dh_pubkey_e); len[2] = wpabuf_len(wps->dh_pubkey_e); addr[3] = wpabuf_head(wps->dh_pubkey_r); len[3] = wpabuf_len(wps->dh_pubkey_r); hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN); wpa_printf(MSG_DEBUG, "WPS: * E-Hash2"); wpabuf_put_be16(msg, ATTR_E_HASH2); wpabuf_put_be16(msg, SHA256_MAC_LEN); hash = wpabuf_put(msg, SHA256_MAC_LEN); /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */ addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN; addr[1] = wps->psk2; hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN); return 0; }
static int wpa_ft_pull_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *s1kh_id, const u8 *r0kh_id, size_t r0kh_id_len, const u8 *pmk_r0_name) { struct ft_remote_r0kh *r0kh; struct ft_r0kh_r1kh_pull_frame frame, f; r0kh = wpa_auth->conf.r0kh_list; while (r0kh) { if (r0kh->id_len == r0kh_id_len && os_memcmp(r0kh->id, r0kh_id, r0kh_id_len) == 0) break; r0kh = r0kh->next; } if (r0kh == NULL) return -1; wpa_printf(MSG_DEBUG, "FT: Send PMK-R1 pull request to remote R0KH " "address " MACSTR, MAC2STR(r0kh->addr)); os_memset(&frame, 0, sizeof(frame)); frame.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB; frame.packet_type = FT_PACKET_R0KH_R1KH_PULL; frame.data_length = host_to_le16(FT_R0KH_R1KH_PULL_DATA_LEN); os_memcpy(frame.ap_address, wpa_auth->addr, ETH_ALEN); /* aes_wrap() does not support inplace encryption, so use a temporary * buffer for the data. */ if (random_get_bytes(f.nonce, sizeof(f.nonce))) { wpa_printf(MSG_DEBUG, "FT: Failed to get random data for " "nonce"); return -1; } os_memcpy(f.pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN); os_memcpy(f.r1kh_id, wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN); os_memcpy(f.s1kh_id, s1kh_id, ETH_ALEN); os_memset(f.pad, 0, sizeof(f.pad)); if (aes_wrap(r0kh->key, (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8, f.nonce, frame.nonce) < 0) return -1; wpa_ft_rrb_send(wpa_auth, r0kh->addr, (u8 *) &frame, sizeof(frame)); return 0; }