static void thread_cancelled(struct sml_control *control) { /* This function is called with a non-NULL control if an SML# thread * is cancelled abnormally, for example, due to pthread_cancel or * pthread_exit. Since SML# code never cancel any thread, a thread * may be cancelled only in C code (pthread provides asynchronous * cancellation, but no clever programmer use it ;p). Therefore, * the current thread does not occupy its sml_control at the * beginning of this function. * Note that tlv_get(current_control) is NULL due to thread exit. */ if (!control) return; /* recover tlv_get(control) temporarily for thread local heap * deallocation */ tlv_set(current_control, control); /* occupy the control to deallocate the thread local heap safely */ control_enter(control); /* control_destroy resets tlv_get(control) to NULL. * This avoids iteration of destructor calls. */ control_destroy(control); }
static void control_destroy(struct sml_control *control) { assert(tlv_get(current_control) == control); #ifndef WITHOUT_MULTITHREAD /* To release the thread local heap exclusively, it must be * occupied by the current thread. */ assert(IS_ACTIVE(load_relaxed(&control->state))); #endif /* !WITHOUT_MULTITHREAD */ if (control->thread_local_heap) { sml_heap_mutator_destroy(control->thread_local_heap); control->thread_local_heap = NULL; } /* Pointers in the stack is safely ignored since the thread has * been terminated. */ control->frame_stack = NULL; control_leave(control); control_unregister(control); tlv_set(current_control, NULL); mutex_destroy(&control->inactive_wait_lock); cond_destroy(&control->inactive_wait_cond); free(control); }
static struct sml_control * control_start(struct frame_stack_range *range) { struct sml_control *control; assert(tlv_get_or_init(current_control) == NULL); control = xmalloc(sizeof(struct sml_control)); #ifndef WITHOUT_MULTITHREAD atomic_init(&control->state, ACTIVE(ASYNC)); mutex_init(&control->inactive_wait_lock); cond_init(&control->inactive_wait_cond); #endif /* !WITHOUT_MULTITHREAD */ control->frame_stack = range; range->next = NULL; control->thread_local_heap = NULL; control->exn_object = NULL; tlv_set(current_control, control); control_register(control); /* thread local heap is allocated after the control is set up. */ control->thread_local_heap = sml_heap_mutator_init(); return control; }
static uint32 wpsap_createM8Sta(WPSAPI_T *g_mc) { char *cp_data; uint16 data16; CTlvCredential *p_tlvCred; uint32 nwKeyLen = 0; char *p_nwKey; uint8 *p_macAddr; uint8 wep_exist = 0; uint8 data8; #ifdef WFA_WPS_20_TESTBED #define DUMMY_CRED_NUM 1 int dummy_cred_remaining = DUMMY_CRED_NUM; bool dummy1_cred_wep[DUMMY_CRED_NUM] = {false, false}; #endif /* WFA_WPS_20_TESTBED */ DevInfo *info = g_mc->dev_info; EsM8Sta *es; /* * Create the Encrypted Settings TLV for STA config * We will also need to delete this blob eventually, as the * SM will not delete it. */ if (info->mp_tlvEsM8Sta) { TUTRACE((TUTRACE_ERR, "wpsap_createM8Sta: info->mp_tlvEsM8Sta exist!")); reg_msg_es_del(info->mp_tlvEsM8Sta, 0); } info->mp_tlvEsM8Sta = (EsM8Sta *)reg_msg_es_new(ES_TYPE_M8STA); if (!info->mp_tlvEsM8Sta) return WPS_ERR_SYSTEM; es = info->mp_tlvEsM8Sta; #ifdef WFA_WPS_20_TESTBED MSS: #endif /* credential */ p_tlvCred = (CTlvCredential *)malloc(sizeof(CTlvCredential)); if (!p_tlvCred) return WPS_ERR_SYSTEM; memset(p_tlvCred, 0, sizeof(CTlvCredential)); /* Fill in credential items */ /* nwIndex */ tlv_set(&p_tlvCred->nwIndex, WPS_ID_NW_INDEX, (void *)1, 0); /* ssid */ cp_data = info->ssid; data16 = strlen(cp_data); #ifdef WFA_WPS_20_TESTBED /* For internal testing purpose */ if (info->b_zpadding) data16 ++; if (dummy_cred_remaining && info->b_mca) { cp_data = info->dummy_ssid; data16 = strlen(cp_data); if (info->b_zpadding) data16 ++; } #endif /* WFA_WPS_20_TESTBED */ tlv_set(&p_tlvCred->ssid, WPS_ID_SSID, cp_data, data16); TUTRACE((TUTRACE_ERR, "MC_CreateTlvEsM8Sta: " "do REAL sec config here...\n")); if (info->auth) data16 = WPS_AUTHTYPE_SHARED; else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_PSK) data16 = WPS_AUTHTYPE_WPAPSK; else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_PSK2) data16 = WPS_AUTHTYPE_WPA2PSK; else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_BOTH) data16 = WPS_AUTHTYPE_WPAPSK | WPS_AUTHTYPE_WPA2PSK; else data16 = WPS_AUTHTYPE_OPEN; #ifdef WFA_WPS_20_TESTBED if (dummy_cred_remaining && info->b_mca) { if (dummy1_cred_wep[dummy_cred_remaining-1] == true) { /* force dummy cred to wep mode */ data16 = WPS_AUTHTYPE_OPEN; } } #endif tlv_set(&p_tlvCred->authType, WPS_ID_AUTH_TYPE, UINT2PTR(data16), 0); TUTRACE((TUTRACE_ERR, "MC_CreateTlvEsM8Sta: " "Auth type = 0x%x...\n", data16)); /* encrType */ if (info->auth) data16 = WPS_ENCRTYPE_WEP; else if (data16 == WPS_AUTHTYPE_OPEN) { if (info->wep) data16 = WPS_ENCRTYPE_WEP; else data16 = WPS_ENCRTYPE_NONE; } else data16 = info->crypto; #ifdef WFA_WPS_20_TESTBED if (dummy_cred_remaining && info->b_mca) { if (dummy1_cred_wep[dummy_cred_remaining-1] == true) { /* force dummy cred to wep mode */ data16 = WPS_ENCRTYPE_WEP; } } #endif tlv_set(&p_tlvCred->encrType, WPS_ID_ENCR_TYPE, UINT2PTR(data16), 0); TUTRACE((TUTRACE_ERR, "MC_CreateTlvEsM8Sta: " "encr type = 0x%x...\n", data16)); if (data16 == WPS_ENCRTYPE_WEP) wep_exist = 1; /* nwKeyIndex */ /* * WSC 2.0, "Network Key Index" deprecated - only included by WSC 1.0 devices. * Ignored by WSC 2.0 or newer devices. */ data8 = info->version2; if (data8 < WPS_VERSION2) { tlv_set(&p_tlvCred->nwKeyIndex, WPS_ID_NW_KEY_INDEX, (void *)1, 0); } /* nwKey */ p_nwKey = info->nwKey; nwKeyLen = strlen(p_nwKey); #ifdef WFA_WPS_20_TESTBED /* For internal testing purpose */ if (info->b_zpadding && p_nwKey && nwKeyLen < SIZE_64_BYTES && strlen(p_nwKey) == nwKeyLen) nwKeyLen ++; #endif /* WFA_WPS_20_TESTBED */ tlv_set(&p_tlvCred->nwKey, WPS_ID_NW_KEY, p_nwKey, nwKeyLen); /* macAddr, Enrollee Station's MAC */ p_macAddr = info->peerMacAddr; data16 = SIZE_MAC_ADDR; tlv_set(&p_tlvCred->macAddr, WPS_ID_MAC_ADDR, (uint8 *)p_macAddr, data16); /* WepKeyIdx */ if (wep_exist) tlv_set(&p_tlvCred->WEPKeyIndex, WPS_ID_WEP_TRANSMIT_KEY, UINT2PTR(info->wepKeyIdx), 0); /* WSC 2.0, WFA "Network Key Shareable" subelement */ data8 = info->version2; if (data8 >= WPS_VERSION2 && info->b_nwKeyShareable) { data16 = 1; subtlv_set(&p_tlvCred->nwKeyShareable, WPS_WFA_SUBID_NW_KEY_SHAREABLE, UINT2PTR(data16), 0); TUTRACE((TUTRACE_ERR, "wps_createM8Sta: Network Key Shareable is TRUE\n")); } if (!wps_sslist_add(&es->credential, p_tlvCred)) { tlv_credentialDelete(p_tlvCred, 0); return WPS_ERR_SYSTEM; } #ifdef WFA_WPS_20_TESTBED /* * Multiple Security Settings for testing purpose * First credential is using dummy SSID, the second one is good for station. */ if (dummy_cred_remaining && info->b_mca) { dummy_cred_remaining--; goto MSS; } #endif /* WFA_WPS_20_TESTBED */ return WPS_SUCCESS; }
static uint32 wpsap_createM7AP(WPSAPI_T *g_mc) { char *cp_data; uint16 data16; uint8 *p_macAddr; CTlvNwKey *p_tlvKey; char *cp_psk; DevInfo *info = g_mc->dev_info; EsM7Ap *es; /* * AP wants to be configured/managed * Let the Enrollee SM know, so that it can be initialized * * Create an Encrypted Settings TLV to be passed to the SM, * so that the SM can pass it to the Registrar in M7 * Also store this TLV locally, so we can delete it once the * registration completes. The SM will not delete it. */ if (info->mp_tlvEsM7Ap) { TUTRACE((TUTRACE_ERR, "wpsap_createM7AP: info->mp_tlvEsM7Ap exist!")); reg_msg_es_del(info->mp_tlvEsM7Ap, 0); } info->mp_tlvEsM7Ap = (EsM7Ap *)reg_msg_es_new(ES_TYPE_M7AP); if (!info->mp_tlvEsM7Ap) return WPS_ERR_SYSTEM; es = info->mp_tlvEsM7Ap; /* SSID */ cp_data = info->ssid; data16 = strlen(cp_data); tlv_set(&es->ssid, WPS_ID_SSID, cp_data, data16); /* MAC addr: should really get this from the NIC driver */ p_macAddr = info->macAddr; data16 = SIZE_MAC_ADDR; tlv_set(&es->macAddr, WPS_ID_MAC_ADDR, p_macAddr, data16); TUTRACE((TUTRACE_ERR, "MC_CreateTlvEsM7Ap: " "do REAL sec config here...\n")); if (info->auth) data16 = WPS_AUTHTYPE_SHARED; else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_PSK) data16 = WPS_AUTHTYPE_WPAPSK; else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_PSK2) data16 = WPS_AUTHTYPE_WPA2PSK; else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_BOTH) data16 = WPS_AUTHTYPE_WPAPSK | WPS_AUTHTYPE_WPA2PSK; else data16 = WPS_AUTHTYPE_OPEN; tlv_set(&es->authType, WPS_ID_AUTH_TYPE, UINT2PTR(data16), 0); TUTRACE((TUTRACE_ERR, "MC_CreateTlvEsM7Ap: " "Auth type = %x...\n", data16)); /* encrType */ if (info->auth) data16 = WPS_ENCRTYPE_WEP; else if (data16 == WPS_AUTHTYPE_OPEN) { if (info->wep) data16 = WPS_ENCRTYPE_WEP; else data16 = WPS_ENCRTYPE_NONE; } else data16 = info->crypto; tlv_set(&es->encrType, WPS_ID_ENCR_TYPE, UINT2PTR(data16), 0); TUTRACE((TUTRACE_ERR, "MC_CreateTlvEsM7Ap: " "encr type = %x...\n", data16)); if (data16 != WPS_ENCRTYPE_NONE) { char *dev_key = NULL; uint32 KeyLen; if (data16 == WPS_ENCRTYPE_WEP) tlv_set(&es->wepIdx, WPS_ID_WEP_TRANSMIT_KEY, UINT2PTR(info->wepKeyIdx), 0); dev_key = info->nwKey; KeyLen = strlen(dev_key); /* nwKey */ p_tlvKey = (CTlvNwKey *)tlv_new(WPS_ID_NW_KEY); if (!p_tlvKey) return WPS_ERR_SYSTEM; if (tlv_allocate(p_tlvKey, WPS_ID_NW_KEY, KeyLen) == -1) { tlv_delete(p_tlvKey, 0); return WPS_ERR_SYSTEM; } cp_psk = p_tlvKey->m_data; memset(cp_psk, 0, KeyLen); memcpy(cp_psk, dev_key, KeyLen); #ifdef BCMWPS_DEBUG_PRINT_KEY TUTRACE((TUTRACE_INFO, "InitiateRegistration_NW_KEY get from AP is key " "%p %s\n", p_tlvKey, cp_psk)); #endif } else { /* nwKey */ p_tlvKey = (CTlvNwKey *)tlv_new(WPS_ID_NW_KEY); if (!p_tlvKey) return WPS_ERR_SYSTEM; if (tlv_allocate(p_tlvKey, WPS_ID_NW_KEY, 0) == -1) { tlv_delete(p_tlvKey, 0); return WPS_ERR_SYSTEM; } } if (!wps_sslist_add(&es->nwKey, p_tlvKey)) { tlv_delete(p_tlvKey, 0); return WPS_ERR_SYSTEM; } return WPS_SUCCESS; }
uint32 nfc_utils_build_cfg(DevInfo *info, uint8 *buf, uint *buflen) { char *p_nwKey, *cp_data; uint8 *p_macAddr, wep_exist = 0, version = WPS_VERSION; uint16 data16; uint32 ret = WPS_SUCCESS, nwKeyLen = 0; BufferObj *bufObj = NULL, *vendorExt_bufObj = NULL; CTlvVendorExt vendorExt; CTlvCredential *p_tlvCred = NULL; TUTRACE((TUTRACE_NFC, "Build NFC Configuration\n")); if (info == NULL || buf == NULL || *buflen == 0) { TUTRACE((TUTRACE_NFC, "nfc_utils_build_cfg: Invalid arguments\n")); return WPS_ERR_SYSTEM; } if ((bufObj = buffobj_new()) == NULL) { TUTRACE((TUTRACE_NFC, "nfc_utils_build_cfg: Out of memory\n")); return WPS_ERR_OUTOFMEMORY; } /* Version */ tlv_serialize(WPS_ID_VERSION, bufObj, &version, WPS_ID_VERSION_S); /* Credential */ if ((p_tlvCred = (CTlvCredential *)malloc(sizeof(CTlvCredential))) == NULL) { TUTRACE((TUTRACE_NFC, "nfc_utils_build_cfg: Out of memory\n")); ret = WPS_ERR_OUTOFMEMORY; goto error; } memset(p_tlvCred, 0, sizeof(CTlvCredential)); /* Credential items */ /* nwIndex */ tlv_set(&p_tlvCred->nwIndex, WPS_ID_NW_INDEX, (void *)1, 0); /* ssid */ cp_data = info->ssid; data16 = strlen(cp_data); tlv_set(&p_tlvCred->ssid, WPS_ID_SSID, cp_data, data16); /* auth */ if (info->auth) data16 = WPS_AUTHTYPE_SHARED; else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_PSK) data16 = WPS_AUTHTYPE_WPAPSK; else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_PSK2) data16 = WPS_AUTHTYPE_WPA2PSK; else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_BOTH) data16 = WPS_AUTHTYPE_WPAPSK | WPS_AUTHTYPE_WPA2PSK; else data16 = WPS_AUTHTYPE_OPEN; tlv_set(&p_tlvCred->authType, WPS_ID_AUTH_TYPE, UINT2PTR(data16), 0); /* encrType */ if (info->auth) data16 = WPS_ENCRTYPE_WEP; else if (data16 == WPS_AUTHTYPE_OPEN) { if (info->wep) data16 = WPS_ENCRTYPE_WEP; else data16 = WPS_ENCRTYPE_NONE; } else data16 = info->crypto; tlv_set(&p_tlvCred->encrType, WPS_ID_ENCR_TYPE, UINT2PTR(data16), 0); if (data16 == WPS_ENCRTYPE_WEP) wep_exist = 1; /* nwKeyIndex * WSC 2.0, "Network Key Index" deprecated - only included by WSC 1.0 devices. * Ignored by WSC 2.0 or newer devices. */ if (info->version2 < WPS_VERSION2) { tlv_set(&p_tlvCred->nwKeyIndex, WPS_ID_NW_KEY_INDEX, (void *)1, 0); } /* nwKey */ p_nwKey = info->nwKey; nwKeyLen = strlen(info->nwKey); tlv_set(&p_tlvCred->nwKey, WPS_ID_NW_KEY, p_nwKey, nwKeyLen); /* enrollee's mac */ p_macAddr = info->peerMacAddr; data16 = SIZE_MAC_ADDR; tlv_set(&p_tlvCred->macAddr, WPS_ID_MAC_ADDR, p_macAddr, data16); /* WepKeyIdx */ if (wep_exist) tlv_set(&p_tlvCred->WEPKeyIndex, WPS_ID_WEP_TRANSMIT_KEY, UINT2PTR(info->wepKeyIdx), 0); /* WSC 2.0, WFA "Network Key Shareable" subelement */ if (info->version2 >= WPS_VERSION2) { /* Always shareable */ data16 = 1; subtlv_set(&p_tlvCred->nwKeyShareable, WPS_WFA_SUBID_NW_KEY_SHAREABLE, UINT2PTR(data16), 0); } tlv_credentialWrite(p_tlvCred, bufObj); /* Version2 */ if (info->version2 >= WPS_VERSION2) { if ((vendorExt_bufObj = buffobj_new()) == NULL) { TUTRACE((TUTRACE_NFC, "nfc_utils_build_cfg: Out of memory\n")); ret = WPS_ERR_OUTOFMEMORY; goto error; } subtlv_serialize(WPS_WFA_SUBID_VERSION2, vendorExt_bufObj, &info->version2, WPS_WFA_SUBID_VERSION2_S); /* Serialize subelemetns to Vendor Extension */ vendorExt.vendorId = (uint8 *)WFA_VENDOR_EXT_ID; vendorExt.vendorData = buffobj_GetBuf(vendorExt_bufObj); vendorExt.dataLength = buffobj_Length(vendorExt_bufObj); tlv_vendorExtWrite(&vendorExt, bufObj); } /* Check copy back avaliable buf length */ if (*buflen < buffobj_Length(bufObj)) { TUTRACE((TUTRACE_NFC, "nfc_utils_build_cfg: In buffer len too short\n")); ret = WPS_ERR_SYSTEM; goto error; } /* Copy back data and length */ *buflen = buffobj_Length(bufObj); memcpy(buf, buffobj_GetBuf(bufObj), buffobj_Length(bufObj)); error: /* Free local vendorExt_bufObj */ if (vendorExt_bufObj) buffobj_del(vendorExt_bufObj); /* Free local p_tlvCred */ if (p_tlvCred) tlv_credentialDelete(p_tlvCred, 0); /* Free local bufObj */ if (bufObj) buffobj_del(bufObj); return ret; }